该操作显示了 cpu 相关分区信息,全局页使用情况,分区页使用情况,分区 slab 使用情况,页缓存使用情况,swap 使用情况等等。
P - 打印当前 CPU 寄存器信息
SysRq : Show Regs Pid: 0, comm: swapper EIP: 0060:[<c042a771>] CPU: 0 EIP is at __do_softirq+0x51/0xbb EFLAGS: 00000286 Not tainted (2.6.18-92.el5 #1) EAX: c0722380 EBX: 00000002 ECX: c072b000 EDX: 00ce1e00 ESI: c06ddb00 EDI: 0000000a EBP: 00000000 DS: 007b ES: 007b CR0: 8005003b CR2: b7f85000 CR3: 14d6f000 CR4: 000006d0 [<c0407461>] do_softirq+0x52/0x9d [<c04059bf>] apic_timer_interrupt+0x1f/0x24 [<c0403b98>] default_idle+0x0/0x59 [<c0403bc9>] default_idle+0x31/0x59 [<c0403c90>] cpu_idle+0x9f/0xb9 [<c06ec9ee>] start_kernel+0x379/0x380 ======================= |
该操作显示了正在执行的进程名,运行函数,寄存器上下文,以及程序的调用栈回溯等信息。这对于分析死锁引起的系统挂起有着非常重要的作用。一般来说我们会多采几次重复样本,以便更加准确的做出系统运行状态的判断。
T - 打印进程列表
SysRq : Show State sibling task PC pid father child younger older …… (snip) …… syslogd S 00003280 2104 4313 1 4316 4279 (NOTLB) dfc1cb68 00000082 b9d5334a 00003280 dd931a70 dd931a70 e08e9376 00000007 dfc1eaa0 c06713c0 b9d85c35 00003280 000328eb 00000000 dfc1ebac c1404fe0 00000010 df4f79c0 df4bd53c c0457dc0 df6438f4 ffffffff 00000000 00000000 Call Trace: [<e08e9376>] ext3_mark_iloc_dirty+0x2d8/0x333 [ext3] [<c0457dc0>] mempool_alloc+0x28/0xc9 [<c06084b1>] schedule_timeout+0x13/0x8c [<c05ac8f2>] datagram_poll+0x15/0xb8 [<c0480ed8>] do_select+0x371/0x3cb [<c048145b>] __pollwait+0x0/0xb2 …… (snip) …… [<c0429566>] do_setitimer+0x4a6/0x4b0 [<c04817d7>] sys_select+0xcf/0x180 [<c0404eff>] syscall_call+0x7/0xb ======================= klogd R running 2664 4316 1 4369 4313 (NOTLB) |
该操作显示了进程列表,包含各进程的名称,进程 PID,父 PID 及兄弟 PID 等相关信息,以及进程的运行状态。对于正在运行中的进程(R),没有太多的信息。对于处于睡眠状态的进程,列出其调用栈回溯信息,以便进行调试跟踪。由于篇幅关系,去掉了大部分冗余的信息。
W - 打印 CPU 信息
SysRq : Show CPUs CPU0: c074be84 00000000 00000000 c053a1fa d23c0000 c0406531 c062ccf1 c0650e94 00000000 00000000 c053a221 c0641b83 00000000 c042a111 00000000 c068c630 00000001 00000077 c053a0cd 00000000 c053a14d c0640322 c0641d0f c06e7fa4 Call Trace: [<c053a1fa>] showacpu+0x0/0x32 [<c0406531>] show_stack+0x20/0x25 [<c053a221>] showacpu+0x27/0x32 [<c042a111>] on_each_cpu+0x17/0x1f [<c053a0cd>] sysrq_handle_showcpus+0x10/0x12 [<c053a14d>] __handle_sysrq+0x7e/0xf6 [<c053a1d5>] handle_sysrq+0x10/0x12 [<c053567d>] kbd_event+0x2e0/0x507 [<c058e1c1>] input_event+0x3e6/0x407 [<c0591a2b>] atkbd_interrupt+0x3f5/0x4da [<c058b058>] serio_interrupt+0x33/0x6a [<c058bcb6>] i8042_interrupt+0x1dd/0x1ef [<c044dd9b>] handle_IRQ_event+0x23/0x49 [<c044de45>] __do_IRQ+0x84/0xd6 [<c04073f4>] do_IRQ+0x93/0xae [<c040592e>] common_interrupt+0x1a/0x20 [<c0403b98>] default_idle+0x0/0x59 [<c0403bc9>] default_idle+0x31/0x59 [<c0403c90>] cpu_idle+0x9f/0xb9 [<c06ec9ee>] start_kernel+0x379/0x380 ======================= CPU1: c14a1f40 00000000 00000000 00000000 00000000 c0406531 c062ccf1 c0650e94 00000000 00000000 c053a221 c0641b83 00000001 c0417b4c 00000001 c040599b 00000001 c0403b98 c14a1000 00000000 00000000 00000000 00000000 0000007b Call Trace: [<c0406531>] show_stack+0x20/0x25 [<c053a221>] showacpu+0x27/0x32 [<c0417b4c>] smp_call_function_interrupt+0x39/0x52 [<c040599b>] call_function_interrupt+0x1f/0x24 [<c0403b98>] default_idle+0x0/0x59 [<c0403bc9>] default_idle+0x31/0x59 [<c0403c90>] cpu_idle+0x9f/0xb9 ======================= |
该操作显示了每 CPU 的寄存器上下文和程序调用栈回溯信息。
其它功能键组合
H - 帮助
SysRq : HELP : loglevel0-8 reBoot Crashdump tErm Full kIll saK showMem Nice powerOff showPc unRaw Sync showTasks Unmount shoWcpus |
它显示了当前系统支持的所有 SysRq 组合,所有的按键均用大写字母表示。
0-8 - 更改 console_loglevel
SysRq : Changing Loglevel Loglevel set to 6 |
上面是 SysRq-6 的输出,它等同于 echo "6" > /proc/sys/kernel/printk 操作,将 console_loglevel 设置为 6 。
C - 触发 Crashdump
SysRq : Trigger a crashdump Kexec: Warning: crash image not loaded Kernel panic - not syncing: SysRq-triggered panic! |
在大多数情况下,我们通过前面的方法即可完成对系统挂起的基本诊断和数据收集。但是在一些特殊情况下,我们仍然需要一份完整的 crashdump 。毕竟 crashdump 包含比 SysRq – MPT 更多的信息,以利用后期做故障分析。
N - 降低实时任务运行优化级
SysRq : Nice All RT Tasks |
这对于由实时任务消耗 CPU 引起的系统挂起会起到立竿见影的作用。
O - 关机
SysRq : Power Off |
该操作会立即关机,一般很少使用。在必要的情况下,也推荐跟随 S – U 一起使用。
结束语
SysRq 的处理机制可圈可点,它能够在系统处于极端环境时响应按键并完成相应的处理。这在大多数时候有用,但也不是绝对的。一种情况是由于磁盘故障 syslogd 可能不再会往磁盘回写 log,因此 SysRq 输出将得不到记录。即使配置了 netconsole,如果恰好是网络相关功能出现错误时,也可能导致 SysRq 输出不可记录。相比之下,将服务器串口终端打开并用软件记录输出的方式虽然原始,但也相对保险。无论如何,SysRq 已经在大多数情况下帮到大忙了。
笔者认为,SysRq 在处理系统挂起时安全重启方面已经比较完善了。但是在提供故障诊断方面还有可待改进的地方。通过现有的 M-P-T 等信息,很难判断每一次系统挂起的真正原因。现实世界的信息总是综合多变的,如果能够提供包括网络 I/O,磁盘 I/O,进程的 CPU 及内存使用情况等等与性能方面的数据,虽然会产生一定的开销,但对于系统挂起时的故障分析来讲,是利大于弊的。
本文的下篇将讲述如何扩展自定义的 SysRq 请求,以便在系统挂起时获取更为丰富的诊断信息,通过这些信息来判断系统挂起的原因,并快速准确的化解它们。(责任编辑:A6)