Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/kern_shutdown.c
Show First 20 Lines • Show All 44 Lines • ▼ Show 20 Lines | |||||
#include "opt_panic.h" | #include "opt_panic.h" | ||||
#include "opt_printf.h" | #include "opt_printf.h" | ||||
#include "opt_sched.h" | #include "opt_sched.h" | ||||
#include "opt_watchdog.h" | #include "opt_watchdog.h" | ||||
#include <sys/param.h> | #include <sys/param.h> | ||||
#include <sys/systm.h> | #include <sys/systm.h> | ||||
#include <sys/bio.h> | #include <sys/bio.h> | ||||
#include <sys/boottrace.h> | |||||
#include <sys/buf.h> | #include <sys/buf.h> | ||||
#include <sys/conf.h> | #include <sys/conf.h> | ||||
#include <sys/compressor.h> | #include <sys/compressor.h> | ||||
#include <sys/cons.h> | #include <sys/cons.h> | ||||
#include <sys/disk.h> | #include <sys/disk.h> | ||||
#include <sys/eventhandler.h> | #include <sys/eventhandler.h> | ||||
#include <sys/filedesc.h> | #include <sys/filedesc.h> | ||||
#include <sys/jail.h> | #include <sys/jail.h> | ||||
▲ Show 20 Lines • Show All 257 Lines • ▼ Show 20 Lines | |||||
static void | static void | ||||
shutdown_nice_task_fn(void *arg, int pending __unused) | shutdown_nice_task_fn(void *arg, int pending __unused) | ||||
{ | { | ||||
int howto; | int howto; | ||||
howto = (uintptr_t)arg; | howto = (uintptr_t)arg; | ||||
/* Send a signal to init(8) and have it shutdown the world. */ | /* Send a signal to init(8) and have it shutdown the world. */ | ||||
PROC_LOCK(initproc); | PROC_LOCK(initproc); | ||||
if (howto & RB_POWEROFF) | if ((howto & RB_POWEROFF) != 0) { | ||||
BOOTTRACE("SIGUSR2 to init(8)"); | |||||
kern_psignal(initproc, SIGUSR2); | kern_psignal(initproc, SIGUSR2); | ||||
else if (howto & RB_POWERCYCLE) | } else if ((howto & RB_POWERCYCLE) != 0) { | ||||
BOOTTRACE("SIGWINCH to init(8)"); | |||||
kern_psignal(initproc, SIGWINCH); | kern_psignal(initproc, SIGWINCH); | ||||
else if (howto & RB_HALT) | } else if ((howto & RB_HALT) != 0) { | ||||
BOOTTRACE("SIGUSR1 to init(8)"); | |||||
kern_psignal(initproc, SIGUSR1); | kern_psignal(initproc, SIGUSR1); | ||||
else | } else { | ||||
BOOTTRACE("SIGINT to init(8)"); | |||||
kern_psignal(initproc, SIGINT); | kern_psignal(initproc, SIGINT); | ||||
} | |||||
PROC_UNLOCK(initproc); | PROC_UNLOCK(initproc); | ||||
} | } | ||||
static struct task shutdown_nice_task = TASK_INITIALIZER(0, | static struct task shutdown_nice_task = TASK_INITIALIZER(0, | ||||
&shutdown_nice_task_fn, NULL); | &shutdown_nice_task_fn, NULL); | ||||
/* | /* | ||||
* Called by events that want to shut down.. e.g <CTL><ALT><DEL> on a PC | * Called by events that want to shut down.. e.g <CTL><ALT><DEL> on a PC | ||||
*/ | */ | ||||
void | void | ||||
shutdown_nice(int howto) | shutdown_nice(int howto) | ||||
{ | { | ||||
if (initproc != NULL && !SCHEDULER_STOPPED()) { | if (initproc != NULL && !SCHEDULER_STOPPED()) { | ||||
BOOTTRACE("shutdown initiated"); | |||||
shutdown_nice_task.ta_context = (void *)(uintptr_t)howto; | shutdown_nice_task.ta_context = (void *)(uintptr_t)howto; | ||||
taskqueue_enqueue(taskqueue_fast, &shutdown_nice_task); | taskqueue_enqueue(taskqueue_fast, &shutdown_nice_task); | ||||
} else { | } else { | ||||
/* | /* | ||||
* No init(8) running, or scheduler would not allow it | * No init(8) running, or scheduler would not allow it | ||||
* to run, so simply reboot. | * to run, so simply reboot. | ||||
*/ | */ | ||||
kern_reboot(howto | RB_NOSYNC); | kern_reboot(howto | RB_NOSYNC); | ||||
▲ Show 20 Lines • Show All 60 Lines • ▼ Show 20 Lines | if (coredump) { | ||||
} | } | ||||
} | } | ||||
dumping--; | dumping--; | ||||
return (error); | return (error); | ||||
} | } | ||||
/* | /* | ||||
* Trace the shutdown reason. | |||||
*/ | |||||
static void | |||||
reboottrace(int howto) | |||||
{ | |||||
if ((howto & RB_DUMP) != 0) { | |||||
if ((howto & RB_HALT) != 0) | |||||
BOOTTRACE("system panic: halting..."); | |||||
if ((howto & RB_POWEROFF) != 0) | |||||
BOOTTRACE("system panic: powering off..."); | |||||
if ((howto & (RB_HALT|RB_POWEROFF)) == 0) | |||||
kevans: style(9): `!(flags)` -> `(flags) == 0` (and below) | |||||
BOOTTRACE("system panic: rebooting..."); | |||||
} else { | |||||
if ((howto & RB_HALT) != 0) | |||||
BOOTTRACE("system halting..."); | |||||
if ((howto & RB_POWEROFF) != 0) | |||||
BOOTTRACE("system powering off..."); | |||||
if ((howto & (RB_HALT|RB_POWEROFF)) == 0) | |||||
BOOTTRACE("system rebooting..."); | |||||
} | |||||
} | |||||
/* | |||||
* kern_reboot(9): Shut down the system cleanly to prepare for reboot, halt, or | * kern_reboot(9): Shut down the system cleanly to prepare for reboot, halt, or | ||||
* power off. | * power off. | ||||
*/ | */ | ||||
void | void | ||||
kern_reboot(int howto) | kern_reboot(int howto) | ||||
{ | { | ||||
static int once = 0; | static int once = 0; | ||||
if (initproc != NULL && curproc != initproc) | |||||
BOOTTRACE("kernel shutdown (dirty) started"); | |||||
else | |||||
BOOTTRACE("kernel shutdown (clean) started"); | |||||
/* | /* | ||||
* Normal paths here don't hold Giant, but we can wind up here | * Normal paths here don't hold Giant, but we can wind up here | ||||
* unexpectedly with it held. Drop it now so we don't have to | * unexpectedly with it held. Drop it now so we don't have to | ||||
* drop and pick it up elsewhere. The paths it is locking will | * drop and pick it up elsewhere. The paths it is locking will | ||||
* never be returned to, and it is preferable to preclude | * never be returned to, and it is preferable to preclude | ||||
* deadlock than to lock against code that won't ever | * deadlock than to lock against code that won't ever | ||||
* continue. | * continue. | ||||
*/ | */ | ||||
Show All 11 Lines | if (!SCHEDULER_STOPPED()) { | ||||
sched_bind(curthread, CPU_FIRST()); | sched_bind(curthread, CPU_FIRST()); | ||||
thread_unlock(curthread); | thread_unlock(curthread); | ||||
KASSERT(PCPU_GET(cpuid) == CPU_FIRST(), | KASSERT(PCPU_GET(cpuid) == CPU_FIRST(), | ||||
("%s: not running on cpu 0", __func__)); | ("%s: not running on cpu 0", __func__)); | ||||
} | } | ||||
#endif | #endif | ||||
/* We're in the process of rebooting. */ | /* We're in the process of rebooting. */ | ||||
rebooting = 1; | rebooting = 1; | ||||
reboottrace(howto); | |||||
/* We are out of the debugger now. */ | /* We are out of the debugger now. */ | ||||
kdb_active = 0; | kdb_active = 0; | ||||
/* | /* | ||||
* Do any callouts that should be done BEFORE syncing the filesystems. | * Do any callouts that should be done BEFORE syncing the filesystems. | ||||
*/ | */ | ||||
EVENTHANDLER_INVOKE(shutdown_pre_sync, howto); | EVENTHANDLER_INVOKE(shutdown_pre_sync, howto); | ||||
BOOTTRACE("shutdown pre sync complete"); | |||||
/* | /* | ||||
* Now sync filesystems | * Now sync filesystems | ||||
*/ | */ | ||||
if (!cold && (howto & RB_NOSYNC) == 0 && once == 0) { | if (!cold && (howto & RB_NOSYNC) == 0 && once == 0) { | ||||
once = 1; | once = 1; | ||||
BOOTTRACE("bufshutdown begin"); | |||||
bufshutdown(show_busybufs); | bufshutdown(show_busybufs); | ||||
BOOTTRACE("bufshutdown end"); | |||||
} | } | ||||
print_uptime(); | print_uptime(); | ||||
cngrab(); | cngrab(); | ||||
/* | /* | ||||
* Ok, now do things that assume all filesystem activity has | * Ok, now do things that assume all filesystem activity has | ||||
* been completed. | * been completed. | ||||
*/ | */ | ||||
EVENTHANDLER_INVOKE(shutdown_post_sync, howto); | EVENTHANDLER_INVOKE(shutdown_post_sync, howto); | ||||
BOOTTRACE("shutdown post sync complete"); | |||||
if ((howto & (RB_HALT|RB_DUMP)) == RB_DUMP && !cold && !dumping) | if ((howto & (RB_HALT|RB_DUMP)) == RB_DUMP && !cold && !dumping) | ||||
doadump(TRUE); | doadump(TRUE); | ||||
/* Now that we're going to really halt the system... */ | /* Now that we're going to really halt the system... */ | ||||
BOOTTRACE("shutdown final begin"); | |||||
if (shutdown_trace) | |||||
boottrace_dump_console(); | |||||
EVENTHANDLER_INVOKE(shutdown_final, howto); | EVENTHANDLER_INVOKE(shutdown_final, howto); | ||||
for(;;) ; /* safety against shutdown_reset not working */ | for(;;) ; /* safety against shutdown_reset not working */ | ||||
/* NOTREACHED */ | /* NOTREACHED */ | ||||
} | } | ||||
/* | /* | ||||
* The system call that results in changing the rootfs. | * The system call that results in changing the rootfs. | ||||
▲ Show 20 Lines • Show All 1,268 Lines • Show Last 20 Lines |
style(9): !(flags) -> (flags) == 0 (and below)