首页 > 系统相关 >如何应对Linux 内核崩溃

如何应对Linux 内核崩溃

时间:2023-12-26 13:34:27浏览次数:43  
标签:kexec initramfs 内核 Linux 崩溃 kdump 加载

如何应对Linux 内核崩溃

kdump 是一种用于获取 Linux 内核崩溃转储的方法,而要找到关于其使用和内部结构的解释性文档可能有一些挑战。在这篇文章中,我将深入探讨 kdump 的基本用法以及 kdump/kexec 在内核中的实现。

首先,让我们了解 kexec。kexec 是一个 Linux 内核到内核的引导加载程序,它可以帮助从第一个内核的上下文快速引导到第二个内核。使用 kexec,可以关闭第一个内核,绕过 BIOS 或固件阶段,并直接跳转到第二个内核,从而实现快速重启,无需经历传统的 BIOS 阶段。

kdump 和 kexec 可以一起使用。当第一个内核崩溃时,kexec 可以引导第二个内核,而第二个内核则用于复制第一个内核的内存转储。之后,可以使用调试工具如 gdb 和 crash 来分析这个崩溃的原因。在这里,我将使用术语“第一内核”表示当前运行的内核,“第二内核”表示通过 kexec 运行的内核,“捕获内核”表示在当前内核崩溃时运行的内核。

kexec 机制涉及到内核和用户空间中的多个组件。内核提供了几个用于 kexec 重启功能的系统调用。用户空间的 kexec 工具(通常是 kexec-tools)利用这些调用,并提供可执行文件,用于加载和引导“第二内核”。一些发行版可能还会添加封装器,以便捕获和保存各种配置转储目标的转储。在这里,我将使用 Fedora Linux 发行版的 kexec-tools。

通过使用 kdump 和 kexec,你可以更有效地处理内核崩溃情况,加速系统的重启过程,并方便地分析和调试内核问题。

Fedora kexec-tools 工具

在 Fedora 操作系统上,你可以通过运行以下命令安装 fedora-kexec-tools:

bashCopy code
sudo dnf install kexec-tools

安装完成后,你可以使用以下命令启动 kdump 服务:

bashCopy code
sudo systemctl start kdump

启动 kdump 服务时,它会创建一个包含保存 vmcore 所需资源的根文件系统(initramfs),以及执行将 vmcore 复制和转储到目标位置的命令。此服务还会加载内核和 initramfs 到内核崩溃区域的适当位置,以便在发生内核崩溃时执行它们。

在 Fedora 中,有两个配置文件可供修改:

  1. /etc/kdump.conf:指定那些在修改后需要重新构建 initramfs 的配置参数。例如,如果将转储目标从本地磁盘更改为 NFS 挂载的磁盘,则需要重新加载与 NFS 相关的内核模块。
  2. /etc/sysconfig/kdump:指定那些在修改后不需要重新构建 initramfs 的配置参数。例如,如果只需修改传递给“捕获内核”的命令行参数,则不需要重新构建 initramfs。

如果内核在 kdump 服务启动后出现故障,那么“捕获内核”将执行,并进一步执行 initramfs 中的 vmcore 保存过程。然后,系统将重新启动到稳定的内核。这种设置使得在系统遇到内核崩溃时能够更有效地保存转储信息和进行故障排除。

kexec-tools 工具

通过编译 kexec-tools 源代码,你将获得一个名为 kexec 的可执行文件。这个同名的可执行文件可以用于两个主要操作:加载和执行“第二内核”或加载“捕获内核”以在内核崩溃时执行。

对于加载“第二内核”,你可以使用以下命令:

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

在这里,--reuse-cmdline 参数表示使用与“第一内核”相同的命令行。通过使用 --initrd 选项传递 initramfs。-l 参数表明你正在加载“第二内核”,这个内核不能在内核崩溃时执行。如果你想要加载并在内核崩溃时执行“捕获内核”,则必须使用 -p 参数,而不是 -l

以下是加载“捕获内核”的示例命令:

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

