Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[PATCH] debug: add sysrq_always_enabled boot option

Most distributions enable sysrq support but set it to 0 by default. Add a
sysrq_always_enabled boot option to always-enable sysrq keys. Useful for
debugging - without having to modify the disribution's config files (which
might not be possible if the kernel is on a live CD, etc.).

Also, while at it, clean up the sysrq interfaces.

[bunk@stusta.de: make sysrq_always_enabled_setup() static]
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Adrian Bunk <bunk@stusta.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by

Ingo Molnar and committed by
Linus Torvalds
5d6f647f e61c9018

+60 -18
+6
Documentation/kernel-parameters.txt
··· 1656 1656 sym53c416= [HW,SCSI] 1657 1657 See header of drivers/scsi/sym53c416.c. 1658 1658 1659 + sysrq_always_enabled 1660 + [KNL] 1661 + Ignore sysrq setting - this boot parameter will 1662 + neutralize any effect of /proc/sys/kernel/sysrq. 1663 + Useful for debugging. 1664 + 1659 1665 t128= [HW,SCSI] 1660 1666 See header of drivers/scsi/t128.c. 1661 1667
+31 -6
drivers/char/sysrq.c
··· 41 41 #include <asm/irq_regs.h> 42 42 43 43 /* Whether we react on sysrq keys or just ignore them */ 44 - int sysrq_enabled = 1; 44 + int __read_mostly __sysrq_enabled = 1; 45 + 46 + static int __read_mostly sysrq_always_enabled; 47 + 48 + int sysrq_on(void) 49 + { 50 + return __sysrq_enabled || sysrq_always_enabled; 51 + } 52 + 53 + /* 54 + * A value of 1 means 'all', other nonzero values are an op mask: 55 + */ 56 + static inline int sysrq_on_mask(int mask) 57 + { 58 + return sysrq_always_enabled || __sysrq_enabled == 1 || 59 + (__sysrq_enabled & mask); 60 + } 61 + 62 + static int __init sysrq_always_enabled_setup(char *str) 63 + { 64 + sysrq_always_enabled = 1; 65 + printk(KERN_INFO "debug: sysrq always enabled.\n"); 66 + 67 + return 1; 68 + } 69 + 70 + __setup("sysrq_always_enabled", sysrq_always_enabled_setup); 71 + 45 72 46 73 static void sysrq_handle_loglevel(int key, struct tty_struct *tty) 47 74 { ··· 406 379 * Should we check for enabled operations (/proc/sysrq-trigger 407 380 * should not) and is the invoked operation enabled? 408 381 */ 409 - if (!check_mask || sysrq_enabled == 1 || 410 - (sysrq_enabled & op_p->enable_mask)) { 382 + if (!check_mask || sysrq_on_mask(op_p->enable_mask)) { 411 383 printk("%s\n", op_p->action_msg); 412 384 console_loglevel = orig_log_level; 413 385 op_p->handler(key, tty); ··· 440 414 */ 441 415 void handle_sysrq(int key, struct tty_struct *tty) 442 416 { 443 - if (!sysrq_enabled) 444 - return; 445 - __handle_sysrq(key, tty, 1); 417 + if (sysrq_on()) 418 + __handle_sysrq(key, tty, 1); 446 419 } 447 420 EXPORT_SYMBOL(handle_sysrq); 448 421
+4 -6
drivers/char/viocons.c
··· 61 61 static DEFINE_SPINLOCK(consolelock); 62 62 static DEFINE_SPINLOCK(consoleloglock); 63 63 64 - #ifdef CONFIG_MAGIC_SYSRQ 65 64 static int vio_sysrq_pressed; 66 - extern int sysrq_enabled; 67 - #endif 68 65 69 66 #define VIOCHAR_NUM_BUF 16 70 67 ··· 933 936 */ 934 937 num_pushed = 0; 935 938 for (index = 0; index < cevent->len; index++) { 936 - #ifdef CONFIG_MAGIC_SYSRQ 937 - if (sysrq_enabled) { 939 + /* 940 + * Will be optimized away if !CONFIG_MAGIC_SYSRQ: 941 + */ 942 + if (sysrq_on()) { 938 943 /* 0x0f is the ascii character for ^O */ 939 944 if (cevent->data[index] == '\x0f') { 940 945 vio_sysrq_pressed = 1; ··· 955 956 continue; 956 957 } 957 958 } 958 - #endif 959 959 /* 960 960 * The sysrq sequence isn't included in this check if 961 961 * sysrq is enabled and compiled into the kernel because
+18 -4
include/linux/sysrq.h
··· 37 37 38 38 #ifdef CONFIG_MAGIC_SYSRQ 39 39 40 + extern int sysrq_on(void); 41 + 42 + /* 43 + * Do not use this one directly: 44 + */ 45 + extern int __sysrq_enabled; 46 + 40 47 /* Generic SysRq interface -- you may call it from any device driver, supplying 41 48 * ASCII code of the key, pointer to registers and kbd/tty structs (if they 42 49 * are available -- else NULL's). 43 50 */ 44 51 45 - void handle_sysrq(int, struct tty_struct *); 46 - void __handle_sysrq(int, struct tty_struct *, int check_mask); 47 - int register_sysrq_key(int, struct sysrq_key_op *); 48 - int unregister_sysrq_key(int, struct sysrq_key_op *); 52 + void handle_sysrq(int key, struct tty_struct *tty); 53 + void __handle_sysrq(int key, struct tty_struct *tty, int check_mask); 54 + int register_sysrq_key(int key, struct sysrq_key_op *op); 55 + int unregister_sysrq_key(int key, struct sysrq_key_op *op); 49 56 struct sysrq_key_op *__sysrq_get_key_op(int key); 50 57 51 58 #else 52 59 60 + static inline int sysrq_on(void) 61 + { 62 + return 0; 63 + } 53 64 static inline int __reterr(void) 54 65 { 55 66 return -EINVAL; 67 + } 68 + static inline void handle_sysrq(int key, struct tty_struct *tty) 69 + { 56 70 } 57 71 58 72 #define register_sysrq_key(ig,nore) __reterr()
+1 -2
kernel/sysctl.c
··· 65 65 extern int sysctl_overcommit_ratio; 66 66 extern int sysctl_panic_on_oom; 67 67 extern int max_threads; 68 - extern int sysrq_enabled; 69 68 extern int core_uses_pid; 70 69 extern int suid_dumpable; 71 70 extern char core_pattern[]; ··· 542 543 { 543 544 .ctl_name = KERN_SYSRQ, 544 545 .procname = "sysrq", 545 - .data = &sysrq_enabled, 546 + .data = &__sysrq_enabled, 546 547 .maxlen = sizeof (int), 547 548 .mode = 0644, 548 549 .proc_handler = &proc_dointvec,