Kdump 工作流程

什么是Kdump?

Kdump是一個(gè)基于kexec的內(nèi)核崩潰轉(zhuǎn)儲(chǔ)機(jī)制,當(dāng)系統(tǒng)崩潰時(shí),kdump使用kexec啟動(dòng)到第二個(gè)內(nèi)核。地?zé)醾€(gè)內(nèi)核叫做捕獲內(nèi)核或者又叫“2nd kernel”,它以很少的內(nèi)存啟動(dòng)捕獲內(nèi)核,并捕獲轉(zhuǎn)儲(chǔ)鏡像。Kdump的概念是目前最可靠的內(nèi)核轉(zhuǎn)儲(chǔ)技術(shù),已被主要的linux廠商使用。(例如Red Hat系列)

什么是Kexec?

Kexec是一種能夠根據(jù)已經(jīng)運(yùn)行內(nèi)核的上下文快速啟動(dòng)新內(nèi)核的一種機(jī)制,而不經(jīng)過(guò)BIOS。BIOS的啟動(dòng)在一些大型機(jī)器或者有大量外設(shè)的機(jī)器上時(shí)特別耗時(shí)。這種機(jī)制能夠節(jié)省需要在不同內(nèi)核之間切換的開(kāi)發(fā)人員的時(shí)間。
Kexec在內(nèi)核空間和用戶空間都有對(duì)應(yīng)的組件,內(nèi)核提供了幾個(gè)kexec重啟功能的系統(tǒng)調(diào)用。用戶空間的軟件包"kexec-tools"使用這些系統(tǒng)調(diào)用,并執(zhí)行加載和引導(dǎo)第二個(gè)內(nèi)核(捕獲內(nèi)核)。
Kexec由兩部分組成,一是內(nèi)核空間的系統(tǒng)調(diào)用kexec_load,負(fù)責(zé)在生產(chǎn)內(nèi)核(或者叫第一個(gè)內(nèi)核)啟動(dòng)時(shí)將捕獲內(nèi)核(或者叫第二個(gè)內(nèi)核)加載到指定的位置。而是用戶空間的kexec-tools,它將捕獲內(nèi)核(second kernel)的地址傳遞給生產(chǎn)內(nèi)核(first kernel),讓系統(tǒng)在崩潰的時(shí)候能夠找到捕獲內(nèi)核(second kernel)的地址并運(yùn)行。

Kdump怎么工作?

在當(dāng)前系統(tǒng)發(fā)生崩潰時(shí),新的捕獲內(nèi)核被加載,然后根據(jù)已設(shè)置的命令去將當(dāng)前之前發(fā)生崩潰的系統(tǒng)的內(nèi)存保存到一個(gè)特殊的文件(vmcore)中。

下面以Fedora26做為測(cè)試演示。(Fedora和CentOS系列的系統(tǒng)已經(jīng)在kenrel中打開(kāi)了CONFIG_KEXEC*選項(xiàng)。)

首先需要在系統(tǒng)啟動(dòng)時(shí)預(yù)留出給第二個(gè)內(nèi)核運(yùn)行的內(nèi)存。內(nèi)核參數(shù)"crashkernel=160M"會(huì)在系統(tǒng)啟動(dòng)時(shí)預(yù)留出160M內(nèi)存的空間給捕獲內(nèi)核運(yùn)行使用。"crashkerel=xM"還支持其他的參數(shù),詳細(xì)的可以參考內(nèi)核參數(shù)文檔 內(nèi)核參數(shù)。

# dmesg | grep -i reserving
[    0.000000] Reserving 160MB of memory at 656MB for crashkernel (System RAM: 2047MB)

系統(tǒng)啟動(dòng)后我們可以從上面的命令中看到已經(jīng)預(yù)留出了160M的內(nèi)存從內(nèi)存的656M處。

安裝用戶態(tài)的包"kexec-tools",軟件包中會(huì)提供kdump所需的服務(wù)和"kexec"快速內(nèi)核啟動(dòng)命令,和壓縮過(guò)濾內(nèi)存的"makedumpfile"命令。

[root@localhost ~]# dnf install -y kexec-tools

配置,修改kdump相關(guān)的配置文件。

[root@localhost ~]# grep -v ^# /etc/kdump.conf 

path /var/crash
core_collector makedumpfile -l --message-level 1 -d 31


[root@localhost ~]# grep -v ^# /etc/sysconfig/kdump
KDUMP_KERNELVER=""

KDUMP_COMMANDLINE=""

KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet"

KDUMP_COMMANDLINE_APPEND="irqpoll nr_cpus=1 reset_devices cgroup_disable=memory mce=off numa=off udev.children-max=2 panic=10 rootflags=nofail acpi_no_memhotplug transparent_hugepage=never nokaslr"

KEXEC_ARGS=""

KDUMP_IMG="vmlinuz"

KDUMP_IMG_EXT=""

配置文件/etc/kdump.conf設(shè)置了kdump發(fā)生時(shí)vmcore文件的存儲(chǔ)方式,此文件修改后需要重啟kdump的服務(wù)。

配置文件/etc/sysconfig/kdump,如果只是修改了COMMANDLINE相關(guān)的參數(shù),則不需要去重新build生成新的initramfs文件。

啟動(dòng)kdump服務(wù):

[root@localhost ~]# systemctl restart kdump
[root@localhost ~]# systemctl status kdump
● kdump.service - Crash recovery kernel arming
   Loaded: loaded (/usr/lib/systemd/system/kdump.service; enabled; vendor preset: disabled)
   Active: active (exited) since Sat 2017-07-15 10:46:22 UTC; 36s ago
  Process: 2172 ExecStop=/usr/bin/kdumpctl stop (code=exited, status=0/SUCCESS)
  Process: 2180 ExecStart=/usr/bin/kdumpctl start (code=exited, status=0/SUCCESS)
 Main PID: 2180 (code=exited, status=0/SUCCESS)

Jul 15 10:46:21 localhost dracut[4264]: -rw-r--r--   1 root     root          127 Mar 28 02:15 usr/share/zoneinfo/Etc/UTC
Jul 15 10:46:21 localhost dracut[4264]: drwxr-xr-x   3 root     root            0 Jun 22 13:38 var
Jul 15 10:46:21 localhost dracut[4264]: lrwxrwxrwx   1 root     root           11 Jun 22 13:38 var/lock -> ../run/lock
Jul 15 10:46:21 localhost dracut[4264]: lrwxrwxrwx   1 root     root            6 Jun 22 13:38 var/run -> ../run
Jul 15 10:46:21 localhost dracut[4264]: drwxr-xr-x   2 root     root            0 Jun 22 13:38 var/tmp
Jul 15 10:46:21 localhost dracut[4264]: ========================================================================
Jul 15 10:46:21 localhost dracut[4264]: *** Creating initramfs image file '/boot/initramfs-4.11.9-300.fc26.x86_64kdump.img' done ***
Jul 15 10:46:22 localhost kdumpctl[2180]: kexec: loaded kdump kernel
Jul 15 10:46:22 localhost kdumpctl[2180]: Starting kdump: [OK]
Jul 15 10:46:22 localhost systemd[1]: Started Crash recovery kernel arming.

所有的服務(wù)都配置完成,如果此時(shí)系統(tǒng)發(fā)生了panic或者其他的一些導(dǎo)致系統(tǒng)崩潰的現(xiàn)象,這是kdump服務(wù)會(huì)將當(dāng)時(shí)的內(nèi)存鏡像按照用戶的配置保存起來(lái)。一個(gè)簡(jiǎn)單的方式是通過(guò)命令來(lái)觸發(fā):

[root@localhost ~]# echo c > /proc/sysrq-trigger

[some console log]
... ...
         Starting Kdump Vmcore Save Service...
kdump: dump target is /dev/vda1
kdump: saving to /sysroot//var/crash/127.0.0.1-2017-07-16-04:21:36/
[    2.718001] EXT4-fs (vda1): re-mounted. Opts: data=ordered
kdump: saving vmcore-dmesg.txt
kdump: saving vmcore-dmesg.txt complete
kdump: saving vmcore
Copying data                       : [100.0 %] -
kdump: saving vmcore complete
... ...
[/some console log]