为了测试内核崩溃,你可以使用以下命令:

bashCopy code
echo c > /proc/sysrq-trigger

这将触发内核崩溃,以便进行测试。有关 kexec-tools 提供的其他选项的详细信息,你可以查阅 man kexec。在转到下一部分之前,建议观看一下 kexec_dump 的演示。

视频地址:

https://img.linux.net.cn//static/video/kexec_kdump_demo-iOq_rJhrKhA.mp4

kdump: 端到端流

在上述流程图中,必须在引导“第一内核”时为捕获内核保留一定量的内存,通过在内核命令行中传递 crashkernel=Y@X 来实现,其中 Y 是保留的内存大小,X 是可选的。通常,使用 crashkernel=256M 对于大多数 x86_64 系统是合适的,但选择适当的内存大小取决于多个因素,包括内核大小、initramfs 的大小以及运行时内存需求。

您可以使用 kexec 可执行文件传递内核和 initramfs 镜像,如上文“kexec-tools”部分所示的命令。值得注意的是,“捕获内核”可以与“第一内核”相同,也可以是不同的。通常,它们是相同的。Initramfs 是可选的,例如,当内核使用 CONFIG_INITRAMFS_SOURCE 编译时,您可能不需要它。通常,使用一个不同的捕获 initramfs 可以更好地执行 vmcore 的自动处理。

当“第一内核”崩溃时,它会执行必要的退出过程并切换到 purgatory(如果存在)。purgatory 的作用包括验证加载二进制文件的 SHA256,如果验证通过,则将控制权传递给“捕获内核”。一旦“捕获内核”接管,它将根据从 elfcorehdr 接收到的系统内存信息创建 vmcore。因此,在“捕获内核”启动后,您将在 /proc/vmcore 中看到来自“第一内核”的转储。根据使用的 initramfs,您可以进一步分析并将其复制到磁盘,也可以设置自动复制,然后重新启动到稳定的内核。

内核系统调用

内核提供了两个与 kexec 相关的系统调用:kexec_load()kexec_file_load()。这两个系统调用用于加载新的内核,以便通过 reboot() 系统调用启动或在内核崩溃时执行。

  1. kexec_load():
kexec_load()

系统调用用于加载一个可以稍后通过

reboot()

执行的新内核。其原型定义如下:

cCopy code
long kexec_load(unsigned long entry, unsigned long nr_segments, struct kexec_segment *segments, unsigned long flags);
  • 用户空间需要传递给不同组件不同的段,如内核、initramfs 等。
kexec

可执行文件帮助准备这些段。

kexec_segment

结构如下:

cCopy codestruct kexec_segment {
  void *buf;     /* 用户空间缓冲区 */
  size_t bufsz;   /* 用户空间缓冲区长度 */
  void *mem;       /* 内核的物理地址 */
  size_t memsz;   /* 物理地址长度 */
};
  • 如果传递 KEXEC_ON_CRASH 标志给 kexec_load(),加载的内核将不使用 reboot(LINUX_REBOOT_CMD_KEXEC) 启动,而是在内核崩溃时执行。要使用 kexec,必须启用 CONFIG_KEXEC,并为 kdump 启用 CONFIG_CRASH_DUMP
  1. kexec_file_load():

是一个更高级别的系统调用,它接受内核和 initramfs 的文件描述符,然后由内核完成其余部分。其原型如下:

cCopy code
long kexec_file_load(int kernel_fd, int initrd_fd, unsigned long cmdline_len, const char __user *cmdline_ptr, unsigned long flags);
  • 与 kexec_load() 不同,kexec_file_load() 还支持传递命令行。在此情况下,内核根据系统体系结构接受和执行命令行。目前,kexec_file_load() 仅支持 x86 和 PowerPC。

当内核崩溃时会发生什么?

