Home  >  Article  >  System Tutorial  >  Linux kernel crash detection tool Kdump

Linux kernel crash detection tool Kdump

王林
王林forward
2024-01-03 19:25:421068browse
Introduction kdump is one way to get a crashed Linux kernel dump, but it can be a bit difficult to find documentation explaining its use and internals. In this article, I will study the basic usage of kdump and how kdump/kexec is implemented in the kernel.

kexec is a Linux kernel-to-kernel bootloader that helps boot from the context of a first kernel to a second kernel. kexec shuts down the first core, bypassing the BIOS or firmware stage, and jumps to the second core. Therefore, the reboot becomes faster without the BIOS stage.

kdump can be used with the kexec application - for example, when the first kernel crashes a second kernel starts up, and the second kernel is used to copy the memory dump of the first kernel, you can use gdb and crash, etc. The tool analyzes the cause of the crash. (In this article, I will use the terms "first kernel" as the currently running kernel, "second kernel" as the kernel running with kexec, and "capture kernel" to mean the kernel running when the current kernel crashes.)

The kexec mechanism has components in the kernel as well as user space. The kernel provides several system calls for the kexec restart functionality. A userspace tool called kexec-tools uses these calls and provides an executable file to load and boot the "second kernel". Some distributions also add wrappers on kexec-tools, which help capture and save dumps of various dump target configurations. In this article, I will use a tool called distro-kexec-tools to avoid confusion between the upstream kexec tools and the distribution-specific kexec-tools code. My examples will use the Fedora Linux distribution.

Fedora kexec-tools tool

Use the dnf install kexec-tools command to install fedora-kexec-tools on the Fedora machine. After installing fedora-kexec-tools, you can execute the systemctl start kdump command to start the kdump service. When this service starts, it creates a root file system (initramfs) that contains the resources to be mounted to the target location, to hold the vmcore, and the commands to copy and dump the vmcore to the target location. The service then loads the kernel and initramfs into appropriate locations within the crashed kernel region so that they can be executed if the kernel crashes.

The Fedora wrapper provides two user configuration files:

/etc/kdump.conf specifies the configuration parameters that need to be rebuilt after modification. For example, if you change the dump target from a local disk to an NFS-mounted disk, you need the NFS-related kernel modules loaded by Capture Kernel.
/etc/sysconfig/kdump specifies configuration parameters that do not require rebuilding the initramfs after modification. For example, if you only need to modify the command line parameters passed to the "capture kernel", you do not need to rebuild the initramfs.
If the kernel fails after the kdump service is started, then a "capture kernel" is performed, which further performs the vmcore save process in the initramfs and then reboots to a stable kernel.

kexec-tools tools

Compile the source code of kexec-tools to get an executable file named kexec. This eponymous executable can be used to load and execute a "second kernel", or load a "capture kernel", which can be executed when the kernel crashes.

Command to load the "second kernel":

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

--reuse-command parameter indicates using the same command line as the "first kernel". Use --initrd to pass initramfs. -l indicates that you are loading a "second kernel" that can be executed by the kexec application itself (kexec -e). Kernels loaded with -l cannot be executed on a kernel panic. In order to load a "capture kernel" that can be executed on a kernel crash, the argument -p must be passed instead of -l.

Command to load the capture kernel:

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

echo c > /pros/sysrq-trigger can be used to crash the kernel for testing. For more information about the options provided by kexec-tools, see man kexec. Before moving on to the next section, take a look at this demo of kexec_dump:


kdump: end-to-end streaming

The figure below shows the flow chart. The crashkernel's memory must be reserved for the capture kernel during booting of the "first kernel". You can pass crashkernel=Y@X on the kernel command line, where @X is optional. crashkernel=256M works for most x86_64 systems; however, choosing the appropriate memory for a crashkernel depends on many factors, such as the size of the kernel and the initramfs, as well as the modules contained in the initramfs and the memory requirements of the application runtime. See the kernel-parameters documentation for more ways to pass crash kernel parameters.
Kdump 检查 Linux 内核崩溃!

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 或“捕获内核”之前,会执行以下操作:

  • 准备 CPU 寄存器(参见内核代码中的 crash_setup_regs());
  • 更新 vmcoreinfo 备注(请参阅 crash_save_vmcoreinfo());
  • 关闭非崩溃的 CPU 并保存准备好的寄存器(请参阅 machine_crash_shutdown() 和 crash_save_cpu());
  • 您可能需要在此处禁用中断控制器;
  • 最后,它执行 kexec 重新启动(请参阅 machine_kexec()),它将加载或刷新 kexec 段到内存,并将控制权传递给进入段的执行文件。输入段可以是下一个内核的 purgatory 或开始地址。
