Merge with Linux 2.4.0-test6-pre2.
[linux-2.6/linux-mips.git] / drivers / char / sysrq.c
blob9650457c0cf3334475387271ef4300ac60013fce
1 /* -*- linux-c -*-
3 * $Id: sysrq.c,v 1.15 1998/08/23 14:56:41 mj Exp $
5 * Linux Magic System Request Key Hacks
7 * (c) 1997 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
8 * based on ideas by Pavel Machek <pavel@atrey.karlin.mff.cuni.cz>
9 */
11 #include <linux/config.h>
12 #include <linux/sched.h>
13 #include <linux/interrupt.h>
14 #include <linux/mm.h>
15 #include <linux/fs.h>
16 #include <linux/mount.h>
17 #include <linux/kdev_t.h>
18 #include <linux/major.h>
19 #include <linux/reboot.h>
20 #include <linux/sysrq.h>
21 #include <linux/kbd_kern.h>
22 #include <linux/quotaops.h>
23 #include <linux/smp_lock.h>
24 #include <linux/module.h>
26 #include <asm/ptrace.h>
28 extern void wakeup_bdflush(int);
29 extern void reset_vc(unsigned int);
30 extern int console_loglevel;
31 extern struct list_head super_blocks;
33 /* Whether we react on sysrq keys or just ignore them */
34 int sysrq_enabled = 1;
36 /* Machine specific power off function */
37 void (*sysrq_power_off)(void) = NULL;
39 EXPORT_SYMBOL(sysrq_power_off);
41 /* Send a signal to all user processes */
43 static void send_sig_all(int sig, int even_init)
45 struct task_struct *p;
47 for_each_task(p) {
48 if (p->mm) { /* Not swapper nor kernel thread */
49 if (p->pid == 1 && even_init) /* Ugly hack to kill init */
50 p->pid = 0x8000;
51 force_sig(sig, p);
57 * This function is called by the keyboard handler when SysRq is pressed
58 * and any other keycode arrives.
61 void handle_sysrq(int key, struct pt_regs *pt_regs,
62 struct kbd_struct *kbd, struct tty_struct *tty)
64 int orig_log_level = console_loglevel;
66 if (!sysrq_enabled)
67 return;
69 if (!key)
70 return;
72 console_loglevel = 7;
73 printk(KERN_INFO "SysRq: ");
74 switch (key) {
75 case 'r': /* R -- Reset raw mode */
76 if (kbd) {
77 kbd->kbdmode = VC_XLATE;
78 printk("Keyboard mode set to XLATE\n");
80 break;
81 #ifdef CONFIG_VT
82 case 'k': /* K -- SAK */
83 printk("SAK\n");
84 if (tty)
85 do_SAK(tty);
86 reset_vc(fg_console);
87 break;
88 #endif
89 case 'b': /* B -- boot immediately */
90 printk("Resetting\n");
91 machine_restart(NULL);
92 break;
93 case 'o': /* O -- power off */
94 if (sysrq_power_off) {
95 printk("Power off\n");
96 sysrq_power_off();
98 break;
99 case 's': /* S -- emergency sync */
100 printk("Emergency Sync\n");
101 emergency_sync_scheduled = EMERG_SYNC;
102 wakeup_bdflush(0);
103 break;
104 case 'u': /* U -- emergency remount R/O */
105 printk("Emergency Remount R/O\n");
106 emergency_sync_scheduled = EMERG_REMOUNT;
107 wakeup_bdflush(0);
108 break;
109 case 'p': /* P -- show PC */
110 printk("Show Regs\n");
111 if (pt_regs)
112 show_regs(pt_regs);
113 break;
114 case 't': /* T -- show task info */
115 printk("Show State\n");
116 show_state();
117 break;
118 case 'm': /* M -- show memory info */
119 printk("Show Memory\n");
120 show_mem();
121 break;
122 case '0' ... '9': /* 0-9 -- set console logging level */
123 orig_log_level = key - '0';
124 printk("Log level set to %d\n", orig_log_level);
125 break;
126 case 'e': /* E -- terminate all user processes */
127 printk("Terminate All Tasks\n");
128 send_sig_all(SIGTERM, 0);
129 orig_log_level = 8; /* We probably have killed syslogd */
130 break;
131 case 'i': /* I -- kill all user processes */
132 printk("Kill All Tasks\n");
133 send_sig_all(SIGKILL, 0);
134 orig_log_level = 8;
135 break;
136 case 'l': /* L -- kill all processes including init */
137 printk("Kill ALL Tasks (even init)\n");
138 send_sig_all(SIGKILL, 1);
139 orig_log_level = 8;
140 break;
141 default: /* Unknown: help */
142 if (kbd)
143 printk("unRaw ");
144 #ifdef CONFIG_VT
145 if (tty)
146 printk("saK ");
147 #endif
148 printk("Boot ");
149 if (sysrq_power_off)
150 printk("Off ");
151 printk("Sync Unmount showPc showTasks showMem loglevel0-8 tErm kIll killalL\n");
152 /* Don't use 'A' as it's handled specially on the Sparc */
155 console_loglevel = orig_log_level;
158 /* Aux routines for the syncer */
160 static int is_local_disk(kdev_t dev) /* Guess if the device is a local hard drive */
162 unsigned int major = MAJOR(dev);
164 switch (major) {
165 case IDE0_MAJOR:
166 case IDE1_MAJOR:
167 case IDE2_MAJOR:
168 case IDE3_MAJOR:
169 case SCSI_DISK0_MAJOR:
170 case SCSI_DISK1_MAJOR:
171 case SCSI_DISK2_MAJOR:
172 case SCSI_DISK3_MAJOR:
173 case SCSI_DISK4_MAJOR:
174 case SCSI_DISK5_MAJOR:
175 case SCSI_DISK6_MAJOR:
176 case SCSI_DISK7_MAJOR:
177 return 1;
178 default:
179 return 0;
183 static void go_sync(struct super_block *sb, int remount_flag)
185 printk(KERN_INFO "%sing device %s ... ",
186 remount_flag ? "Remount" : "Sync",
187 kdevname(sb->s_dev));
189 if (remount_flag) { /* Remount R/O */
190 int ret, flags;
191 struct list_head *p;
193 if (sb->s_flags & MS_RDONLY) {
194 printk("R/O\n");
195 return;
198 file_list_lock();
199 for (p = sb->s_files.next; p != &sb->s_files; p = p->next) {
200 struct file *file = list_entry(p, struct file, f_list);
201 if (file->f_dentry && file_count(file)
202 && S_ISREG(file->f_dentry->d_inode->i_mode))
203 file->f_mode &= ~2;
205 file_list_unlock();
206 DQUOT_OFF(sb);
207 fsync_dev(sb->s_dev);
208 flags = MS_RDONLY;
209 if (sb->s_op && sb->s_op->remount_fs) {
210 ret = sb->s_op->remount_fs(sb, &flags, NULL);
211 if (ret)
212 printk("error %d\n", ret);
213 else {
214 sb->s_flags = (sb->s_flags & ~MS_RMT_MASK) | (flags & MS_RMT_MASK);
215 printk("OK\n");
217 } else
218 printk("nothing to do\n");
219 } else {
220 fsync_dev(sb->s_dev); /* Sync only */
221 printk("OK\n");
226 * Emergency Sync or Unmount. We cannot do it directly, so we set a special
227 * flag and wake up the bdflush kernel thread which immediately calls this function.
228 * We process all mounted hard drives first to recover from crashed experimental
229 * block devices and malfunctional network filesystems.
232 int emergency_sync_scheduled;
234 void do_emergency_sync(void)
236 struct super_block *sb;
237 int remount_flag;
239 lock_kernel();
240 remount_flag = (emergency_sync_scheduled == EMERG_REMOUNT);
241 emergency_sync_scheduled = 0;
243 for (sb = sb_entry(super_blocks.next);
244 sb != sb_entry(&super_blocks);
245 sb = sb_entry(sb->s_list.next))
246 if (is_local_disk(sb->s_dev))
247 go_sync(sb, remount_flag);
249 for (sb = sb_entry(super_blocks.next);
250 sb != sb_entry(&super_blocks);
251 sb = sb_entry(sb->s_list.next))
252 if (!is_local_disk(sb->s_dev) && MAJOR(sb->s_dev))
253 go_sync(sb, remount_flag);
255 unlock_kernel();
256 printk(KERN_INFO "Done.\n");