跳转到内容跳转到页面导航:上一页 [访问键 p]/下一页 [访问键 n]
适用于 openSUSE Leap 15.6

18 Kexec 和 Kdump 编辑源文件

Kexec 是一种从当前运行的内核启动到另一个内核的工具。您可以执行更快的系统重新启动,而无需任何硬件初始化。您还可以准备系统启动到另一个内核,如果系统崩溃。

18.1 简介 编辑源文件

使用 Kexec,您可以无需硬重启就用另一个内核替换正在运行的内核。该工具有几个用处

  • 更快的系统重启

    如果您需要频繁重启系统,Kexec 可以为您节省大量时间。

  • 避免不可靠的固件和硬件

    计算机硬件很复杂,系统启动过程中可能会出现严重问题。您不能总是立即更换不可靠的硬件。Kexec 将内核引导到已初始化硬件的受控环境中。不成功系统启动的风险因此被最小化。

  • 保存崩溃内核的转储

    Kexec 保持物理内存的内容。在 生产 内核失败后,捕获 内核(运行在保留内存范围内的附加内核)会保存失败内核的状态。保存的镜像可以帮助您进行后续分析。

  • 无需 GRUB 2 配置即可启动

    当系统使用 Kexec 启动内核时,它会跳过引导加载程序阶段。正常的引导过程可能会因为引导加载程序配置中的错误而失败。使用 Kexec,您不需要依赖有效的引导加载程序配置。

18.2 必需的软件包 编辑源文件

要在 openSUSE® Leap 上使用 Kexec 以加快重启或避免潜在的硬件问题,请确保已安装软件包 kexec-tools。它包含一个名为 kexec-bootloader 的脚本,该脚本读取引导加载程序配置并使用与正常引导加载程序相同的内核选项运行 Kexec。

为了设置一个帮助您在内核崩溃时获取调试信息的环境,请确保已安装软件包 makedumpfile

openSUSE Leap 中使用 Kdump 的首选方法是通过 YaST Kdump 模块。要使用 YaST 模块,请确保已安装软件包 yast2-kdump

18.3 Kexec 内部原理 编辑源文件

Kexec 最重要的组件是 /sbin/kexec 命令。您可以通过两种不同的方式使用 Kexec 加载内核

  • 将内核加载到生产内核的地址空间中以进行常规重启

    # kexec -l KERNEL_IMAGE

    您可以使用 kexec -e 稍后启动此内核。

  • 将内核加载到保留的内存区域

    # kexec -p KERNEL_IMAGE

    当系统崩溃时,此内核会自动启动。

要启动另一个内核并保留生产内核的数据,以便在系统崩溃时,您需要为系统内存保留一个专用的区域。生产内核永远不会加载到此区域,因为它必须始终可用。它用于捕获内核,以便可以保留生产内核的内存页。

要保留该区域,请将选项 crashkernel 附加到生产内核的引导命令行。要确定 crashkernel 的必要值,请遵循 第 18.4 节,“计算 crashkernel 分配大小” 中的说明。

这不是捕获内核的参数。捕获内核不使用 Kexec。

捕获内核加载到保留区域并等待内核崩溃。然后,Kdump 尝试调用捕获内核,因为生产内核在此阶段不再可靠。这意味着即使 Kdump 也可能失败。

要加载捕获内核,您需要包含内核引导参数。在大多数情况下,初始 RAM 文件系统用于引导。您可以使用 --initrd=FILENAME 指定它。使用 --append=CMDLINE,您可以将选项附加到要引导的内核的命令行。

需要包含生产内核的命令行。您可以简单地使用 --append="$(cat /proc/cmdline)" 复制命令行,或使用 --append="$(cat /proc/cmdline) more_options" 添加更多选项。

例如,要加载 /boot/vmlinuz-6.4.0-150600.9-default 内核镜像,并使用当前运行的生产内核的命令行和 /boot/initrd 文件,请运行以下命令

#  kexec -l /boot/vmlinuz-6.4.0-150600.9-default \
 --append="$(cat /proc/cmdline)" --initrd=/boot/initrd

您可以随时卸载先前加载的内核。要卸载使用 -l 选项加载的内核,请使用 kexec -u 命令。要卸载使用 -p 选项加载的崩溃内核,请使用 kexec -p -u 命令。