ELF 程序头

kdump 中涉及的大多数转储核心都是 ELF 格式。因此,理解 ELF 程序头部很重要,特别是当您想要找到 vmcore 准备的问题。每个 ELF 文件都有一个程序头:

  • 由系统加载器读取,
  • 描述如何将程序加载到内存中,
  • 可以使用 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 段提供了有关 CPU 信息,load 段提供了关于复制的系统内存组件的信息。
vmcore 从 elfcorehdr 开始,它具有与 ELF 程序头相同的结构。参见下图中 elfcorehdr 的表示:
Kdump 检查 Linux 内核崩溃!

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 note

Crash notes 是每个 CPU 中用于在系统崩溃的情况下存储 CPU 状态的区域;它有关于当前 PID 和 CPU 寄存器的信息。

vmcoreinfo

该 note 段具有各种内核调试信息,如结构体大小、符号值、页面大小等。这些值由捕获内核解析并嵌入到 /proc/vmcore 中。 vmcoreinfo 主要由 makedumpfile 应用程序使用。在 Linux 内核,include/linux/kexec.h 宏定义了一个新的 vmcoreinfo。 一些示例宏如下所示:

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

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 没有成功

检查是否分配了崩溃内存。

  • cat /sys/kernel/kexec_crash_size should not have a zero value.
  • cat /proc/iomem | grep "Crash kernel" There should be an allocated range.
  • If not assigned, pass the correct crashkernel= parameter on the command line.
  • If it is not displayed, pass the parameter -d in the kexec command and send the output information to the kexec-tools mailing list.
Can't see anything on the console (like "bye") after the last message of "first kernel"
  • Check whether the kexec -l kernel_image command after kexec -e works.
  • A supported architecture or machine-specific option may be missing.
  • It may be that purgatory's SHA verification failed. If your architecture doesn't support the console in purgatory, it can be difficult to debug.
  • It may be that the "second kernel" has already crashed.
  • Pass your system's earlycon or earlyprintk options to the "second kernel" command line.
  • Use the kexec-tools mailing list to share the first kernel and capture the kernel's dmesg logs.
resource fedora-kexec-tools
  • GitHub repository: git://pkgs.fedoraproject.org/kexec-tools
  • Mail list: [email protected]
  • Description: Specs files and scripts provide user-friendly commands and services so that kexec-tools can be automated in different user scenarios.
kexec-tools
  • GitHub repository: git://git.kernel.org/pub/scm/utils/kernel/kexec/kexec-tools.git
  • Mail list: [email protected]
  • Description: Use the kernel system call and provide the user command kexec.
Linux kernel
  • GitHub repository: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
  • Mail list: [email protected]
  • Description: Implements the kexec_load(), kexec_file_load(), reboot() system calls and architecture-specific code such as machine_kexec() and machine_crash_shutdown().
Makedumpfile
  • GitHub repository: git://git.code.sf.net/p/makedumpfile/code
  • Mail list: [email protected]
  • Description: Compress and filter unnecessary components from dump files.

(Title: Penguin, Boot, modification: Opensource.com. CC BY-SA 4.0)

About the Author:

Pratyush Anand - Pratyush is working with Red Hat as a Linux kernel expert. He is responsible for several kexec/kdump issues faced by Red Hat products and upstream. He also handles other kernel debugging, tracing, and performance issues around the ARM64 platform supported by Red Hat. In addition to the Linux kernel, he has contributed to the upstream kexec-tools and makedumpfile projects. He is an open source enthusiast and promotes FOSS by giving volunteer lectures at educational institutions.


The above is the detailed content of Linux kernel crash detection tool Kdump. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:linuxprobe.com. If there is any infringement, please contact admin@php.cn delete