跳到内容跳到页面导航:上一页 [access key p]/下一页 [access key n]
documentation.suse.com / SUSE Linux Enterprise Server 文档 / 系统分析和微调指南 / 处理系统转储 / Kexec 和 Kdump
适用范围 SUSE Linux Enterprise Server 15 SP5

18 Kexec 和 Kdump

Kexec 是一种可以从当前运行的内核引导进入另一内核的工具。您可以在不执行任何硬件初始化的情况下加快系统重引导速度。您还可以准备好系统,以便在系统崩溃的情况下引导进入另一内核。

18.1 简介

使用 Kexec 可将运行中的内核替换为另一内核,而无需硬性重引导。该工具非常有用,原因如下:

  • 加快系统重引导速度

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

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

    计算机硬件非常复杂,在系统启动期间可能会出现严重问题。您并不总能立即更换掉不可靠的硬件。Kexec 可将内核引导到已初始化硬件的受控环境。这样,就可以最大程度地减少系统启动失败的风险。

  • 保存崩溃内核的转储

    Kexec 可以保留物理内存的内容。在生产内核发生故障后,捕获内核(在预留内存范围内运行的附加内核)会保存有故障内核的状态。保存的映像可帮助您进行后续分析。

  • 无需 GRUB 2 配置即可引导

    当系统使用 Kexec 引导内核时,会跳过引导加载程序阶段。常规引导过程可能会由于引导加载程序配置中的错误而失败。使用 Kexec,您就不需要考虑引导加载程序配置是否有效。

18.2 所需的软件包

要在 SUSE® Linux Enterprise Server 上使用 Kexec 来加速重引导或避免潜在的硬件问题,请确保已安装 kexec-tools 软件包。该软件包包含名为 kexec-bootloader 的脚本,该脚本会读取引导加载程序配置,并使用与常规引导加载程序相同的内核选项来运行 Kexec。

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

SUSE Linux Enterprise Server 中使用 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" 添加更多选项即可。

始终可以卸载先前装载的内核。要卸载通过 -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

    所有值均以 MB 为单位。

  2. 请记下 LowHigh 的值。

    注意
    注意:LowHigh 值的含义

    在 AMD64/Intel 64 计算机上,High 值表示所有可用内存的内存预留量。Low 值表示 DMA32 区域中的内存预留量,即,所有内存不超过 4 GB 上限。

    SIZE_LOW 是仅支持 32 位的设备所需的内存量。内核将为 DMA32 回弹缓冲区分配 64M。如果您的服务器不包含任何仅支持 32 位的设备,为 SIZE_LOW 指定 72M 的默认分配大小应可确保一切正常。一种可能的例外情况是,在 NUMA 计算机上,似乎需要更多的 Low 内存。可以使用 numa=off 引导 Kdump 内核,以确保常规内核分配不使用 Low 内存。

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

    SIZE_HIGH = RECOMMENDATION + (LUNs / 2)

    此公式中使用了以下参数:

    • SIZE_HIGH: High 的结果值。

    • RECOMMENDATION: kdumptool calibrateHigh 推荐的值。

    • LUNs: 预期要在计算机上创建的最大 LUN 内核路径数。请从此数字中排除多路径设备,因为会忽略这些设备。

  4. 如果设备驱动程序在 DMA32 区域中预留了大量的内存,则还需要调整 Low 值。但是,没有任何简单公式可以计算这些值。因此,找到适当大小可能需要经历一个反复试验的过程。

    一开始请使用 kdumptool calibrate 推荐的 Low 值。

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

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

    请将以下内核选项追加到引导加载程序配置:

    crashkernel=SIZE_HIGH,high crashkernel=SIZE_LOW,low

    请将占位符 SIZE_HIGHSIZE_LOW 替换为前面步骤中的相应值,并追加字母 M(表示 MB)。

    例如,以下设置有效:

    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 值。

过程 18.2︰ POWER 和 IBM Z 上的分配大小
  1. 要获取计算机的基值,请在终端中运行以下命令:

    # kdumptool calibrate

    此命令会返回值列表。所有值均以 MB 为单位。

  2. 请记下 Low 的值。

  3. 根据附加到计算机的 LUN 内核路径(存储设备的路径)数量调整上一步骤中的 Low 值。可使用以下公式计算合理值(以 MB 为单位):

    SIZE_LOW = RECOMMENDATION + (LUNs / 2)

    此公式中使用了以下参数:

    • SIZE_LOW: Low 的结果值。

    • RECOMMENDATION: kdumptool calibrateLow 推荐的值。

    • LUNs: 预期要在计算机上创建的最大 LUN 内核路径数。请从此数字中排除多路径设备,因为会忽略这些设备。

  4. 现在,需要在正确的位置设置值。

    如果您使用的是命令行

    请将以下内核选项追加到引导加载程序配置:

    crashkernel=SIZE_LOW

    请将占位符 SIZE_LOW 替换为前面步骤中的相应值,并追加字母 M(表示 MB)。

    例如,以下设置有效:

    crashkernel=108M
    如果使用的是 YaST

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

提示
提示:排除 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

先前已装载到旧内核的地址空间中的新内核会重新写入,并立即接管控制权。它会如常显示启动消息。当新内核引导时,会跳过所有硬件和固件检查。请确保未显示任何警告消息。

提示
提示:在 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。

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

18.7 Kdump 基本配置

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

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

提示
提示:通过网络转储

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

重要
重要:必须在配置期间挂载 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. 使用 Magic SysRq 组合键的 procfs 接口调用内核恐慌操作:

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

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

YaST Kdump 模块的屏幕截图
图 18.1︰ YaST Kdump 模块:启动页

