Skip to content

Commit

Permalink
[PATCH] Refactor sys_reboot into reusable parts
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Eric W. Biederman authored and Linus Torvalds committed Jul 26, 2005
1 parent 47f61f3 commit 4a00ea1
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 42 deletions.
9 changes: 9 additions & 0 deletions include/linux/reboot.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,15 @@ extern void machine_shutdown(void);
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 /* _LINUX_REBOOT_H */
106 changes: 64 additions & 42 deletions kernel/sys.c
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,62 @@ asmlinkage long sys_getpriority(int which, int who)
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,
Expand Down Expand Up @@ -389,12 +445,7 @@ asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, void __user
lock_kernel();
switch (cmd) {
case LINUX_REBOOT_CMD_RESTART:
notifier_call_chain(&reboot_notifier_list, SYS_RESTART, NULL);
system_state = SYSTEM_RESTART;
device_suspend(PMSG_FREEZE);
device_shutdown();
printk(KERN_EMERG "Restarting system.\n");
machine_restart(NULL);
kernel_restart(NULL);
break;

case LINUX_REBOOT_CMD_CAD_ON:
Expand All @@ -406,23 +457,13 @@ asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, void __user
break;

case LINUX_REBOOT_CMD_HALT:
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();
kernel_halt();
unlock_kernel();
do_exit(0);
break;

case LINUX_REBOOT_CMD_POWER_OFF:
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();
kernel_power_off();
unlock_kernel();
do_exit(0);
break;
Expand All @@ -434,33 +475,14 @@ asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, void __user
}
buffer[sizeof(buffer) - 1] = '\0';

notifier_call_chain(&reboot_notifier_list, SYS_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);
kernel_restart(buffer);
break;

#ifdef CONFIG_KEXEC
case LINUX_REBOOT_CMD_KEXEC:
{
struct kimage *image;
image = xchg(&kexec_image, 0);
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
kernel_kexec();
unlock_kernel();
return -EINVAL;

#ifdef CONFIG_SOFTWARE_SUSPEND
case LINUX_REBOOT_CMD_SW_SUSPEND:
{
Expand Down

0 comments on commit 4a00ea1

Please sign in to comment.