蚊章汇 - Pratyush Anand
type: channel
link: https://linuxcn.bwsl.wang/author/655/
description: Pratyush Anand
items: 使用 Kdump 检查 Linux 内核崩溃

使用 Kdump 检查 Linux 内核崩溃
type: item
date: 2017-07-30T23:02:00+08:00
description: 让我们先看一下 kdump 的基本使用方法，和 kdump/kexec 在内核中是如何实现。kdump 是获取崩溃的 Linux 内核转储的一种方法，但是想找到解释其使用和内部结构的文档可能有点困难。在本文中，我将研究 kdump 的基本使用方法，和 kdump/kexec 在内核中是如何实现。kexec 是一个 Linux 内核到内核的引导加载程序，可以帮助从第一个内核的上下文引导到第二个内核。kexec 会关闭第一个内核，绕过 BIOS 或固件阶段，并跳转到第二个内核。因此，在没有 BIOS 阶段的情况下，重新启动变得更快。kdump 可以与 kexec 应用程序一起使用 —— 例如，当第一个内核崩溃时第二个内核启动，第二个内核用于复制第一个内核的内存转储，可以使用 gdb 和 crash 等工具分析崩溃的原因。（在本文中，我将使用术语“第一内核”作为当前运行的内核，“第二内核” 作为使用 kexec 运行的内核，“捕获内核” 表示在当前内核崩溃时运行的内核。）kexec 机制在内核以及用户空间中都有组件。内核提供了几个用于 kexec 重启功能的系统调用。名为 kexec-tools 的用户空间工具使用这些调用，并提供可执行文件来加载和引导“第二内核”。有的发行版还会在 kexec-tools 上添加封装器，这有助于捕获并保存各种转储目标配置的转储。在本文中，我将使用名为 distro-kexec-tools 的工具来避免上游 kexec 工具和特定于发行版的 kexec-tools 代码之间的混淆。我的例子将使用 Fedora Linux 发行版。Fedora kexec-tools 工具使用 dnf install kexec-tools 命令在 Fedora 机器上安装 fedora-kexec-tools。在安装 fedora-kexec-tools 后可以执行 systemctl start kdump 命令来启动 kdump 服务。当此服务启动时，它将创建一个根文件系统（initramfs），其中包含了要挂载到目标位置的资源，以保存 vmcore，以及用来复制和转储 vmcore 到目标位置的命令。然后，该服务将内核和 initramfs 加载到崩溃内核区域内的合适位置，以便在内核崩溃时可以执行它们。Fedora 封装器提供了两个用户配置文件：/etc/kdump.conf 指定修改后需要重建 initramfs 的配置参数。例如，如果将转储目标从本地磁盘更改为 NFS 挂载的磁盘，则需要由“捕获内核”所加载的 NFS 相关的内核模块。/etc/sysconfig/kdump 指定修改后不需要重新构建 initramfs 的配置参数。例如，如果只需修改传递给“捕获内核”的命令行参数，则不需要重新构建 initramfs。如果内核在 kdump 服务启动之后出现故障，那么“捕获内核”就会执行，其将进一步执行 initramfs 中的 vmcore 保存过程，然后重新启动到稳定的内核。kexec-tools 工具编译 kexec-tools 的源代码得到了一个名为 kexec 的可执行文件。这个同名的可执行文件可用于加载和执行“第二内核”，或加载“捕获内核”，它可以在内核崩溃时执行。加载“第二内核”的命令：# kexec -l kernel.img --initrd=initramfs-image.img –reuse-cmdline --reuse-command 参数表示使用与“第一内核”相同的命令行。使用 --initrd 传递 initramfs。 -l 表明你正在加载“第二内核”，其可以由 kexec 应用程序本身执行（kexec -e）。使用 -l 加载的内核不能在内核崩溃时执行。为了加载可以在内核崩溃时执行的“捕获内核”，必须传递参数 -p 取代 -l。加载捕获内核的命令：# kexec -p kernel.img --initrd=initramfs-image.img –reuse-cmdline echo c > /pros/sysrq-trigger 可用于使内核崩溃以进行测试。有关 kexec-tools 提供的选项的详细信息，请参阅 man kexec。在转到下一个部分之前，请看这个 kexec\_dump 的演示：kdump: 端到端流下图展示了流程图。必须在引导“第一内核”期间为捕获内核保留 crashkernel 的内存。您可以在内核命令行中传递 crashkernel=Y@X，其中 @X 是可选的。crashkernel=256M 适用于大多数 x86\_64 系统；然而，为崩溃内核选择适当的内存取决于许多因素，如内核大小和 initramfs，以及 initramfs 中包含的…