Linux Magic System Request Key Hacks¶

Linux Magic System Request Key Hacks¶

Linux Magic System Request Key Hacks¶

sysrq.c 文档

什么是 magic SysRq 键?¶

这是一个“神奇”的组合键,你可以按下它,内核会对它做出响应,而不管它正在做什么,除非它完全锁死了。

如何启用 magic SysRq 键?¶

在配置内核时,你需要对 'Magic SysRq key (CONFIG_MAGIC_SYSRQ)' 说“yes”。当运行一个编译了 SysRq 的内核时,/proc/sys/kernel/sysrq 控制着允许通过 SysRq 键调用的功能。该文件中的默认值由 CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE 配置符号设置,该符号本身默认为 1。以下是 /proc/sys/kernel/sysrq 中可能的值:

0 - 完全禁用 sysrq

1 - 启用 sysrq 的所有功能

>1 - 允许的 sysrq 功能的位掩码(有关详细的功能说明,请参见下文)

2 = 0x2 - enable control of console logging level

4 = 0x4 - enable control of keyboard (SAK, unraw)

8 = 0x8 - enable debugging dumps of processes etc.

16 = 0x10 - enable sync command

32 = 0x20 - enable remount read-only

64 = 0x40 - enable signalling of processes (term, kill, oom-kill)

128 = 0x80 - allow reboot/poweroff

256 = 0x100 - allow nicing of all RT tasks

你可以使用以下命令设置文件中的值

echo "number" >/proc/sys/kernel/sysrq

该数字可以以十进制或带有 0x 前缀的十六进制形式写入。CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE 必须始终以十六进制形式写入。

请注意,/proc/sys/kernel/sysrq 的值仅影响通过键盘的调用。始终允许通过 /proc/sysrq-trigger 调用任何操作(由具有管理员权限的用户)。

如何使用 magic SysRq 键?¶

在 x86 上你按下组合键 ALT-SysRq-<命令键>。

注意

某些键盘可能没有标有“SysRq”的键。“SysRq”键也称为“Print Screen”键。此外,某些键盘无法处理同时按下的这么多键,因此您可能会更好地按下 Alt,按下 SysRq,释放 SysRq,按下 <命令键>,释放所有键。

在 SPARC 上我相信,你按下 ALT-STOP-<命令键>。

在串行控制台上(仅限 PC 风格的标准串行端口)你发送一个 BREAK,然后在 5 秒内发送一个命令键。发送两次 BREAK 被解释为正常的 BREAK。

在 PowerPC 上按下 ALT - Print Screen(或 F13)- <命令键>。Print Screen(或 F13)- <命令键> 可能就足够了。

在其他如果你知道其他架构的组合键,请提交补丁以包含在本节中。

在所有向 /proc/sysrq-trigger 写入单个字符。只处理第一个字符,字符串的其余部分将被忽略。但是,不建议写入任何额外的字符,因为该行为未定义,并且可能会在将来的版本中发生更改。例如:

echo t > /proc/sysrq-trigger

或者,写入以 underscore 开头的多个字符。这样,所有字符都将被处理。例如:

echo _reisub > /proc/sysrq-trigger

<命令键> 区分大小写。

什么是“命令”键?¶

命令

功能

b

将立即重启系统,而无需同步或卸载你的磁盘。

c

将执行系统崩溃,如果已配置,则会进行崩溃转储。

d

显示所有持有的锁。

e

向所有进程发送 SIGTERM,除了 init。

f

将调用 oom killer 来杀死一个内存占用进程,但如果无法杀死任何东西,则不要 panic。

g

由 kgdb(内核调试器)使用

h

将显示帮助(实际上,除了此处列出的键之外的任何其他键都将显示帮助。但 h 很容易记住 :-))

i

向所有进程发送 SIGKILL,除了 init。

j

强制 “Just thaw it” - 通过 FIFREEZE ioctl 冻结的文件系统。

k

