summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjonathan <jonathan@NetBSD.org>1997-12-04 09:05:35 +0000
committerjonathan <jonathan@NetBSD.org>1997-12-04 09:05:35 +0000
commitfc3fa7cd7f9ada81468dac9ffeef6876b1d659fd (patch)
tree2154eca635c07e317940c0d4344258148f6f8dd6
parent06c1873d83c358a3842bb28d80295ec8025857bb (diff)
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).
-rw-r--r--distrib/utils/sysinst/defs.h9
-rw-r--r--distrib/utils/sysinst/main.c18
-rw-r--r--distrib/utils/sysinst/menus.mi.eng4
-rw-r--r--distrib/utils/sysinst/menus.mi.fr4
-rw-r--r--distrib/utils/sysinst/target.c89
5 files changed, 112 insertions, 12 deletions
diff --git a/distrib/utils/sysinst/defs.h b/distrib/utils/sysinst/defs.h
index 61dfea89015..0dc893d2f9d 100644
--- a/distrib/utils/sysinst/defs.h
+++ b/distrib/utils/sysinst/defs.h
@@ -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));
diff --git a/distrib/utils/sysinst/main.c b/distrib/utils/sysinst/main.c
index e026069d85b..f7d5f409965 100644
--- a/distrib/utils/sysinst/main.c
+++ b/distrib/utils/sysinst/main.c
@@ -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
diff --git a/distrib/utils/sysinst/menus.mi.eng b/distrib/utils/sysinst/menus.mi.eng
index 851a646c032..9d9870360b3 100644
--- a/distrib/utils/sysinst/menus.mi.eng
+++ b/distrib/utils/sysinst/menus.mi.eng
@@ -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",
diff --git a/distrib/utils/sysinst/menus.mi.fr b/distrib/utils/sysinst/menus.mi.fr
index c0d54b6b1f4..1fe02e3f658 100644
--- a/distrib/utils/sysinst/menus.mi.fr
+++ b/distrib/utils/sysinst/menus.mi.fr
@@ -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",
diff --git a/distrib/utils/sysinst/target.c b/distrib/utils/sysinst/target.c
index 8dded6adcb7..4248ad449e1 100644
--- a/distrib/utils/sysinst/target.c
+++ b/distrib/utils/sysinst/target.c
@@ -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...
@@ -509,6 +528,64 @@ FILE* target_fopen (const char *filename, const char *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);
}