Linux中SysRq的使用
2019-07-13 07:01发布
生成海报
SysRq 键可以直接从内核输出信息。只要不是禁止中断状态,即使死机时也可以获取信息。SysRq 键在确认内核运行、调查内核死机原因等各种情况下都非常有效。
- 2.需要kernel打开CONFIG_MAGIC_SYSRQ选项支持
drivers/tty/sysrq.c
static int __init sysrq_init(void){ sysrq_init_procfs(); //注册proc入口 if (sysrq_on()) //按键的话需要开关控制 sysrq_register_handler(); //注册按键处理入口 return 0;}module_init(sysrq_init);
sysrq proc的支持:static void sysrq_init_procfs(void){ if (!proc_create("sysrq-trigger", S_IWUSR, NULL, &proc_sysrq_trigger_operations)) pr_err("Failed to register proc interface
");}
static const struct file_operations proc_sysrq_trigger_operations = { .write = write_sysrq_trigger, .llseek = noop_llseek,};
static ssize_t write_sysrq_trigger(struct file *file, const char __user *buf, size_t count, loff_t *ppos){ if (count) { char c; if (get_user(c, buf)) return -EFAULT; __handle_sysrq(c, false); } return count;}
void __handle_sysrq(int key, bool check_mask){ struct sysrq_key_op *op_p; ...
op_p = __sysrq_get_key_op(key); if (op_p) { /* * Should we check for enabled operations (/proc/sysrq-trigger * should not) and is the invoked operation enabled? */ if (!check_mask || sysrq_on_mask(op_p->enable_mask)) { printk("%s
", op_p->action_msg); console_loglevel = orig_log_level; op_p->handler(key); } else { printk("This sysrq operation is disabled.
"); } } ...}
struct sysrq_key_op *__sysrq_get_key_op(int key){ struct sysrq_key_op *op_p = NULL; int i;
i = sysrq_key_table_key2index(key); if (i != -1) op_p = sysrq_key_table[i];
return op_p;}
static struct sysrq_key_op *sysrq_key_table[36] = { &sysrq_loglevel_op, /* 0 */ &sysrq_loglevel_op, /* 1 */ &sysrq_loglevel_op, /* 2 */ &sysrq_loglevel_op, /* 3 */ &sysrq_loglevel_op, /* 4 */ &sysrq_loglevel_op, /* 5 */ &sysrq_loglevel_op, /* 6 */ &sysrq_loglevel_op, /* 7 */ &sysrq_loglevel_op, /* 8 */ &sysrq_loglevel_op, /* 9 */ /* * a: Don't use for system provided sysrqs, it is handled specially on * sparc and will never arrive. */ NULL, /* a */ &sysrq_reboot_op, /* b */ &sysrq_crash_op, /* c & ibm_emac driver debug */ &sysrq_showlocks_op, /* d */ &sysrq_term_op, /* e */ &sysrq_moom_op, /* f */ /* g: May be registered for the kernel debugger */ NULL, /* g */ NULL, /* h - reserved for help */ &sysrq_kill_op, /* i */#ifdef CONFIG_BLOCK &sysrq_thaw_op, /* j */#else NULL, /* j */#endif &sysrq_SAK_op, /* k */#ifdef CONFIG_SMP &sysrq_showallcpus_op, /* l */#else NULL, /* l */#endif &sysrq_showmem_op, /* m */ &sysrq_unrt_op, /* n */ /* o: This will often be registered as 'Off' at init time */ NULL, /* o */ &sysrq_showregs_op, /* p */ &sysrq_show_timers_op, /* q */ &sysrq_unraw_op, /* r */ &sysrq_sync_op, /* s */ &sysrq_showstate_op, /* t */ &sysrq_mountro_op, /* u */ /* v: May be registered for frame buffer console restore */ NULL, /* v */ &sysrq_showstate_blocked_op, /* w */ /* x: May be registered on ppc/powerpc for xmon */ /* x: May be registered on sparc64 for global PMU dump */ NULL, /* x */ /* y: May be registered on sparc64 for global register dump */ NULL, /* y */ &sysrq_ftrace_dump_op, /* z */}
sysrq按键的支持:首先需要打开开关打开这个功能,运行: # echo 1 > /proc/sys/kernel/sysrq关闭这个功能: # echo 0 > /proc/sys/kernel/sysrq
#ifdef CONFIG_MAGIC_SYSRQ { .procname = "sysrq", .data = &__sysrq_enabled, .maxlen = sizeof (int), .mode = 0644, .proc_handler = sysrq_sysctl_handler, },#endif
int sysrq_toggle_support(int enable_mask){ bool was_enabled = sysrq_on();
sysrq_enabled = enable_mask;
if (was_enabled != sysrq_on()) { if (sysrq_on()) sysrq_register_handler(); else sysrq_unregister_handler(); }
return 0;}由实现可以看出支持动态打开和关闭
注册sysrq按键处理函数:static inline void sysrq_register_handler(void){ int error;
error = input_register_handler(&sysrq_handler); if (error) pr_err("Failed to register input handler, error %d", error); else sysrq_handler_registered = true;}
static struct input_handler sysrq_handler = { .filter = sysrq_filter, //哪些消息给sysrq去处理 .connect = sysrq_connect, .disconnect = sysrq_disconnect, .name = "sysrq", .id_table = sysrq_ids,};
static bool sysrq_filter(struct input_handle *handle, unsigned int type, unsigned int code, int value){ ...
default: if (sysrq->active && value && value != 2) { sysrq->need_reinject = false; __handle_sysrq(sysrq_xlate[code], true); } break; } ....}可以看出sysrq按键最终和proc一样都是调用__handle_sysrq()来处理
查看内存信息:# echo 'm' > /proc/sysrq-trigger
重启:# echo 'b' > /proc/sysrq-trigger
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