1 [17899.255261] sysrq: SysRq : HELP : loglevel(0-9) reboot(b) crash(c) terminate-all-tasks(e) memory-full-oom-kill(f) kill-all-tasks(i) thaw-filesystems(j) sak(k) show-backtrace-all-active-cpus(l) show-memory-usage(m) nice-all-RT-tasks(n) poweroff(o) show-registers(p) show-all-timers(q) unraw(r) sync(s) show-task-states(t) unmount(u) force-fb(V) show-blocked-tasks(w) dump-ftrace-buffer(z)
SysRq 鍵在 QWERT 鍵盤上與 PrtSc
同鍵,通過按下 ALT+SysRq+<command key>
可以直接向linux kernel發送預設的系統操作指令。 這套組合鍵提供了一系列在系統崩潰時常用到的功能,比如同步數據、殺進程、卸載文件系統,甚至系統重啟
轉自:http://blog.lujun9972.win/blog/2018/08/22/linux%E4%B8%8B%E7%9A%84sysrq%E9%94%AE/index.html
啟用SysRq
對內核的要求
啟用 SysRq
的前提是在linux kernel編譯時啟用了 CONFIG_MAGIC_SYSRQ
選項.
在目前主流的發行版linux中都啟用了該選項,但若你是自己編譯的內核,則有必要搜索一下內核的config文件了,確保里面有一句
CONFIG_MAGIC_SYSRQ=y
內核中還有一個與SysRq相關的配置項:
CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x01b6
這個配置項指定了默認SysRq的值,這個值表示kernel會對哪些功能產生反應。
查看當前SysRq的值
我們可以通過查看 /proc/sys/kernel/sysrq
的值來判斷Kernel會對哪些功能產生反應.
cat /proc/sys/kernel/sysrq
16
這里你會看到一個數字,這個數字可以轉換成一個9位比特的形式,其中每一位的比特都有一個含義如下:
數字 | 位數 | 意義 |
---|---|---|
0 | 1 | 完全禁用sysrq |
1 | 1 | 允許所有的sysrq功能 |
2 | 2 | 允許控制終端日志級別 |
4 | 3 | 允許控制鍵盤輸入類型(SAK,unraw) |
8 | 4 | 允許調試進程dump |
16 | 5 | 允許執行sync命令 |
32 | 6 | 允許重新掛載文件系統為之讀 |
64 | 7 | 允許發送信號給進程(term,kill,oom-kill) |
128 | 8 | 允許重啟/關機 |
256 | 9 | 允許調整實時任務的優先級 |
因此,我這里的 16
表示允許通過 SysRq 來同步數據到磁盤中去, 而數字 130
轉換成二進制就是 010000010
,根據表中的對應關系很容易看出允許重啟/關機以及調整終端日志級別。
更改SysRq的值
如果只是希望臨時更改 SysRq
的值,那么很簡單,只需要將新的值寫入到 /proc/sys/kernel/sysrq
中去
echo "1" |sudo tee /proc/sys/kernel/sysrq
或者通過 sysctl
來進行設置
sysctl -w kernel.sysrq=1
如果需要每次啟動時都自動修改SysRq的值,則需要修改配置文件
echo "kernel.sysrq = 1"|sudo tee -a /etc/sysctl.conf
使用SysRq
使用SysRq有兩種方式:
一種是直接通過鍵盤 Alt+SysRq+<command key>(部分筆記本上是Alt+Fn+PrtSrc+<command key>)
來出發,
還有一種是直接通過 /proc/sysrq-trigger
接口來完成.
echo “ b ” |sudo tee /proc/sysrq-trigger
其中,這里每個 command-key
都對應一種kernel的行為,而且需要說明的是,不同種類的鍵盤上,相同kernel行為對應的 command-key
居然是不同的!
下面表格就是各個kernel行為對應的 command-key
的說明:
Action | QWERTY | Dvorak | AZERTY | Colemak |
---|---|---|---|---|
設置控制台日志級別(console_loglevel),它決定了哪些kernel信息會被輸出到控制台上 | 0 - 9 | 0 - 9 | 0 - 9(without ⇧ Shift) | 0 - 9 |
不同步並卸載文件系統,立即重啟系統 | b | x | b | b |
讓系統立即崩潰. 在配置得當的情況下會產生一個 crashdump | c | j | c | c |
顯示所有排它鎖 (需要內核啟用CONFIG_LOCKDEP選項) | d | e | d | s |
發送 SIGTERM 信號到除了 init (PID 1) 外的所有進程 | e | . | e | f |
觸發 oom_kill, 會隨機殺掉一個進程以緩解 OOM | f | u | f | t |
當進入內核模式時,切換到內核的 framebuffer 控制台. 若有內核調試器 kdb,則進入該調試器中 | g | i | g | d |
在控制台上輸出一個簡短的幫助信息. (其他不能識別的key也會輸出幫助信息) | h | d | h | h |
發送 SIGKILL 信號到除了 init (PID 1) 外的所有進程 | i | c | i | u |
強制通過 FIFREEZE ioctl 凍結文件系統. | j | h | j | n |
殺掉當前虛擬控制台中的所有進程 (包括 X 和 SVGALib 程序). | k | t | k | e |
列出所有活動CPU上的 stack backtrace | l | n | l | i |
在控制台上輸出當前內存信息 | m | m | , | m |
重置所有高優先級和實時任務的 nice 級別 | n | b | n | k |
關閉系統 | o | r | o | y |
在控制台輸出當前寄存器和標志位信息 | p | l | p | ; |
Display all active high-resolution timers and clock sources. | q | ' | a | q |
將鍵盤從 raw 模式(常被諸如X11和SVGALib這樣的程序所使用)切換到 XLATE模式 | r | p | r | p |
同步所有已掛載的文件系統 | s | o | s | r |
在控制台輸出當前任務列表 | t | y | t | g |
重新以只讀模式重新掛載所有已掛載的文件系統 | u | g | u | l |
強制恢復 framebuffer console. 若為ARM處理器,則會導致 ETM buffer dump. | v | k | v | v |
顯示所有阻塞狀態(狀態為D)的任務 | w | , | z | w |
Used by xmon interface on PPC/PowerPC platforms. | x | q | x | x |
顯示全局的CPU寄存器內容 (僅對SPARC-64平台有效) | y | f | y | j |
Dump the ftrace buffer | z | ; | w | z |
輸出一份簡單的系統支持SysRq的鍵列表 | space | space | space | space |
常見的幾種功能鍵組合
下面列出幾個常見的功能鍵組合:
R-E-I-S-U-B:安全重啟系統
這套組合鍵大致相當於reboot命令:
- unRaw – 把鍵盤設置為 XLATE 模式,使按鍵可以穿透 x server 捕捉傳遞給內核
- tErminate – 向除 init 外進程發送 SIGTERM 信號,讓其自行結束. 這一步推薦等待30秒讓進程有足夠的時間進行收尾的嗯做。
- kIll - 向除 init 以外所有進程發送 SIGKILL 信號,強制結束進程. 這一步推薦等待10秒,保證所有進程都退出了
- Sync – 同步緩沖區數據到硬盤,避免數據丟失. 這一步在能看到輸出的情況下等到"Emergency Sync complete" 后再做后續動作,否則推薦等待10秒
- Unmount – 將所有已經掛載的文件系統 重新掛載為只讀. 該操作通常也有一定延時,請等到"Emergency Remount complete" 出現過后再進行后續操作,否則推薦等待10秒
- reBoot - 立即重啟計算機
恢復系統掛起
若僅僅是因為資源消耗過量引起系統掛起就重啟系統顯然是不好的,我們可以嘗試通過回收一些資源的方式來回復系統掛起。
SysRq中用來結束進程的command-key包括 E-I-K-F,其中:
- E 和 I 太凶殘,它會殺掉除了 init 外的所有進程,屬於殺敵一千自損八百的操作。因此在一般情況下不會輕易使用
- F 則是利用 OOM-Kiler選擇一個進程來結束,對於由於內存不足引起的掛起比較有效,但有時候OOMKiller也可能會誤判殺掉一些長期運行的后台程序。
- K 殺掉與當前控制台有關的進程組,比較推薦用這種方法回復系統
此外,若系統掛起是由於實時任務消耗太多CPU引起的,則可以通過 N
來降低實時任務運行的優先級來緩解掛起症狀。
獲取系統信息
SysRq還提供了幾個用於獲取系統信息的commandkey,在恢復系統掛起前推薦執行這些commandkey,以記錄下當前系統狀態。
- M
- 打印內存使用信息
- W
- 打印CPU寄存器上下文和程序調用棧回溯信息
- P
- 打印CPU寄存器信息,比如正在執行的進程名,運行函數,寄存器上下文,以及程序的調用棧回溯等
- T
- 打印進程列表,各進程的名稱,進程 PID,父 PID 兄弟 PID 以及進程運行狀態等相關信息
查看SysRq的輸出信息
從上面的列表中我們可以看到,使用SysRq能夠輸出大量的信息。這些信息,默認會輸出到syslog中. 同時,若設置的 console_loglevel(0-9)
大於 default_message_loglevel
則輸出也會輸出到本地控制台終端上去。 另外,若設置的 console_loglevel
大於 default_message_loglvel
則輸出還會通過netconsole輸出到遠程機器上去。
總體來說,syslog中記錄的日志應該是最完整的,然而由於負責記錄日志的 syslogd
本身是一個用戶進程,在某些情況下可能會被殺掉,從而導致日志記錄不下來。
echo " "|sudo tee /proc/sysrq-trigger dmesg |tail -n 1
[17899.255261] sysrq: SysRq : HELP : loglevel(0-9) reboot(b) crash(c) terminate-all-tasks(e) memory-full-oom-kill(f) kill-all-tasks(i) thaw-filesystems(j) sak(k) show-backtrace-all-active-cpus(l) show-memory-usage(m) nice-all-RT-tasks(n) poweroff(o) show-registers(p) show-all-timers(q) unraw(r) sync(s) show-task-states(t) unmount(u) force-fb(V) show-blocked-tasks(w) dump-ftrace-buffer(z)