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

我們?nèi)绾螒?yīng)對 Linux 內(nèi)核崩潰

系統(tǒng) Linux
kdump 和 kexec 可以一起使用。當(dāng)?shù)谝粋€內(nèi)核崩潰時,kexec 可以引導(dǎo)第二個內(nèi)核,而第二個內(nèi)核則用于復(fù)制第一個內(nèi)核的內(nèi)存轉(zhuǎn)儲。

kdump 是一種用于獲取 Linux 內(nèi)核崩潰轉(zhuǎn)儲的方法,而要找到關(guān)于其使用和內(nèi)部結(jié)構(gòu)的解釋性文檔可能有一些挑戰(zhàn)。在這篇文章中,我將深入探討 kdump 的基本用法以及 kdump/kexec 在內(nèi)核中的實現(xiàn)。

首先,讓我們了解 kexec。kexec 是一個 Linux 內(nèi)核到內(nèi)核的引導(dǎo)加載程序,它可以幫助從第一個內(nèi)核的上下文快速引導(dǎo)到第二個內(nèi)核。使用 kexec,可以關(guān)閉第一個內(nèi)核,繞過 BIOS 或固件階段,并直接跳轉(zhuǎn)到第二個內(nèi)核,從而實現(xiàn)快速重啟,無需經(jīng)歷傳統(tǒng)的 BIOS 階段。

kdump 和 kexec 可以一起使用。當(dāng)?shù)谝粋€內(nèi)核崩潰時,kexec 可以引導(dǎo)第二個內(nèi)核,而第二個內(nèi)核則用于復(fù)制第一個內(nèi)核的內(nèi)存轉(zhuǎn)儲。之后,可以使用調(diào)試工具如 gdb 和 crash 來分析這個崩潰的原因。在這里,我將使用術(shù)語“第一內(nèi)核”表示當(dāng)前運(yùn)行的內(nèi)核,“第二內(nèi)核”表示通過 kexec 運(yùn)行的內(nèi)核,“捕獲內(nèi)核”表示在當(dāng)前內(nèi)核崩潰時運(yùn)行的內(nèi)核。

kexec 機(jī)制涉及到內(nèi)核和用戶空間中的多個組件。內(nèi)核提供了幾個用于 kexec 重啟功能的系統(tǒng)調(diào)用。用戶空間的 kexec 工具(通常是 kexec-tools)利用這些調(diào)用,并提供可執(zhí)行文件,用于加載和引導(dǎo)“第二內(nèi)核”。一些發(fā)行版可能還會添加封裝器,以便捕獲和保存各種配置轉(zhuǎn)儲目標(biāo)的轉(zhuǎn)儲。在這里,我將使用 Fedora Linux 發(fā)行版的 kexec-tools。

通過使用 kdump 和 kexec,你可以更有效地處理內(nèi)核崩潰情況,加速系統(tǒng)的重啟過程,并方便地分析和調(diào)試內(nèi)核問題。

Fedora kexec-tools 工具

在 Fedora 操作系統(tǒng)上,你可以通過運(yùn)行以下命令安裝 fedora-kexec-tools:

bashCopy code
sudo dnf install kexec-tools

安裝完成后,你可以使用以下命令啟動 kdump 服務(wù):

bashCopy code
sudo systemctl start kdump

啟動 kdump 服務(wù)時,它會創(chuàng)建一個包含保存 vmcore 所需資源的根文件系統(tǒng)(initramfs),以及執(zhí)行將 vmcore 復(fù)制和轉(zhuǎn)儲到目標(biāo)位置的命令。此服務(wù)還會加載內(nèi)核和 initramfs 到內(nèi)核崩潰區(qū)域的適當(dāng)位置,以便在發(fā)生內(nèi)核崩潰時執(zhí)行它們。

在 Fedora 中,有兩個配置文件可供修改:

  1. /etc/kdump.conf:指定那些在修改后需要重新構(gòu)建 initramfs 的配置參數(shù)。例如,如果將轉(zhuǎn)儲目標(biāo)從本地磁盤更改為 NFS 掛載的磁盤,則需要重新加載與 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í)行,并進(jìn)一步執(zhí)行 initramfs 中的 vmcore 保存過程。然后,系統(tǒng)將重新啟動到穩(wěn)定的內(nèi)核。這種設(shè)置使得在系統(tǒng)遇到內(nèi)核崩潰時能夠更有效地保存轉(zhuǎn)儲信息和進(jìn)行故障排除。

