自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

使用Kdump檢查Linux內(nèi)核崩潰

系統(tǒng) Linux
kdump 是獲取崩潰的 Linux 內(nèi)核轉(zhuǎn)儲的一種方法,但是想找到解釋其使用和內(nèi)部結(jié)構(gòu)的文檔可能有點困難。在本文中,我將研究 kdump 的基本使用方法,和 kdump/kexec 在內(nèi)核中是如何實現(xiàn)。

[[198842]]

讓我們先看一下 kdump 的基本使用方法,和 kdump/kexec 在內(nèi)核中是如何實現(xiàn)。

kdump 是獲取崩潰的 Linux 內(nèi)核轉(zhuǎn)儲的一種方法,但是想找到解釋其使用和內(nèi)部結(jié)構(gòu)的文檔可能有點困難。在本文中,我將研究 kdump 的基本使用方法,和 kdump/kexec 在內(nèi)核中是如何實現(xiàn)。

kexec 是一個 Linux 內(nèi)核到內(nèi)核的引導(dǎo)加載程序,可以幫助從***個內(nèi)核的上下文引導(dǎo)到第二個內(nèi)核。kexec 會關(guān)閉***個內(nèi)核,繞過 BIOS 或固件階段,并跳轉(zhuǎn)到第二個內(nèi)核。因此,在沒有 BIOS 階段的情況下,重新啟動變得更快。

kdump 可以與 kexec 應(yīng)用程序一起使用 —— 例如,當(dāng)***個內(nèi)核崩潰時第二個內(nèi)核啟動,第二個內(nèi)核用于復(fù)制***個內(nèi)核的內(nèi)存轉(zhuǎn)儲,可以使用 gdb 和 crash 等工具分析崩潰的原因。(在本文中,我將使用術(shù)語“***內(nèi)核”作為當(dāng)前運行的內(nèi)核,“第二內(nèi)核” 作為使用 kexec 運行的內(nèi)核,“捕獲內(nèi)核” 表示在當(dāng)前內(nèi)核崩潰時運行的內(nèi)核。)

kexec 機制在內(nèi)核以及用戶空間中都有組件。內(nèi)核提供了幾個用于 kexec 重啟功能的系統(tǒng)調(diào)用。名為 kexec-tools 的用戶空間工具使用這些調(diào)用,并提供可執(zhí)行文件來加載和引導(dǎo)“第二內(nèi)核”。有的發(fā)行版還會在 kexec-tools 上添加封裝器,這有助于捕獲并保存各種轉(zhuǎn)儲目標(biāo)配置的轉(zhuǎn)儲。在本文中,我將使用名為 distro-kexec-tools 的工具來避免上游 kexec 工具和特定于發(fā)行版的 kexec-tools 代碼之間的混淆。我的例子將使用 Fedora Linux 發(fā)行版。

Fedora kexec-tools 工具

使用 dnf install kexec-tools 命令在 Fedora 機器上安裝 fedora-kexec-tools。在安裝 fedora-kexec-tools 后可以執(zhí)行 systemctl start kdump 命令來啟動 kdump 服務(wù)。當(dāng)此服務(wù)啟動時,它將創(chuàng)建一個根文件系統(tǒng)(initramfs),其中包含了要掛載到目標(biāo)位置的資源,以保存 vmcore,以及用來復(fù)制和轉(zhuǎn)儲 vmcore 到目標(biāo)位置的命令。然后,該服務(wù)將內(nèi)核和 initramfs 加載到崩潰內(nèi)核區(qū)域內(nèi)的合適位置,以便在內(nèi)核崩潰時可以執(zhí)行它們。

Fedora 封裝器提供了兩個用戶配置文件:

  1. /etc/kdump.conf 指定修改后需要重建 initramfs 的配置參數(shù)。例如,如果將轉(zhuǎn)儲目標(biāo)從本地磁盤更改為 NFS 掛載的磁盤,則需要由“捕獲內(nèi)核”所加載的 NFS 相關(guān)的內(nèi)核模塊。
  2. /etc/sysconfig/kdump 指定修改后不需要重新構(gòu)建 initramfs 的配置參數(shù)。例如,如果只需修改傳遞給“捕獲內(nèi)核”的命令行參數(shù),則不需要重新構(gòu)建 initramfs。

如果內(nèi)核在 kdump 服務(wù)啟動之后出現(xiàn)故障,那么“捕獲內(nèi)核”就會執(zhí)行,其將進一步執(zhí)行 initramfs 中的 vmcore 保存過程,然后重新啟動到穩(wěn)定的內(nèi)核。

