文章轉載自:
http://www.361way.com/centos-kdump/3751.html
一、什麼是kdump
kdump 是一種先進的基於 kexec 的內核崩潰轉儲機制。當系統崩潰時,kdump 使用 kexec 啓動到第二個內核。第二個內核通常叫做捕獲內核,以很小內存啓動以捕獲轉儲鏡像。第一個內核保留了內存的一部分給第二內核啓動用。由於 kdump 利用 kexec 啓動捕獲內核,繞過了 BIOS,所以第一個內核的內存得以保留。這是內核崩潰轉儲的本質。
kdump 需要兩個不同目的的內核,生產內核和捕獲內核。生產內核是捕獲內核服務的對像。捕獲內核會在生產內核崩潰時啓動起來,與相應的 ramdisk 一起組建一個微環境,用以對生產內核下的內存進行收集和轉存。
二、kdump執行流程
爲了更容易理解這裏我以三張圖展示下kdump的執行流程,首先看的是Vivek Goyal 的PPT中兩幅圖
下面兩副圖是來自於IBM技術論壇上的rhel6.2和suse11下的執行流程圖
rhel6.2的執行流程
suse11下的執行流程
三、kdump 的安裝及測試
1、相關包的安裝
這裏以centos6.x下的安裝爲例
- kexec-tools
- kexec package
- kernel-debuginfo //需單獨另外安裝,yum源裏沒有
- crash analysis package
- 安裝命令如下
- # yum -y install kernel kexec-tools
如果需要圖形化的配置工具,還要安裝system-config-kdump包。
2、grub內核配置
編輯 /boot/grub/grub.conf 配置文件,修改用到的引導部分,加入crashkernel部分,
- 參數格式是:
- crashkernel=nn[KMG]@ss[KMG]
- nn表示要爲crashkernel預留多少內存
- ss表示爲crashkernel預留內存的起始位置
示例如下:
- root (hd0,0)
- kernel /vmlinuz-2.6.18-92.el5 ro root=LABEL=/ crashkernel=256M@16M
- initrd /initrd-2.6.18-92.el5.img
- 或
- root (hd0,0)
- kernel /vmlinuz-2.6.32-431.17.1.el6.x86_64 ro root=/dev/mapper/vg_centos-lv_root rd_NO_LUKS LANG=en_US.UTF-8 rd_LVM_LV=vg_centos/lv_swap rd_NO_MD SYSFONT=latarcyrheb-sun16 crashkernel=128M@48M rd_LVM_LV=vg_centos/lv_root KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet
- initrd /initramfs-2.6.32-431.17.1.el6.x86_64.img
修改完成並重啓後,可以通過cat /proc/cmdline 查看kernel 啓動配置選項 ,此處修改重啓後我的/proc/cmdline文件爲:
ro root=/dev/mapper/vg_centos-lv_root rd_NO_LUKS LANG=en_US.UTF-8 rd_LVM_LV=vg_centos/lv_swap rd_NO_MD SYSFONT=latarcyrheb-sun16 crashkernel=128M@48M rd_LVM_LV=vg_centos/lv_root KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet
注:在centos 7.x上,開始使用grub2 引導,配置路徑文件爲
- UEFI引導時
- /boot/efi/EFI/centos/grub.cfg
- BIOS引導時
- /boot/grub2/grub.cfg
小技巧:修改該值可以直接使用grubby命令進行修改grub.cfg文件(該命令同樣適用於grub2和UEFI引導的情況)如:
- [root@localhost boot]# grubby --update-kernel=DEFAULT --args=crashkernel=128M
3、啓動kdump服務
在centos6.x上可以使用下面的命令啓動kdump服務(在suse11企業版中,kdump服務名爲boot.kdump)
- # /etc/init.d/kdump start
- Starting kdump: [FAILED]
發現啓動失敗,通過查看/var/log/message日誌,可以發現如下內容:
- kdump: No crashkernel parameter specified for running kernel
注:
a、這裏我嘗試過grub.cfg裏配置crashkernel=auto 、crashkernel=128M@16M,啓動失敗,後來看到oracle 站點上的示例,改爲crashkernl=128M@48M後,發現kdump服務可以啓動成功,而且每次修改後都需要reboot重啓系統,後來查了下手動指定@xxxM的時候可能會失敗的原因,是因爲如果第二個內核與第一個內核在地址空間上有重疊的話,會導致第二個內核啓動失敗,所以此處可以直接設置爲crashkernel=128M。
b、crashkernle 的值也要根據具體自己的實際物理內存大小靈活調整,如實際物理內存實在足夠大,可以設置爲256M、512M 。
c、crashkernel 的值設置後,使用free -m 要看時,會發現內存少了@ 號前面配置的值大小。如,我配置的是crashkernel@128M@48M,就會少128M內存。
再次啓動kdump服務
- [root@361way sysconfig]# /etc/init.d/kdump restart
- Stopping kdump: [ OK ]
- No kdump initial ramdisk found. [WARNING]
- Rebuilding /boot/initrd-2.6.32-431.17.1.el6.x86_64kdump.img
- Starting kdump: [ OK ]
會發現會在/boot 目錄下新增一個以kdump結尾的內核文件。
- [root@361way boot]# ls
- config-2.6.32-431.17.1.el6.x86_64 grub lost+found System.map-2.6.32-431.17.1.el6.x86_64
- config-2.6.32-431.el6.x86_64 initramfs-2.6.32-431.17.1.el6.x86_64.img memtest86+-4.10 System.map-2.6.32-431.el6.x86_64
- efi initramfs-2.6.32-431.el6.x86_64.img symvers-2.6.32-431.17.1.el6.x86_64.gz vmlinuz-2.6.32-431.17.1.el6.x86_64
- elf-memtest86+-4.10 initrd-2.6.32-431.17.1.el6.x86_64kdump.img symvers-2.6.32-431.el6.x86_64.gz vmlinuz-2.6.32-431.el6.x86_64
注:在centos 7.x 上開始使用systemd進行服務進程的啓動管理,啓動服務折方法需要通過以下方法執行
- # systemctl enable kdump.service //配置服務的開機自啓動
- # systemctl start kdump.service //啓動kdump服務
4、測試模擬kdump
配置完成後,需要重啓機器加載新的內核。可以使用下面的方法默認kdmp生成
- # service kdump on //設置服務開機自啓動
- # reboot //重啓系統使剛剛所有的修改生效
- # sync
- # echo c > /proc/sysrq-trigger
執行後,機器會重啓,重啓進入系統後,會在/var/crash 目錄生成kdmp文件,文件內容可以通過crash命令進行分析,後面會對此進行專門的介紹。
四、kdump的高級配置
和kdump相關的配置文件有兩個:一個是/etc/sysconfig/kdump,該文件內的內容一般無需修改 -- 網上一些技術站上在kdump服務啓動不成功時修改這裏,這裏提示下,如果是通過yum源正常安裝的,該文件無需修改;一個是/etc/kdump.conf 。這裏指的高級配置主機是/etc/kdump.conf ,該配置文件的可配置選項可通過man 5 kdump.conf 獲取幫助,這裏只列舉下常用到的部分:
1、設置kdump文件成生的位置
控制路徑的主要有兩部分:
- #raw /dev/sda5
- #ext4 /dev/sda3
- #ext4 LABEL=/boot
- #ext4 UUID=03138356-5e61-4ab3-b58e-27507ac41937
- #nfs my.server.com:/export/tmp
- #ssh [email protected]
- path /var/crash
前面的部分用於設置存儲的設備或分區位置--可以是raw裸設備、本地分區、網絡路徑在本地的掛載點或通過ssh傳輸,path則是相對的存儲路徑。如我們通過nfs 將遠程的一個分區掛載到本地的/mnt分區下,kdump文件就存儲在/mnt/var/crash/下。默認上面的部分不設置就是相對根分區的相對路徑,即/var/crash 。
需要特別指出的是,如果使用ssh進行傳輸,需要配置key認證,使用/etc/init.d/kdump propagate即可配置ssh認證傳輸,如下:
- kdump.conf中指定ssh網絡傳輸
- ssh [email protected]/data/
- 執行下面的命令會配置本機到192.168.0.100主機的key認證傳輸
- # service kdump propagate
- Generating new ssh keys… done.
- The authenticity of host '192.168.0.100 (192.168.0.100)' can't be established.
- RSA key fingerprint is 31:c2:d8:b6:eb:2e:03:64:cd:ba:56:e9:49:6e:5d:6c.
- Are you sure you want to continue connecting (yes/no)? yes
- Warning: Permanently added '192.168.0.100' (RSA) to the list of known hosts.
- [email protected]'s password:
- /root/.ssh/kdump_id_rsa.pub has been added to ~root/.ssh/authorized_keys2 on
- 192.168.0.100
按照上面的配置,當有kdump生成時,會通過scp傳輸存儲在192.168.0.100主機的/data/var/crash 目錄下。
2、core_collector控制
該處是信息收集大小的關鍵,主要用到makedumpfile命令,centos 上的默認配置如下:
- core_collector makedumpfile -c --message-level 1 -d 31
-c 表示啓動zlib進行數據壓縮
--message-level 指定了信息收集的級別,1爲只打印process indicator 日誌信息,默認值爲7,具體見下表
- Message | progress common error debug report
- Level | indicator message message message message
- ---------+------------------------------------------------------
- 0 |
- 1 | X
- 2 | X
- 4 | X
- * 7 | X X X
- 8 | X
- 16 | X
- 31 | X X X X X
-d 指定了kdump的過濾級別,具體見下表
- | cache cache
- Dump | zero without with user free
- Level | page private private data page
- -------+---------------------------------------
- 0 |
- 1 | X
- 2 | X
- 4 | X X
- 8 | X
- 16 | X
- 31 | X X X X X
31表示過濾掉以上五種全部信息,這樣kdump生成的速度就會更快,生成的vmcore文件也會較小。如果此處使用值0 ,表示不過濾任何信息,在kdump生成時,會記錄主機當前的所有信息。這就是爲什麼在kdump生成時,有些主機只有幾十M大小生成,有些主機確有幾十 G大小的原因。更多用法可以查看makedumpfile命令的幫助文檔。
3、指定default配置
該處的配置,我也參考了網上的一些配置,一些技術文檔上使用的是defult reboot選項,而默認的是defult shell ,兩者之間的區別是:
- reboot: If the default action is reboot simply reboot the system and loose the core that you are trying to retrieve.
- shell: If the default action is shell, then drop to an hush session inside the initramfs from where you can try to record the core manually.Exiting this shell reboots the system.
在查看/usr/share/doc/kexec-tools-2.0.0/kexec-kdump-howto.txt幫助手冊中的解釋更容易理解一些,如下:
- reboot --> reboot the system.
- shell --> drop to a shell with-in initrd. A user can try to capture the
- vmcore manually.
從這個解釋可以看到選擇shell 可以手工的DIY一些東西,而選擇reboot 會在kdump生成後簡單直接的reboot 系統。除了上在兩個選項,還會poweroff 、halt 可選,如果不是技術研究的目錄,在生產環境上我想誰不會選擇kdump生成後讓系統掛起吧。
除上面三處之外,還有其他配置部分,如debug_mem 的配置等。具體可以看kdump.conf 的man 結果。
五、crash進行結果分析
crash包需要yum -y install crash 單獨安裝過,另外crash 命令需要依賴kernel-debuginfo 包(該包又依賴kernel-debuginfo-common包),該包的下載地址:http://debuginfo.centos.org/6/x86_64/ 。下載前先要確認下自己主機的內核版本。我在測試機上是通過下面的命令執行的:
- # uname -r
- 2.6.32-431.17.1.el6.x86_64
- # wget http://debuginfo.centos.org/6/x86_64/kernel-debuginfo-common-x86_64-2.6.32-431.17.1.el6.x86_64.rpm
- # wget http://debuginfo.centos.org/6/x86_64/kernel-debuginfo-2.6.32-431.17.1.el6.x86_64.rpm
下載完成後,通過rpm -ivh將這兩個包安裝。然後通過下面的命令進行crash分析
- # pwd
- /var/crash/127.0.0.1-2014-09-16-14:35:49
- # crash /usr/lib/debug/lib/modules/2.6.32-431.17.1.el6.x86_64/vmlinux vmcore
- crash 6.1.0-5.el6
- Copyright (C) 2002-2012 Red Hat, Inc.
- Copyright (C) 2004, 2005, 2006, 2010 IBM Corporation
- Copyright (C) 1999-2006 Hewlett-Packard Co
- Copyright (C) 2005, 2006, 2011, 2012 Fujitsu Limited
- Copyright (C) 2006, 2007 VA Linux Systems Japan K.K.
- Copyright (C) 2005, 2011 NEC Corporation
- Copyright (C) 1999, 2002, 2007 Silicon Graphics, Inc.
- Copyright (C) 1999, 2000, 2001, 2002 Mission Critical Linux, Inc.
- This program is free software, covered by the GNU General Public License,
- and you are welcome to change it and/or distribute copies of it under
- certain conditions. Enter "help copying" to see the conditions.
- This program has absolutely no warranty. Enter "help warranty" for details.
- GNU gdb (GDB) 7.3.1
- Copyright (C) 2011 Free Software Foundation, Inc.
- License GPLv3+: 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: /usr/lib/debug/lib/modules/2.6.32-431.17.1.el6.x86_64/vmlinux
- DUMPFILE: vmcore [PARTIAL DUMP]
- CPUS: 1
- DATE: Tue Sep 16 22:35:49 2014
- UPTIME: 00:05:33
- LOAD AVERAGE: 0.00, 0.00, 0.00
- TASKS: 175
- NODENAME: localhost.localdomain
- RELEASE: 2.6.32-431.17.1.el6.x86_64
- VERSION: #1 SMP Wed May 7 23:32:49 UTC 2014
- MACHINE: x86_64 (3398 Mhz)
- MEMORY: 1 GB
- PANIC: "Oops: 0002 [#1] SMP " (check log for details)
- PID: 1412
- COMMAND: "bash"
- TASK: ffff88003d0b2040 [THREAD_INFO: ffff88003c33c000]
- CPU: 0
- STATE: TASK_RUNNING (PANIC)
- crash> bt
- PID: 1412 TASK: ffff88003d0b2040 CPU: 0 COMMAND: "bash"
- #0 [ffff88003c33d9e0] machine_kexec at ffffffff81038f3b
- #1 [ffff88003c33da40] crash_kexec at ffffffff810c59f2
- #2 [ffff88003c33db10] oops_end at ffffffff8152b7f0
- #3 [ffff88003c33db40] no_context at ffffffff8104a00b
- #4 [ffff88003c33db90] __bad_area_nosemaphore at ffffffff8104a295
- #5 [ffff88003c33dbe0] bad_area at ffffffff8104a3be
- #6 [ffff88003c33dc10] __do_page_fault at ffffffff8104ab6f
- #7 [ffff88003c33dd30] do_page_fault at ffffffff8152d73e
- #8 [ffff88003c33dd60] page_fault at ffffffff8152aaf5
- [exception RIP: sysrq_handle_crash+22]
- RIP: ffffffff8134b516 RSP: ffff88003c33de18 RFLAGS: 00010096
- RAX: 0000000000000010 RBX: 0000000000000063 RCX: 0000000000000000
- RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000063
- RBP: ffff88003c33de18 R8: 0000000000000000 R9: ffffffff81645da0
- R10: 0000000000000001 R11: 0000000000000000 R12: 0000000000000000
- R13: ffffffff81b01a40 R14: 0000000000000286 R15: 0000000000000004
- ORIG_RAX: ffffffffffffffff CS: 0010 SS: 0018
- #9 [ffff88003c33de20] __handle_sysrq at ffffffff8134b7d2
- #10 [ffff88003c33de70] write_sysrq_trigger at ffffffff8134b88e
- #11 [ffff88003c33dea0] proc_reg_write at ffffffff811f2f1e
- #12 [ffff88003c33def0] vfs_write at ffffffff81188c38
- #13 [ffff88003c33df30] sys_write at ffffffff81189531
- #14 [ffff88003c33df80] system_call_fastpath at ffffffff8100b072
- RIP: 00000036e3adb7a0 RSP: 00007fff22936c10 RFLAGS: 00010206
- RAX: 0000000000000001 RBX: ffffffff8100b072 RCX: 0000000000000400
- RDX: 0000000000000002 RSI: 00007fab7908b000 RDI: 0000000000000001
- RBP: 00007fab7908b000 R8: 000000000000000a R9: 00007fab79084700
- R10: 00000000ffffffff R11: 0000000000000246 R12: 0000000000000002
- R13: 00000036e3d8e780 R14: 0000000000000002 R15: 00000036e3d8e780
- ORIG_RAX: 0000000000000001 CS: 0033 SS: 002b
- crash>
上面,只是簡單的通過打印堆棧信息,顯示主機在出現kdump生成時,pid 爲1412的bash進程操作。從上面的顯示信息中也簡單的看到有 write_sysrq_trigger 函數觸發。crash在定位問題原因時,爲我們提供了下面的命令:
- crash> ?
- * files mach repeat timer
- alias foreach mod runq tree
- ascii fuser mount search union
- bt gdb net set vm
- btop help p sig vtop
- dev ipcs ps struct waitq
- dis irq pte swap whatis
- eval kmem ptob sym wr
- exit list ptov sys q
- extend log rd task
- crash version: 6.1.0-5.el6 gdb version: 7.3.1
- For help on any command above, enter "help <command>".
- For help on input options, enter "help input".
- For help on output options, enter "help output".
由於crash的內容也較多,以下是針對suse下信息提到的一個腳本:
- mkdir -p /tmp/kdump
- crash $* <<EOF >/tmp/kdump/kdumpoutput.txt 2>&1
- log >/tmp/kdump/log.txt
- sys >/tmp/kdump/sys.txt
- bt >/tmp/kdump/bt.tx
- foreach bt >/tmp/kdump/all-bt.txt
- foreach files>/tmp/kdump/all-files.txt
- ps >/tmp/kdump/ps.txt
- swap>/tmp/kdump/swap.txt
- runq >/tmp/kdump/runq.txt
- mount >/tmp/kdump/mount.txt
- net >/tmp/kdump/net.txt
- dev >/tmp/kdump/dev.txt
- dev -i >/tmp/kdump/dev-i.txt
- dev -p >/tmp/kdump/dev-p.txt
- files >/tmp/kdump/files.txt
- irq >/tmp/kdump/irq.txt
- kmem -f >/tmp/kdump/pmemory.txt
- kmem -i >/tmp/kdump/memory.txt
- mach >/tmp/kdump/mach.txt
- mod >/tmp/kdump/modules.txt
- net -s >/tmp/kdump/net-s.txt
- ps -t >/tmp/kdump/ps-t.txt
- ps -c >/tmp/kdump/ps-c.txt
- sig >/tmp/kdump/sig.txt
- set >/tmp/kdump/set.txt
- task >/tmp/kdump/task.txt
- foreach task >/tmp/kdump/all-task.txt
- sym -l >/tmp/kdump/sys-l.txt
- sym -M >/tmp/kdump/sys-M.txt
- quit
- EOF
使用下面的腳本按如下方法執行:
- # getcoreinfo.sh -f vmlinux-3.0.76-0.11-default.gz vmlinux-3.0.76-0.11-default.debug vmcore
六、kdump涉及的sysctl 配置
查閱了網上很多有關kdump的資料,發現在配置kdump時,對sysctl.conf 內的一些配置也進行了調整。這裏也列舉下,可以根據具體的情況酌情進行修改。
- kernel.sysrq=1
- kernel.unknown_nmi_panic=1
- kernel.softlockup_panic=1
kernel.sysrq=1,如果通過/proc文件配置 ,上面的配置等價於echo 1 > /proc/sys/kernel/sysrq ,打開sysrq鍵的功能以後,有終端訪問權限的用戶將會擁有一些特別的功能。如果系統出現掛起的情況或在診斷一些和內核相關,
使用這些組合鍵能即時打印出內核的信息。因此,除非是要調試,解決問題,一般情況下,不要打開此功能。如果一定要打開,請確保你的終端訪問的安全性。具體可以參看百度百科上給出的解釋。
kernel.unknown_nmi_panic=1 ,如果系統已經是處在Hang的狀態的話,那麼可以使用NMI按鈕來觸發Kdump。開啓這個選項可以:echo 1 > /proc/sys/kernel/unknown_nmi_panic 需要注意的是,啓用這個特性的話,是不能夠同時啓用NMI_WATCHDOG的!否則系統會Panic!
kernel.softlockup_panic=1,其對應的是/proc/sys/kernel/softlockup_panic的值,值爲1可以讓內核在死鎖或者死循環的時候可以宕機重啓。如果你的機器中安裝了kdump,在重啓之後,你會得到一份內核的core文件,這時從core文件中查找問題就方便很多了,而且再也不用手動重啓機器了。如果你的內核是標準內核的話,可以通過修改/proc/sys/kernel/softlockup_thresh來修改超時的閾值,如果是CentOS內核的話,對應的文件是/proc/sys/kernel/watchdog_thresh。
除此之外,一些站點上還會建議修改開啓oops painc的功能,這個也具體根據實際需要修改吧。
PS:自動配置kdump的功能,我已經腳本化,放在了我的github上。
後記:
在後面使用中發現有出現kdump與現有模塊衝突導致一直無法生成kdump的情況,這裏的是VCS 的vxfs與fusion io的iomemory-vsl4模板與kdump衝突。可以通過blacklist參數將其在/etc/kdump.conf中屏蔽---suse下爲/etc/sysconfig/kdump。如下:
- blacklist vxfs
- blacklist iomemory-vsl4
關於blacklist參數,redhat原廠工程師給予的解釋是:blacklist參數的作用是當觸發kdump時,在進入第二內核(一般稱爲capture kernel或kdump kernel)時不加載指定的模塊。這個參數只會在發生kdump時起作用,不會影響系統正常運行。
還需要注意的是在涉及到配置文件變動時,如生成路徑修改或blacklist內容增加,都需要重新生成kdump的RAM文件,不然其在發生問題時還是使用老的img RAM文件,該文件在/boot下以kdump.img結尾的文件就是:
- #ls -l /boot
- total 35024
- -rw-r--r--. 1 root root 105195 Nov 11 2013 config-2.6.32-431.el6.x86_64
- drwxr-xr-x. 3 root root 4096 Sep 15 12:12 efi
- drwxr-xr-x. 2 root root 4096 Sep 22 16:44 grub
- -rw-------. 1 root root 17135661 Sep 15 12:25 initramfs-2.6.32-431.el6.x86_64.img
- -rw------- 1 root root 11743320 Sep 22 16:35 initrd-2.6.32-431.el6.x86_64kdump.img
- drwx------. 2 root root 16384 Sep 15 12:01 lost+found
- -rw-r--r--. 1 root root 193758 Nov 11 2013 symvers-2.6.32-431.el6.x86_64.gz
- -rw-r--r--. 1 root root 2518236 Nov 11 2013 System.map-2.6.32-431.el6.x86_64
- -rwxr-xr-x. 1 root root 4128944 Nov 11 2013 vmlinuz-2.6.32-431.el6.x86_64
遇到配置變動時,可以將/boot下的initrd-`uname -r`kdump.img文件mv走,再通過重啓kdump服務生成新的kdump.img文件。如下:
注:SUSE下重新生成使用的是/etc/init.d/boot.kdump restart 命令。
在kdump重新生成後,最好重啓下主機。另一個kdump配置裏需要注意的參數是:MKDUMPRD_ARGS="--allow-missing" ,增加完該參數,會在主機每次啓動時自動檢查kdump配置並重新rebuild kdump.img文件。
kdump壓縮
下面的命令是壓縮vmcore的,請嘗試操作下面的命令看是否可以壓縮(可能比較耗費時間和部分系統資源),實際原理就是由原crash級別,改爲級別31:
- makedumpfile -c -d 31 -x vmlinux-3.0.76-0.11-default.debug /xx/xx/vmcore /xx/shorter-vmcore
還在記得/xx/shorter-vmcore 存放目錄有足夠大的空間。