启动窗口中选择启用 Kdump

当您首次打开该窗口时,系统会自动生成 Kdump 内存的值。但是,这并不意味着这些值始终足以满足需求。要设置正确的值,请遵循第 18.4 节 “计算 crashkernel 分配大小”中的说明操作。

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

如果您在计算机上设置了 Kdump,后来决定更改 Kdump 的可用 RAM 或硬盘容量,YaST 将继续显示并使用已过时的内存值。

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

在左窗格中单击转储过滤,然后检查要包含在转储中的页。无需包含以下内存内容即可调试内核问题:

  • 以零填充的页

  • 缓存页

  • 用户数据页

  • 可用页

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

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

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

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

18.7.3 Kdump 通过 SSH 传输

转储文件常常包含敏感数据,因此应防范未经授权透露这些数据。要允许通过不安全的网络传输此类数据,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 传输文件的首选方法。目标主机必须启用 SFTP 子系统(默认为 SLE)。示例:

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

    其他某些发行套件使用 SSH 在目标主机上运行某些命令。SUSE Linux Enterprise Server 也可以使用此方法。目标主机上的 Kdump 用户必须具有一个可执行以下命令的登录外壳:mkdirddmv。示例:

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

18.8 分析崩溃转储

获取转储后,便可以开始对它进行分析了。系统提供了多个选项。

用于分析转储的初始工具为 GDB。您甚至可以在最新的环境中使用此工具,不过,它也存在一些缺点和限制:

  • GDB 并非专用于调试内核转储的工具。

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

  • GDB 不能识别除 ELF 转储以外的其他格式(无法调试压缩的转储)。

由于这些原因,我们实施的实用程序是 crash。crash 能够分析崩溃转储,还能调试运行中的系统。它提供了专用于调试 Linux 内核的功能,更适合用于高级调试。

如果您想要调试 Linux 内核,需要额外安装其调试信息软件包。使用以下命令检查您的系统上是否已安装该软件包:

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

如果您为系统订阅了联机更新,便可以在 SUSE Linux Enterprise Server 15 SP5 相关的 *-Debuginfo-Updates 联机安装储存库中找到 debuginfo 软件包。使用 YaST 启用该储存库。

要在生成转储的计算机上的 crash 中打开捕获的转储,请使用如下所示的命令:

crash /boot/vmlinux-2.6.32.8-0.1-default.gz \
/var/crash/2010-04-23-11\:17/vmcore

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

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

SUSE Linux Enterprise Server 随附了 kdumpid 实用程序(包含在同名的软件包中)用于识别未知的内核转储。可以使用此实用程序来提取基本信息,例如体系结构和内核版本。它支持 lkcd、diskdump、Kdump 文件和 ELF 转储。使用 -v 开关调用此实用程序时,它会尝试提取额外信息,例如计算机类型、内核标题字符串和内核配置风格。

18.8.1 内核二进制文件格式

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

18.8.1.1 AMD64/Intel 64

SUSE 提供的适用于 AMD64/Intel 64 的内核软件包中包含两个内核文件:vmlinuzvmlinux.gz

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

    Linux 内核由两个部分组成:内核本身 (vmlinux),以及由引导加载程序运行的设置代码。这两个部分关联在一起创建了 vmlinuz(请注意字母 zx 的差别)。

    在内核源树中,该文件名为 bzImage

  • vmlinux.gz 这是可由 crash 和 GDB 使用的压缩 ELF 映像。在 AMD64/Intel 64 上,引导加载程序本身永远不会使用 ELF 映像。因此,只随附了一个压缩版本。

18.8.1.2 POWER

POWER 上的 yaboot 引导加载程序也支持装载 ELF 映像,但不支持压缩的 ELF 映像。在 POWER 内核软件包中,有一个 ELF Linux 内核文件 vmlinux。对于 crash 而言,POWER 是最简单的体系结构。

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

仅当另一台计算机运行相同体系结构的 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-5.3.18-8-default.gz \
/var/crash/2020-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-5.3.18-8-default.gz
   DEBUGINFO: /usr/lib/debug/boot/vmlinux-5.3.18-8-default.debug
    DUMPFILE: /var/crash/2020-04-23-11:17/vmcore
        CPUS: 2
        DATE: Thu Apr 23 13:17:01 2020
      UPTIME: 00:10:41
LOAD AVERAGE: 0.01, 0.09, 0.09
       TASKS: 42
    NODENAME: eros
     RELEASE: 5.3.18-8-default
     VERSION: #1 SMP 2020-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 外壳的内部命令。

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 外壳的内部 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。Kdump 配置选项在 YaST 控制中心中的系统 › 内核 Kdump 下提供。以下 Kdump 选项可能对您有用。

可以使用 KDUMP_SAVEDIR 选项更改内核转储的目录。请注意,内核转储大小可能会非常大。如果减去预估转储大小后的可用磁盘空间低于 KDUMP_FREE_DISK_SIZE 选项指定的值,Kdump 将拒绝保存转储。请注意,KDUMP_SAVEDIR 可识别 URL 格式 PROTOCOL://SPECIFICATION,其中 PROTOCOLfileftpsftpnfscifsspecification 因协议而异。例如,要在 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 实用程序支持对压缩的转储进行动态解压缩。

重要
重要:对 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 来简化调试。您可以在 http://alicia.sourceforge.net/ 上找到 crash 实用程序的此基于 Perl 的前端。

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

  • 由 Daniel P. Bovet 和 Marco Cesati 发布的 Understanding the Linux Kernel (ISBN 978-0-596-00565-8) 中非常全面地概述了 Linux 内核的内部结构。