kexec-tools 工具

編譯 kexec-tools 的源代碼得到了一個名為 kexec 的可執(zhí)行文件。這個同名的可執(zhí)行文件可用于加載和執(zhí)行“第二內(nèi)核”,或加載“捕獲內(nèi)核”,它可以在內(nèi)核崩潰時執(zhí)行。

加載“第二內(nèi)核”的命令:

  1. # kexec -l kernel.img --initrd=initramfs-image.img –reuse-cmdline 

--reuse-command 參數(shù)表示使用與“***內(nèi)核”相同的命令行。使用 --initrd 傳遞 initramfs。 -l 表明你正在加載“第二內(nèi)核”,其可以由 kexec 應(yīng)用程序本身執(zhí)行(kexec -e)。使用 -l 加載的內(nèi)核不能在內(nèi)核崩潰時執(zhí)行。為了加載可以在內(nèi)核崩潰時執(zhí)行的“捕獲內(nèi)核”,必須傳遞參數(shù) -p 取代 -l。

加載捕獲內(nèi)核的命令:

  1. # kexec -p kernel.img --initrd=initramfs-image.img –reuse-cmdline 

echo c > /pros/sysrq-trigger 可用于使內(nèi)核崩潰以進行測試。有關(guān) kexec-tools 提供的選項的詳細(xì)信息,請參閱 man kexec。在轉(zhuǎn)到下一個部分之前,請看這個 kexec_dump 的演示: 

 

 kdump: 端到端流

下圖展示了流程圖。必須在引導(dǎo)“***內(nèi)核”期間為捕獲內(nèi)核保留 crashkernel 的內(nèi)存。您可以在內(nèi)核命令行中傳遞 crashkernel=Y@X,其中 @X 是可選的。crashkernel=256M 適用于大多數(shù) x86_64 系統(tǒng);然而,為崩潰內(nèi)核選擇適當(dāng)?shù)膬?nèi)存取決于許多因素,如內(nèi)核大小和 initramfs,以及 initramfs 中包含的模塊和應(yīng)用程序運行時的內(nèi)存需求。有關(guān)傳遞崩潰內(nèi)核參數(shù)的更多方法,請參閱 kernel-parameters 文檔。 

 

pratyush_f1.png

您可以將內(nèi)核和 initramfs 鏡像傳遞給 kexec 可執(zhí)行文件,如(kexec-tools)部分的命令所示。“捕獲內(nèi)核”可以與“***內(nèi)核”相同,也可以不同。通常,一樣即可。Initramfs 是可選的;例如,當(dāng)內(nèi)核使用 CONFIG_INITRAMFS_SOURCE 編譯時,您不需要它。通常,從***個 initramfs 中保存一個不一樣的捕獲 initramfs,因為在捕獲 initramfs 中自動執(zhí)行 vmcore 的副本能獲得更好的效果。當(dāng)執(zhí)行 kexec 時,它還加載了 elfcorehdr 數(shù)據(jù)和 purgatory 可執(zhí)行文件(LCTT 譯注:purgatory 就是一個引導(dǎo)加載程序,是為 kdump 定作的。它被賦予了“煉獄”這樣一個古怪的名字應(yīng)該只是一種調(diào)侃)。 elfcorehdr 具有關(guān)于系統(tǒng)內(nèi)存組織的信息,而 purgatory 可以在“捕獲內(nèi)核”執(zhí)行之前執(zhí)行并驗證第二階段的二進制或數(shù)據(jù)是否具有正確的 SHA。purgatory 也是可選的。

當(dāng)“***內(nèi)核”崩潰時,它執(zhí)行必要的退出過程并切換到 purgatory(如果存在)。purgatory 驗證加載二進制文件的 SHA256,如果是正確的,則將控制權(quán)傳遞給“捕獲內(nèi)核”。“捕獲內(nèi)核”根據(jù)從 elfcorehdr 接收到的系統(tǒng)內(nèi)存信息創(chuàng)建 vmcore。因此,“捕獲內(nèi)核”啟動后,您將看到 /proc/vmcore 中“***內(nèi)核”的轉(zhuǎn)儲。根據(jù)您使用的 initramfs,您現(xiàn)在可以分析轉(zhuǎn)儲,將其復(fù)制到任何磁盤,也可以是自動復(fù)制的,然后重新啟動到穩(wěn)定的內(nèi)核。

內(nèi)核系統(tǒng)調(diào)用

內(nèi)核提供了兩個系統(tǒng)調(diào)用:kexec_load() 和 kexec_file_load(),可以用于在執(zhí)行 kexec -l 時加載“第二內(nèi)核”。它還為 reboot() 系統(tǒng)調(diào)用提供了一個額外的標(biāo)志,可用于使用 kexec -e 引導(dǎo)到“第二內(nèi)核”。

kexec_load():kexec_load() 系統(tǒng)調(diào)用加載一個可以在之后通過 reboot() 執(zhí)行的新的內(nèi)核。其原型定義如下:

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

用戶空間需要為不同的組件傳遞不同的段,如內(nèi)核,initramfs 等。因此,kexec 可執(zhí)行文件有助于準(zhǔn)備這些段。kexec_segment 的結(jié)構(gòu)如下所示:

  1. struct kexec_segment { 
  2.     void *buf; 
  3.     /* 用戶空間緩沖區(qū) */ 
  4.     size_t bufsz; 
  5.     /* 用戶空間中的緩沖區(qū)長度 */ 
  6.     void *mem; 
  7.     /* 內(nèi)核的物理地址 */ 
  8.     size_t memsz; 
  9.     /* 物理地址長度 */ 
  10. }; 

當(dāng)使用 LINUX_REBOOT_CMD_KEXEC 調(diào)用 reboot() 時,它會引導(dǎo)進入由 kexec_load 加載的內(nèi)核。如果標(biāo)志 KEXEC_ON_CRASH 被傳遞給 kexec_load(),則加載的內(nèi)核將不會使用 reboot(LINUX_REBOOT_CMD_KEXEC) 來啟動;相反,這將在內(nèi)核崩潰中執(zhí)行。必須定義 CONFIG_KEXEC 才能使用 kexec,并且為 kdump 定義 CONFIG_CRASH_DUMP。

kexec_file_load():作為用戶,你只需傳遞兩個參數(shù)(即 kernel 和 initramfs)到 kexec 可執(zhí)行文件。然后,kexec 從 sysfs 或其他內(nèi)核信息源中讀取數(shù)據(jù),并創(chuàng)建所有段。所以使用 kexec_file_load() 可以簡化用戶空間,只傳遞內(nèi)核和 initramfs 的文件描述符。其余部分由內(nèi)核本身完成。使用此系統(tǒng)調(diào)用時應(yīng)該啟用 CONFIG_KEXEC_FILE。它的原型如下:

  1. long kexec_file_load(int kernel_fd, int initrd_fd, unsigned long 
  2. cmdline_len, const char __user * cmdline_ptr, unsigned long 
  3. flags); 

請注意,kexec_file_load 也可以接受命令行,而 kexec_load() 不行。內(nèi)核根據(jù)不同的系統(tǒng)架構(gòu)來接受和執(zhí)行命令行。因此,在 kexec_load() 的情況下,kexec-tools 將通過其中一個段(如在 dtb 或 ELF 引導(dǎo)注釋等)中傳遞命令行。

目前,kexec_file_load() 僅支持 x86 和 PowerPC。

當(dāng)內(nèi)核崩潰時會發(fā)生什么

當(dāng)***個內(nèi)核崩潰時,在控制權(quán)傳遞給 purgatory 或“捕獲內(nèi)核”之前,會執(zhí)行以下操作:

  • 準(zhǔn)備 CPU 寄存器(參見內(nèi)核代碼中的 crash_setup_regs());
  • 更新 vmcoreinfo 備注(請參閱 crash_save_vmcoreinfo());
  • 關(guān)閉非崩潰的 CPU 并保存準(zhǔn)備好的寄存器(請參閱 machine_crash_shutdown() 和 crash_save_cpu());
  • 您可能需要在此處禁用中斷控制器;
  • ***,它執(zhí)行 kexec 重新啟動(請參閱 machine_kexec()),它將加載或刷新 kexec 段到內(nèi)存,并將控制權(quán)傳遞給進入段的執(zhí)行文件。輸入段可以是下一個內(nèi)核的 purgatory 或開始地址。

ELF 程序頭

kdump 中涉及的大多數(shù)轉(zhuǎn)儲核心都是 ELF 格式。因此,理解 ELF 程序頭部很重要,特別是當(dāng)您想要找到 vmcore 準(zhǔn)備的問題。每個 ELF 文件都有一個程序頭:

  • 由系統(tǒng)加載器讀取,
  • 描述如何將程序加載到內(nèi)存中,
  • 可以使用 Objdump -p elf_file 來查看程序頭。

