Index: sys/kern/kern_shutdown.c =================================================================== --- sys/kern/kern_shutdown.c +++ sys/kern/kern_shutdown.c @@ -427,7 +427,14 @@ void kern_reboot(int howto) { - static int once = 0; + static enum { + do_pre_sync, + do_sync, + do_uptime, + do_post_sync, + do_dump, + do_shutdown, + } progress = do_pre_sync; /* * Normal paths here don't hold Giant, but we can wind up here @@ -463,33 +470,65 @@ /* * Do any callouts that should be done BEFORE syncing the filesystems. */ - EVENTHANDLER_INVOKE(shutdown_pre_sync, howto); + if (progress == do_pre_sync) { + atomic_fetchadd_int(&progress, 1); + EVENTHANDLER_INVOKE(shutdown_pre_sync, howto); + } /* * Now sync filesystems */ - if (!cold && (howto & RB_NOSYNC) == 0 && once == 0) { - once = 1; - bufshutdown(show_busybufs); + if (progress == do_sync) { + atomic_fetchadd_int(&progress, 1); + if (!cold && (howto & RB_NOSYNC) == 0) { + bufshutdown(show_busybufs); + } } - print_uptime(); + /* + * Report uptime and grab the console + */ + if (progress == do_uptime) { + atomic_fetchadd_int(&progress, 1); - cngrab(); + print_uptime(); + cngrab(); + } /* * Ok, now do things that assume all filesystem activity has * been completed. */ - EVENTHANDLER_INVOKE(shutdown_post_sync, howto); + if (progress == do_post_sync) { + atomic_fetchadd_int(&progress, 1); + EVENTHANDLER_INVOKE(shutdown_post_sync, howto); + } - if ((howto & (RB_HALT|RB_DUMP)) == RB_DUMP && !cold && !dumping) - doadump(TRUE); + /* + * Try to do a dump, if appropriate. + */ + if (progress == do_dump) { + atomic_fetchadd_int(&progress, 1); - /* Now that we're going to really halt the system... */ - EVENTHANDLER_INVOKE(shutdown_final, howto); + if ((howto & (RB_HALT | RB_DUMP)) == RB_DUMP && + !cold && !dumping) + doadump(TRUE); + } + + /* + * Let's give the 'nice ways' of shutting down the system a shot + */ + if (progress == do_shutdown) { + atomic_fetchadd_int(&progress, 1); - for(;;) ; /* safety against shutdown_reset not working */ + EVENTHANDLER_INVOKE(shutdown_final, howto); + } + + /* + * And if all else fails, tight loop... Though one of the final handlers + * should have already reset or shut down. + */ + for(;;) ; /* NOTREACHED */ }