通常在出現系統崩潰後,大家會擔心再次出現故障,但是發現系統各日志中並沒有記錄到任何死機前後的信息,無法分析故障原因,認為已經無藥可救。但是,實際上,Linux 有多種機制來保證發生系統崩潰後,可以獲取有價值的信息用以分析問題。確定是硬件故障,還是應用程序bug 導致的。
Linux 中,有如下幾種方法來獲取各種崩潰時產生的信息。
1.Core dump
Core dump 通常用來調試應用程序錯誤,當某些應用程序運行出現異常崩潰時,可以開啟系統的 core dump 功能,來得到一個程序崩潰時的內存信息,用來分析崩潰原因:
在/etc/profile裡加上(或者修改)一條:
ulimit -c 0
運行命令:sysctl -w "kernel.core_name_format=/coredump/%n.core"
該命令意思是指core文件放在/coredump目錄下,文件名是進程名+.core
2.Diskdump
diskdump工具提供了在單機上創建和采集vmcore(kernel dump)的能力,而無須使用網絡。當內核本身出現崩潰的時候,當前的內存和CPU狀態以及相關的信息都會被保存到一個支持diskdump的磁盤上的保留分區上。在下一次重新啟動的時候,當系統重新啟動,diskdump的初始化腳本會從保留分區中讀取保存的信息並創建一個vcore文件,然後這個文件被再次存放到/var/crash/目錄下,文件名為127.0.0.1-
如下是一個配置 HP SCSI 設備上啟用 diskdump 的過程,如果不是 HP SCSI 設備(即設備名為 /dev/sdX的形式),則無須執行第三、四兩個步驟。但需要在第一步前先執行命令: modprobe
diskdump
第一步:編輯 /etc/sysconfig/diskdump文件,將一個空白分區的設備名填入後保存退出,例如:
DEVICE=/dev/cciss/c0d0p2
第二步:初使化 dump 設備
#service diskdump initialformat
警告:該分區的所以數據會丟失。
第三步:使用 cciss_dump 模塊替換當前的 cciss 模塊:
在 /etc/modprobe.conf 找到如下行:
alias scsi_hostadapter cciss
修改為:
alias scsi_hostadapter cciss_dump
再增加一行:
options cciss_dump dump_drive=1
注:假設diskdump文件中配置的為 /dev/cciss/c0d[#a]p[#b], 請設置為: options cciss_dump dump_drive=[#a]
第四步:重建 initrd 文件:
#mv /boot/initrd-`uname -r`.img /boot/initrd-`uname -r`.img.old
#mkinitrd /boot/initrd-`uname -r`.img `uname -r`
第五步:設置 diskdump 服務能夠開機自啟動:
# chkconfig diskdump on
3.Netdump
如果使用紅旗DC4.0 或 3.0 版本系統,是不能支持 diskdump 的,可以利用netdump 來達到輸出vmcore 的目的。但是Netdump要求至少有一個服務器以及任意數目的客戶端。服務器用來接收客戶端死機時的信息,客戶端是經常死機的機器。
(一)服務器配置:
(1).檢驗netdump服務器是否安裝完畢:
rpm -q netdump-server
如果未安裝,請在光盤 RedFlag/RPMS/ 目錄中找到 netdump-server 打頭的軟件包,執行命令:
rpm -ivh netdump-server-x.x.x.rpm (x為版本號)
進行安裝。
(2).服務器包安裝後,用命令:
passwd netdump
更改用戶的密碼.
(3).打開服務:
chkconfig netdump-server on
(4).運行服務器:
service netdump-server start
(二)客戶端配置:
(1).校驗客戶端是否已安裝
rpm -q netdump
如果未安裝,在光盤 RedFlag/RPMS/ 目錄中找到 netdum 打頭的軟件包,執行命令:
rpm -ivh netdump-x.x.x.rpm (x為版本號)
安裝.
(2).編輯文件/etc/sysconfig/netdump,添加如下行:
DEV=eth0
NETDUMPADDR=172.16.81.182
NETDUMPMACADDR=00:0C:29:79:F4:E0
172.16.81.182指 netdump 服務器地址。
(3).運行下面的命令,出現提示符時輸入密碼:
service netdump propagate
(4).打開客戶端:
chkconfig netdump on
(5).運行客戶端:
service netdump start
(6).測試
為了測試netdump的配置是否正確,在netdump客戶機上做下面操作:
cp /usr/share/doc/netdump-xxxxxx/crash.c .
gcc -DKERNEL -DMODULE -I/lib/modules/$(uname -r)/build/include -c crash.c
insmod ./crash.o
這會造成系統崩潰,你會在netdump服務器的/var/crash/<客戶端IP>/目錄下,看到一個核心轉儲。當客戶機正在轉儲數據到服務器的時候,你會看到一個名叫“vmcore-incomplete"的文件。當轉儲結束後,該文件會改名成 "vmcore"。"vmcore"文件的大小會變化,可能達到幾個GB.在一個內存是512M的系統上,上面的測試會產生大約510M的vmcore文件。
怎麼判斷網卡是否支持netdump功能?
內核調試工具netdump需要網卡驅動支持netpoll功能。netpoll的目的是讓內核在網絡和I/O子系統尚不能完整可用時,依然能發送和接收數據包。主要用於網絡控制台(net console)和遠程內核調試(KGDBoE)中。實現netpoll功能,主要是要實現kernel中的poll_controller函數,該函數定義:void (*poll_controller)(strUCt net_device *dev)。該函數的作用是在缺少設備中斷的情況下,還能對控制器做出響應。幾乎所有的poll_controller函數都定義成如下形式:
void my_poll_controller(struct net_device *dev) {
disable_device_interrupt(dev);
call_interrupt_handler(dev->irq, dev);
enable_device_interrupt(dev);
}
所以,poll_controller只是模擬了來自指定設備的中斷。一個最簡單的判斷一個網卡驅動是否這次支持netpoll功能的方法是安裝內核源代碼,然後在代碼樹 /usr/src/kernel-<version>中搜索HAVE_POLL_CONTROLLER的定義, grep -r "HAVE_POLL_CONTROLLER" /usr/src/linux-<version>/drivers/net示例如下:
# grep -r "HAVE_POLL_CONTROLLER" /usr/src/linux-2.4/drivers/net
/usr/src/linux-2.4/drivers/net/3c59x.c:#ifdef HAVE_POLL_CONTROLLER
/usr/src/linux-2.4/drivers/net/3c59x.c:#ifdef HAVE_POLL_CONTROLLER
/usr/src/linux-2.4/drivers/net/e100/e100_main.c:#ifdef HAVE_POLL_CONTROLLER
/usr/src/linux-2.4/drivers/net/e100/e100_main.c:#ifdef HAVE_POLL_CONTROLLER
/usr/src/linux-2.4/drivers/net/e1000/e1000_main.c:#ifdef HAVE_POLL_CONTROLLER
/usr/src/linux-2.4/drivers/net/e1000/e1000_main.c:#ifdef HAVE_POLL_CONTROLLER
/usr/src/linux-2.4/drivers/net/e1000/e1000_main.c:#ifdef HAVE_POLL_CONTROLLER
/usr/src/linux-2.4/drivers/net/eepro100.c:#ifdef HAVE_POLL_CONTROLLER
/usr/src/linux-2.4/drivers/net/eepro100.c:#ifdef HAVE_POLL_CONTROLLER
/usr/src/linux-2.4/drivers/net/pcnet32.c:#ifdef HAVE_POLL_CONTROLLER
/usr/src/linux-2.4/drivers/net/pcnet32.c:#ifdef HAVE_POLL_CONTROLLER
/usr/src/linux-2.4/drivers/net/tg3.c:#ifdef HAVE_POLL_CONTROLLER
/usr/src/linux-2.4/drivers/net/tg3.c:#ifdef HAVE_POLL_CONTROLLER
/usr/src/linux-2.4/drivers/net/tlan.c:#ifdef HAVE_POLL_CONTROLLER
/usr/src/linux-2.4/drivers/net/tlan.c:#ifdef HAVE_POLL_CONTROLLER
/usr/src/linux-2.4/drivers/net/tulip/tulip_core.c:#ifdef HAVE_POLL_CONTROLLER
/usr/src/linux-2.4/drivers/net/tulip/tulip_core.c:#ifdef HAVE_POLL_CONTROLLER
從輸出可以看到,3c59x, e100, e1000, eepro100, pcnet32, tg3, tlan和tulip都支持netpoll。
如果系統使用了這些網卡,那麼系統應該支持netpoll,那麼就支持netdump。
如果希望進一步確認網卡是否是使用這些網卡,可以查看/etc/modules.conf:
# cat /etc/modules.conf
alias eth1 e100
alias eth0 3c59x
4.SysRq
SysRq組合鍵是一組"魔術組合鍵",只要內核沒有被完全鎖住,鍵盤還能夠使用,不管內核在做什麼事情,使用這些組合鍵可以立即打印出內核的信息。
使用sysrq組合鍵是了解系統目前運行情況的最好方式。如果系統出現掛起的情況或者在診斷一些和內核相關,比較怪異,比較難重現的問題的時候,使用sysrq鍵是一個比較好的方式。
為了安全起見,默認SysRq組合鍵是關閉的。
打開這個功能,運行:
# echo 1 > /proc/sys/kernel/sysrq
關閉這個功能:
# echo 0 > /proc/sys/kernel/sysrq
如果想讓此功能一直生效,在/etc/sysctl.conf裡面設置kernel.sysrq的值為1. 重新啟動以後,此功能將會自動打開。
kernel.sysrq = 1
因為打開sysrq鍵的功能以後,有終端訪問權限的用戶將會擁有一些特殊的功能。因此,除非是要調試,解決問題,一般情況下,不要打開此功能。如果一定要打開,請確保您的終端訪問的安全性。
如何觸發一個sysrq事件?
有幾種方式可以觸發sysrq事件。在帶有AT鍵盤的一般系統上,在終端上輸入一下組合鍵:
Alt+PrintScreen+[CommandKey]
例如,要讓內核導出內存信息(CommandKey "m"),您應該同時按下Alt 和 Print Screen 鍵,然後按下 m 鍵. 提示: 此組合鍵在Xwindows上是無法使用的。所以,您先要切換到文本虛擬終端下。如果您現在是在圖形界面,可以按Ctrl+Alt+F1切換到虛擬終端。
當我觸發一個sysrq事件的時候,結果保存在什麼地方?
當一個sysrq命令被觸發,內核將會打印信息到內核的環形緩沖並輸出到系統控制台。此信息一般也會通過syslog輸出到/var/log/messages.
有時候,可能系統已經無法響應,syslogd可能無法記錄此信息。在這種情況下,建議您配置一個串口終端來收集這個信息。
那些類型的sysrq事件可以被觸發?
sysrq功能被打開後,有幾種sysrq事件可以被觸發。不同的內核版本可能會有些不同。但有一些是共用的:
* m - 導出關於內存分配的信息
* t - 導出線程狀態信息
* p - 到處當前CPU寄存器信息和標志位的信息
* c - 故意讓系統崩潰(在使用netdump或者diskdump的時候有用)
* s - 立即同步所有掛載的文件系統
* u - 立即重新掛載所有的文件系統為只讀
* b - 立即重新啟動系統
* o - 立即關機(如果機器配置並支持此項功能)
故障分析
雖然我們可以通過上述的幾種方法來獲取應用程序或操作系統崩潰時的各種信息,但是分析這些問題有一定難度。
常見問題
軟件相關
系統平時運行一切正常,自從新實施了一項應用後,頻繁發生崩潰現象,此類問題多數與應用程序Bug有關,不一定在所有相同配置系統中都會產生,但是一旦觸發該Bug,就有可能發生崩潰。
系統平時運行一切正常,自從新實施了一項應用後,頻繁發生崩潰現象,也有一些情況是新增的應用需要做一定的操作系統配置,沒有設置的話,也有可能出現資源利用問題,導致崩潰發生。
系統平時運行一切正常,自從新實施了一項應用後,頻繁發生崩潰現象,也有一些情況是應用的版本與操作系統版本不匹配,應用軟件所需的系統庫文件版本不對應,容易引發應用程序崩潰。
系統平時運行正常,近期沒有任何新增應用,也沒有更改系統配置,卻接連發生多次崩潰現象。此類問題多數是壓力增大,超出了硬件所能承受的負載,耗盡資源,發生崩潰。
系統平時運行正常,近期無新增應用,系統負載也不高,卻發生崩潰現象。不排除操作系統本身的問題,有可能某種操作誘發了一個系統Bug,發生崩潰。
硬件相關
新增內存後,系統經常發生崩潰現象,此類問題有可能是32位機器配置了超過12GB的內存,但沒有使用 hugemem 核心導致,具體原因可參見第一節中的說明。
機器使用期限較長,某個硬件發生故障,也會導致系統崩潰的發生。
新配置的機器經常發生崩潰現象,有可能硬件較新,而驅動程序版本較低,一般可通過升級驅動解決,驅動一般集成在內核當中,常見的辦法是升級內核版本。