vmcore 的 ELF 程序頭的示例如下:

  1. # objdump -p vmcore 
  2. vmcore: 
  3. file format elf64-littleaarch64 
  4. Program Header: 
  5. NOTE off 0x0000000000010000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**0 filesz 
  6. 0x00000000000013e8 memsz 0x00000000000013e8 flags --- 
  7. LOAD off 0x0000000000020000 vaddr 0xffff000008080000 paddr 0x0000004000280000 align 2**0 filesz 
  8. 0x0000000001460000 memsz 0x0000000001460000 flags rwx 
  9. LOAD off 0x0000000001480000 vaddr 0xffff800000200000 paddr 0x0000004000200000 align 2**0 filesz 
  10. 0x000000007fc00000 memsz 0x000000007fc00000 flags rwx 
  11. LOAD off 0x0000000081080000 vaddr 0xffff8000ffe00000 paddr 0x00000040ffe00000 align 2**0 filesz 
  12. 0x00000002fa7a0000 memsz 0x00000002fa7a0000 flags rwx 
  13. LOAD off 0x000000037b820000 vaddr 0xffff8003fa9e0000 paddr 0x00000043fa9e0000 align 2**0 filesz 
  14. 0x0000000004fc0000 memsz 0x0000000004fc0000 flags rwx 
  15. LOAD off 0x00000003807e0000 vaddr 0xffff8003ff9b0000 paddr 0x00000043ff9b0000 align 2**0 filesz 
  16. 0x0000000000010000 memsz 0x0000000000010000 flags rwx 
  17. LOAD off 0x00000003807f0000 vaddr 0xffff8003ff9f0000 paddr 0x00000043ff9f0000 align 2**0 filesz 
  18. 0x0000000000610000 memsz 0x0000000000610000 flags rwx 

在這個例子中,有一個 note 段,其余的是 load 段。note 段提供了有關(guān) CPU 信息,load 段提供了關(guān)于復(fù)制的系統(tǒng)內(nèi)存組件的信息。

vmcore 從 elfcorehdr 開始,它具有與 ELF 程序頭相同的結(jié)構(gòu)。參見下圖中 elfcorehdr 的表示: 

 

pratyush_f2.png

kexec-tools 讀取 /sys/devices/system/cpu/cpu%d/crash_notes 并準(zhǔn)備 CPU PT_NOTE 的標(biāo)頭。同樣,它讀取 /sys/kernel/vmcoreinfo 并準(zhǔn)備 vmcoreinfo PT_NOTE 的標(biāo)頭,從 /proc/iomem 讀取系統(tǒng)內(nèi)存并準(zhǔn)備存儲器 PT_LOAD 標(biāo)頭。當(dāng)“捕獲內(nèi)核”接收到 elfcorehdr 時,它從標(biāo)頭中提到的地址中讀取數(shù)據(jù),并準(zhǔn)備 vmcore。

Crash note

Crash notes 是每個 CPU 中用于在系統(tǒng)崩潰的情況下存儲 CPU 狀態(tài)的區(qū)域;它有關(guān)于當(dāng)前 PID 和 CPU 寄存器的信息。

vmcoreinfo

該 note 段具有各種內(nèi)核調(diào)試信息,如結(jié)構(gòu)體大小、符號值、頁面大小等。這些值由捕獲內(nèi)核解析并嵌入到 /proc/vmcore 中。 vmcoreinfo 主要由 makedumpfile 應(yīng)用程序使用。在 Linux 內(nèi)核,include/linux/kexec.h 宏定義了一個新的 vmcoreinfo。 一些示例宏如下所示:

  • VMCOREINFO_PAGESIZE()
  • VMCOREINFO_SYMBOL()
  • VMCOREINFO_SIZE()
  • VMCOREINFO_STRUCT_SIZE()

makedumpfile

vmcore 中的許多信息(如可用頁面)都沒有用處。makedumpfile 是一個用于排除不必要的頁面的應(yīng)用程序,如:

  • 填滿零的頁面;
  • 沒有私有標(biāo)志的緩存頁面(非專用緩存);
  • 具有私有標(biāo)志的緩存頁面(專用緩存);
  • 用戶進程數(shù)據(jù)頁;
  • 可用頁面。

此外,makedumpfile 在復(fù)制時壓縮 /proc/vmcore 的數(shù)據(jù)。它也可以從轉(zhuǎn)儲中刪除敏感的符號信息; 然而,為了做到這一點,它首先需要內(nèi)核的調(diào)試信息。該調(diào)試信息來自 VMLINUX 或 vmcoreinfo,其輸出可以是 ELF 格式或 kdump 壓縮格式。