18.4 计算 crashkernel 分配大小 编辑源文件

要使用 Kexec 和捕获内核,以及以任何方式使用 Kdump,需要为捕获内核分配 RAM。分配大小取决于计算机的预期硬件配置,因此您需要指定它。

分配大小还取决于计算机的硬件架构。确保遵循适用于您系统架构的过程。

过程 18.1: AMD64/Intel 64 上的分配大小
  1. 要找出计算机的基本值,请运行以下命令

    # kdumptool calibrate
    Total: 49074
    Low: 72
    High: 180
    MinLow: 72
    MaxLow: 3085
    MinHigh: 0
    MaxHigh: 45824

    所有值都以兆字节为单位。

  2. 记下 LowHigh 的值。

    Note
    注意:LowHigh 值的含义

    在 AMD64/Intel 64 计算机上,High 值代表所有可用内存的内存保留。 Low 值代表 DMA32 区域中的内存保留,即高达 4 GB 的所有内存。

    SIZE_LOW 是仅 32 位设备所需的内存量。内核为 DMA32 缓冲分配 64M。如果您的服务器没有仅 32 位的设备,则使用默认分配的 72M 作为 SIZE_LOW 应该可以正常工作。在 NUMA 机器上,这可能是一个例外,它可能会显示需要更多的 Low 内存。可以通过 numa=off 引导捕获内核来确保常规内核分配不使用 Low 内存。

  3. 根据计算机上附加的 LUN 路径(存储设备路径)数量调整上一步中的 High 值。可以使用以下公式以兆字节为单位计算一个合理的值

    SIZE_HIGH = RECOMMENDATION + (LUNs / 2)

    此公式中使用以下参数

    • SIZE_HIGH.  High 的结果值。

    • RECOMMENDATION.  kdumptool calibrateHigh 推荐的值。

    • LUNs.  您期望计算机上创建的最大 LUN 路径数。从该数字中排除多路径设备,因为这些设备会被忽略。要获取系统上当前可用的 LUN 数量,请运行以下命令

      >  cat /proc/scsi/scsi | grep Lun | wc -l
  4. 如果设备的驱动程序在 DMA32 区域进行许多保留,则还需要调整 Low 值。但是,没有简单的公式可以计算这些值。因此,找到正确的大小可能是一个反复试验的过程。

    对于初学者,请使用 kdumptool calibrate 推荐的 Low 值。

  5. 现在需要在正确的位置设置这些值。

    如果您直接更改内核命令行

    将以下内核选项附加到您的引导加载程序配置

    crashkernel=SIZE_HIGH,high crashkernel=SIZE_LOW,low

    将占位符 SIZE_HIGHSIZE_LOW 替换为前几步中的适当值,并附加字母 M(表示兆字节)。

    例如,以下是有效的

    crashkernel=36M,high crashkernel=72M,low
    如果您正在使用 YaST GUI

    Kdump 低内存 设置为确定的 Low 值。

    Kdump 高内存 设置为确定的 High 值。

    如果您正在使用 YaST 命令行界面

    使用以下命令

    # yast kdump startup enable alloc_mem=LOW,HIGH

    LOW 替换为确定的 Low 值。将 HIGH 替换为确定的 HIGH 值。

Tip
提示:排除 IBM Z 上未使用的和非活动的 CCW 设备

根据可用设备的数量,由 crashkernel 内核参数指定的计算内存量可能不足。与其增加该值,您可以选择限制内核可见的设备数量。这降低了 crashkernel 设置所需的内存量。

  1. 要忽略设备,您可以运行 cio_ignore 工具以生成适当的节,以忽略所有设备,但当前活动或正在使用的设备除外。

    > sudo cio_ignore -u -k
    cio_ignore=all,!da5d,!f500-f502

    当您运行 cio_ignore -u -k 时,块列表会立即生效并替换任何现有的块列表。未使用的设备不会被清除,因此它们仍然出现在通道子系统中。但是,添加新的通道设备(通过 z/VM 中的 CP ATTACH 或 LPAR 中的动态 I/O 配置更改)会将它们视为被阻止。为了防止这种情况,请先运行 sudo cio_ignore -l 并恢复到该状态,然后再运行 cio_ignore -u -k。或者,将生成的节添加到常规内核引导参数中。

  2. 现在将包含上述节的 cio_ignore 内核参数添加到 /etc/sysconfig/kdump 中的 KDUMP_CMDLINE_APPEND 中,例如

    KDUMP_COMMANDLINE_APPEND="cio_ignore=all,!da5d,!f500-f502"
  3. 通过重新启动 kdump 来激活设置

    systemctl restart kdump.service