当内核崩溃时,以下操作将在将控制权传递给 purgatory 或“捕获内核”之前执行:

  • 准备 CPU 寄存器。
  • 更新 vmcoreinfo 备注。
  • 关闭非崩溃的 CPU 并保存准备好的寄存器。
  • 在此阶段可能需要禁用中断控制器。
  • 执行 kexec 重新启动,加载或刷新 kexec 段到内存,并将控制权传递给执行文件。输入段可以是下一个内核的 purgatory 或起始地址。

ELF(Executable and Linkable Format)ELF 程序头和崩溃转储

ELF(Executable and Linkable Format)是一种常用于可执行文件和共享库的文件格式。在崩溃转储中,ELF 程序头对于描述如何将程序加载到内存中非常重要。在 vmcore 中,大多数转储核心都是 ELF 格式的,因此理解 ELF 程序头是很有帮助的。

每个 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 的表示:

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。

  1. Crash Notes (/sys/devices/system/cpu/cpu%d/crash_notes):
  • Crash notes 是用于在系统崩溃时存储有关 CPU 状态的区域。它包含有关当前 PID 和 CPU 寄存器的信息。
  1. VMcoreinfo (/sys/kernel/vmcoreinfo):
  • VMcoreinfo 是一个包含内核调试信息的文件。kexec-tools 读取此文件并准备 vmcoreinfo PT_NOTE 的标头。其中包含一些关键的宏定义,如 VMCOREINFO_PAGESIZEVMCOREINFO_SYMBOLVMCOREINFO_SIZEVMCOREINFO_STRUCT_SIZE 等。
  1. makedumpfile:

是一个应用程序,用于处理/proc/vmcore的数据,排除不必要的页面并在复制时进行压缩。它还可以从转储中删除敏感的符号信息。

通常在 kdump 环境中使用,可以使用以下示例命令:

bashCopy code
# makedumpfile -l --message-level 1 -d 31 /proc/vmcore makedumpfilecore
  • 详细信息请参阅 man makedumpfile

kdump 调试

对于初学者使用 kdump 时可能遇到的问题:

问题:kexec -p kernel_image 执行失败

问题:在“第一内核”结束后,在控制台上没有看到任何输出(例如“bye”)

  • 这可以帮助在早期阶段看到更多的调试输出。
  • 确保第二内核的设置和参数正确。可能需要在命令行中传递额外的选项以启用调试信息。
  • 如果体系结构不支持 purgatory 中的控制台,很难进行调试。确认 SHA 验证是否通过。
  • 检查是否有适用于您的体系结构和机器的正确配置。有些平台可能需要特定的设置。
  • 确保 kexec -e 命令成功启动了第二内核。
  • 检查 kexec -e 之后的 kexec -l kernel_image 命令是否正常工作。
  • 确认是否缺少支持的体系结构或特定机器的选项。
  • 验证 purgatory 的 SHA 验证是否失败。
  • 检查是否第二内核早已崩溃。
  • 在第二内核的命令行中传递 earlycon 或 earlyprintk 选项。
  • 如果问题仍然存在,使用 kexec-tools 邮件列表共享第一个内核和捕获内核的 dmesg 日志。
  • kexec -d -p kernel_image
  • 在启动时确保使用正确的内存参数,例如 crashkernel=256M
  • 运行 cat /proc/iomem | grep "Crash kernel",应该显示一个合适的分配范围。如果没有显示,可能是由于未正确传递 crashkernel= 参数。
  • 运行 cat /sys/kernel/kexec_crash_size,它不应该返回零值。如果为零,表示崩溃内存没有正确分配。
  • 检查是否分配了崩溃内存。
  • 验证 /proc/iomem 中是否有 "Crash kernel" 的分配范围。
  • 在命令行中确保传递正确的 crashkernel= 参数。
  • 如果问题仍然存在,使用 -d 参数运行 kexec 命令,将输出信息发送到 kexec-tools 邮件列表。

标签:kexec,initramfs,内核,Linux,崩溃,kdump,加载
From: https://blog.51cto.com/u_64214/8981897

