[PATCH] Refactor sys_reboot into reusable parts
Because the factors of sys_reboot don't exist people calling into the reboot path duplicate the code badly, leading to inconsistent expectations of code in the reboot path. This patch should is just code motion. Signed-off-by: Eric W. Biederman <ebiederm@xmission.com> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
parent
47f61f397c
commit
4a00ea1e18
2 changed files with 73 additions and 42 deletions
|
@ -55,6 +55,15 @@ extern void machine_shutdown(void);
|
||||||
struct pt_regs;
|
struct pt_regs;
|
||||||
extern void machine_crash_shutdown(struct pt_regs *);
|
extern void machine_crash_shutdown(struct pt_regs *);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Architecture independent implemenations of sys_reboot commands.
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern void kernel_restart(char *cmd);
|
||||||
|
extern void kernel_halt(void);
|
||||||
|
extern void kernel_power_off(void);
|
||||||
|
extern void kernel_kexec(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* _LINUX_REBOOT_H */
|
#endif /* _LINUX_REBOOT_H */
|
||||||
|
|
106
kernel/sys.c
106
kernel/sys.c
|
@ -361,6 +361,62 @@ asmlinkage long sys_getpriority(int which, int who)
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void kernel_restart(char *cmd)
|
||||||
|
{
|
||||||
|
notifier_call_chain(&reboot_notifier_list, SYS_RESTART, cmd);
|
||||||
|
system_state = SYSTEM_RESTART;
|
||||||
|
device_suspend(PMSG_FREEZE);
|
||||||
|
device_shutdown();
|
||||||
|
if (!cmd) {
|
||||||
|
printk(KERN_EMERG "Restarting system.\n");
|
||||||
|
} else {
|
||||||
|
printk(KERN_EMERG "Restarting system with command '%s'.\n", cmd);
|
||||||
|
}
|
||||||
|
printk(".\n");
|
||||||
|
machine_restart(cmd);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(kernel_restart);
|
||||||
|
|
||||||
|
void kernel_kexec(void)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_KEXEC
|
||||||
|
struct kimage *image;
|
||||||
|
image = xchg(&kexec_image, 0);
|
||||||
|
if (!image) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
notifier_call_chain(&reboot_notifier_list, SYS_RESTART, NULL);
|
||||||
|
system_state = SYSTEM_RESTART;
|
||||||
|
device_suspend(PMSG_FREEZE);
|
||||||
|
device_shutdown();
|
||||||
|
printk(KERN_EMERG "Starting new kernel\n");
|
||||||
|
machine_shutdown();
|
||||||
|
machine_kexec(image);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(kernel_kexec);
|
||||||
|
|
||||||
|
void kernel_halt(void)
|
||||||
|
{
|
||||||
|
notifier_call_chain(&reboot_notifier_list, SYS_HALT, NULL);
|
||||||
|
system_state = SYSTEM_HALT;
|
||||||
|
device_suspend(PMSG_SUSPEND);
|
||||||
|
device_shutdown();
|
||||||
|
printk(KERN_EMERG "System halted.\n");
|
||||||
|
machine_halt();
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(kernel_halt);
|
||||||
|
|
||||||
|
void kernel_power_off(void)
|
||||||
|
{
|
||||||
|
notifier_call_chain(&reboot_notifier_list, SYS_POWER_OFF, NULL);
|
||||||
|
system_state = SYSTEM_POWER_OFF;
|
||||||
|
device_suspend(PMSG_SUSPEND);
|
||||||
|
device_shutdown();
|
||||||
|
printk(KERN_EMERG "Power down.\n");
|
||||||
|
machine_power_off();
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(kernel_power_off);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Reboot system call: for obvious reasons only root may call it,
|
* Reboot system call: for obvious reasons only root may call it,
|
||||||
|
@ -389,12 +445,7 @@ asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, void __user
|
||||||
lock_kernel();
|
lock_kernel();
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case LINUX_REBOOT_CMD_RESTART:
|
case LINUX_REBOOT_CMD_RESTART:
|
||||||
notifier_call_chain(&reboot_notifier_list, SYS_RESTART, NULL);
|
kernel_restart(NULL);
|
||||||
system_state = SYSTEM_RESTART;
|
|
||||||
device_suspend(PMSG_FREEZE);
|
|
||||||
device_shutdown();
|
|
||||||
printk(KERN_EMERG "Restarting system.\n");
|
|
||||||
machine_restart(NULL);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LINUX_REBOOT_CMD_CAD_ON:
|
case LINUX_REBOOT_CMD_CAD_ON:
|
||||||
|
@ -406,23 +457,13 @@ asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, void __user
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LINUX_REBOOT_CMD_HALT:
|
case LINUX_REBOOT_CMD_HALT:
|
||||||
notifier_call_chain(&reboot_notifier_list, SYS_HALT, NULL);
|
kernel_halt();
|
||||||
system_state = SYSTEM_HALT;
|
|
||||||
device_suspend(PMSG_SUSPEND);
|
|
||||||
device_shutdown();
|
|
||||||
printk(KERN_EMERG "System halted.\n");
|
|
||||||
machine_halt();
|
|
||||||
unlock_kernel();
|
unlock_kernel();
|
||||||
do_exit(0);
|
do_exit(0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LINUX_REBOOT_CMD_POWER_OFF:
|
case LINUX_REBOOT_CMD_POWER_OFF:
|
||||||
notifier_call_chain(&reboot_notifier_list, SYS_POWER_OFF, NULL);
|
kernel_power_off();
|
||||||
system_state = SYSTEM_POWER_OFF;
|
|
||||||
device_suspend(PMSG_SUSPEND);
|
|
||||||
device_shutdown();
|
|
||||||
printk(KERN_EMERG "Power down.\n");
|
|
||||||
machine_power_off();
|
|
||||||
unlock_kernel();
|
unlock_kernel();
|
||||||
do_exit(0);
|
do_exit(0);
|
||||||
break;
|
break;
|
||||||
|
@ -434,33 +475,14 @@ asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, void __user
|
||||||
}
|
}
|
||||||
buffer[sizeof(buffer) - 1] = '\0';
|
buffer[sizeof(buffer) - 1] = '\0';
|
||||||
|
|
||||||
notifier_call_chain(&reboot_notifier_list, SYS_RESTART, buffer);
|
kernel_restart(buffer);
|
||||||
system_state = SYSTEM_RESTART;
|
|
||||||
device_suspend(PMSG_FREEZE);
|
|
||||||
device_shutdown();
|
|
||||||
printk(KERN_EMERG "Restarting system with command '%s'.\n", buffer);
|
|
||||||
machine_restart(buffer);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#ifdef CONFIG_KEXEC
|
|
||||||
case LINUX_REBOOT_CMD_KEXEC:
|
case LINUX_REBOOT_CMD_KEXEC:
|
||||||
{
|
kernel_kexec();
|
||||||
struct kimage *image;
|
unlock_kernel();
|
||||||
image = xchg(&kexec_image, 0);
|
return -EINVAL;
|
||||||
if (!image) {
|
|
||||||
unlock_kernel();
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
notifier_call_chain(&reboot_notifier_list, SYS_RESTART, NULL);
|
|
||||||
system_state = SYSTEM_RESTART;
|
|
||||||
device_suspend(PMSG_FREEZE);
|
|
||||||
device_shutdown();
|
|
||||||
printk(KERN_EMERG "Starting new kernel\n");
|
|
||||||
machine_shutdown();
|
|
||||||
machine_kexec(image);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef CONFIG_SOFTWARE_SUSPEND
|
#ifdef CONFIG_SOFTWARE_SUSPEND
|
||||||
case LINUX_REBOOT_CMD_SW_SUSPEND:
|
case LINUX_REBOOT_CMD_SW_SUSPEND:
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue