想要了解 Linux 內(nèi)核轉(zhuǎn)儲機制,就要從 kexec - > kdump - > crash 這個遞進過程去分析。
??只有清楚他們在各個過程負責的任務、功能,搞通了工作原理、功能后,就去實際環(huán)境中使用,最后再去分析其源碼,只有這樣你是真正的知道了整個轉(zhuǎn)儲機制。
一. 工具介紹及其所負責任務
- kexec
- kdump
- crash
1. kexec工具
kexec是內(nèi)核更換,免于再次經(jīng)歷固件的工具,節(jié)省了內(nèi)核開發(fā)者的時間。kexec實現(xiàn)了在一個內(nèi)核里啟動另一個內(nèi)核。
安裝
yum install kexec-tools
kexec兩種使用方式
kexec -l /boot/vmlinuz+ --initrd=/boot/initramfs+ --append="root=/dev/sdaX ro"
2. kdump
kdump是內(nèi)核轉(zhuǎn)儲工具,kexec是實現(xiàn)kdump機制的關鍵。kdump是基于kexec的內(nèi)核崩潰轉(zhuǎn)儲機制。內(nèi)存轉(zhuǎn)存機制。

安裝
# yum install kexec-tools
# yum install kernel-debuginfo #包管理器會解決其依賴common包
需要檢測本系統(tǒng)內(nèi)核是否已經(jīng)選中支持kexec system call,若在“/boot/config-XXXXX”中CONFIG_KEXEC=y則是本版本號的內(nèi)核已開啟;若=n,則需要重新編譯內(nèi)核,選中CONFIG_KEXEC。
替換內(nèi)核的兩個步驟,第一個把新內(nèi)核的模塊目錄(在編譯內(nèi)核時創(chuàng)建一個臨時目錄安裝編譯好內(nèi)核的模塊)
# 編譯好內(nèi)核之后,建立一個臨時目錄lib
mkdir -pv lib-kexecKdump-kernel
# 安裝內(nèi)核模塊
make modules_install INSTALL_MOD_PATH=./lib/
- 復制lib/下編譯好內(nèi)核版本號目錄的模塊,到/lib/modules/下。
一.內(nèi)核崩潰轉(zhuǎn)儲的本質(zhì)
當系統(tǒng)崩潰時,kdump利用kexec啟動另一個內(nèi)核,這一個內(nèi)核叫捕獲內(nèi)核,以很小的內(nèi)存啟動捕獲內(nèi)核,第一個內(nèi)核保留了內(nèi)存的一部分給捕獲內(nèi)核啟動用。kdump利用kexec啟動捕獲內(nèi)核,免去啟動BIOS(繞過BIOS,沒有經(jīng)歷BIOS,節(jié)省了系統(tǒng)啟動的時間),所以第一個內(nèi)核的內(nèi)存得以保留。
捕獲內(nèi)核只會使用分配給他的內(nèi)存空間,不會污染第一內(nèi)核的內(nèi)存數(shù)據(jù)。
二.kdump由兩部分組成
內(nèi)核空間的系統(tǒng)調(diào)用,由kexec_load在生產(chǎn)內(nèi)核啟動時把捕獲內(nèi)核加載到指定地址。
用戶空間的工具kexec-tools,將捕獲內(nèi)核的地址傳遞給生產(chǎn)內(nèi)核,在系統(tǒng)崩潰時能找到捕獲內(nèi)核地址,并運行它。
三.如何使用kdump
定制自定義的轉(zhuǎn)儲捕獲內(nèi)核(編譯內(nèi)核前開啟kdump、vmcore),即捕獲內(nèi)核。
或者將第一個內(nèi)核本身作為轉(zhuǎn)儲捕獲內(nèi)核使用,但此方法只支持可重定位內(nèi)核的體系結構。
四.觀察前一個內(nèi)核內(nèi)存方式
通過/dev/oldmem設備接口。
通過/proc/vmcore
五.修改內(nèi)核引導參數(shù),為啟動捕獲內(nèi)核預留內(nèi)存
- 在grub啟動時,修改/boot/grub.cfg;若EFI啟動則在/boot/efi/EFI/fedora/grub.cfg。其實只是在里面加入了捕獲內(nèi)核的預留內(nèi)存值的關鍵字“crashkernel=X@Y”,修改位置在類似:“l(fā)inux linuxefi /vmlinuz-4.17.7-200.fc28.x86_64 root=/dev/mapper/fedora-root ro”之后的位置,X:捕獲內(nèi)核預留的內(nèi)存大小,Y:代表保留內(nèi)存的起始位置地址。
要設置好“Y保留內(nèi)存的起始位置地址”,則需要知道你編譯捕獲內(nèi)核時的內(nèi)核載入地址(會在在編譯內(nèi)核開啟kdump、vmcore時的第二行會有設置修改)。
### 修改后的文件
menuentry 'Fedora (4.17.7-200.fc28.x86_64) 28 (Workstation Edition)' --class fedora --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'gnulinux-4.16.3-301.fc28.x86_64-advanced-56130196-332b-4c5d-8387-67bba2d45054' {
load_video
set gfxpayload=keep
insmod gzio
insmod part_gpt
insmod ext2
set root='hd0,gpt2'
if [ x$feature_platform_search_hint = xy ]; then
search --no-floppy --fs-uuid --set=root crashkernel=auto --hint-bios=hd0,gpt2 --hint-efi=hd0,gpt2 --hint-baremetal=ahci0,gpt2 9cc3b942-1abe-4b8e-98fb-c0cd1186223e
else
search --no-floppy --fs-uuid --set=root 9cc3b942-1abe-4b8e-98fb-c0cd1186223e
fi
linuxefi /vmlinuz-4.17.7-200.fc28.x86_64 root=/dev/mapper/fedora-root ro resume=/dev/mapper/fedora-swap crashkernel=auto rd.lvm.lv=fedora/root rd.lvm.lv=fedora/swap rhgb quiet LANG=zh_CN.UTF-8
initrdefi /initramfs-4.17.7-200.fc28.x86_64.img
}
-
開啟kdump服務
- x86平臺:
systemctl start kdump && systemctl enable kdump- mips平臺:不用自己手動啟動此服務。
第一個內(nèi)核啟動后,載入轉(zhuǎn)儲捕獲內(nèi)核
載入轉(zhuǎn)儲捕獲內(nèi)核,命令規(guī)范:
kexec -p <dump-capture-kernel-vmlinux-image> \
--initrd=<initrd-for-dump-capture-kernel> --args-linux \
--append="root=<root-dev> <arch-specific-options>"
- 當執(zhí)行“kexec -p”后,可能會有root沒有掛載的情況。是因為initrd參數(shù)未起作用,然后在“root=”變量使用設備號(/dev/sdaX),不要使用“hd0,msdogs”或“UUID”,則可以成功。若系統(tǒng)裝有crash,則“/var/crash/”有vmcore;若未裝vmcore存在于“/proc/vmcore”。
- 測試配置是否有效
- 使用sysrq-c中斷將系統(tǒng)崩潰,讓kdump捕獲崩潰時產(chǎn)生的vmcore,默認存放位置在/var/crash/host@time,配置文件/etc/dump.conf。
echo c > /proc/sysrq-trigger
- 成功,重新進入穩(wěn)定系統(tǒng)。若系統(tǒng)裝有crash,則“/var/crash/”有vmcore;若未裝vmcore存在于“/proc/vmcore”。
編譯內(nèi)核時小技巧
make menconfig
- 啟用或者禁用某項時,可按“/”搜索某項模塊或服務,搜索結果會顯示出此服務的地址,與此服務模塊依賴的模塊是否啟用。
參考文獻:linux kdump.txt:https://www.kernel.org/doc/Documentation/kdump/kdump.txt
crash
對內(nèi)核崩潰轉(zhuǎn)儲文件做分析的工具,更好的使用此工具,請認真閱讀man crash。
crash kernel-debuginfo vmcore