kexec-tools 工具

通過編譯 kexec-tools 源代碼,你將獲得一個名為 kexec 的可執(zhí)行文件。這個同名的可執(zhí)行文件可以用于兩個主要操作:加載和執(zhí)行“第二內(nèi)核”或加載“捕獲內(nèi)核”以在內(nèi)核崩潰時執(zhí)行。

對于加載“第二內(nèi)核”,你可以使用以下命令:

bashCopy code
# kexec -l kernel.img --initrd=initramfs-image.img --reuse-cmdline

在這里,--reuse-cmdline 參數(shù)表示使用與“第一內(nèi)核”相同的命令行。通過使用 --initrd 選項傳遞 initramfs。-l 參數(shù)表明你正在加載“第二內(nèi)核”,這個內(nèi)核不能在內(nèi)核崩潰時執(zhí)行。如果你想要加載并在內(nèi)核崩潰時執(zhí)行“捕獲內(nèi)核”,則必須使用 -p 參數(shù),而不是 -l。

以下是加載“捕獲內(nèi)核”的示例命令:

bashCopy code
# kexec -p kernel.img --initrd=initramfs-image.img --reuse-cmdline

為了測試內(nèi)核崩潰,你可以使用以下命令:

bashCopy code
echo c > /proc/sysrq-trigger

這將觸發(fā)內(nèi)核崩潰,以便進(jìn)行測試。有關(guān) kexec-tools 提供的其他選項的詳細(xì)信息,你可以查閱 man kexec。在轉(zhuǎn)到下一部分之前,建議觀看一下 kexec_dump 的演示。

視頻地址:

https://img.linux.net.cn//static/video/kexec_kdump_demo-iOq_rJhrKhA.mp4

kdump: 端到端流

圖片圖片

在上述流程圖中,必須在引導(dǎo)“第一內(nèi)核”時為捕獲內(nèi)核保留一定量的內(nèi)存,通過在內(nèi)核命令行中傳遞 crashkernel=Y@X 來實現(xiàn),其中 Y 是保留的內(nèi)存大小,X 是可選的。通常,使用 crashkernel=256M 對于大多數(shù) x86_64 系統(tǒng)是合適的,但選擇適當(dāng)?shù)膬?nèi)存大小取決于多個因素,包括內(nèi)核大小、initramfs 的大小以及運(yùn)行時內(nèi)存需求。

您可以使用 kexec 可執(zhí)行文件傳遞內(nèi)核和 initramfs 鏡像,如上文“kexec-tools”部分所示的命令。值得注意的是,“捕獲內(nèi)核”可以與“第一內(nèi)核”相同,也可以是不同的。通常,它們是相同的。Initramfs 是可選的,例如,當(dāng)內(nèi)核使用 CONFIG_INITRAMFS_SOURCE 編譯時,您可能不需要它。通常,使用一個不同的捕獲 initramfs 可以更好地執(zhí)行 vmcore 的自動處理。

當(dāng)“第一內(nèi)核”崩潰時,它會執(zhí)行必要的退出過程并切換到 purgatory(如果存在)。purgatory 的作用包括驗證加載二進(jìn)制文件的 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,您可以進(jìn)一步分析并將其復(fù)制到磁盤,也可以設(shè)置自動復(fù)制,然后重新啟動到穩(wěn)定的內(nèi)核。

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

內(nèi)核提供了兩個與 kexec 相關(guān)的系統(tǒng)調(diào)用:kexec_load() 和 kexec_file_load()。這兩個系統(tǒng)調(diào)用用于加載新的內(nèi)核,以便通過 reboot() 系統(tǒng)調(diào)用啟動或在內(nèi)核崩潰時執(zhí)行。

  1. kexec_load():
kexec_load()

系統(tǒng)調(diào)用用于加載一個可以稍后通過

reboot()

執(zhí)行的新內(nèi)核。其原型定義如下:

cCopy code
long kexec_load(unsigned long entry, unsigned long nr_segments, struct kexec_segment *segments, unsigned long flags);
  • 用戶空間需要傳遞給不同組件不同的段,如內(nèi)核、initramfs 等。
kexec

可執(zhí)行文件幫助準(zhǔn)備這些段。

kexec_segment

結(jié)構(gòu)如下:

