Module Name:    src
Committed By:   dyoung
Date:           Fri Apr 17 20:45:09 UTC 2009

Modified Files:
        src/sys/kern: kern_pmf.c

Log Message:
Do not interleave device detachment with device shutdown.  Instead, try
over and over to detach all of the devices.  Stop when we cannot detach
even a single device in a cycle.  Call shutdown hooks on all of the
devices that remain attached.

This is another step toward the detach/unmount cycle that will help us
tear down arbitrary stacks of filesystems, ccd(4), raid(4), and vnd(4).


To generate a diff of this commit:
cvs rdiff -u -r1.25 -r1.26 src/sys/kern/kern_pmf.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/kern/kern_pmf.c
diff -u src/sys/kern/kern_pmf.c:1.25 src/sys/kern/kern_pmf.c:1.26
--- src/sys/kern/kern_pmf.c:1.25	Thu Apr 16 07:47:16 2009
+++ src/sys/kern/kern_pmf.c	Fri Apr 17 20:45:09 2009
@@ -1,4 +1,4 @@
-/* $NetBSD: kern_pmf.c,v 1.25 2009/04/16 07:47:16 skrll Exp $ */
+/* $NetBSD: kern_pmf.c,v 1.26 2009/04/17 20:45:09 dyoung Exp $ */
 
 /*-
  * Copyright (c) 2007 Jared D. McNeill <jmcne...@invisible.ca>
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_pmf.c,v 1.25 2009/04/16 07:47:16 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_pmf.c,v 1.26 2009/04/17 20:45:09 dyoung Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -288,37 +288,72 @@
 	while ((dv = deviter_next(&s->di)) != NULL && !device_is_active(dv))
 		;
 
+	if (dv == NULL)
+		s->initialized = false;
+
 	return dv;
 }
 
-void
-pmf_system_shutdown(int how)
+static bool
+detach_all(int how)
 {
 	static struct shutdown_state s;
 	device_t curdev;
+	bool progress = false;
 
-	aprint_debug("Shutting down devices:");
-	suspendsched();
+	if ((how & RB_NOSYNC) != 0)
+		return false;
+
+	for (curdev = shutdown_first(&s); curdev != NULL;
+	     curdev = shutdown_next(&s)) {
+		aprint_debug(" detaching %s, ", device_xname(curdev));
+		if (config_detach(curdev, DETACH_SHUTDOWN) == 0) {
+			progress = true;
+			aprint_debug("success.");
+		} else
+			aprint_debug("failed.");
+	}
+	return progress;
+}
+
+static bool
+shutdown_all(int how)
+{
+	static struct shutdown_state s;
+	device_t curdev;
+	bool progress = false;
 
 	for (curdev = shutdown_first(&s); curdev != NULL;
 	     curdev = shutdown_next(&s)) {
-		aprint_debug(" attempting %s shutdown", device_xname(curdev));
-		if ((boothowto & RB_NOSYNC) == 0 &&
-		    config_detach(curdev, DETACH_SHUTDOWN) == 0)
-			aprint_debug("(detached)");
-		else if (!device_pmf_is_registered(curdev))
-			aprint_debug("(skipped)");
+		aprint_debug(" shutting down %s, ", device_xname(curdev));
+		if (!device_pmf_is_registered(curdev))
+			aprint_debug("skipped.");
 #if 0 /* needed? */
 		else if (!device_pmf_class_shutdown(curdev, how))
-			aprint_debug("(failed)");
+			aprint_debug("failed.");
 #endif
 		else if (!device_pmf_driver_shutdown(curdev, how))
-			aprint_debug("(failed)");
+			aprint_debug("failed.");
 		else if (!device_pmf_bus_shutdown(curdev, how))
-			aprint_debug("(failed)");
+			aprint_debug("failed.");
+		else {
+			progress = true;
+			aprint_debug("success.");
+		}
 	}
+	return progress;
+}
 
-	aprint_debug(".\n");
+void
+pmf_system_shutdown(int how)
+{
+	aprint_debug("Shutting down devices:");
+	suspendsched();
+
+	while (detach_all(how))
+		;
+
+	shutdown_all(how);
 }
 
 bool

Reply via email to