18.5 基本的 Kexec 用法 编辑源文件

要使用 Kexec,请确保相应的服务已启用并正在运行

  • 确保 Kexec 服务在系统启动时加载

    > sudo systemctl enable kexec-load.service
  • 确保 Kexec 服务正在运行

    > sudo systemctl start kexec-load.service

要验证您的 Kexec 环境是否正常工作,请尝试使用 Kexec 重新启动到新内核。确保没有用户当前登录,并且系统上没有正在运行的重要服务。然后运行以下命令

systemctl kexec

先前加载到旧内核地址空间的内核会重写它并立即接管控制权。它会显示通常的启动消息。当新内核启动时,它会跳过所有硬件和固件检查。确保没有出现警告消息。

Tip
提示:使用 reboot 命令与 Kexec 一起使用

要使 reboot 使用 Kexec 而不是执行常规重启,请运行以下命令

ln -s /usr/lib/systemd/system/kexec.target /etc/systemd/system/reboot.target

你可以随时通过删除 etc/systemd/system/reboot.target 来撤销此操作。

18.6 如何配置 Kexec 进行常规重启 编辑源代码

Kexec 经常用于频繁重启。例如,如果硬件检测例程需要很长时间才能运行完成,或者启动不可靠。

当系统使用 Kexec 重启时,固件和引导加载程序将不会被使用。你对引导加载程序配置所做的任何更改,在计算机执行硬重启之前都会被忽略。

18.7 基本 Kdump 配置 编辑源代码

你可以使用 Kdump 来保存内核转储。如果内核崩溃,将崩溃环境的内存镜像复制到文件系统很有用。然后你可以调试转储文件以找到内核崩溃的原因。这被称为 核心转储

Kdump 的工作方式类似于 Kexec(参见 第 18 章,Kexec 和 Kdump)。捕获内核在正在运行的生产内核崩溃后执行。区别在于,Kexec 用捕获内核替换生产内核。使用 Kdump,你仍然可以访问崩溃的生产内核的内存空间。你可以在 Kdump 内核的环境中保存崩溃内核的内存快照。

Tip
提示:通过网络进行转储

在本地存储空间有限的环境中,你需要设置通过网络的内核转储。Kdump 支持配置指定的网络接口,并通过 initrd 启动它。LAN 和 VLAN 接口都受支持。使用 YaST 或在 /etc/sysconfig/kdump 文件中使用 KDUMP_NETCONFIG 选项指定网络接口和模式(DHCP 或静态)。

Important
重要:Kdump 的目标文件系统必须在配置期间挂载

配置 Kdump 时,你可以指定保存转储镜像的位置(默认:/var/crash)。此位置必须在配置 Kdump 时挂载,否则配置将失败。

18.7.1 手动 Kdump 配置 编辑源代码

Kdump 从 /etc/sysconfig/kdump 文件读取其配置。为了确保 Kdump 在你的系统上工作,其默认配置就足够了。要使用 Kdump 的默认设置,请按照以下步骤操作

  1. 按照 第 18.4 节,“计算 crashkernel 分配大小” 中的说明确定 Kdump 所需的内存量。确保设置内核参数 crashkernel

  2. 重新启动计算机。

  3. 启用 Kdump 服务

    # systemctl enable kdump
  4. 你可以编辑 /etc/sysconfig/kdump 中的选项。阅读注释可以帮助你理解各个选项的含义。

  5. 使用 sudo systemctl start kdump 运行 init 脚本一次,或重新启动系统。

在配置 Kdump 使用默认值后,检查它是否按预期工作。确保没有用户当前登录,并且你的系统上没有正在运行的重要服务。然后按照以下步骤操作

  1. 使用 systemctl isolate rescue.target 切换到救援目标。

  2. 重新启动 Kdump 服务

    # systemctl start kdump
  3. 使用以下命令卸载除根文件系统之外的所有磁盘文件系统

    # umount -a
  4. 以只读模式重新挂载根文件系统

    # mount -o remount,ro /
  5. 使用 procfs 接口通过 Magic SysRq 键调用 内核恐慌

    # echo c > /proc/sysrq-trigger
