Hotaru's Notebook

SysRq 键 - Linux 系统崩掉前最后的救命稻草

Preface

今天看英语语法的时候 随意的看了一眼键盘,意外的发现 除了 pause breakscroll 这几个键以外,还有个 SysRq。然后查了一下,发现这个键在 Linux 下大有用途:

In Linux, the kernel can be configured to provide functions for system debugging and crash recovery. This use is known as the “Magic SysRq key”. 在 Linux 下,通过对内核进行配置 可以让它来提供一些功能,比如调试操作系统以及崩溃恢复(Crash Recovery)。这种 SysRq 用法被称之为 “Magic SysRq key”。 - System request - wikipedia.org

当 Linux 系统崩溃但还没到 kernel panic 的地步的时候(比如 CPU soft lockup),就可以使用这棵最后的救命稻草。下面我就来介绍一下 SysRq 的使用方法。

sysctl 简单介绍

有些发行版上的 SysRq 功能是关闭的,想开启它的话需要修改配置文件 /etc/sysctl.conf 并配合 sysctl 命令使配置生效。 sysctl.conf 文件的基本格式:每一行放一条属性,格式为 <variable>=<value>,比如开启 SysRq 的话就是 kernel.sysrq=1。 修改 sysctl.conf 后不会立即生效,需要执行命令 sysctl -p 来重新载入 /etc/sysctl.conf。 还有一种方法可以使配置立即生效:使用命令 sysctl -w <variable>=<value>,但重启系统后会失效。

其实 sysctl -w-w 不写也行,有 -w 参数的话 在按 Tab 自动补全时候会在 <variable> 末尾自动加上个 =,仅此而已。

配置 kernel.sysrq 属性

使用命令 sysctl kernel.sysrq 可以获取这个属性的值,有些系统上值为 0,有些则是 176,这些值的含义如下表所示:

bin dec hex 说明
0 0000 0000 0 0x0 禁用 SysRq 的全部功能
0 0000 0001 1 0x1 启用 SysRq 的全部功能
0 0000 0010 2 0x2 允许修改控制台日志级别
0 0000 0100 4 0x4 允许修改对键盘的控制(SAK, unraw)
0 0000 1000 8 0x8 允许进程的调试转储(Debugging dumps) 等等
0 0001 0000 16 0x10 允许同步命令
0 0010 0000 32 0x20 允许重新挂载(remount)为只读
0 0100 0000 64 0x40 允许给进程发信号(term, kill, oom-kill)
0 1000 0000 128 0x80 允许重启/关机
1 0000 0000 256 0x100 allow nicing for all RT tasks

176 这个值不存在于上面这个表里,其实应该把它转换成2进制来看 0 1011 0000,或者这样 176 = 128 + 32 + 16

0 1 0 1 1 0 0 0 0
  128   32 16        

也就是只使用了下面这3个:

bin dec hex 说明
0 0001 0000 16 0x10 允许同步命令
0 0010 0000 32 0x20 允许重新挂载(remount)为只读
0 1000 0000 128 0x80 允许重启/关机

比如如果我需要 “同步命令” “重新挂载为只读” “允许重启/关机” “修改对键盘的控制” “给进程发信号”,那就把它们对应的十进制数字都加起来就行了,也就是 16(同步命令) + 32(重新挂载为只读) + 128(允许重启/关机) + 4(修改对键盘的控制) + 64(给进程发信号) = 244,然后设置 kernel.sysrq=244 就能拥有上述功能了。

使用 SysRq 快捷键

使用方法很简单,按下 Alt + SysRq + 下表里任一字母注: 有些 SysRq 键和 PrintScreen 是同一个键,但使用方法和上面一样。 注2: 下面表格翻译得很烂,建议阅读 原文

字母 作用
b 立即重启电脑并且不会同步和卸载文件系统,与直接按下主机上的 RESET 按钮等效
c 通过空指针解引用来触发异常导致 kernel panic 来获取 crashdump(如果配置了 crashdump 的话)
d 显示所有锁,比如 CPU soft lockup
e 发送 SIGTERM 给所有进程,但不包括 init 进程
f 让 OOM Killer 杀掉所有特别吃内存的进程,如果没有进程被杀则不会触发 panic
g 由 kgdb 使用 (kernel debugger)
h 显示帮助信息(任何不在帮助信息列表里的键可以,但是 h 更好记一些)
i 发送 SIGKILL 给所有进程,但不包括 init 进程
j 强制解冻所有由 FIFREEZE ioctl 冻结的文件系统
k 杀掉当前虚拟控制台的所有进程(借此可以在登录tty时避免被病毒窃取密码)
l 显示目前所有活动的CPU的调用栈(stack backtrace)
m 转储目前的内存信息并打印到控制台
n 让所有实时性的任务的优先级可调(nice-able)
o 立即关机
p 转储当前寄存器(current registers)和标志(flags)到控制台
q 显示所有计时器
r unraw, 比如 xorg 卡死了, 用这个就可以从 xorg 夺取对键盘的控制权
s 将所有未写入硬盘的数据立即写入硬盘(与 sync 命令等效)
t 显示当前所有任务及其信息到控制台
u 尝试将所有已挂载的文件系统挂载为只读
v 强制恢复帧缓冲(framebuffer)控制台
w 显示所有卡住了的任务
z 转储 ftrace buffer
0~9 设置内核打印消息到屏幕的日志级别, 0 则只打印 panic 之类的, 值越大打印得越详细

一个比较常见的用法就是当系统几乎完全 down 掉的情况下,依次执行 REISUB,展开来就是 “Reboot Even If System Utterly Broken”,解释如下:

unRaw       从 X.org 夺回键盘的控制权
 tErminate  发送 SIGTERM 给所有进程,所有进程正常的结束自己
 kIll       发送 SIGKILL 给所有进程,强制杀掉所有进程
  Sync      将所有未写入硬盘的数据立即写入硬盘
  Unmount   将所有已挂载的文件系统挂载为只读
reBoot      立即重启系统

References

  1. System request - wikipedia.org
  2. Magic SysRq key

#Linux #SysRq