Linux Magic System Request Key Hacks

1. 什么是magic SysRq key?

这是一种神奇的组合键, 它可以让内核忽略任何正在进行的任务来响应你, 除非内核已经完全锁死. 


2. 如何启用magic SysRq key?

你需要在编译内核时把" Magic  SysRq  key (CONFIG_ MAGIC _SYSRQ)"选项设置为"yes"(译注: 现在大部分发行版都把SysRq支持编译进了内核,验证命令:
代码:
grep CONFIG_MAGIC_SYSRQ  /boot/config-$(uname -r)
)
当你运行一个编译进SysRq支持的内核时, /proc/sys/kernel/sysrq文件控制是否接受SysRq请求. 默认状态下, 该文件内容为1, 表示接受任何SysRq请求(在旧版本的内核中, SysRq默认被禁止, 你需要在运行时启用它, 但是现在已经不是这样了. 译注: 现在部分发行版的内核依然是默认不接受SysRq请求的). 下面是/proc/sys/kernel/sysrq文件有效值的列表: 
代码:
  0 - 不接受任何SysRq请求
  1 - 接受所有SysRq请求
  2 - 启用控制终端日志等级的功能(译注: 详见后文相关的SysRq组合键)
  4 - 允许键盘控制(SAK,unraw)(译注: 详见后文相关的SysRq组合键)
  8 - 启用进程debug转储
 16 - 允许sync命令
 32 - 允许remount read-only
 64 - 允许对进程发送的信号(term, kill, oom-kill)
128 - 允许reboot/poweroff
256 - 允许降低实时任务的优化级
你可以通过以下命令设置sysrq文件的值:
代码:
 echo "number" >/proc/sys/kernel/sysrq
(译注: 该方法只在运行时有效, 内核被重新引导以后会还原为原始状态。如果想永久设置该值可以参照以下方法, 以fedora为例: 编辑/etc/sysctl.conf文件, 将其中kernel.sysrq的值设置为1. 修改后通过sysctl -p命令让内核立即读取此参数.)

注意: /proc/sys/kernel/sysrq的值只影响通过键盘发出的命令. 通过/proc/sysrq-trigger接口进行的操作不受此值的影响, 并且总是被内核接受的(通过该接口操作需要root权限). 


3. 如何使用magic SysRq key?

x86 
按下组合键'Alt+SysRq+<command  key >'. 
注意: 有些键盘没有名为'SysRq'的键, 那么可以使用'Print Screen'键. 也有些键盘可能不能一次同时按下组合键, 你可以按照以下步骤来操作: "按下Alt"=>"按下SysRq"=>"释放SysRq"=>"按下<command key>"=>"释放所有键".
SPARC
按下组合键'Alt+STOP+<command  key >'

通过串行接口连接的终端(只针对标准的PC串行接口)
按一次BREAK(按ctrl+Break才能向终端发命令), 然后在5秒内按下<command  key >. 连按两次BREAK表示一个正常的BREAK指令.

PowerPC
按下组合键'Alt+Print Screen(or F13)+<command  key >', 只使用组合键'Print Screen(or F13)+<command  key >'应该也可以. 

平台无关
向/proc/sysrq-trigger写入一个字符.例如:
代码:
echo t > /proc/sysrq-trigger

4. 什么是<command key>?
代码:
'b' - 立刻重启系统,在此之前不会同步硬盘缓冲也不会卸载硬盘.
'c' - 通过一个空指针引用来产生一次内核崩溃,如果已经进行了相关配置, 将会产生一份崩溃转储.  
'd' - 显示所有已经获取的锁 
'e' - 对init以外的进程发送SIGTERM信号
'f' - 调用oom_kill杀死引起内存泄漏的进程
'g' - 在ppc和使用sh的平台上被kgdb使用
'h' - 显示帮助(这里列举的其他某些命令键也会显示帮助,不过'h'最好记)
'i' - 对init以外的进程发送SIGKILL信号
'j' - 强制解锁被FIFREEZE ioctl冻结的文件系统
'k' - Secure Access Key(SAK), 杀死所有当前虚拟终端中的进程.
      注意: 请阅读后文关于SAK的重要提示
'l' - 显示一份关于所有活动CPU中程序调用栈回溯信息
'm' - 在当前终端显示内存的转储信息
'n' - 降低实时进程的nice级别
'o' - 立即关机, 相当于poweroff
'p' - 在当前终端显示CPU寄存器的转储信息 
'q' - 转储每个cpu中的高精度计时器列表,并且显示所有的时钟事件设备的详细信息
'r' - 把键盘工作模式从raw模式变成ASCII模式(unraw)
's' - 同步磁盘缓冲
't' - 在当前终端显示进程列表和相关信息
'u' - 把所有已经挂载的文件系统重新挂载为只读模式
'v' - 在当前终端显示Voyager SMP体系中的CPU信息
'w' - 转储处于uninterruptable状态的进程 
'x' - 在ppc/powerpc平台上被xmon接口使用
'z' - 转储ftrace缓冲
'0'-'9' - 设置终端的日志级别, 以控制在终端上显示哪些内核信息.(比如'0'级别只会再终端上显示诸如PANICs或者OOPSes之类的紧急信息. )



5. 命令键可以用来做什么?

比如, 命令建'r'(unraw) 在你X或者svgalib程序崩溃的时候就非常有用.


