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