修改linux內核代碼或者內核模塊的時候,搞不好就會造成linux死機崩潰,crash死機后/var/log/kern.log里面不會有任何異常信息記錄。這時候kdump就會派上用場了,網上kdump的中英文介紹資料很多,但是很多都是基於系統自帶的linux進行說明的,這里記錄一下在新編譯的內核上使用kdump遇到的問題
1、首先使用ubuntu的config文件編譯的內核可以使用kdump
2、在上面的config文件后打開內核編譯的DEBUG_INFO選項,編譯安裝內核后,結果kdmup不起作用,crash后電腦直接卡死沒反應,有下面幾個現象
通過service --status-all查看,kdump服務成功啟動
通過kdump-config show 查看,kdump not ready。
重新啟動kdump服務。提示啟動成功,但是查看/var/log/syslog,看到有提示"Could not find a free area of memory of xxxxx",kdump預留內存不足,通過/proc/iomem查看已經預留了crash memory,但是預留的crash memory與syslog中提示的內存非常接近
重新啟動筆記本,在grub命令行編輯啟動命令,設置crash memory為256M,之前grub配置文件中為128M,重啟后,發現kdump服務ok,通過kdump-config show查看kdump 也是ready狀態。
通過echo c > /proc/sysrq-trigger觸發內核崩潰,看到kdump有響應,但是並不會重啟筆記本,也不會記錄crash信息
3、既然沒有配置DEBUG_INFO時候編譯的內核可以kdump,配置DEBUG_INFO后編譯的內核反而不能kdump,那么在安裝嘗試把DEBUG信息去掉
objcopy --strip-debug ./vmlinux.o (建議先備份vmlinux.o)
make modules_installs INSTALL_MOD_STRIP=1 install
上面兩條命令一個是把內核中的debug信息去掉,另外一個命令則是在安裝內核模塊的時候,同樣把內核模塊的debug info去掉,INSTALL_MOD_STRIP這個參數實際上就是從內核makefile中找到的,INSTALL_MOD_STRIP在makefile中就是控制strip-debug是否使能的。
4、經過上面把內核以及內核模塊的調試信息去掉后,確認kdump可以正常使用了
root@Inspiron:/home/lybxin# crash doc/ubuntu-compile/vmlinux /var/crash/201610291718/dump.201610291718crash 7.1.4Copyright(C)2002-2015 RedHat,Inc.Copyright(C)2004,2005,2006,2010 IBM CorporationCopyright(C)1999-2006 Hewlett-PackardCoCopyright(C)2005,2006,2011,2012 FujitsuLimitedCopyright(C)2006,2007 VA LinuxSystemsJapan K.K.Copyright(C)2005,2011 NEC CorporationCopyright(C)1999,2002,2007 SiliconGraphics,Inc.Copyright(C)1999,2000,2001,2002 MissionCriticalLinux,Inc.This program is free software, covered by the GNU GeneralPublicLicense,and you are welcome to change it and/or distribute copies of it undercertain conditions. Enter"help copying" to see the conditions.This program has absolutely no warranty. Enter"help warranty"for details.GNU gdb (GDB)7.6Copyright(C)2013FreeSoftwareFoundation,Inc.LicenseGPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>This is free software: you are free to change and redistribute it.There is NO WARRANTY, to the extent permitted by law. Type"show copying"and "show warranty"for details.This GDB was configured as "x86_64-unknown-linux-gnu"...KERNEL: doc/ubuntu-compile/vmlinuxDUMPFILE:/var/crash/201610291718/dump.201610291718 [PARTIAL DUMP]CPUS:4DATE:SatOct2917:17:442016UPTIME:00:03:39LOAD AVERAGE:0.69,1.06,0.50TASKS:582NODENAME:InspironRELEASE:4.4.13+VERSION:#35 SMP Fri Oct 28 23:13:30 CST 2016MACHINE: x86_64 (2526Mhz)MEMORY:3.9 GBPANIC:"sysrq: SysRq : Trigger a crash"PID:2656COMMAND:"bash"TASK: ffff880081543e80 [THREAD_INFO: ffff880124db8000]CPU:0STATE: TASK_RUNNING (SYSRQ)crash> btPID:2656 TASK: ffff880081543e80 CPU:0 COMMAND:"bash"#0 [ffff880124dbbaf0] machine_kexec at ffffffff8105ae6b#1 [ffff880124dbbb50] crash_kexec at ffffffff8110cb12#2 [ffff880124dbbc20] oops_end at ffffffff81030c29#3 [ffff880124dbbc48] no_context at ffffffff81069c35#4 [ffff880124dbbca8] __bad_area_nosemaphore at ffffffff81069f00#5 [ffff880124dbbcf0] bad_area at ffffffff8106a0d3#6 [ffff880124dbbd18] __do_page_fault at ffffffff8106a5eb#7 [ffff880124dbbd70] do_page_fault at ffffffff8106a6b2#8 [ffff880124dbbd90] page_fault at ffffffff81832178[exception RIP: sysrq_handle_crash+22]RIP: ffffffff814f42b6 RSP: ffff880124dbbe48 RFLAGS:00010282RAX:000000000000000f RBX:0000000000000063 RCX:0000000000000000RDX:0000000000000000 RSI: ffff880137c0dc78 RDI:0000000000000063RBP: ffff880124dbbe48 R8:0000000000000002 R9:00000000000003edR10:0000000000000001 R11:00000000000003ed R12:0000000000000004R13:0000000000000000 R14: ffffffff81ebada0 R15:0000000000000000ORIG_RAX: ffffffffffffffff CS:0010 SS:0018#9 [ffff880124dbbe50] __handle_sysrq at ffffffff814f4a8a#10 [ffff880124dbbe80] write_sysrq_trigger at ffffffff814f4f0f#11 [ffff880124dbbe98] proc_reg_write at ffffffff81279782#12 [ffff880124dbbeb8] __vfs_write at ffffffff8120b438#13 [ffff880124dbbec8] vfs_write at ffffffff8120bdc9#14 [ffff880124dbbf08] sys_write at ffffffff8120ca85#15 [ffff880124dbbf50] entry_SYSCALL_64_fastpath at ffffffff8182fff2RIP:00007fe506368a10 RSP:00007ffd28c06838 RFLAGS:00000246RAX: ffffffffffffffda RBX:00000000006f4378 RCX:00007fe506368a10RDX:0000000000000002 RSI:00000000011bc408 RDI:0000000000000001RBP:00007ffd28c06770 R8:00007fe506637780 R9:00007fe506c6b700R10:0000000000000001 R11:0000000000000246 R12:00007fe506c6d5d0R13:0000000000000000 R14:00007fe506c8f168 R15:00007ffd28c06798ORIG_RAX:0000000000000001 CS:0033 SS:002b
后記:
實際上編譯debug info后遇到兩個問題,第一個是預留的crash內存不足的問題,另外一個是預留足夠內存后雖然kdump服務正常了,但是內核崩潰的時候仍然不能啟動kdump服務
對於第一個預留內存不足的問題,后來查看kdump-tools和kexec-tools的源碼,原來kdump-config show執行的時候,就是讀取的/sys/kernel/kexec_crash_loaded這個文件的值,如果kexec_crash_loaded為0就表示kdump沒有處於ready狀態。接着查看內核源碼,/sys/kernel/kexec_crash_loaded文件對應內核變量kexec_crash_image,而這個變量只會在兩個系統調用中進行修改,一個是kexec_load另外一個是kexec_file_load,而我並沒有修改kexec相關的代碼,因此內核這塊出問題的概率比較小。
通過跟蹤kdump服務的啟動腳本執行過程,原來啟動kdump服務最終執行的命令是/bin/systemctl --no-pager start kdump-tools.service ,而systemctl則會通過/run/systemd/private這個socket與init進程通信,init最終又會執行kexec-tools中的kexec程序,在kexec執行的時候則會查找預留的carsh memory,當預留的內存不足的時候就會輸出"Could not find a free area of memory of xxxxx"錯誤信息,當預留的內存充足的時候,則會執行kexec_load系統調用進行加載。
對於第二個,kdump服務啟動后還不能正常使用kdump的問題,打開debug info和debug info對比,發現預留的crash memory位置不同,估計多半和內核的內存機制與kexec機制有關系,這塊不太懂了,沒有深入研究了。好在單獨剝離debug info后可以正常使用kdump。
grub啟動文件中crashkernel參數的解析,可以參考內核代碼parse_crashkernel
命令備記:
objcopy --only-keep-debug ./vmlinux.o vmlinux.debug
objcopy --strip-debug ./vmlinux.o
INSTALL_MOD_STRIP=1
strace -f -F -ff -o kdump /bin/systemctl --no-pager start kdump-tools.service
linux/boot/vmlinuz-4.4.13 root=UUID=1ba5f5c5-70c3-4936-b757-821899fe6264 ro quiet splash crashkernel=384M-:128M $vt_handoff