當(dāng)系統(tǒng)重啟后就能在指定的目錄下看到生成的vmcore文件??梢詤⒖寂渲梦募?/etc/kdump.conf"里的"path"字段。

[root@localhost ~]# ls -lt /var/crash/*/
total 33492
-rw-------. 1 root root 34253115 Jul 16 04:21 vmcore
-rw-r--r--. 1 root root    40360 Jul 16 04:21 vmcore-dmesg.txt

轉(zhuǎn)儲(chǔ)文件被保存后可以用"crash"這個(gè)軟件包來(lái)分析這個(gè)"vmcore"文件。

開(kāi)始提到了Kexec內(nèi)核部分提供了一些系統(tǒng)調(diào)用,"kexec_load()" 和 "kexec_file_load()",其中一個(gè)用來(lái)加載捕獲內(nèi)核 - "kexec -l",另外一個(gè)來(lái)提供系統(tǒng)重啟 - "kexec -e"。

系統(tǒng)調(diào)用"kexec_load()"可以加載一個(gè)新的內(nèi)核并之后能夠被"reboot()"調(diào)用。它是被這樣定義的:

long kexec_load(unsigned long entry, unsigned long nr_segments,
                       struct kexec_segment *segments, unsigned long flags);

其中一個(gè)比較重要的是"kexec_segment"結(jié)構(gòu)體:

struct kexec_segment {
    void   *buf;        /* Buffer in user space */
    size_t  bufsz;      /* Buffer length in user space */
    void   *mem;        /* Physical address of kernel */
    size_t  memsz;      /* Physical address length */
};

當(dāng)reboot()的參數(shù)為"LINUX_REBOOT_CMD_KEXEC"并被調(diào)用時(shí),則啟動(dòng)新的內(nèi)核時(shí)就調(diào)用"kexec_load()"系統(tǒng)調(diào)用。另外“CONFIG_KEXEC”必須在編譯kernel時(shí)被打開(kāi)。

系統(tǒng)調(diào)用"kexec_load_file()"會(huì)設(shè)置2個(gè)參數(shù)"kernel"和"initramfs"給"kexec"命令。"kexec"會(huì)讀取這些數(shù)據(jù)來(lái)創(chuàng)建對(duì)應(yīng)的數(shù)據(jù)段。

long kexec_file_load(int kernel_fd, int initrd_fd,
                           unsigned long cmdline_len, const char *cmdline,
                           unsigned long flags);

同樣的"CONFIG_KEXEC_FILE"參數(shù)也要在內(nèi)核編譯時(shí)被打開(kāi)。

目前的大多數(shù)發(fā)行版都已經(jīng)打開(kāi)了"KEXEC"相關(guān)的配置參數(shù)。

以上就是一個(gè)kdump的簡(jiǎn)單流程。有關(guān)"kdump"能夠捕獲到的內(nèi)核崩潰時(shí)間可以參考文檔"/usr/share/doc/kexec-tools/kexec-kdump-howto.txt"?;蛘哒?qǐng)參考我們寫(xiě)的測(cè)試用例 kdump-test。

參考資料:
kdump-paper
kdump-introduction
fedora-kexec-tools

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,506評(píng)論 19 139
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,781評(píng)論 25 709
  • Ubuntu的發(fā)音 Ubuntu,源于非洲祖魯人和科薩人的語(yǔ)言,發(fā)作 oo-boon-too 的音。了解發(fā)音是有意...
    螢火蟲(chóng)de夢(mèng)閱讀 100,587評(píng)論 9 468
  • OSSIC是由4位羅技前員工組建的音響公司,熱衷于解決耳機(jī)界的一個(gè)大難題:如何盡可能準(zhǔn)確地將聲音「空間化」?團(tuán)隊(duì)的...
    VR看天下閱讀 520評(píng)論 0 1
  • 寫(xiě)在前面 新到一個(gè)公司,拉下代碼后,發(fā)現(xiàn)編譯時(shí)間在10分鐘以上,不知道為啥這么長(zhǎng)時(shí)間,之前開(kāi)發(fā)過(guò)程中沒(méi)有遇到過(guò)這樣...
    vincentgemini閱讀 6,676評(píng)論 0 8

友情鏈接更多精彩內(nèi)容