patch-2.1.30 linux/kernel/sys.c
Next file: linux/kernel/time.c
Previous file: linux/kernel/softirq.c
Back to the patch index
Back to the overall index
- Lines: 174
- Date:
Thu Mar 20 17:27:37 1997
- Orig file:
v2.1.29/linux/kernel/sys.c
- Orig date:
Tue Feb 4 06:44:25 1997
diff -u --recursive --new-file v2.1.29/linux/kernel/sys.c linux/kernel/sys.c
@@ -4,7 +4,6 @@
* Copyright (C) 1991, 1992 Linus Torvalds
*/
-#include <linux/config.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/kernel.h>
@@ -23,10 +22,8 @@
#include <linux/tty.h>
#include <linux/smp.h>
#include <linux/smp_lock.h>
-#if defined(CONFIG_APM) && defined(CONFIG_APM_POWER_OFF)
-#include <linux/apm_bios.h>
-#endif
#include <linux/notifier.h>
+#include <linux/reboot.h>
#include <asm/uaccess.h>
#include <asm/io.h>
@@ -37,12 +34,26 @@
int C_A_D = 1;
+
/*
- * List of functions to call at shutdown. This is used to stop any
- * idling DMA operations and the like.
+ * Notifier list for kernel code which wants to be called
+ * at shutdown. This is used to stop any idling DMA operations
+ * and the like.
*/
-
-struct notifier_block *boot_notifier_list=NULL;
+
+struct notifier_block *reboot_notifier_list = NULL;
+
+int register_reboot_notifier(struct notifier_block * nb)
+{
+ return notifier_chain_register(&reboot_notifier_list, nb);
+}
+
+int unregister_reboot_notifier(struct notifier_block * nb)
+{
+ return notifier_chain_unregister(&reboot_notifier_list, nb);
+}
+
+
extern void adjust_clock(void);
@@ -189,10 +200,6 @@
#endif
-extern void hard_reset_now(void);
-#ifdef __sparc__
-extern void halt_now(void);
-#endif
extern asmlinkage int sys_kill(int, int);
/*
@@ -202,42 +209,69 @@
* You can also set the meaning of the ctrl-alt-del-key here.
*
* reboot doesn't sync: do that yourself before calling this.
+ *
*/
-asmlinkage int sys_reboot(int magic, int magic_too, int flag)
+asmlinkage int sys_reboot(int magic1, int magic2, int cmd, void * arg)
{
+ char buffer[256];
+
+ /* We only trust the superuser with rebooting the system. */
if (!suser())
return -EPERM;
- if (magic != 0xfee1dead ||
- (magic_too != 672274793 && magic_too != 85072278))
+
+ /* For safety, we require "magic" arguments. */
+ if (magic1 != LINUX_REBOOT_MAGIC1 ||
+ (magic2 != LINUX_REBOOT_MAGIC2 && magic2 != LINUX_REBOOT_MAGIC2A))
return -EINVAL;
+ lock_kernel();
+ switch (cmd) {
+ case LINUX_REBOOT_CMD_RESTART:
+ notifier_call_chain(&reboot_notifier_list, SYS_RESTART, NULL);
+ printk(KERN_EMERG "Restarting system.\n");
+ machine_restart(NULL);
+ break;
- if (flag == 0x01234567)
- {
- /* SMP: We need to lock during the shutdown still */
- lock_kernel();
- notifier_call_chain(&boot_notifier_list, SYS_DOWN, NULL);
- hard_reset_now();
- }
- else if (flag == 0x89ABCDEF)
+ case LINUX_REBOOT_CMD_CAD_ON:
C_A_D = 1;
- else if (!flag)
+ break;
+
+ case LINUX_REBOOT_CMD_CAD_OFF:
C_A_D = 0;
- else if (flag == 0xCDEF0123) {
- /* SMP: We need to lock during the shutdown still */
- lock_kernel();
- printk(KERN_EMERG "System halted\n");
-#ifdef __sparc__
- halt_now();
-#endif
- sys_kill(-1, SIGKILL);
-#if defined(CONFIG_APM) && defined(CONFIG_APM_POWER_OFF)
- apm_set_power_state(APM_STATE_OFF);
-#endif
- notifier_call_chain(&boot_notifier_list, SYS_HALT, NULL);
+ break;
+
+ case LINUX_REBOOT_CMD_HALT:
+ notifier_call_chain(&reboot_notifier_list, SYS_HALT, NULL);
+ printk(KERN_EMERG "System halted.\n");
+ machine_halt();
do_exit(0);
- } else
+ break;
+
+ case LINUX_REBOOT_CMD_POWER_OFF:
+ notifier_call_chain(&reboot_notifier_list, SYS_POWER_OFF, NULL);
+ printk(KERN_EMERG "Power down.\n");
+ machine_power_off();
+ do_exit(0);
+ break;
+
+ case LINUX_REBOOT_CMD_RESTART2:
+ if (strncpy_from_user(&buffer[0], (char *)arg, sizeof(buffer) - 1) < 0) {
+ unlock_kernel();
+ return -EFAULT;
+ }
+ buffer[sizeof(buffer) - 1] = '\0';
+
+ notifier_call_chain(&reboot_notifier_list, SYS_RESTART, buffer);
+ printk(KERN_EMERG "Restarting system with command '%s'.\n", buffer);
+ machine_restart(buffer);
+ break;
+
+ default:
+ unlock_kernel();
return -EINVAL;
+ break;
+ };
+ unlock_kernel();
return 0;
}
@@ -248,12 +282,10 @@
*/
void ctrl_alt_del(void)
{
- if (C_A_D)
- {
- notifier_call_chain(&boot_notifier_list, SYS_DOWN, NULL);
- hard_reset_now();
- }
- else
+ if (C_A_D) {
+ notifier_call_chain(&reboot_notifier_list, SYS_RESTART, NULL);
+ machine_restart(NULL);
+ } else
kill_proc(1, SIGINT, 1);
}
FUNET's LINUX-ADM group, [email protected]
TCL-scripts by Sam Shen, [email protected]