相关文章

  • linux常用命令(笔记)
    1、telnet进去后怎么退出:telnet10.102.5.11922查看ip,端口通讯状况退出的话:Ctrl+]然后输入q退出,如下图:2、linux下查看tomcat版本curl172.16.45.231:8080|grep"ApacheTomcat"curlIP:端口|grep"ApacheTomcat"3、关于CPU命令——查看CPU型号cat/......
  • linux下服务器ping不通公网域名(不定时更新)
    1、服务器开通的公网访问,但是ping不通域名,可配置hosts重试保存后,重试,OK2、服务器公网IP也ping不通,修改网卡配置,配置DNS重启网卡后,问题解决......
  • Linux系统CPU状态信息详解:解读us, sy, ni, id, wa, hi, si, st的含义
    Cpu(s):0.0%us,0.5%sy,0.0%ni,99.5%id,0.0%wa,0.0%hi,0.0%si,0.0%st上面一组字符,有何含义?今天我们一起来解读。在计算机系统中,CPU是核心组件,负责执行程序中的指令。为了更好地理解系统的运行状况,我们需要关注CPU的各种状态信息。本文将详细介绍这些状态信息,并以具体示例进行解释。......
  • 分享一些linux云计算开发面试题
    近年来,随着云计算的快速发展,对于中高级Linux云计算开发人才的需求也越来越大。在面试过程中,面试官通常会提出一系列与Linux云计算开发相关的问题,以评估面试者的技术实力和解决问题的能力。本文将围绕中高级Linux云计算开发面试题展开讨论,并给出相关问答。 一、虚拟化技术 1.什么......
  • Linux openEuler(欧拉系统)无公网实现ssh远程连接(高效运维!)
    欧拉操作系统(openEuler,简称“欧拉”)是面向数字基础设施的操作系统,支持服务器、云计算、边缘openEuler是面向数字基础设施的操作系统,支持服务器、云计算、边缘计算、嵌入式等应用场景,支持多样性计算,致力于提供安全、稳定、易用的操作系统Cpolar是一种安全的内网穿透云服务,......
  • GScan v0.1 被攻击入侵后 溯源 安全应急响应 Linux主机排查 实现主机侧Checklist的自
    GScanv0.1本程序旨在为安全应急响应人员对Linux主机排查时提供便利,实现主机侧Checklist的自动全面化检测,根据检测结果自动数据聚合,进行黑客攻击路径溯源。CheckList检测项自动化程序的CheckList项如下:1、主机信息获取2、系统初始化alias检查3、文件类安全扫描3.1、系统重要文......
  • 在linux中查看运行指定进程资源占用(cpu+gpu)
    在运行程序时有时候会需要查看资源占用,以方便部署在其他服务器上时进行参考。以下是总结了我在linux上查找程序进程资源的两种方法(cpu和gpu都有)。CPU1.查找进程号如果进程较多,输入ps-ef|grep+指令关键词进行搜索。如果运行的是python程序,可以输入ps-ef|greppytho......
  • linux经典电灯驱动(古老版,参考用)
    驱动程序#include<linux/types.h>#include<linux/kernel.h>#include<linux/delay.h>#include<linux/ide.h>#include<linux/init.h>#include<linux/module.h>#include<linux/errno.h>#include<linux/gpio.h>#inc......
  • linux声音处理 alsa & jack 是什么
    alsa(AdvancedLinuxSoundArchitecture)是什么:简单的说,linux之前的内核里处理声音使用oss,后来大家觉得不好用,重写了声音部分,改名叫alsa(更高级的),并且提供了用户空间库(alsa-lib),供应用程序方便调用。官方说明:高级Linux声音架构(ALSA)为Linux操作系统提供音频和MIDI......
  • node.js安装到Linux
    下载地址:https://nodejs.org/dist/1、准备node安装包,可以进入镜像站 ,自行选择版本进行下载,这里下载的是 node-v12.22.3-linux-x64.tar.xz2、将本地的安装包上传到linux服务器上,我这里放在/home/software目录下3、在/usr/local下创建node文件夹mkdir/usr/local/......