Heim >System-Tutorial >LINUX >Kdump, das Linux-Kernel-Crash-Erkennungstool
Einführung | kdump ist eine Möglichkeit, einen abgestürzten Linux-Kernel-Dump zu erhalten, es kann jedoch etwas schwierig sein, eine Dokumentation zu finden, die seine Verwendung und Interna erklärt. In diesem Artikel werde ich die grundlegende Verwendung von kdump und die Implementierung von kdump/kexec im Kernel untersuchen. |
kexec ist ein Linux-Kernel-zu-Kernel-Bootloader, der das Booten vom Kontext eines ersten Kernels zu einem zweiten Kernel unterstützt. kexec fährt den ersten Kern herunter, umgeht die BIOS- oder Firmware-Phase und springt zum zweiten Kern. Daher wird der Neustart ohne die BIOS-Stufe schneller.
kdump kann mit einer kexec-Anwendung verwendet werden. Wenn beispielsweise der erste Kernel abstürzt und ein zweiter Kernel gestartet wird, wird der zweite Kernel verwendet, um den Speicherauszug des ersten Kernels zu kopieren, der mit Tools wie gdb und analysiert werden kann Absturz Die Ursache des Absturzes. (In diesem Artikel verwende ich die Begriffe „erster Kernel“ als den aktuell ausgeführten Kernel, „zweiter Kernel“ als den Kernel, der mit kexec ausgeführt wird, und „Kernel erfassen“, um den Kernel zu bezeichnen, der ausgeführt wird, wenn der aktuelle Kernel abstürzt.)
Der Kexec-Mechanismus verfügt über Komponenten im Kernel und im Benutzerbereich. Der Kernel stellt mehrere Systemaufrufe für die Kexec-Neustartfunktion bereit. Ein Userspace-Tool namens kexec-tools nutzt diese Aufrufe und stellt eine ausführbare Datei zum Laden und Booten des „zweiten Kernels“ bereit. Einige Distributionen fügen auch Wrapper für kexec-tools hinzu, die dabei helfen, Dumps verschiedener Dump-Zielkonfigurationen zu erfassen und zu speichern. In diesem Artikel verwende ich ein Tool namens distro-kexec-tools, um Verwechslungen zwischen den Upstream-Kexec-Tools und dem distributionsspezifischen Kexec-Tools-Code zu vermeiden. In meinen Beispielen wird die Fedora-Linux-Distribution verwendet.
Fedora Kexec-Tools-ToolVerwenden Sie den Befehl dnf install kexec-tools, um Fedora-kexec-tools auf dem Fedora-Computer zu installieren. Nach der Installation von Fedora-Kexec-Tools können Sie den Befehl systemctl start kdump ausführen, um den kdump-Dienst zu starten. Wenn dieser Dienst gestartet wird, erstellt er ein Root-Dateisystem (initramfs), das die Ressourcen enthält, die am Zielspeicherort bereitgestellt werden sollen, um den VMcore zu speichern, und die Befehle zum Kopieren und Dumpen des VMcores an den Zielspeicherort. Der Dienst lädt dann den Kernel und die Initramfs an geeignete Speicherorte innerhalb der abgestürzten Kernelregion, sodass sie ausgeführt werden können, wenn der Kernel abstürzt.
Der Fedora-Wrapper stellt zwei Benutzerprofile bereit:
/etc/kdump.conf gibt die Konfigurationsparameter an, die nach der Änderung neu erstellt werden müssen. Wenn Sie beispielsweise das Speicherauszugsziel von einer lokalen Festplatte auf eine über NFS bereitgestellte Festplatte ändern, müssen die NFS-bezogenen Kernelmodule von Capture Kernel geladen werden.
/etc/sysconfig/kdump gibt Konfigurationsparameter an, die nach der Änderung keinen erneuten Aufbau der initramfs erfordern. Wenn Sie beispielsweise nur die an den „Capture-Kernel“ übergebenen Befehlszeilenparameter ändern müssen, müssen Sie initramfs nicht neu erstellen.
Wenn der Kernel nach dem Start des kdump-Dienstes ausfällt, wird ein „Capture-Kernel“ durchgeführt, der den vmcore-Speichervorgang im initramfs weiter durchführt und dann einen Neustart mit einem stabilen Kernel durchführt.
Kompilieren Sie den Quellcode von kexec-tools und erhalten Sie eine ausführbare Datei mit dem Namen kexec. Diese gleichnamige ausführbare Datei kann zum Laden und Ausführen eines „zweiten Kernels“ oder zum Laden eines „Capture-Kernels“ verwendet werden, der ausgeführt werden kann, wenn der Kernel abstürzt.
Befehl zum Laden des „zweiten Kernels“:
# kexec -l kernel.img --initrd=initramfs-image.img –reuse-cmdline
--reuse-command-Parameter bedeutet, dass dieselbe Befehlszeile wie beim „ersten Kernel“ verwendet wird. Verwenden Sie --initrd, um initramfs zu übergeben. -l zeigt an, dass Sie einen „zweiten Kernel“ laden, der von der kexec-Anwendung selbst ausgeführt werden kann (kexec -e). Mit -l geladene Kernel können bei einer Kernel-Panik nicht ausgeführt werden. Um einen „Capture-Kernel“ zu laden, der bei einem Kernel-Absturz ausgeführt werden kann, muss das Argument -p anstelle von -l übergeben werden.
Befehl zum Laden des Capture-Kernels:
# kexec -p kernel.img --initrd=initramfs-image.img –reuse-cmdline
echo c > /pros/sysrq-trigger kann verwendet werden, um den Kernel zum Testen zum Absturz zu bringen. Weitere Informationen zu den von kexec-tools bereitgestellten Optionen finden Sie unter man kexec. Bevor Sie mit dem nächsten Abschnitt fortfahren, werfen Sie einen Blick auf diese Demo von kexec_dump:
Das Bild unten zeigt das Flussdiagramm. Beim Booten des „ersten Kernels“ muss der Speicher des Crashkernels für den Capture-Kernel reserviert werden. Sie können crashkernel=Y@X in der Kernel-Befehlszeile übergeben, wobei @X optional ist. crashkernel=256M funktioniert für die meisten x86_64-Systeme; die Auswahl des geeigneten Speichers für einen Crashkernel hängt jedoch von vielen Faktoren ab, wie z. B. der Größe des Kernels und der Initramfs sowie den in den Initramfs enthaltenen Modulen und den Speicheranforderungen der Anwendung Laufzeit. Weitere Möglichkeiten zur Übergabe von Crash-Kernel-Parametern finden Sie in der Dokumentation zu Kernel-Parametern.
pratyush_f1.png
您可以将内核和 initramfs 镜像传递给 kexec 可执行文件,如(kexec-tools)部分的命令所示。“捕获内核”可以与“第一内核”相同,也可以不同。通常,一样即可。Initramfs 是可选的;例如,当内核使用 CONFIG_INITRAMFS_SOURCE 编译时,您不需要它。通常,从第一个 initramfs 中保存一个不一样的捕获 initramfs,因为在捕获 initramfs 中自动执行 vmcore 的副本能获得更好的效果。当执行 kexec 时,它还加载了 elfcorehdr 数据和 purgatory 可执行文件(LCTT 译注:purgatory 就是一个引导加载程序,是为 kdump 定作的。它被赋予了“炼狱”这样一个古怪的名字应该只是一种调侃)。 elfcorehdr 具有关于系统内存组织的信息,而 purgatory 可以在“捕获内核”执行之前执行并验证第二阶段的二进制或数据是否具有正确的 SHA。purgatory 也是可选的。
当“第一内核”崩溃时,它执行必要的退出过程并切换到 purgatory(如果存在)。purgatory 验证加载二进制文件的 SHA256,如果是正确的,则将控制权传递给“捕获内核”。“捕获内核”根据从 elfcorehdr 接收到的系统内存信息创建 vmcore。因此,“捕获内核”启动后,您将看到 /proc/vmcore 中“第一内核”的转储。根据您使用的 initramfs,您现在可以分析转储,将其复制到任何磁盘,也可以是自动复制的,然后重新启动到稳定的内核。
内核提供了两个系统调用:kexec_load() 和 kexec_file_load(),可以用于在执行 kexec -l 时加载“第二内核”。它还为 reboot() 系统调用提供了一个额外的标志,可用于使用 kexec -e 引导到“第二内核”。
kexec_load():kexec_load() 系统调用加载一个可以在之后通过 reboot() 执行的新的内核。其原型定义如下:
long kexec_load(unsigned long entry, unsigned long nr_segments, struct kexec_segment *segments, unsigned long flags);
用户空间需要为不同的组件传递不同的段,如内核,initramfs 等。因此,kexec 可执行文件有助于准备这些段。kexec_segment 的结构如下所示:
struct kexec_segment { void *buf; /* 用户空间缓冲区 */ size_t bufsz; /* 用户空间中的缓冲区长度 */ void *mem; /* 内核的物理地址 */ size_t memsz; /* 物理地址长度 */ };
当使用 LINUX_REBOOT_CMD_KEXEC 调用 reboot() 时,它会引导进入由 kexec_load 加载的内核。如果标志 KEXEC_ON_CRASH 被传递给 kexec_load(),则加载的内核将不会使用 reboot(LINUX_REBOOT_CMD_KEXEC) 来启动;相反,这将在内核崩溃中执行。必须定义 CONFIG_KEXEC 才能使用 kexec,并且为 kdump 定义 CONFIG_CRASH_DUMP。
kexec_file_load():作为用户,你只需传递两个参数(即 kernel 和 initramfs)到 kexec 可执行文件。然后,kexec 从 sysfs 或其他内核信息源中读取数据,并创建所有段。所以使用 kexec_file_load() 可以简化用户空间,只传递内核和 initramfs 的文件描述符。其余部分由内核本身完成。使用此系统调用时应该启用 CONFIG_KEXEC_FILE。它的原型如下:
long kexec_file_load(int kernel_fd, int initrd_fd, unsigned long cmdline_len, const char __user * cmdline_ptr, unsigned long flags);
请注意,kexec_file_load 也可以接受命令行,而 kexec_load() 不行。内核根据不同的系统架构来接受和执行命令行。因此,在 kexec_load() 的情况下,kexec-tools 将通过其中一个段(如在 dtb 或 ELF 引导注释等)中传递命令行。
目前,kexec_file_load() 仅支持 x86 和 PowerPC。
当内核崩溃时会发生什么当第一个内核崩溃时,在控制权传递给 purgatory 或“捕获内核”之前,会执行以下操作:
kdump 中涉及的大多数转储核心都是 ELF 格式。因此,理解 ELF 程序头部很重要,特别是当您想要找到 vmcore 准备的问题。每个 ELF 文件都有一个程序头:
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 段提供了有关 CPU 信息,load 段提供了关于复制的系统内存组件的信息。
vmcore 从 elfcorehdr 开始,它具有与 ELF 程序头相同的结构。参见下图中 elfcorehdr 的表示:
pratyush_f2.png
kexec-tools 读取 /sys/devices/system/cpu/cpu%d/crash_notes 并准备 CPU PT_NOTE 的标头。同样,它读取 /sys/kernel/vmcoreinfo 并准备 vmcoreinfo PT_NOTE 的标头,从 /proc/iomem 读取系统内存并准备存储器 PT_LOAD 标头。当“捕获内核”接收到 elfcorehdr 时,它从标头中提到的地址中读取数据,并准备 vmcore。
Crash noteCrash notes 是每个 CPU 中用于在系统崩溃的情况下存储 CPU 状态的区域;它有关于当前 PID 和 CPU 寄存器的信息。
vmcoreinfo该 note 段具有各种内核调试信息,如结构体大小、符号值、页面大小等。这些值由捕获内核解析并嵌入到 /proc/vmcore 中。 vmcoreinfo 主要由 makedumpfile 应用程序使用。在 Linux 内核,include/linux/kexec.h 宏定义了一个新的 vmcoreinfo。 一些示例宏如下所示:
vmcore 中的许多信息(如可用页面)都没有用处。makedumpfile 是一个用于排除不必要的页面的应用程序,如:
此外,makedumpfile 在复制时压缩 /proc/vmcore 的数据。它也可以从转储中删除敏感的符号信息; 然而,为了做到这一点,它首先需要内核的调试信息。该调试信息来自 VMLINUX 或 vmcoreinfo,其输出可以是 ELF 格式或 kdump 压缩格式。
典型用法:
# makedumpfile -l --message-level 1 -d 31 /proc/vmcore makedumpfilecore
详细信息请参阅 man makedumpfile。
kdump 调试新手在使用 kdump 时可能会遇到的问题:
kexec -p kernel_image 没有成功检查是否分配了崩溃内存。
(Titel: Penguin, Boot, Modifikation: Opensource.com. CC BY-SA 4.0)
Über den Autor:
Pratyush Anand – Pratyush arbeitet mit Red Hat als Linux-Kernel-Experte. Er ist für mehrere Kexec/Kdump-Probleme verantwortlich, mit denen Red Hat-Produkte und Upstream-Produkte konfrontiert sind. Er kümmert sich auch um andere Kernel-Debugging-, Tracing- und Leistungsprobleme rund um die von Red Hat unterstützte ARM64-Plattform. Zusätzlich zum Linux-Kernel hat er zu den Upstream-Projekten kexec-tools und makedumpfile beigetragen. Er ist ein Open-Source-Enthusiast und fördert FOSS, indem er ehrenamtlich Vorträge an Bildungseinrichtungen hält.
Das obige ist der detaillierte Inhalt vonKdump, das Linux-Kernel-Crash-Erkennungstool. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!