公司动态

Linux sysrq紧急魔术键handle_sysrq调度

📅 2026/7/21 4:29:06
Linux sysrq紧急魔术键handle_sysrq调度
Linux sysrq紧急魔术键handle_sysrq调度SysRqSystem Request是Linux内核提供的一套紧急管理功能组合键即使在系统挂起或无响应时仍能通过键盘输入或/proc接口执行关键操作。其核心调度函数是handle_sysrq接收一个字符参数并查找对应的操作处理函数。SysRq操作通过sysrq_key_op描述每个操作包含处理函数、帮助文本和启用掩码struct sysrq_key_op {void (*handler)(int keys);const char *help_msg;const char *action_msg;int enable_mask;};所有操作被组织在sysrq_key_table中static struct sysrq_key_op *sysrq_key_table[SYSRQ_KEY_TABLE_SIZE] {sysrq_loglevel_ops, /* 0-9 日志级别 */...sysrq_reboot_ops, /* b 立即重启 */sysrq_crashdump_ops, /* c 触发crash dump */sysrq_term_ops, /* e 向所有进程发送SIGTERM */sysrq_moom_ops, /* f 调用oom killer */sysrq_help_ops, /* h 显示帮助 */sysrq_kill_ops, /* i 向所有进程发送SIGKILL */sysrq_thaw_ops, /* j 解冻所有文件系统 */sysrq_ftrace_dump_ops, /* l ftrace dump */sysrq_sync_ops, /* s 同步所有挂载的文件系统 */sysrq_showtask_ops, /* t 显示任务信息 */sysrq_unmount_ops, /* u 重新挂载所有文件系统为只读 */sysrq_showstate_ops, /* p 显示寄存器 */};handle_sysrq函数根据传入的key从表中查找对应的ops并调用handlervoid handle_sysrq(int key){struct sysrq_key_op *op_p;int orig_log_level;unsigned long flags;if (sysrq_on())__handle_sysrq(key, false);}static void __handle_sysrq(int key, bool check_mask){struct sysrq_key_op *op_p;int orig_log_level;int i;if ((key 36) (key 126))i key - 36; /* 将ASCII码映射为表索引 */elsei key;op_p sysrq_key_table[i];if (!op_p || !op_p-handler)return;/* 检查当前sysrq掩码是否允许该操作 */if (!sysrq_on_mask(op_p-enable_mask))return;pr_info(SysRq : %s\n, op_p-action_msg);/* 提高日志级别确保消息可见 */orig_log_level console_loglevel;console_loglevel CONSOLE_EXTENDED;op_p-handler(key);console_loglevel orig_log_level;}以sysrq_reboot_ops为例reboot操作通过emergency_restart绕过正常关机流程直接重置硬件static struct sysrq_key_op sysrq_reboot_ops {.handler sysrq_handle_reboot,.help_msg reboot(b),.action_msg Emergency Reboot,.enable_mask SYSRQ_ENABLE_BOOT,};static void sysrq_handle_reboot(int key){emergency_restart();}sysrq_handle_crash直接触发panic用于测试kdump配置static void sysrq_handle_crash(int key){char *killer NULL;pr_info(sysrq: Trigger a crash\n);*killer 1; /* 制造NULL指针解引用 */}SysRq触发路径有三个入口1. 键盘中断当用户按下AltSysRq命令键时键盘驱动调用handle_sysrq。在AT键盘驱动中中断处理函数kbd_keycode识别到SysRq按下事件后设置sysrq_alt状态static void kbd_keycode(struct vc_data *vc, unsigned char keycode, ...){if (keycode KEY_SYSRQ) {sysrq_alt 1;return;}if (sysrq_alt keycode ! KEY_LEFTALT keycode ! KEY_RIGHTALT) {handle_sysrq(keycode);sysrq_alt 0;return;}}2. /proc/sysrq-trigger接口写入字符直接触发无需键盘硬件支持static ssize_t write_sysrq_trigger(struct file *file,const char __user *buf, size_t count, loff_t *ppos){char c;if (get_user(c, buf))return -EFAULT;handle_sysrq(c);return count;}3. 串口SysRq在串口终端中输入break信号序列后跟随命令字符。可调节的sysrq掩码通过/proc/sys/kernel/sysrq控制决定哪些功能可用。掩码值按位分配1为所有功能0为禁用大于1时按bitmask精细控制#define SYSRQ_ENABLE_LOG (1 0)#define SYSRQ_ENABLE_SYNC (1 1)#define SYSRQ_ENABLE_REMOUNT (1 2)#define SYSRQ_ENABLE_SIGNAL (1 3)#define SYSRQ_ENABLE_BOOT (1 4)#define SYSRQ_ENABLE_RT (1 5)在SMP系统中handle_sysrq被设计为只有接收到SysRq的CPU执行操作。对于像t显示任务信息这样的操作每个CPU可能只看到部分信息但整体设计优先考虑操作的原子性和低延迟。