cCopy codestruct kexec_segment {
  void *buf;     /* 用戶空間緩沖區(qū) */
  size_t bufsz;   /* 用戶空間緩沖區(qū)長度 */
  void *mem;       /* 內(nèi)核的物理地址 */
  size_t memsz;   /* 物理地址長度 */
};
  • 如果傳遞 KEXEC_ON_CRASH 標(biāo)志給 kexec_load(),加載的內(nèi)核將不使用 reboot(LINUX_REBOOT_CMD_KEXEC) 啟動,而是在內(nèi)核崩潰時執(zhí)行。要使用 kexec,必須啟用 CONFIG_KEXEC,并為 kdump 啟用 CONFIG_CRASH_DUMP。
  1. kexec_file_load():

是一個更高級別的系統(tǒng)調(diào)用,它接受內(nèi)核和 initramfs 的文件描述符,然后由內(nèi)核完成其余部分。其原型如下:

cCopy code
long kexec_file_load(int kernel_fd, int initrd_fd, unsigned long cmdline_len, const char __user *cmdline_ptr, unsigned long flags);
  • 與 kexec_load() 不同,kexec_file_load() 還支持傳遞命令行。在此情況下,內(nèi)核根據(jù)系統(tǒng)體系結(jié)構(gòu)接受和執(zhí)行命令行。目前,kexec_file_load() 僅支持 x86 和 PowerPC。

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

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

  • 準(zhǔn)備 CPU 寄存器。
  • 更新 vmcoreinfo 備注。
  • 關(guān)閉非崩潰的 CPU 并保存準(zhǔn)備好的寄存器。
  • 在此階段可能需要禁用中斷控制器。
  • 執(zhí)行 kexec 重新啟動,加載或刷新 kexec 段到內(nèi)存,并將控制權(quán)傳遞給執(zhí)行文件。輸入段可以是下一個內(nèi)核的 purgatory 或起始地址。

ELF(Executable and Linkable Format)ELF 程序頭和崩潰轉(zhuǎn)儲

ELF(Executable and Linkable Format)是一種常用于可執(zhí)行文件和共享庫的文件格式。在崩潰轉(zhuǎn)儲中,ELF 程序頭對于描述如何將程序加載到內(nèi)存中非常重要。在 vmcore 中,大多數(shù)轉(zhuǎn)儲核心都是 ELF 格式的,因此理解 ELF 程序頭是很有幫助的。

每個 ELF 文件都有一個程序頭,由系統(tǒng)加載器讀取,描述了如何將程序加載到內(nèi)存中。你可以使用 objdump -p elf_file 來查看程序頭。

以下是 vmcore 的 ELF 程序頭的示例:

# objdump -p vmcore
vmcore:     file format elf64-littleaarch64
Program Header:
  NOTE off   0x0000000000010000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**0
        filesz 0x00000000000013e8 memsz 0x00000000000013e8 flags ---
  LOAD off   0x0000000000020000 vaddr 0xffff000008080000 paddr 0x0000004000280000 align 2**0
        filesz 0x0000000001460000 memsz 0x0000000001460000 flags rwx
  LOAD off   0x0000000001480000 vaddr 0xffff800000200000 paddr 0x0000004000200000 align 2**0
        filesz 0x000000007fc00000 memsz 0x000000007fc00000 flags rwx
  LOAD off   0x0000000081080000 vaddr 0xffff8000ffe00000 paddr 0x00000040ffe00000 align 2**0
        filesz 0x00000002fa7a0000 memsz 0x00000002fa7a0000 flags rwx
  LOAD off   0x000000037b820000 vaddr 0xffff8003fa9e0000 paddr 0x00000043fa9e0000 align 2**0
        filesz 0x0000000004fc0000 memsz 0x0000000004fc0000 flags rwx
  LOAD off   0x00000003807e0000 vaddr 0xffff8003ff9b0000 paddr 0x00000043ff9b0000 align 2**0
        filesz 0x0000000000010000 memsz 0x0000000000010000 flags rwx
  LOAD off   0x00000003807f0000 vaddr 0xffff8003ff9f0000 paddr 0x00000043ff9f0000 align 2**0
        filesz 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 的表示:

圖片圖片

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。

  1. Crash Notes (/sys/devices/system/cpu/cpu%d/crash_notes):

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

  1. VMcoreinfo (/sys/kernel/vmcoreinfo):
  • VMcoreinfo 是一個包含內(nèi)核調(diào)試信息的文件。kexec-tools 讀取此文件并準(zhǔn)備 vmcoreinfo PT_NOTE 的標(biāo)頭。其中包含一些關(guān)鍵的宏定義,如 VMCOREINFO_PAGESIZE、VMCOREINFO_SYMBOL、VMCOREINFO_SIZE、VMCOREINFO_STRUCT_SIZE 等。
  1. makedumpfile:

