Commit 7a54f46b authored by Joel Stanley's avatar Joel Stanley Committed by Linus Torvalds

kernel/reboot.c: add orderly_reboot for graceful reboot

The kernel has orderly_poweroff which allows the kernel to initiate a
graceful shutdown of userspace, by running /sbin/poweroff.  This adds
orderly_reboot that will cause userspace to shut itself down by calling

This will be used for shutdown initiated by a system controller on
platforms that do not use ACPI.

orderly_reboot() should be used when the system wants to allow userspace
to gracefully shut itself down.  For cases where the system may imminently
catch on fire, the existing emergency_restart() provides an immediate
reboot without involving userspace.
Signed-off-by: default avatarJoel Stanley <>
Cc: Fabian Frederick <>
Cc: Benjamin Herrenschmidt <>
Cc: Michael Ellerman <>
Cc: Rusty Russell <>
Cc: Jeremy Kerr <>
Cc: David S. Miller <>
Signed-off-by: default avatarAndrew Morton <>
Signed-off-by: default avatarLinus Torvalds <>
parent 7975a9b7
......@@ -70,7 +70,8 @@ void ctrl_alt_del(void);
extern char poweroff_cmd[POWEROFF_CMD_PATH_LEN];
extern int orderly_poweroff(bool force);
extern void orderly_poweroff(bool force);
extern void orderly_reboot(void);
* Emergency restart, callable from an interrupt handler.
......@@ -387,8 +387,9 @@ void ctrl_alt_del(void)
char poweroff_cmd[POWEROFF_CMD_PATH_LEN] = "/sbin/poweroff";
static const char reboot_cmd[] = "/sbin/reboot";
static int __orderly_poweroff(bool force)
static int run_cmd(const char *cmd)
char **argv;
static char *envp[] = {
......@@ -397,8 +398,7 @@ static int __orderly_poweroff(bool force)
int ret;
argv = argv_split(GFP_KERNEL, poweroff_cmd, NULL);
argv = argv_split(GFP_KERNEL, cmd, NULL);
if (argv) {
ret = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_EXEC);
......@@ -406,8 +406,33 @@ static int __orderly_poweroff(bool force)
ret = -ENOMEM;
return ret;
static int __orderly_reboot(void)
int ret;
ret = run_cmd(reboot_cmd);
if (ret) {
pr_warn("Failed to start orderly reboot: forcing the issue\n");
return ret;
static int __orderly_poweroff(bool force)
int ret;
ret = run_cmd(poweroff_cmd);
if (ret && force) {
pr_warn("Failed to start orderly shutdown: forcing the issue\n");
* I guess this should try to kick off some daemon to sync and
* poweroff asap. Or not even bother syncing if we're doing an
......@@ -436,15 +461,33 @@ static DECLARE_WORK(poweroff_work, poweroff_work_func);
* This may be called from any context to trigger a system shutdown.
* If the orderly shutdown fails, it will force an immediate shutdown.
int orderly_poweroff(bool force)
void orderly_poweroff(bool force)
if (force) /* do not override the pending "true" */
poweroff_force = true;
return 0;
static void reboot_work_func(struct work_struct *work)
static DECLARE_WORK(reboot_work, reboot_work_func);
* orderly_reboot - Trigger an orderly system reboot
* This may be called from any context to trigger a system reboot.
* If the orderly reboot fails, it will force an immediate reboot.
void orderly_reboot(void)
static int __init reboot_setup(char *str)
for (;;) {
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment