Index: sys/kern/kern_shutdown.c =================================================================== --- sys/kern/kern_shutdown.c +++ sys/kern/kern_shutdown.c @@ -426,7 +426,7 @@ void kern_reboot(int howto) { - static int once = 0; + static int progress = 0; /* * Normal paths here don't hold Giant, but we can wind up here @@ -462,33 +462,64 @@ /* * Do any callouts that should be done BEFORE syncing the filesystems. */ - EVENTHANDLER_INVOKE(shutdown_pre_sync, howto); + if (progress == 0) { + progress++; + EVENTHANDLER_INVOKE(shutdown_pre_sync, howto); + } /* * Now sync filesystems */ - if (!cold && (howto & RB_NOSYNC) == 0 && once == 0) { - once = 1; - bufshutdown(show_busybufs); + if (progress == 1) { + progress++; + if (!cold && (howto & RB_NOSYNC) == 0) { + bufshutdown(show_busybufs); + } } - print_uptime(); + /* + * Report uptime and grab the console + */ + if (progress == 2) { + progress++; - cngrab(); + print_uptime(); + cngrab(); + } /* * Ok, now do things that assume all filesystem activity has * been completed. */ - EVENTHANDLER_INVOKE(shutdown_post_sync, howto); + if (progress == 3) { + progress++; + 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 == 4) { + progress++; - /* 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 == 5) { + progress++; - 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 */ }