Important
重要:内核转储的大小

KDUMP_KEEP_OLD_DUMPS 选项控制保留的内核转储数量(默认值为 5)。如果不进行压缩,转储的大小最多可以达到物理内存或 RAM 的大小。确保 /var 分区上有足够的空间。

捕获内核启动,并将崩溃的内核内存快照保存到文件系统。保存路径由 KDUMP_SAVEDIR 选项给出,默认值为 /var/crash。如果将 KDUMP_IMMEDIATE_REBOOT 设置为 yes,系统将自动重新启动生产内核。登录并检查是否在 /var/crash 下创建了转储。

18.7.2 YaST 配置 编辑源代码

要使用 YaST 配置 Kdump,你需要安装 yast2-kdump 包。然后,启动 YaST 控制中心系统 类别中的 内核 Kdump 模块,或在命令行中以 root 身份输入 yast2 kdump

Screenshot of the YaST Kdump Module
图 18.1:YaST Kdump 模块:启动页面

启动 窗口中,选择 启用 Kdump

第一次打开窗口时会自动生成 Kdump 内存 的值。但是,这并不意味着它们总是足够的。要设置正确的值,请按照 第 18.4 节,“计算 crashkernel 分配大小” 中的说明操作。

Important
重要:在硬件更改后,再次设置 Kdump 内存

如果你已在计算机上设置 Kdump,然后决定更改可用的 RAM 或硬盘驱动器数量,YaST 仍然会显示和使用过时的内存值。

要解决此问题,请再次确定必要的内存,如 第 18.4 节,“计算 crashkernel 分配大小” 中所述。然后在 YaST 中手动设置它。

单击左侧窗格中的 转储筛选,并检查要包含在转储中的页面。你不需要包含以下内存内容来调试内核问题

  • 填充为零的页面

  • 缓存页面

  • 用户数据页面

  • 空闲页面

转储目标 窗口中,选择转储目标的类型以及要保存转储的 URL。如果你选择了网络协议,例如 FTP 或 SSH,则还需要输入相关访问信息。

Tip
提示:与其他应用程序共享转储目录

可以指定一个用于保存 Kdump 转储的路径,其他应用程序也会在该路径中保存其转储。在清理其旧转储文件时,Kdump 会安全地忽略其他应用程序的转储文件。

填写 电子邮件通知 窗口信息,如果你希望 Kdump 通过电子邮件通知你其事件,并在 专家设置 窗口中微调 Kdump 后使用 确定 确认你的更改。Kdump 现在已配置。

18.7.3 通过 SSH 进行 Kdump 编辑源代码

转储文件通常包含敏感数据,应防止未经授权的泄露。为了允许通过不安全的网络传输此类数据,Kdump 可以使用 SSH 协议将转储文件保存到远程计算机。

  1. Kdump 必须知道目标主机身份。这对于确保敏感数据永远不会发送到冒名顶替者至关重要。当 Kdump 生成新的 initrd 时,它会运行 ssh-keygen -F TARGET_HOST 来查询目标主机身份。只有当 TARGET_HOST 公钥已知时才有效。实现这一点的简单方法是在 Kdump 主机上以 root 身份建立到 TARGET_HOST 的 SSH 连接。

  2. Kdump 必须能够验证到目标机器的身份。目前仅支持公钥身份验证。默认情况下,Kdump 使用 root 的私钥,但建议为 Kdump 创建一个单独的密钥。可以使用 ssh-keygen 来完成此操作

    1. # ssh-keygen -f ~/.ssh/kdump_key
    2. 当提示输入密码短语时,按 Enter(即,不使用任何密码短语)。

    3. 打开 /etc/sysconfig/kdump 并将 KDUMP_SSH_IDENTITY 设置为 kdump_key。如果文件未放置在 ~/.ssh 下,可以使用完整路径。

  3. 设置 Kdump SSH 密钥以授权登录到远程主机。

    # ssh-copy-id -i ~/.ssh/kdump_key TARGET_HOST
  4. 设置 KDUMP_SAVEDIR。有两种选择

    安全文件传输协议 (SFTP)

    SFTP 是通过 SSH 传输文件的首选方法。openSUSE Leap 默认启用目标主机上的 SFTP 子系统。示例

    KDUMP_SAVEDIR=sftp://TARGET_HOST/path/to/dumps
    安全 Shell 协议 (SSH)

    其他一些发行版使用 SSH 在目标主机上运行某些命令。openSUSE Leap 也可以使用此方法。目标主机上的 Kdump 用户必须具有可以执行以下命令的登录 shell:mkdirddmv。示例

    KDUMP_SAVEDIR=ssh://TARGET_HOST/path/to/dumps
  5. 重新启动 Kdump 服务以使用新的配置。

