SysRq 键 - Linux 系统崩掉前最后的救命稻草
Preface
今天看英语语法的时候 随意的看了一眼键盘,意外的发现 除了 pause
break
和 scroll
这几个键以外,还有个 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 立即重启系统