Implement TODO item to unwind target mounts on completion:

* Add mount_with_unwind() that adds mountpoint to a LIFO queue
    of  mountpoints to undo on error.   Use in target_mount().
  * Add unwind_mounts() which traverses the LIFO queue and unmounts
    filesystems, silently ignoring errors.
  * create toplevel() function which displays banner message and
    calls unwind_mounts().
  * change toplevel menu to call toplevel() instead of inline banner.

Where to do unwinds needs more thought.  Perhaps we should only unwind
if an upgrade or install appears unsuccessful, so after a successful
install, the target is mounted (e.g., for upgrading /etc/rc.conf).
This commit is contained in:
jonathan 1997-12-04 09:05:35 +00:00
parent 06c1873d83
commit fc3fa7cd7f
5 changed files with 112 additions and 12 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: defs.h,v 1.22 1997/11/25 06:53:07 thorpej Exp $ */
/* $NetBSD: defs.h,v 1.23 1997/12/04 09:05:38 jonathan Exp $ */
/*
* Copyright 1997 Piermont Information Systems Inc.
@ -139,7 +139,8 @@ enum DLTR {A,B,C,D,E,F,G,H};
EXTERN char partname[] INIT("abcdefgh");
EXTERN int bsdlabel[16][5];
EXTERN char fsmount[16][20] INIT({""});
EXTERN char bsddiskname[80];
#define DISKNAME_SIZE 80
EXTERN char bsddiskname[DISKNAME_SIZE];
EXTERN char *doessf INIT("");
/* scsi_fake communication */
@ -203,6 +204,9 @@ void md_copy_filesystem __P((void));
void md_make_bsd_partitions __P((void));
int md_update __P((void));
/* from main.c */
void toplevel __P((void));
/* from disks.c */
int find_disks __P((void));
void disp_cur_part __P((int,int));
@ -278,3 +282,4 @@ int target_mount __P((const char *fstype, const char *from, const char* on));
int target_test __P((const char*, const char*));
int target_verify_dir __P((const char *path));
int target_verify_file __P((const char *path));
void unwind_mounts __P((void));

View File

@ -1,4 +1,4 @@
/* $NetBSD: main.c,v 1.6 1997/11/25 06:53:10 thorpej Exp $ */
/* $NetBSD: main.c,v 1.7 1997/12/04 09:05:35 jonathan Exp $ */
/*
* Copyright 1997 Piermont Information Systems Inc.
@ -92,6 +92,22 @@ int main(int argc, char **argv)
}
/* toplevel menu handler ... */
void toplevel(void)
{
/* Display banner message in (english, francais, deutche..) */
msg_display (MSG_hello);
/*
* Undo any stateful side-effects of previous menu choices.
* XXX must be idempotent, since we get run each time the main
* menu is displayed.
*/
unwind_mounts();
/* ... */
}
/* The usage ... */
void

View File

@ -1,4 +1,4 @@
/* $NetBSD: menus.mi.eng,v 1.14 1997/11/25 20:35:02 phil Exp $ */
/* $NetBSD: menus.mi.eng,v 1.15 1997/12/04 09:05:37 jonathan Exp $ */
/*
* Copyright 1997 Piermont Information Systems Inc.
@ -58,7 +58,7 @@
default x=20, y=12, no exit;
menu netbsd, title " NetBSD-@@VERSION@@ Install System";
display action { msg_display (MSG_hello); };
display action { toplevel(); };
option "Install NetBSD to hard disk",
action { do_install(); };
option "Upgrade NetBSD on a hard disk",

View File

@ -1,4 +1,4 @@
/* $NetBSD: menus.mi.fr,v 1.1 1997/11/27 10:10:05 bouyer Exp $ */
/* $NetBSD: menus.mi.fr,v 1.2 1997/12/04 09:05:36 jonathan Exp $ */
/*
* Copyright 1997 Piermont Information Systems Inc.
@ -58,7 +58,7 @@
default x=20, y=12, no exit;
menu netbsd, title " NetBSD-@@VERSION@@ Programme d'installation";
display action { msg_display (MSG_hello); };
display action { toplevel(); };
option "Installation de NetBSD sur disque dur",
action { do_install(); };
option "Mise à jour de NetBSD sur disque dur",

View File

@ -1,4 +1,4 @@
/* $NetBSD: target.c,v 1.12 1997/12/02 03:02:29 jonathan Exp $ */
/* $NetBSD: target.c,v 1.13 1997/12/04 09:05:35 jonathan Exp $ */
/*
* Copyright 1997 Jonathan Stone
@ -37,7 +37,7 @@
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: target.c,v 1.12 1997/12/02 03:02:29 jonathan Exp $");
__RCSID("$NetBSD: target.c,v 1.13 1997/12/04 09:05:35 jonathan Exp $");
#endif
@ -83,8 +83,27 @@ int target_test(const char *test, const char *path);
void backtowin(void);
/* turn on what-is-root? debugging. */
/*#define DEBUG_ROOT*/
void unwind_mounts __P((void));
int mount_with_unwind(const char *fstype, const char *from, const char *on);
/* Record a mount for later unwinding of target mounts. */
struct unwind_mount {
struct unwind_mount *um_prev;
char um_mountpoint[STRSIZE];
};
/* Unwind-mount stack */
struct unwind_mount *unwind_mountlist = NULL;
/*
* Debugging options
*/
/*#define DEBUG_ROOT*/ /* turn on what-is-root? debugging. */
/*#define DEBUG_UNWIND*/ /* turn on unwind-target-mount debugging. */
/*
* debugging helper. curses...
@ -508,6 +527,64 @@ FILE* target_fopen (const char *filename, const char *type)
return fopen(target_expand(filename), type);
}
/*
* Do a mount and record the mountpoint in a list of mounts to
* unwind after completing or aborting a mount.
*/
int
mount_with_unwind(const char *fstype, const char *from, const char *on)
{
int error;
struct unwind_mount * m;
m = malloc(sizeof(*m));
if (m == 0)
return (ENOMEM); /* XXX */
strncpy(m->um_mountpoint, on, STRSIZE);
m->um_prev = unwind_mountlist;
unwind_mountlist = m;
#ifdef DEBUG_UNWIND
endwin();
fprintf(stderr, "mounting %s with unwind\n", on);
backtowin();
#endif
error = run_prog("/sbin/mount %s %s %s", fstype, from, on);
return (error);
}
/*
* unwind the mount stack, umounting mounted filesystems.
* For now, ignore any errors in unmount.
* (Why would we be unable to unmount? The user has suspended
* us and forked shell sitting somewhere in the target root?)
*/
void
unwind_mounts()
{
struct unwind_mount *m, *prev;
prev = NULL;
for (m = unwind_mountlist; m; ) {
struct unwind_mount *prev;
#ifdef DEBUG_UNWIND
endwin();
fprintf(stderr, "unmounting %s\n", m->um_mountpoint);
backtowin();
#endif
run_prog("/sbin/umount %s 2>/dev/null", m->um_mountpoint);
prev = m->um_prev;
free(m);
m = prev;
}
unwind_mountlist = NULL;
}
/*
* Do a mount onto a moutpoint in the install target.
* NB: does not prefix mount-from, which probably breaks nullfs mounts.
@ -517,7 +594,9 @@ int target_mount(const char *fstype, const char *from, const char *on)
int error;
const char *realmount = target_expand(on);
error = run_prog("/sbin/mount %s %s %s", fstype, from, realmount);
/* mount and record for unmonting when done. */
error = mount_with_unwind(fstype, from, realmount);
return (error);
}