18.8 分析崩溃转储 编辑源代码

获得转储后,就可以对其进行分析了。有几种选择。

分析转储的原始工具是 GDB。即使在最新的环境中,你也可以使用它,但它有几个缺点和限制

  • GDB 并非专门设计用于调试内核转储。

  • GDB 不支持 32 位平台上的 ELF64 二进制文件。

  • GDB 不支持 ELF 以外的格式(它无法调试压缩转储)。

这就是为什么实施了 crash 实用程序。它分析崩溃转储并调试正在运行的系统。它提供专门用于调试 Linux 内核的功能,更适合高级调试。

要调试 Linux 内核,还需要安装其调试信息包。使用以下命令检查系统上是否已安装该包

> zypper se kernel | grep debug
Important
重要:包含调试信息的软件包的存储库

如果你已订阅系统的在线更新,你可以在 openSUSE Leap 15.6 相关的 *-Debuginfo-Updates 在线安装存储库中找到“debuginfo”包。使用 YaST 启用存储库。

要在生成转储的机器上使用 crash 打开捕获的转储,请使用如下命令

crash /boot/vmlinux-6.4.0-150600.9-default.gz \
/var/crash/2024-04-23-11\:17/vmcore

第一个参数表示内核镜像。第二个参数是由 Kdump 捕获的转储文件。默认情况下,你可以在 /var/crash 下找到此文件。

Tip
提示:从内核崩溃转储中获取基本信息

openSUSE Leap 附带了 kdumpid 实用程序(包含在同名软件包中),用于识别未知的内核转储。它可以用来提取基本信息,例如架构和内核版本。它支持 lkcd、diskdump、Kdump 文件和 ELF 转储。调用时使用 -v 选项,它会尝试提取其他信息,例如机器类型、内核 banner 字符串和内核配置风味。

18.8.1 内核二进制格式 编辑源代码

Linux 内核采用可执行和可链接格式 (ELF)。此文件称为 vmlinux,并在编译过程中直接生成。并非所有引导加载程序都支持 ELF 二进制文件,尤其是在 AMD64/Intel 64 架构上。在 openSUSE® Leap 支持的不同架构上存在以下解决方案。

18.8.1.1 AMD64/Intel 64 编辑源代码

AMD64/Intel 64 架构的内核软件包包含两个内核文件:vmlinuzvmlinux.gz

  • vmlinuz 这是由引导加载程序执行的文件。

    Linux 内核由两部分组成:内核本身 (vmlinux) 和由引导加载程序运行的设置代码。这两部分链接在一起以创建 vmlinuz(请注意区别:zx 的区别)。

    在内核源代码树中,该文件称为 bzImage

  • vmlinux.gz 这是一个压缩的 ELF 镜像,可被 crash 和 GDB 使用。在 AMD64/Intel 64 上,引导加载程序本身从不使用 ELF 镜像。因此,仅发送压缩版本。

18.8.1.2 POWER 编辑源代码

POWER 上的 yaboot 引导加载程序也支持加载 ELF 镜像,但不支持压缩镜像。在 POWER 内核软件包中,有一个 ELF Linux 内核文件 vmlinux。考虑到 crash,这是最简单的架构。

如果您决定在另一台机器上分析转储,则必须检查计算机的架构以及调试所需的文件。

只有当另一台计算机运行相同架构的 Linux 系统时,才能分析该转储。要检查兼容性,请在两台计算机上使用命令 uname -i 并比较输出。

