Module Name:    src
Committed By:   dyoung
Date:           Fri Jun 26 23:40:27 UTC 2009

Modified Files:
        src/sys/arch/i386/i386: machdep.c
        src/sys/arch/sparc64/sparc64: machdep.c

Log Message:
During a normal shutdown, gracefully tear down arbitrary stacks of
filesystems and (pseudo-)devices, according to the algorithm at A3
and A4, below.

Proposed and discussed at
<http://mail-index.netbsd.org/tech-kern/2009/04/20/msg004864.html>.  No
objections.

During an emergency shutdown (e.g., shutdown -n, or after a panic),
shutdown is simple as always: filesystems are not sync'd or unmounted,
and devices are not detached.

It was necessary to change the order of operations during shutdown,
but the new order is more sensible: if a core dump is desired, then
cpu_reboot(9) dumps it first.  cpu_reboot(9) does not call legacy
shutdown hooks any longer: they can interfere with device detachment
and PMF shutdown, and very few legacy hooks remain.

Here is the old order of operations:

B1 sync filesystems and TOD clock
B2 unmount filesystems
B3 dump core
B4 detach devices
B5 run legacy shutdown hooks
B6 run PMF shutdown hooks
B7 suspend interrupts
B8 MD reboot/shutdown/powerdown

And here is the new order:

A1 dump core
A2 sync filesystems and TOD clock
A3 unmount one or more filesystems OR
   detach one or more devices OR
   forcefully unmount one filesystem OR
   skip to 5
A4 repeat at 3
A5 run PMF shutdown hooks
A6 suspend interrupts
A7 MD reboot/shutdown/powerdown

Tested on Dell Dimension 3000, Dell PowerEdge 1950, Sun Fire V120,
Soekris net4521 and net4801.

VS: ----------------------------------------------------------------------


