Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 361668
b: refs/heads/master
c: 2ca067e
h: refs/heads/master
v: v3
  • Loading branch information
Oleg Nesterov authored and Linus Torvalds committed Mar 22, 2013
1 parent cbf01eb commit 62746be
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 26 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: d00285884c0892bb1310df96bce6056e9ce9b9d9
refs/heads/master: 2ca067efd82939dfd87827d29d36a265823a4c2f
57 changes: 32 additions & 25 deletions trunk/kernel/sys.c
Original file line number Diff line number Diff line change
Expand Up @@ -2185,9 +2185,8 @@ SYSCALL_DEFINE3(getcpu, unsigned __user *, cpup, unsigned __user *, nodep,

char poweroff_cmd[POWEROFF_CMD_PATH_LEN] = "/sbin/poweroff";

static int __orderly_poweroff(void)
static int __orderly_poweroff(bool force)
{
int argc;
char **argv;
static char *envp[] = {
"HOME=/",
Expand All @@ -2196,20 +2195,40 @@ static int __orderly_poweroff(void)
};
int ret;

argv = argv_split(GFP_ATOMIC, poweroff_cmd, &argc);
if (argv == NULL) {
argv = argv_split(GFP_KERNEL, poweroff_cmd, NULL);
if (argv) {
ret = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_EXEC);
argv_free(argv);
} else {
printk(KERN_WARNING "%s failed to allocate memory for \"%s\"\n",
__func__, poweroff_cmd);
return -ENOMEM;
__func__, poweroff_cmd);
ret = -ENOMEM;
}

ret = call_usermodehelper_fns(argv[0], argv, envp, UMH_WAIT_EXEC,
NULL, NULL, NULL);
argv_free(argv);
if (ret && force) {
printk(KERN_WARNING "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
* emergency shutdown?
*/
emergency_sync();
kernel_power_off();
}

return ret;
}

static bool poweroff_force;

static void poweroff_work_func(struct work_struct *work)
{
__orderly_poweroff(poweroff_force);
}

static DECLARE_WORK(poweroff_work, poweroff_work_func);

/**
* orderly_poweroff - Trigger an orderly system poweroff
* @force: force poweroff if command execution fails
Expand All @@ -2219,21 +2238,9 @@ static int __orderly_poweroff(void)
*/
int orderly_poweroff(bool force)
{
int ret = __orderly_poweroff();

if (ret && force) {
printk(KERN_WARNING "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
* emergency shutdown?
*/
emergency_sync();
kernel_power_off();
}

return ret;
if (force) /* do not override the pending "true" */
poweroff_force = true;
schedule_work(&poweroff_work);
return 0;
}
EXPORT_SYMBOL_GPL(orderly_poweroff);

0 comments on commit 62746be

Please sign in to comment.