如果您打算在另一台计算机上分析转储,还需要来自 kernelkernel debug 包的适当文件。

  1. 将内核转储、来自 /boot 的内核镜像及其关联的调试信息文件从 /usr/lib/debug/boot 放入单个空目录中。

  2. 此外,将来自 /lib/modules/$(uname -r)/kernel/ 的内核模块以及来自 /usr/lib/debug/lib/modules/$(uname -r)/kernel/ 的关联调试信息文件复制到名为 modules 的子目录中。

  3. 在包含转储、内核镜像、其调试信息文件和 modules 子目录的目录中,启动 crash 实用程序

    > crash VMLINUX-VERSION vmcore

无论您在哪个计算机上分析转储,crash 实用程序都会生成类似以下的输出

> crash /boot/vmlinux-6.4.0-150600.9-default.gz \
/var/crash/2024-04-23-11\:17/vmcore
crash 7.2.1
Copyright (C) 2002-2017  Red Hat, Inc.
Copyright (C) 2004, 2005, 2006, 2010  IBM Corporation
Copyright (C) 1999-2006  Hewlett-Packard Co
Copyright (C) 2005, 2006, 2011, 2012  Fujitsu Limited
Copyright (C) 2006, 2007  VA Linux Systems Japan K.K.
Copyright (C) 2005, 2011  NEC Corporation
Copyright (C) 1999, 2002, 2007  Silicon Graphics, Inc.
Copyright (C) 1999, 2000, 2001, 2002  Mission Critical Linux, Inc.
This program is free software, covered by the GNU General Public License,
and you are welcome to change it and/or distribute copies of it under
certain conditions.  Enter "help copying" to see the conditions.
This program has absolutely no warranty.  Enter "help warranty" for details.

GNU gdb (GDB) 7.6
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-unknown-linux-gnu".

      KERNEL: /boot/vmlinux-6.4.0-150600.9-default.gz
   DEBUGINFO: /usr/lib/debug/boot/vmlinux-6.4.0-150600.9-default.debug
    DUMPFILE: /var/crash/2024-04-23-11:17/vmcore
        CPUS: 2
        DATE: Thu Apr 23 13:17:01 2024
      UPTIME: 00:10:41
LOAD AVERAGE: 0.01, 0.09, 0.09
       TASKS: 42
    NODENAME: eros
     RELEASE: 6.4.0-150600.9-default
     VERSION: #1 SMP 2024-03-31 14:50:44 +0200
     MACHINE: x86_64  (2999 Mhz)
      MEMORY: 16 GB
       PANIC: "SysRq : Trigger a crashdump"
         PID: 9446
     COMMAND: "bash"
        TASK: ffff88003a57c3c0  [THREAD_INFO: ffff880037168000]
         CPU: 1
       STATE: TASK_RUNNING (SYSRQ)
crash> 

命令输出首先打印有用的数据:内核崩溃时有 42 个任务正在运行。崩溃的原因是由 PID 为 9446 的任务触发的 SysRq 触发器。这是一个 Bash 进程,因为使用的 echo 是 Bash shell 的内部命令。

crash 实用程序建立在 GDB 之上,并提供了许多额外的命令。如果您在不带任何参数的情况下输入 bt,则会打印崩溃时刻运行的任务的回溯。

crash> bt
PID: 9446   TASK: ffff88003a57c3c0  CPU: 1   COMMAND: "bash"
 #0 [ffff880037169db0] crash_kexec at ffffffff80268fd6
 #1 [ffff880037169e80] __handle_sysrq at ffffffff803d50ed
 #2 [ffff880037169ec0] write_sysrq_trigger at ffffffff802f6fc5
 #3 [ffff880037169ed0] proc_reg_write at ffffffff802f068b
 #4 [ffff880037169f10] vfs_write at ffffffff802b1aba
 #5 [ffff880037169f40] sys_write at ffffffff802b1c1f
 #6 [ffff880037169f80] system_call_fastpath at ffffffff8020bfbb
    RIP: 00007fa958991f60  RSP: 00007fff61330390  RFLAGS: 00010246
    RAX: 0000000000000001  RBX: ffffffff8020bfbb  RCX: 0000000000000001
    RDX: 0000000000000002  RSI: 00007fa959284000  RDI: 0000000000000001
    RBP: 0000000000000002   R8: 00007fa9592516f0   R9: 00007fa958c209c0
    R10: 00007fa958c209c0  R11: 0000000000000246  R12: 00007fa958c1f780
    R13: 00007fa959284000  R14: 0000000000000002  R15: 00000000595569d0
    ORIG_RAX: 0000000000000001  CS: 0033  SS: 002b