安全访问键 (SAK) 杀死当前虚拟控制台上的所有程序。注意:请参阅下面 SAK 部分中的重要评论。

l

显示所有活动 CPU 的堆栈回溯。

m

将当前内存信息转储到你的控制台。

n

用于使 RT 任务可以 nice

o

将关闭你的系统(如果已配置并支持)。

p

将当前寄存器和标志转储到你的控制台。

q

将转储每个 CPU 的所有已激活的 hrtimer 列表(但不是常规的 timer_list 定时器)以及有关所有 clockevent 设备的详细信息。

r

关闭键盘原始模式,并将其设置为 XLATE。

s

将尝试同步所有已挂载的文件系统。

t

将当前任务列表及其信息转储到你的控制台。

u

将尝试以只读方式重新挂载所有已挂载的文件系统。

v

强制恢复帧缓冲控制台

v

导致 ETM 缓冲区转储 [ARM 特定]

w

转储处于不可中断(阻塞)状态的任务。

x

由 ppc/powerpc 平台上的 xmon 接口使用。在 sparc64 上显示全局 PMU 寄存器。在 MIPS 上转储所有 TLB 条目。

y

显示全局 CPU 寄存器 [SPARC-64 特定]

z

转储 ftrace 缓冲区

0-9

设置控制台日志级别,控制哪些内核消息将打印到你的控制台。(例如,0 将使其只有紧急消息(如 PANIC 或 OOPS)才会显示在你的控制台上。)

R

在控制台上重放内核日志消息。

好的,那么我可以用它们做什么?¶

当你的 X 服务器或 svgalib 程序崩溃时,unraw(r) 非常方便。

当你想要确保在控制台上没有木马程序运行时,sak(k)(安全访问键)非常有用,该木马程序可能会在你尝试登录时获取你的密码。它将杀死给定控制台上的所有程序,从而让你确保你看到的登录提示实际上是来自 init 的,而不是某些木马程序。

重要提示

以其真实形式,它不是真正的 SAK,就像 c2 兼容系统中的那样,并且不应将其误认为如此。

似乎其他人发现它作为(系统注意键)很有用,当你想要退出一个不允许你切换控制台的程序时,它很有用。(例如,X 或 svgalib 程序。)

当你无法关闭时,reboot(b) 很好,它相当于按下“reset”按钮。

当系统挂起时,crash(c) 可用于手动触发崩溃转储。请注意,如果没有任何可用的转储机制,这只会触发崩溃。

sync(s) 在拔出可移动介质之前或在使用不提供正常关机的救援 shell 之后很方便 - 它将确保你的数据安全地写入磁盘。请注意,直到你在屏幕上看到 “OK” 和 “Done” 出现,同步才完成。

umount(u) 可用于将文件系统标记为已正确卸载。从运行系统的角度来看,它们将以只读方式重新挂载。直到你在屏幕上看到 “OK” 和 “Done” 消息出现,重新挂载才完成。

当你的控制台被你不希望看到的内核消息淹没时,日志级别 0-9 很有用。选择 0 将阻止除最紧急的内核消息之外的所有消息到达你的控制台。(如果 syslogd/klogd 处于活动状态,它们仍然会被记录。)

如果你有一些你无法以任何其他方式杀死的失控进程,特别是如果它正在生成其他进程,则 term(e) 和 kill(i) 很有用。

如果你的系统由于通过 FIFREEZE ioctl 冻结(可能是根)文件系统而变得无响应,“just thaw it(j)” 很有用。

当系统挂起或者你无法使用 dmesg 命令查看 printk 缓冲区中的消息时,Replay logs(R) 可用于查看内核日志消息。如果控制台系统繁忙,用户可能需要多次按下组合键。如果它完全锁死,则不会打印消息。输出消息取决于当前的控制台日志级别,可以使用 sysrq[0-9] 修改(参见上文)。

有时在使用 SysRq 后它似乎会“卡住”,我该怎么办?¶