典型用法:

  1. # makedumpfile -l --message-level 1 -d 31 /proc/vmcore makedumpfilecore 

詳細(xì)信息請參閱 man makedumpfile。

kdump 調(diào)試

新手在使用 kdump 時可能會遇到的問題:

kexec -p kernel_image 沒有成功

  • 檢查是否分配了崩潰內(nèi)存。
  • cat /sys/kernel/kexec_crash_size 不應(yīng)該有零值。
  • cat /proc/iomem | grep "Crash kernel" 應(yīng)該有一個分配的范圍。
  • 如果未分配,則在命令行中傳遞正確的 crashkernel= 參數(shù)。
  • 如果沒有顯示,則在 kexec 命令中傳遞參數(shù) -d,并將輸出信息發(fā)送到 kexec-tools 郵件列表。

在“***內(nèi)核”的***一個消息之后,在控制臺上看不到任何東西(比如“bye”)

  • 檢查 kexec -e 之后的 kexec -l kernel_image 命令是否工作。
  • 可能缺少支持的體系結(jié)構(gòu)或特定機器的選項。
  • 可能是 purgatory 的 SHA 驗證失敗。如果您的體系結(jié)構(gòu)不支持 purgatory 中的控制臺,則很難進行調(diào)試。
  • 可能是“第二內(nèi)核”早已崩潰。
  • 將您的系統(tǒng)的 earlycon 或 earlyprintk 選項傳遞給“第二內(nèi)核”的命令行。
  • 使用 kexec-tools 郵件列表共享***個內(nèi)核和捕獲內(nèi)核的 dmesg 日志。

資源

fedora-kexec-tools

  • GitHub 倉庫:git://pkgs.fedoraproject.org/kexec-tools
  • 郵件列表:kexec@lists.fedoraproject.org
  • 說明:Specs 文件和腳本提供了用戶友好的命令和服務(wù),以便 kexec-tools 可以在不同的用戶場景下實現(xiàn)自動化。

kexec-tools

  • GitHub 倉庫:git://git.kernel.org/pub/scm/utils/kernel/kexec/kexec-tools.git
  • 郵件列表:kexec@lists.infradead.org
  • 說明:使用內(nèi)核系統(tǒng)調(diào)用并提供用戶命令 kexec。

Linux kernel

  • GitHub 倉庫: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
  • 郵件列表:kexec@lists.infradead.org
  • 說明:實現(xiàn)了 kexec_load()、kexec_file_load()、reboot() 系統(tǒng)調(diào)用和特定體系結(jié)構(gòu)的代碼,例如 machine_kexec() 和 machine_crash_shutdown()。

Makedumpfile

  • GitHub 倉庫: git://git.code.sf.net/p/makedumpfile/code
  • 郵件列表:kexec@lists.infradead.org
  • 說明:從轉(zhuǎn)儲文件中壓縮和過濾不必要的組件。

(題圖:Penguin、 Boot,修改:Opensource.com. CC BY-SA 4.0)

責(zé)任編輯:龐桂玉 來源: Linux中國
相關(guān)推薦

2021-03-05 07:14:08

Linuxcrashvmcore

2023-12-26 15:06:00

Linux內(nèi)核轉(zhuǎn)儲

2020-06-10 10:50:15

Linuxpstore內(nèi)核

2021-10-06 20:00:08

LinuxLinux內(nèi)核Kasan

2025-01-16 09:35:08

Ubuntukdump數(shù)據(jù)

2009-12-07 09:55:12

2011-09-28 10:25:23

2022-07-13 14:26:26

Linux

2012-10-29 11:25:05

IBMdw

2021-07-12 12:25:21

LinuxSIGIO使用

2023-03-10 11:12:12

2021-02-20 06:08:07

LinuxWindows內(nèi)核

2012-09-28 10:19:32

IBMdw

2010-03-02 09:17:32

Linux local

2018-08-09 08:00:00

Linux命令內(nèi)存用量

2021-10-11 10:33:02

Linux jps命令Java

2024-01-17 17:36:06

Linuxsystemd

2021-08-06 20:22:27

Linuxdu命令

2017-02-10 19:20:02

Linuxnc命令遠(yuǎn)程端口

2018-11-13 12:52:50

Linux內(nèi)核?;厮?/a>
點贊
收藏

51CTO技術(shù)棧公眾號