crash> 

现在很清楚发生了什么:Bash shell 的内部 echo 命令将一个字符发送到 /proc/sysrq-trigger。在相应的处理程序识别到该字符后,它调用了 crash_kexec() 函数。该函数调用了 panic(),Kdump 保存了一个转储。

除了基本的 GDB 命令和 bt 的扩展版本外,crash 实用程序还定义了其他与 Linux 内核结构相关的命令。这些命令了解 Linux 内核的内部数据结构,并以人类可读的格式呈现其内容。例如,您可以使用 ps 列出崩溃时刻运行的任务。使用 sym,您可以列出所有内核符号及其对应的地址,或者查询单个符号的值。使用 files,您可以显示进程的所有打开的文件描述符。使用 kmem,您可以显示有关内核内存使用的详细信息。使用 vm,您可以检查进程的虚拟内存,甚至到单个页面映射的级别。有用的命令列表很长,其中许多命令都接受各种选项。

我们提到的命令反映了常用 Linux 命令的功能,例如 pslsof。要了解使用调试器确切的事件序列,您需要知道如何使用 GDB 并具备强大的调试技能。这两者都超出了本文档的范围。此外,您需要了解 Linux 内核。本文档末尾提供了几个有用的参考信息来源。

18.9 高级 Kdump 配置 编辑源代码

Kdump 的配置存储在 /etc/sysconfig/kdump 中。您也可以使用 YaST 进行配置。Kdump 配置选项在 系统 › 内核 KdumpYaST 控制中心 中可用。以下 Kdump 选项对您可能有用。

您可以使用 KDUMP_SAVEDIR 选项更改内核转储的目录。请记住,内核转储的大小可能很大。如果剩余磁盘空间(减去估计的转储大小)低于 KDUMP_FREE_DISK_SIZE 选项指定的值,Kdump 将拒绝保存转储。KDUMP_SAVEDIR 了解 URL 格式 PROTOCOL://SPECIFICATION,其中 PROTOCOLfileftpsftpnfscifs 中的一个,而 specification 因每个协议而异。例如,要在 FTP 服务器上保存内核转储,请使用以下 URL 作为模板:ftp://username:password@ftp.example.com:123/var/crash

内核转储很大,包含许多对于分析而言不必要的页面。使用 KDUMP_DUMPLEVEL 选项,您可以省略这些页面。该选项了解 0 到 31 之间的数值。如果您指定 0,则转储大小最大。如果您指定 31,则会生成最小的转储。有关可能的完整值表,请参阅 kdump 的手册页 (man 7 kdump)。

有时,减小内核转储的大小很有用。例如,您可以这样做以便通过网络传输转储或在转储目录中节省磁盘空间。这可以通过将 KDUMP_DUMPFORMAT 设置为 compressed 来完成。crash 实用程序支持动态解压缩压缩转储。

Important
重要提示:Kdump 配置文件更改

在更改 /etc/sysconfig/kdump 文件后,您需要运行 systemctl restart kdump.service。否则,更改仅在下次重新启动系统时生效。

18.10 更多信息 编辑源代码

没有关于 Kexec 和 Kdump 用法的单一综合参考。但是,有一些有用的资源处理某些方面

有关 crash 转储分析和调试工具的更多详细信息,请使用以下资源

  • 除了 GDB 的信息页 (info gdb) 之外,https://sourceware.org/gdb/documentation/ 上还有可打印的指南。

  • crash 实用程序具有全面的在线帮助。使用 help COMMAND 显示 command 的在线帮助。

  • 如果您具备必要的 Perl 技能,可以使用 Alicia 来简化调试。这个基于 Perl 的 crash 实用程序前端可以在 https://alicia.sourceforge.net/ 上找到。

  • 如果您更喜欢使用 Python,则应安装 Pykdump。此软件包可帮助您通过 Python 脚本控制 GDB。

  • Daniel P. Bovet 和 Marco Cesati 的 Understanding the Linux Kernel(ISBN 978-0-596-00565-8)提供了 Linux 内核内部的全面概述。

打印此页面