发生这种情况时,尝试在键盘的两侧轻敲 shift、alt 和 control,然后再次按下无效的 sysrq 序列。(即,类似于 alt-sysrq-z)。

切换到另一个虚拟控制台 (ALT+Fn) 然后再切换回来也应该有所帮助。

我按下了 SysRq,但似乎没有任何反应,怎么回事?¶

有些键盘为 SysRq 生成的键码与预定义的值 99 不同(请参阅 include/uapi/linux/input-event-codes.h 中的 KEY_SYSRQ),或者根本没有 SysRq 键。在这些情况下,运行 showkey -s 以找到适当的扫描码序列,并使用 setkeycodes 99 将此序列映射到通常的 SysRq 代码(例如,setkeycodes e05b 99)。最好将此命令放在启动脚本中。顺便说一句,你不输入任何内容十秒钟即可退出 showkey。

我想向模块添加 SysRQ 键事件,它是如何工作的?¶

为了在表中注册一个基本函数,你必须首先包含头文件 include/linux/sysrq.h,这将定义你需要的其他一切。接下来,你必须创建一个 sysrq_key_op 结构,并填充 A) 你将使用的键处理程序函数,B) 一个 help_msg 字符串,当 SysRQ 打印帮助时将打印该字符串,以及 C) 一个 action_msg 字符串,将在调用你的处理程序之前立即打印该字符串。你的处理程序必须符合“sysrq.h”中的原型。

创建 sysrq_key_op 之后,你可以调用内核函数 register_sysrq_key(int key, const struct sysrq_key_op *op_p);,如果表键“key”中的该槽位为空白,这将注册由 op_p 指向的操作。在模块卸载时,你必须调用函数 unregister_sysrq_key(int key, const struct sysrq_key_op *op_p),这将从键“key”中删除由 “op_p” 指向的键操作,仅当它当前已在该槽位中注册时。这是为了防止自你注册以来该槽位已被覆盖。

Magic SysRQ 系统通过针对键操作查找表注册键操作来工作,该表在 “drivers/tty/sysrq.c” 中定义。此键表在编译时已注册了许多操作,但它是可变的,并且导出了 2 个函数用于与其交互。

register_sysrq_key and unregister_sysrq_key.

当然,永远不要在表中留下无效的指针。也就是说,当调用 register_sysrq_key() 的模块退出时,它必须调用 unregister_sysrq_key() 来清理它使用的 sysrq 键表条目。表中的空指针始终是安全的。 :)

如果由于某种原因,你觉得需要从 handle_sysrq 调用的函数中调用 handle_sysrq 函数,你必须意识到你处于锁中(你也在中断处理程序中,这意味着不要睡眠!),因此你必须调用 __handle_sysrq_nolock 代替。

当我按下 SysRq 键组合时,控制台上只出现标题?¶

Sysrq 输出受到与所有其他控制台输出相同的控制台日志级别控制。这意味着,如果内核像发行版内核上常见的那样“quiet”启动,即使它将出现在 dmesg 缓冲区中,并且可以通过 dmesg 命令访问以及 /proc/kmsg 的消费者访问,输出也可能不会出现在实际控制台上。作为一个特定的例外,来自 sysrq 命令的标题行会像当前日志级别最高一样传递给所有控制台消费者。如果仅发出标题,则几乎可以肯定内核日志级别太低。如果你需要在控制台通道上输出,那么你需要使用 alt-sysrq-8 暂时提高控制台日志级别或

echo 8 > /proc/sysrq-trigger

请记住在触发你感兴趣的 sysrq 命令后将日志级别恢复正常。

我有更多问题,我可以问谁?¶

只需在 linux-kernel 邮件列表中提问linux-kernel@vger.kernel.org

致谢¶

由 Mydraal 编写

由 Adam Sulmicki 更新

由 Jeremy M. Dolan 于 2001/01/28 10:15:59 添加

由 Crutcher Dunnavant 添加到

相关推荐