当你登录前想确定是否有木马进程在运行的时候, 命令键'k'(Secure Access  Key )也同样非常有效.它会杀死当前终端中的所有进程, 这样你就可以确定你看到的登录提示符是由init给出而不是由木马程序伪造的.
重要: 实际上它并不像符合C2安全等级的系统中的SAK那样是一个真正的SAK, 不过其效果与真正的SAK是等同的.
并且有些人还发现当他们想要退出那些阻止你切换到终的端程序时(比如X或者一个svgalib程序), 命令键'k'一样非常有效. 

命令键'b'(reboot)在你无法正常关机的时候很好用. 不过你应该在这之前使用命令键's'(sync)和命令键'u'(umount).

命令键'c'(crash)用来在系统挂起时手工触发一个崩溃转储. 注意: 这个操作仅仅用来在没有任何其他转储机制的情况下触发崩溃。

当你的系统锁死的时候, 命令键's'(sync) 是很有力的工具. 它可以让你同步磁盘缓冲, 以此来降低丢失数据和检测磁盘的几率. 注意: 只有你在屏幕上看到"OK"和"Done"的时候, 才表示sync操作已经完成.(如果你的内核确实处在非常糟糕的情况下, 那么你可能永远也看不到OK或者Done...)

基本上, 命令键'u'(umount)和's'有着同样的用处. 通常我在系统锁死的时候, 先使用's', 接着使用'u', 然后使用'r'. 这样让我少了很多检查硬盘的次数. 和's'一样,直到你看到了
"OK"和"Done"的时候, 才表示操作完成.

如果你的终端被你不想看到的内核信息刷屏的话,那么你要考虑在'0'~'9'之间调整日志等级. 选择日志等级'0'将会阻止最紧急的内核信息以外的信息出现在你的屏幕上.(当然, 如果syslogd/klogd在运行的话, 被阻止的信息依然会写入到日志文件中. )

命令键'e'(term)和命令键'i'(kill)可以有效的杀死那些无法用其它方法终止的失控进程, 在这些失控进程拥有子进程的时候尤为有效.

如果你的系统因为一个被FIFREEZE ioctl冻结的文件系统而不响应的话, 那么应该使用命令键 'j'.

6. 有时使用了SysRq以后出现了'stuck', 我应该怎么办?
我也碰到过这种情况. 通过按下键盘同一边的Shift, Alt和Ctrl, 然后再按下一个无效的sysrq组合键可以解决这种问题.(比如组合键Alt+SysRq+Z). 切换到其他终端再切换回来也应该能解决问题.

7. 我按了SysRq键以后没反应是什么问题?
有些键盘的SysRq键发出的scancodes和预定义的0x54不同. 如果你键盘上的SysRq键盘默认状态下不工作, 用命令:
代码:
showkey -s
找出它默认的scancodes序列, 然后使用命令:
代码:
setkeycodes <scancode序列> 84
来把它改变成预定义的SysRq键scancodes(84是0x54的十进制表示)。最好把这些写进一个开机脚本. 另外, 执行完showkey命令以后, 10秒内不要按键盘上的任何键.

8. 我想要在一个内核模块中加入SysRq keys events, 我应该怎么做?
(待译)

9. 为什么当我按下SysRq组合键以后, 终端上只显示了信息的头部?
像其他终端输出一样, SysRq的输出也受到终端的日志等级控制. 也就是说, 如果内核带有参数'quiet'启动(这在各发行版中很常见), 那么SysRq的输出信息虽然会写入dmesg的缓冲(可以通过dmesg命令或者/proc/kmsg文件看到),却不会出现在终端里. 但是作为一个特例, SysRq输出信息的头部被发送到所有终端, 就好像当前终端有着最高的日志等级. 如果只有信息的头部被打印出来,那么几乎可以肯定是因为内核参数设置的日志等级太低. 如果你需要临时提高终端的日志等级, 可以使用组合键Alt+SysRq+8, 或者用命令:
代码:
echo 8 > /proc/sysrq-trigger
记住使用完SysRq以后,把日志等级调回正常的值.

10. 我还有更多的问题, 谁能回答我?
我会尽可能快的回答你在SysRq上遇到的任何问题. --Crutcher

感谢:
Written by Mydraal <[email protected]>
Updated by Adam Sulmicki <[email protected]>
Updated by Jeremy M. Dolan <[email protected]> 2001/01/28 10:15:59
Added to by Crutcher Dunnavant <[email protected]>


原文出处及译文参考资料:
文档原文来自2.6.32版linux内核文档, 可从2.6.32版linux内核源码中获取. 
原文亦可从 http://lxr.linux.no/linux+v2.6.32/Do...tion/sysrq.txt 获取.
译文部分术语及SysRq命令键功能翻译参考了罗布<[email protected]>和张冬<[email protected]>的《利用SysRq键排除和诊断系统故障》.
《利用SysRq键排除和诊断系统故障》( http://www.ibm.com/developerworks/cn/linux/l-cn-sysrq/ )中对部分SysRq命令键做了更详细的解释, 同时也例举了更多SysRq使用实例.

译注: 
因为本人对于编程开发几乎一窍不通, 所以涉及到内核模块开发的第8部分不敢贸然翻译, 希望能有专业人士完成此部分的翻译. 另外由于个人水平所限, 以及疏忽, 难免出现错误, 希望读者指正.

你可能感兴趣的:(Linux Magic System Request Key Hacks)