aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2005-07-26 13:24:14 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-07-26 17:35:41 -0400
commit4a00ea1e18228e5ef99d4780671fda97226bda30 (patch)
treed77c793ef68df78b3c9a73eab16438732f875c3c
parent47f61f397cc08b5a9a815bd03cb10c48dab66034 (diff)
[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>
-rw-r--r--include/linux/reboot.h9
-rw-r--r--kernel/sys.c106
2 files changed, 73 insertions, 42 deletions
diff --git a/include/linux/reboot.h b/include/linux/reboot.h
index 2d4dd23168dd..828ba4f107d9 100644
--- a/include/linux/reboot.h
+++ b/include/linux/reboot.h
@@ -55,6 +55,15 @@ extern void machine_shutdown(void);
55struct pt_regs; 55struct pt_regs;
56extern void machine_crash_shutdown(struct pt_regs *); 56extern void machine_crash_shutdown(struct pt_regs *);
57 57
58/*
59 * Architecture independent implemenations of sys_reboot commands.
60 */
61
62extern void kernel_restart(char *cmd);
63extern void kernel_halt(void);
64extern void kernel_power_off(void);
65extern void kernel_kexec(void);
66
58#endif 67#endif
59 68
60#endif /* _LINUX_REBOOT_H */ 69#endif /* _LINUX_REBOOT_H */
diff --git a/kernel/sys.c b/kernel/sys.c
index 5fc10d3e3891..7e033809ef5f 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -361,6 +361,62 @@ out_unlock:
361 return retval; 361 return retval;
362} 362}
363 363
364void kernel_restart(char *cmd)
365{
366 notifier_call_chain(&reboot_notifier_list, SYS_RESTART, cmd);
367 system_state = SYSTEM_RESTART;
368 device_suspend(PMSG_FREEZE);
369 device_shutdown();
370 if (!cmd) {
371 printk(KERN_EMERG "Restarting system.\n");
372 } else {
373 printk(KERN_EMERG "Restarting system with command '%s'.\n", cmd);
374 }
375 printk(".\n");
376 machine_restart(cmd);
377}
378EXPORT_SYMBOL_GPL(kernel_restart);
379
380void kernel_kexec(void)
381{
382#ifdef CONFIG_KEXEC
383 struct kimage *image;
384 image = xchg(&kexec_image, 0);
385 if (!image) {
386 return;
387 }
388 notifier_call_chain(&reboot_notifier_list, SYS_RESTART, NULL);
389 system_state = SYSTEM_RESTART;
390 device_suspend(PMSG_FREEZE);
391 device_shutdown();
392 printk(KERN_EMERG "Starting new kernel\n");
393 machine_shutdown();
394 machine_kexec(image);
395#endif
396}
397EXPORT_SYMBOL_GPL(kernel_kexec);
398
399void kernel_halt(void)
400{
401 notifier_call_chain(&reboot_notifier_list, SYS_HALT, NULL);
402 system_state = SYSTEM_HALT;
403 device_suspend(PMSG_SUSPEND);
404 device_shutdown();
405 printk(KERN_EMERG "System halted.\n");
406 machine_halt();
407}
408EXPORT_SYMBOL_GPL(kernel_halt);
409
410void kernel_power_off(void)
411{
412 notifier_call_chain(&reboot_notifier_list, SYS_POWER_OFF, NULL);
413 system_state = SYSTEM_POWER_OFF;
414 device_suspend(PMSG_SUSPEND);
415 device_shutdown();
416 printk(KERN_EMERG "Power down.\n");
417 machine_power_off();
418}
419EXPORT_SYMBOL_GPL(kernel_power_off);
364 420
365/* 421/*
366 * Reboot system call: for obvious reasons only root may call it, 422 * 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
389 lock_kernel(); 445 lock_kernel();
390 switch (cmd) { 446 switch (cmd) {
391 case LINUX_REBOOT_CMD_RESTART: 447 case LINUX_REBOOT_CMD_RESTART:
392 notifier_call_chain(&reboot_notifier_list, SYS_RESTART, NULL); 448 kernel_restart(NULL);
393 system_state = SYSTEM_RESTART;
394 device_suspend(PMSG_FREEZE);
395 device_shutdown();
396 printk(KERN_EMERG "Restarting system.\n");
397 machine_restart(NULL);
398 break; 449 break;
399 450
400 case LINUX_REBOOT_CMD_CAD_ON: 451 case LINUX_REBOOT_CMD_CAD_ON:
@@ -406,23 +457,13 @@ asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, void __user
406 break; 457 break;
407 458
408 case LINUX_REBOOT_CMD_HALT: 459 case LINUX_REBOOT_CMD_HALT:
409 notifier_call_chain(&reboot_notifier_list, SYS_HALT, NULL); 460 kernel_halt();
410 system_state = SYSTEM_HALT;
411 device_suspend(PMSG_SUSPEND);
412 device_shutdown();
413 printk(KERN_EMERG "System halted.\n");
414 machine_halt();
415 unlock_kernel(); 461 unlock_kernel();
416 do_exit(0); 462 do_exit(0);
417 break; 463 break;
418 464
419 case LINUX_REBOOT_CMD_POWER_OFF: 465 case LINUX_REBOOT_CMD_POWER_OFF:
420 notifier_call_chain(&reboot_notifier_list, SYS_POWER_OFF, NULL); 466 kernel_power_off();
421 system_state = SYSTEM_POWER_OFF;
422 device_suspend(PMSG_SUSPEND);
423 device_shutdown();
424 printk(KERN_EMERG "Power down.\n");
425 machine_power_off();
426 unlock_kernel(); 467 unlock_kernel();
427 do_exit(0); 468 do_exit(0);
428 break; 469 break;
@@ -434,33 +475,14 @@ asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, void __user
434 } 475 }
435 buffer[sizeof(buffer) - 1] = '\0'; 476 buffer[sizeof(buffer) - 1] = '\0';
436 477
437 notifier_call_chain(&reboot_notifier_list, SYS_RESTART, buffer); 478 kernel_restart(buffer);
438 system_state = SYSTEM_RESTART;
439 device_suspend(PMSG_FREEZE);
440 device_shutdown();
441 printk(KERN_EMERG "Restarting system with command '%s'.\n", buffer);
442 machine_restart(buffer);
443 break; 479 break;
444 480
445#ifdef CONFIG_KEXEC
446 case LINUX_REBOOT_CMD_KEXEC: 481 case LINUX_REBOOT_CMD_KEXEC:
447 { 482 kernel_kexec();
448 struct kimage *image; 483 unlock_kernel();
449 image = xchg(&kexec_image, 0); 484 return -EINVAL;
450 if (!image) { 485
451 unlock_kernel();
452 return -EINVAL;
453 }
454 notifier_call_chain(&reboot_notifier_list, SYS_RESTART, NULL);
455 system_state = SYSTEM_RESTART;
456 device_suspend(PMSG_FREEZE);
457 device_shutdown();
458 printk(KERN_EMERG "Starting new kernel\n");
459 machine_shutdown();
460 machine_kexec(image);
461 break;
462 }
463#endif
464#ifdef CONFIG_SOFTWARE_SUSPEND 486#ifdef CONFIG_SOFTWARE_SUSPEND
465 case LINUX_REBOOT_CMD_SW_SUSPEND: 487 case LINUX_REBOOT_CMD_SW_SUSPEND:
466 { 488 {