本文从一次典型的系统挂起事件,引出 SysRq 键的用途。然后介绍了如何启用 SysRq,以及使用 SysRq 的两种方式。接着通过 SysRq 在不同场合的用途分别介绍了各个功能键的使用,并对每个功能键的样例输出做了简单分析。最后,笔者从自身角度对 SysRq 功能做了一个简单的评价,并提供了一部分参考资料,以便读者进一步了解 SysRq 。本文所有操作实例均在 RHEL5u2 x86/kernel 2.6.18-92 上进行,体系与内核的差异会对 SysRq 的信息收集和显示有少许影响,详情请参考内核文档中的 sysrq.txt 关于平台部分的描述。
SysRq 是什么
你是否遇到服务器不能通过 SSH 登录,也不能通过本地终端登录,但是却能 ping 通,数字键盘锁还可以响应击键操作的情况?在这种情况下,你除了按下电源或复位键之外,还做过什么吗?你是否想过这种情况是可能恢复的呢?你是否想过收集更多的信息来定位这次系统挂起的原因呢?上述情况,可称之为“可中断的系统挂起”。换句话来讲,系统因为某种原因已经停止对大部分正常服务的响应,但是系统仍然可以响应键盘的按键中断请求。在这种情况下,一组称为 SysRq 的按键组合将发挥它的神奇作用。
SysRq 经常被称为 Magic System Request,它被定义为一系列按键组合。之所以说它神奇,是因为它在系统挂起,大多数服务已无法响应的情况下,还能通过按键组合来完成一系列预先定义的系统操作。通过它,不但可以在保证磁盘数据安全的情况下重启一台挂起的服务器,避免数据丢失和重启后长时间的文件系统检查,还可以收集包括系统内存使用,CPU 任务处理,进程运行状态等系统运行信息,甚至还可能在无需重启的情况下挽回一台已经停止响应的服务器。
启用 SysRq
内核的支持
要启用 SysRq 功能,首先必须确保内核已经加入 CONFIG_MAGIC_SYSRQ 支持。在现今 Linux 发行版中,无一例外的均已加入该功能的支持,验证如下:
# grep “ CONFIG_MAGIC_SYSRQ ” /boot/config-`uname – r` CONFIG_MAGIC_SYSRQ=y |
通过 sysctl 启用
SysRq 功能默认在 RHEL5u2 上是禁用的。可以通过 proc 文件系统来启用它。使用 sysctl 命令启用它,并通过 /proc 来检查其可用性。
# sysctl -w kernel.sysrq=1 kernel.sysrq = 1 # cat /proc/sys/kernel/sysrq 1 |
kernel.sysrq 还可接受除 0 和 1 以外的启用参数,详情请参考 sysrq 内核文档。
保持重启后生效
通过把” kernel.sysrq = 1 ”设置到 /etc/sysctl.conf 中,可以使 SysRq 在下次系统重启后仍然生效。请注意,在非 RHEL 系统中,也许需要通过其它的配置文件来使之重启后生效。
使用 SysRq
网上有道题,问在只有 shell,init、halt、shutdown 等命令都不工作的情况下如何重启系统。答案就是 SysRq,通过 SysRq – B 来完成系统的重启。
早期的 SysRq 只支持键盘操作。要使用 SysRq,必须直接对主机进行键盘操作。要想执行 SysRq-B 来重启系统,只能通过直接键盘操作 Alt – SysRq – B 来完成(这里的 B 仅指 B 按键,不区分大小写)。 kernel 2.5.64 上的一个 patch 增加了 /proc/sysrq-trigger 接口,使得用户可能通过 /proc 接口来进行 SysRq 操作,换而言之,在现今大部分构建在 2.6 内核上的发行版,对主机键盘的物理接触已经不再是 SysRq 的必要条件。用户只需要登录到系统上,就可以直接使用 echo “ b ” > /proc/sysrq-trigger 来重启系统。在下文中,为描述的简洁,SysRq-<?> 均代表 Alt-SysRq-<?> 或者 echo “ ? ” > /proc/sysrq-trigger 。
众所周知,系统挂起的很多时候 ssh 登录也未必响应,在缺乏对主机物理操作条件下,/proc/sysrq-trigger 也因为无法获取登录 shell 而无法操作。于是出现了一个名为 sysrqd 的开源项目,它允许通过网络来直接来触发 SysRq 。该程序只有 300 行左右代码,监听 TCP 端口 4094,通过自定义密码验证过后,即可对 /proc/sysrq-trigger 进行操作。但是由于此程序在用户空间实现,在系统挂起时该程序的可用性,以及其安全性均受到广泛质疑。其实如果这个服务做到内核空间,以类似响应 ARP 形式进行处理,再加上合理的认证方式,或许在大多数系统挂起的时候可以起到更加实际的作用。当然,在现代服务器的远程管理模块日趋先进的前提下,是否能通过网络来触发 SysRq 好像并不是那么重要。
查看 SysRq 输出
SysRq 并不只能重启服务器,如果只是这样,那我们也不需要查看它的输出了。很多时候,我们使用 SysRq 是为了查看服务器的 CPU,内存或进程信息。 SysRq 默认会输出到本地控制台终端,并写入 syslog,但这并不是个好主意。因为对于大多数系统挂起的情况,我们已经无法再访问这两个信息源,在无法判定系统故障的情况下,只好无奈的使用后面即将介绍的 R-E-I-S-U-B 序列来重启服务器。接下来将介绍 SysRq 输出的几种方法。只有最大程度的获取到 SysRq 输出,才能更好的利用 SysRq 提供的其它功能。
输出到本地终端
SysRq 默认会根据 console_loglevel 输出到本地终端。只要 console_loglevel 大于 default_message_loglevel,SysRq 信息就会输出到本地控制台终端。它在测试的时候都好用,但一到关键时刻,系统挂起无法切换,大量输出造成滚屏,以及信息无法记录等问题随之而来。
输出到 syslog
根据 syslog 的默认配置,SysRq 默认会记录到 /var/log/messages,并且这里记录的信息与 console_loglevel 无关,基本是完整的。但是由于负责记录日志的 syslogd 本身也是一个用户进程,在执行后面即将介绍的 SysRq-E, SysRq-I 时也会被终结,这就意味着 syslog 记录的信息在一定情况下将不再完整。同时由于系统挂起时查看 syslog 日志本身就是一件难上加难的事,这里记录的信息往往只能用在系统恢复过后的故障分析,对故障发生时的实时诊断并没有太大的帮助。
通过 netconsole 输出
利用 netconsole 功能,可以获得一个通过远程 syslog 服务器输出的显示终端,服务器的 SysRq 输出将被远程的 syslog 服务器捕获。在服务器挂起,无法查看 syslog 日志,同时也无法切换到本地控制台终端的时候,这种形式的输出就显得举足轻重。与本地终端类似,只要 console_loglevel 大于 default_message_loglevel,SysRq 信息就会通过 netconsole 输出到远程。它在大多数情况都生效,哪怕是内核网络部分出现问题。因为 netconsole 的网络发送部分是独立存在的,并不依赖于网卡驱动程序。
输出到串口终端
要想通过串口获取 SysRq 输出,首先需要在 grub 的 kernel 行添加类似 ” console=ttyS0,115200 ” 的串口输出配置,重启服务器以启用内核串口输出。然后从另一台主机上用串口线连接服务器,并用 minicom 等程序捕获其输出。这是一种通常的使用方式。然而利用 Serial over IP 产品,管理员无需现身嘈杂的机房就能通过网络获得服务器的串口输出,查看并截取字符形式的输出。这是相对现代的使用方式。通过这两种方式,我们都可以方便的获取到 SysRq 在串口上输出。
SysRq 功能键组合
安全重启系统
到目前为止,我们可见到的大多数 SysRq 推荐用法都是系统挂起后的安全重启,用此方法来避免数据丢失。这个 SysRq 序列是 R-E-I-S-U-B 。要知道,该序列早在 SysRq 首次于 Linux 实现的 2.1.43 内核中就存在了。它基本等价于 reboot 命令,会依次停止系统上运行的进程,回写磁盘缓冲区,再安全的重启系统。需要注意的是,E 会向除 init 以外所有进程发送可捕获的 SIGTERM 信号,这就意味着程序可能需要一定时间来进行结束进程前的善后处理,视系统负载和任务数量,这个时间可能会达到几十秒。 I 发送的是不可捕获的 SIGKILL 信号,相对而言没有更多的延迟。同时,S 和 U 这两个动作均与磁盘相关。当系统具有一定负载时,这两个动作均不会立即完成,而是需要一定的时间,通常为几秒钟。所以,R-E-I-S-U-B 这个序列的推荐使用方式是:R – 1 秒 – E – 30 秒 – I – 10 秒 – S – 5 秒 – U – 5 秒 – B,而不是一气呵成地按下这六个键,试想一次正常的 reboot 命令也不是在一瞬间完成的吧。
下面列出各个序列的示例输出及简单说明:
R - 把键盘设置为 ASCII 模式
SysRq: Keyboard mode set to XLATE |
有关键盘工作模式,请参考资料中的 kbd_mode 手册。
E - 向除 init 以外所有进程发送 SIGTERM 信号
SysRq: Terminate All Tasks |