是一個應(yīng)用程序,用于處理/proc/vmcore的數(shù)據(jù),排除不必要的頁面并在復(fù)制時進(jìn)行壓縮。它還可以從轉(zhuǎn)儲中刪除敏感的符號信息。

通常在 kdump 環(huán)境中使用,可以使用以下示例命令:

bashCopy code
# makedumpfile -l --message-level 1 -d 31 /proc/vmcore makedumpfilecore
  • 詳細(xì)信息請參閱 man makedumpfile。

kdump 調(diào)試

對于初學(xué)者使用 kdump 時可能遇到的問題:

問題:kexec -p kernel_image 執(zhí)行失敗

問題:在“第一內(nèi)核”結(jié)束后,在控制臺上沒有看到任何輸出(例如“bye”)

這可以幫助在早期階段看到更多的調(diào)試輸出。

  • 確保第二內(nèi)核的設(shè)置和參數(shù)正確??赡苄枰诿钚兄袀鬟f額外的選項以啟用調(diào)試信息。
  • 如果體系結(jié)構(gòu)不支持 purgatory 中的控制臺,很難進(jìn)行調(diào)試。確認(rèn) SHA 驗證是否通過。
  • 檢查是否有適用于您的體系結(jié)構(gòu)和機(jī)器的正確配置。有些平臺可能需要特定的設(shè)置。
  • 確保 kexec -e 命令成功啟動了第二內(nèi)核。
  • 檢查 kexec -e 之后的 kexec -l kernel_image 命令是否正常工作。
  • 確認(rèn)是否缺少支持的體系結(jié)構(gòu)或特定機(jī)器的選項。
  • 驗證 purgatory 的 SHA 驗證是否失敗。
  • 檢查是否第二內(nèi)核早已崩潰。
  • 在第二內(nèi)核的命令行中傳遞 earlycon 或 earlyprintk 選項。
  • 如果問題仍然存在,使用 kexec-tools 郵件列表共享第一個內(nèi)核和捕獲內(nèi)核的 dmesg 日志。
  • kexec -d -p kernel_image
  • 在啟動時確保使用正確的內(nèi)存參數(shù),例如 crashkernel=256M。
  • 運(yùn)行 cat /proc/iomem | grep "Crash kernel",應(yīng)該顯示一個合適的分配范圍。如果沒有顯示,可能是由于未正確傳遞 crashkernel= 參數(shù)。
  • 運(yùn)行 cat /sys/kernel/kexec_crash_size,它不應(yīng)該返回零值。如果為零,表示崩潰內(nèi)存沒有正確分配。
  • 檢查是否分配了崩潰內(nèi)存。
  • 驗證 /proc/iomem 中是否有 "Crash kernel" 的分配范圍。
  • 在命令行中確保傳遞正確的 crashkernel= 參數(shù)。
  • 如果問題仍然存在,使用 -d 參數(shù)運(yùn)行 kexec 命令,將輸出信息發(fā)送到 kexec-tools 郵件列表。
責(zé)任編輯:武曉燕 來源: 步步運(yùn)維步步坑
相關(guān)推薦

2017-08-02 14:37:31

LinuxKdump內(nèi)核崩潰

2020-06-10 10:50:15

Linuxpstore內(nèi)核

2021-09-03 08:44:51

內(nèi)核模塊Linux社區(qū)

2009-12-29 10:20:17

2021-03-05 07:14:08

Linuxcrashvmcore

2017-10-25 20:52:03

內(nèi)核權(quán)限空指針異常

2010-09-09 14:07:32

2021-11-03 12:34:41

黑客網(wǎng)絡(luò)釣魚攻擊

2018-06-05 15:02:32

2016-08-10 12:52:31

2024-04-11 10:02:06

iOS鍵盤Android

2022-03-17 08:54:59

軟件系統(tǒng)重構(gòu)

2022-11-23 15:38:53

2015-08-03 10:43:58

Linux內(nèi)核驅(qū)動

2020-12-29 09:11:33

LinuxLinux內(nèi)核

2009-03-09 11:01:34

2021-02-20 06:08:07

LinuxWindows內(nèi)核

2013-10-17 09:37:07

2018-06-19 09:07:57

Linux內(nèi)核模塊

2013-01-22 11:10:11

點(diǎn)贊
收藏

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