To generate a diff of this commit:
cvs rdiff -u -r1.668 -r1.669 src/sys/arch/i386/i386/machdep.c
cvs rdiff -u -r1.242 -r1.243 src/sys/arch/sparc64/sparc64/machdep.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/i386/i386/machdep.c
diff -u src/sys/arch/i386/i386/machdep.c:1.668 src/sys/arch/i386/i386/machdep.c:1.669
--- src/sys/arch/i386/i386/machdep.c:1.668	Wed Apr  1 03:56:54 2009
+++ src/sys/arch/i386/i386/machdep.c	Fri Jun 26 23:40:27 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: machdep.c,v 1.668 2009/04/01 03:56:54 tls Exp $	*/
+/*	$NetBSD: machdep.c,v 1.669 2009/06/26 23:40:27 dyoung Exp $	*/
 
 /*-
  * Copyright (c) 1996, 1997, 1998, 2000, 2004, 2006, 2008, 2009
@@ -67,7 +67,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.668 2009/04/01 03:56:54 tls Exp $");
+__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.669 2009/06/26 23:40:27 dyoung Exp $");
 
 #include "opt_beep.h"
 #include "opt_compat_ibcs2.h"
@@ -862,12 +862,28 @@
 	tf->tf_eflags &= ~(PSL_T|PSL_VM|PSL_AC);
 }
 
-int	waittime = -1;
+static void
+maybe_dump(int howto)
+{
+	int s;
+
+	/* Disable interrupts. */
+	s = splhigh();
+
+	/* Do a dump if requested. */
+	if ((howto & (RB_DUMP | RB_HALT)) == RB_DUMP)
+		dumpsys();
+
+	splx(s);
+}
 
 void
 cpu_reboot(int howto, char *bootstr)
 {
-	int s = 0;	/* XXX gcc */
+	static bool syncdone = false;
+	struct lwp *l;
+
+	l = (curlwp == NULL) ? &lwp0 : curlwp;
 
 	if (cold) {
 		howto |= RB_HALT;
@@ -875,34 +891,43 @@
 	}
 
 	boothowto = howto;
-	if ((howto & RB_NOSYNC) == 0 && waittime < 0) {
-		waittime = 0;
-		vfs_shutdown();
-		/*
-		 * If we've been adjusting the clock, the todr
-		 * will be out of synch; adjust it now.
-		 */
-		if (time_adjusted != 0)
-			resettodr();
-	}
 
-	/* Disable interrupts. */
-	s = splhigh();
-
-	/* Do a dump if requested. */
-	if ((howto & (RB_DUMP | RB_HALT)) == RB_DUMP)
-		dumpsys();
+	/* XXX used to dump after vfs_shutdown() and before
+	 * detaching devices / shutdown hooks / pmf_system_shutdown().
+	 */
+	maybe_dump(howto);
 
-haltsys:
-	doshutdownhooks();
+	/*
+	 * If we've panic'd, don't make the situation potentially
+	 * worse by syncing or unmounting the file systems.
+	 */
+	if ((howto & RB_NOSYNC) == 0 && panicstr == NULL) {
+		if (!syncdone) {
+			syncdone = true;
+			/* XXX used to force unmount as well, here */
+			vfs_sync_all(l);
+			/*
+			 * If we've been adjusting the clock, the todr
+			 * will be out of synch; adjust it now.
+			 *
+			 * XXX used to do this after unmounting all
+			 * filesystems with vfs_shutdown().
+			 */
+			if (time_adjusted != 0)
+				resettodr();
+		}
 
-	if (!cold) {
-		splx(s);
+		while (vfs_unmountall1(l, false, false) ||
+		       config_detach_all(boothowto) ||
+		       vfs_unmount_forceone(l))
+			;	/* do nothing */
+	} else
+		suspendsched();
 
-		pmf_system_shutdown(boothowto);
+	pmf_system_shutdown(boothowto);
 
-		splhigh();
-	}
+	splhigh();
+haltsys:
 
 	if ((howto & RB_POWERDOWN) == RB_POWERDOWN) {
 #ifdef XEN

Index: src/sys/arch/sparc64/sparc64/machdep.c
diff -u src/sys/arch/sparc64/sparc64/machdep.c:1.242 src/sys/arch/sparc64/sparc64/machdep.c:1.243
--- src/sys/arch/sparc64/sparc64/machdep.c:1.242	Thu May 21 08:13:43 2009
+++ src/sys/arch/sparc64/sparc64/machdep.c	Fri Jun 26 23:40:27 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: machdep.c,v 1.242 2009/05/21 08:13:43 jnemeth Exp $ */
+/*	$NetBSD: machdep.c,v 1.243 2009/06/26 23:40:27 dyoung Exp $ */
 
 /*-
  * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
@@ -71,7 +71,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.242 2009/05/21 08:13:43 jnemeth Exp $");
+__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.243 2009/06/26 23:40:27 dyoung Exp $");
 
 #include "opt_ddb.h"
 #include "opt_multiprocessor.h"
@@ -560,14 +560,31 @@
 
 struct pcb dumppcb;
 
+static void
+maybe_dump(int howto)
+{
+	int s;
+
+	/* Disable interrupts. */
+	s = splhigh();
+
+	/* Do a dump if requested. */
+	if ((howto & (RB_DUMP | RB_HALT)) == RB_DUMP)
+		dumpsys();
+
+	splx(s);
+}
+
 void
 cpu_reboot(int howto, char *user_boot_string)
 {
 	static bool syncdone = false;
 	int i;
 	static char str[128];
+	struct lwp *l;
+
+	l = (curlwp == NULL) ? &lwp0 : curlwp;
 
-	/* If system is cold, just halt. */
 	if (cold) {
 		howto |= RB_HALT;
 		goto haltsys;
@@ -577,34 +594,47 @@
 	fb_unblank();
 #endif
 	boothowto = howto;
+
+	/* If rebooting and a dump is requested, do it.
+	 *
+	 * XXX used to dump after vfs_shutdown() and before
+	 * detaching devices / shutdown hooks / pmf_system_shutdown().
+	 */
+	maybe_dump(howto);
+
 	if ((howto & RB_NOSYNC) == 0 && !syncdone) {
 		extern struct lwp lwp0;
 
-		/* XXX protect against curlwp->p_stats.foo refs in sync() */
-		if (curlwp == NULL)
-			curlwp = &lwp0;
+		if (!syncdone) {
 		syncdone = true;
 		vfs_shutdown();
+			/* XXX used to force unmount as well, here */
+			vfs_sync_all(l);
+			/*
+			 * If we've been adjusting the clock, the todr
+			 * will be out of synch; adjust it now.
+			 *
+			 * resettodr will only do this only if inittodr()
+			 * has already been called.
+			 *
+			 * XXX used to do this after unmounting all
+			 * filesystems with vfs_shutdown().
+			 */
+			resettodr();
+		}
 
-		/*
-		 * If we've been adjusting the clock, the todr
-		 * will be out of synch; adjust it now.
-		 * resettodr will only do this only if inittodr()
-		 * has already been called.
-		 */
-		resettodr();
-	}
-	(void) splhigh();		/* ??? */
+		while (vfs_unmountall1(l, false, false) ||
+		       config_detach_all(boothowto) ||
+		       vfs_unmount_forceone(l))
+			;	/* do nothing */
+	} else
+		suspendsched();
 
-	/* If rebooting and a dump is requested, do it. */
-	if (howto & RB_DUMP)
-		dumpsys();
+	pmf_system_shutdown(boothowto);
 
-haltsys:
-	/* Run any shutdown hooks. */
-	doshutdownhooks();
+	splhigh();
 
-	pmf_system_shutdown(boothowto);
+haltsys:
 
 #ifdef MULTIPROCESSOR
 	/* Stop all secondary cpus */

Reply via email to