[PATCH] Refactor sys_reboot into reusable parts
authorEric W. Biederman <ebiederm@xmission.com>
Tue, 26 Jul 2005 17:24:14 +0000 (11:24 -0600)
committerLinus Torvalds <torvalds@g5.osdl.org>
Tue, 26 Jul 2005 21:35:41 +0000 (14:35 -0700)
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>
include/linux/reboot.h
kernel/sys.c

index 2d4dd23168dd2dac2470f3d169742cd297975bc2..828ba4f107d908473cf6005127b6ea1980b704ed 100644 (file)
@@ -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 */
index 5fc10d3e3891a41b65e65e4a1b636db77313cd32..7e033809ef5fdd5406803bb7f6abf5bbdbaf8a75 100644 (file)
@@ -361,6 +361,62 @@ out_unlock:
        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,
@@ -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:
@@ -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;
@@ -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:
                {