Centos7.9操作系统kdump crash文件vmcore未生成问题
Centos7.9操作系统kdump crash文件未生成问题
- 一、背景说明
- 1、问题背景
- 二、排查思路
- 1、先了解下crashkernel
- `crashkernel`设置方式示例
- 如何配置`crashkernel`
- 验证`crashkernel`配置
- 2、再了解下kdump
- 2.1 Kdump 的基本概念
- 2.1.1. 生产内核(Production Kernel)
- 2.1.2. 捕获内核(Capture Kernel)
- 2.1.3. Ramdisk
- 2.1.4. ELF 文件
- 2.2 Kdump 的工作原理
- 2.2.1. Kexec 机制
- 2.2.2. 内核空间:`kexec_load()`
- 2.2.3. 用户空间:kexec-tools
- 2.3 Kdump 的工作流程
- 2.3.1. 预留内存
- 2.3.2. 生产内核运行
- 2.3.3. 系统崩溃
- 2.3.4. 捕获内核启动
- 2.3.5. 数据转储
- 2.3.6. 数据分析
- 1. GDB
- 2. Crash
- 使用 `gdb` 分析 `vmcore` 文件
- 1. 准备工作
- 2. 分析内存内容
- 3. 分析崩溃原因
- 使用 `crash` 分析 `vmcore` 文件
- 1. 准备工作
- 2. 使用 `crash` 命令
- 3. 经典场景分析案例
- 案例 1:内核崩溃由于内存损坏
- 案例 2:内核崩溃由于驱动程序问题
- 案例 3:内核崩溃由于系统资源耗尽
- 2.4 Kdump 的应用场景
- Kdump 的优势
- 三、解决方案
- 1. 方案一调整crashkernel(需重启系统)
- 1.1 低内存预留的重要性
- 1.2高内存预留的重要性
- 1.3为什么两者都需要预留?
- 1.4 模拟crash
- 2、方案二 (验证次数较少) 修改kdumpctl
- 2.1 替换cmdline
- 2.2 模拟crash
- 四、总结
一、背景说明
1、问题背景
近期公司一台线上服务器系统出现崩溃,已经配置了kdump,但未生成相关的crash文件。服务器配置:
浪潮SA5212M5,Gold5118*2 内存配置为128GB.
[root@test-99-230 log]# cat /etc/default/grub
GRUB_TIMEOUT=5
GRUB_DISTRIBUTOR="CentOS Linux"
GRUB_DEFAULT=saved
GRUB_DISABLE_SUBMENU=true
GRUB_TERMINAL_OUTPUT="console"
GRUB_CMDLINE_LINUX="crashkernel=169M biosdevname=0 net.ifnames=0 rhgb quiet"
GRUB_DISABLE_RECOVERY="true"
GRUB_GFXPAYLOAD_LINUX=text
[root@test-99-230 log]#[root@test-99-230 log]# grep -rn crash /var/log/messages
3410:Aug 5 05:43:58 test-99-230 kernel: Command line: BOOT_IMAGE=/vmlinuz-3.10.0-1160.el7.x86_64 root=UUID=87afdba4-8e9d-4349-a068-23ac53d18164 ro crashkernel=169M biosdevname=0 net.ifnames=0 rhgb quiet
3529:Aug 5 05:43:58 test-99-230 kernel: Reserving 169MB of memory at 576MB for crashkernel (System RAM: 130563MB)
3814:Aug 5 05:43:58 test-99-230 kernel: Kernel command line: BOOT_IMAGE=/vmlinuz-3.10.0-1160.el7.x86_64 root=UUID=87afdba4-8e9d-4349-a068-23ac53d18164 ro crashkernel=169M biosdevname=0 net.ifnames=0 rhgb quiet
4269:Aug 5 05:43:58 test-99-230 kernel: crash memory driver: version 1.1
4552:Aug 5 05:43:59 test-99-230 kernel: megaraid_sas 0000:5e:00.0: firmware crash dump#011: no
5951:Aug 5 06:18:47 test-99-230 kernel: Command line: BOOT_IMAGE=/vmlinuz-3.10.0-1160.el7.x86_64 root=UUID=87afdba4-8e9d-4349-a068-23ac53d18164 ro crashkernel=169M biosdevname=0 net.ifnames=0 rhgb quiet
6070:Aug 5 06:18:47 test-99-230 kernel: Reserving 169MB of memory at 576MB for crashkernel (System RAM: 130563MB)
6355:Aug 5 06:18:47 test-99-230 kernel: Kernel command line: BOOT_IMAGE=/vmlinuz-3.10.0-1160.el7.x86_64 root=UUID=87afdba4-8e9d-4349-a068-23ac53d18164 ro crashkernel=169M biosdevname=0 net.ifnames=0 rhgb quiet
6810:Aug 5 06:18:47 test-99-230 kernel: crash memory driver: version 1.1
从crashkernel=169M中可以看出,配置的第二内核内存是169MB,通过不断模拟触发crash场景,最终定位本次未产生crash文件根因为
第二内核预留的内核较小,导致第二内核在运行期间加载驱动时内存不够使用发生oom(内存溢出)现象
因为OS本身已经使能kdump,所以在内核发生崩溃后会启动crashdump服务,即会加载第二内核。
但是第二内核在启动过程中因为前期为其crashkernel预留的内存不够,在加载驱动时发生oom(内存溢出),因此vmcore生成失败。
二、排查思路
1、先了解下crashkernel
在Linux操作系统中,kdump是一个用于捕获系统崩溃转储(crash dump)的机制。为了使kdump能够正常工作,系统需要预留一部分内存,这部分内存称为crashkernel。
crashkernel参数用于指定在系统启动时预留多少内存用于崩溃转储。这些预留的内存不会被操作系统的其他部分使用,确保在系统崩溃时,kdump有足够的资源来保存内存转储。
以下是crashkernel
参数的几种常见设置方式及其示例:
-
自动预留内存 (
crashkernel=auto
)crashkernel=auto
这种设置允许系统根据总内存自动配置预留的内存量。这是最简单的一种设置方式,适用于大多数用户。
-
固定预留内存 (
crashkernel=<size>
)crashkernel=128M
这种方式明确指定预留内存的大小,例如128MB。这种设置方式适用于已知需要多少内存用于
kdump
的情况。 -
可变预留内存 (
crashkernel=<range1>:<size1>,<range2>:<size2>
)crashkernel=512M-2G:64M,2G-:128M
这种设置方式根据系统的总内存来预留不同大小的内存。例如,当系统总内存小于512MB时,不预留内存;在512MB到2GB之间时,预留64MB;大于2GB时,预留128MB。
-
偏移预留内存 (
crashkernel=<size>@<offset>
)crashkernel=128M@16M
这种方式从指定的偏移地址(例如16MB)开始预留指定大小的内存(例如128MB)。如果offset参数设置为0或完全省略,
kdump
会自动偏移预留内存。对于一般用户来说,这种方式通常不指定offset,因为很难确定预留内存的起始位置。 -
可变预留+偏移预留内存 (
crashkernel=<range1>:<size1>,<range2>:<size2>@<offset>
)crashkernel=512M-2G:64M,2G-:128M@16M
这种方式结合了可变预留和偏移预留的特点。例如,从16MB开始预留内存,根据系统总内存的不同,预留64MB或128MB。
crashkernel
设置方式示例
设置方式 | 示例 | 示例含义 |
---|---|---|
自动预留 | crashkernel=auto | 允许基于系统的总内存自动地配置预留内存, |
确切的值 | crashkernel=128M | 预留128M内存 |
可变预留 | crashkernel=512M-2G:64M,2G-:128M | 系统总内存小于512M时,不预留;在512M-2G时,预留64M;大于2G预留128M |
偏移预留 | crashkernel=128M@16M | 从16 MB开始预留128 MB内存。如果offset参数设置为0或完全省略,kdump会自动偏移预留内存。不过,offset一般不指定,对于一般用户来讲,很难确定预留内存的起始位置。 |
可变预留+偏移预留 | crashkernel=512M-2G:64M,2G-:128M@16M | 从16MB开始预留内存,预留64M或者128M,取决于系统总内存的大小。 |
如何配置crashkernel
配置crashkernel
参数需要修改引导加载程序(如GRUB)的配置文件。以下是配置步骤:
-
打开GRUB配置文件:
sudo vi /etc/default/grub
-
找到
GRUB_CMDLINE_LINUX
这一行,并添加crashkernel
参数。例如:GRUB_CMDLINE_LINUX="crashkernel=512M-2G:64M,2G-:128M"
-
更新GRUB配置:
sudo grub2-mkconfig -o /boot/grub2/grub.cfg
-
重启系统使配置生效:
sudo reboot
验证crashkernel
配置
重启系统后,可以通过以下命令验证crashkernel
配置是否生效:
dmesg | grep -i crashkernel
2、再了解下kdump
Kdump 是 Linux 系统中一种强大的内核崩溃转储工具,它的出现大大增强了系统管理员对系统崩溃的诊断能力。自 2005 年首次推出以来,Kdump 已成为许多 Linux 系统中不可或缺的组件,帮助用户在系统崩溃后获取重要的内存转储信息。本文将详细介绍 Kdump 的工作原理、实现机制、以及如何有效地使用它来排查系统崩溃问题。
2.1 Kdump 的基本概念
2.1.1. 生产内核(Production Kernel)
生产内核是系统正常运行时的内核,它负责处理所有的系统调用、驱动程序和用户空间的请求。在正常情况下,生产内核负责维护系统的稳定性和性能。
2.1.2. 捕获内核(Capture Kernel)
捕获内核是一个特殊的内核,在系统崩溃时启动,用于收集生产内核的内存数据。捕获内核在生产内核崩溃后被引导,以便在不干扰生产内核的情况下保存内存转储数据。
2.1.3. Ramdisk
Ramdisk 是一种将内存区域虚拟化为硬盘驱动器的机制。通过使用 ramdisk,可以大幅提高读写速度,因为数据直接存储在内存中,而不需要经过传统的磁盘 I/O 操作。在 Kdump 中,ramdisk 用于存储捕获内核和相关的数据。
2.1.4. ELF 文件
ELF(Executable and Linkable Format)文件是一种标准的文件格式,用于存储可执行文件、目标代码和共享库。在 Kdump 中,ELF 文件用于存储内存的转储数据,以便进行后续分析。
2.2 Kdump 的工作原理
Kdump 的工作原理依赖于 Kexec 机制。Kdump 的核心思想是预留一部分内存来加载捕获内核,并在系统崩溃时启动捕获内核来处理内存转储。以下是 Kdump 的详细工作流程:
2.2.1. Kexec 机制
Kexec 是一种快速启动机制,它允许在当前运行的内核环境下直接启动另一个内核,而无需经过传统的 BIOS 启动过程。Kexec 的实现包括两个主要组成部分:
- 内核空间系统调用:
kexec_load()
:这是一个系统调用,用于将捕获内核和其 ramdisk 加载到当前内核中。kexec_load()
接受捕获内核的地址,并将其加载到生产内核中。 - 用户空间工具:kexec-tools:这是一个用户空间工具集,用于执行 Kexec 相关操作。
kexec-tools
包含kexec
程序,它负责调用kexec_load()
并传递捕获内核的地址。
2.2.2. 内核空间:kexec_load()
在内核空间,kexec_load()
系统调用用于将捕获内核和 ramdisk 加载到内存中。该调用将捕获内核的内存映像和 ramdisk 存储位置传递给生产内核。生产内核在运行过程中保留一部分内存用于加载捕获内核。
当系统崩溃时,生产内核会调用 machine_kexec()
函数,这通常是一个硬件相关的函数,用于引导捕获内核。捕获内核会从生产内核的内存中读取崩溃数据,并生成 /proc/vmcore
文件,该文件包含生产内核的内存映像。
2.2.3. 用户空间:kexec-tools
在用户空间,kexec-tools
工具集用于准备和加载捕获内核。kexec-tools
包含以下组件:
- kexec:这是一个用户空间程序,负责调用
kexec_load()
并将捕获内核和 ramdisk 加载到生产内核中。kexec
还负责配置捕获内核的启动参数和内存位置。 - purgatory:这是一个小型的用户空间程序,用于处理在崩溃时捕获内核的启动。它负责将捕获内核和 ramdisk 加载到内存中,并传递必要的启动信息。
2.3 Kdump 的工作流程
Kdump 的工作流程包括以下几个步骤:
2.3.1. 预留内存
在系统启动时,crashkernel
参数用于指定用于捕获内核的内存量。例如,crashkernel=128M
表示预留 128MB 的内存给捕获内核。这个预留内存区域必须在系统启动时配置,以确保系统在崩溃时能够启动捕获内核。
2.3.2. 生产内核运行
生产内核正常运行,处理所有的系统调用和用户请求。生产内核会定期将捕获内核和 ramdisk 加载到预留内存中,并配置捕获内核的启动参数。
2.3.3. 系统崩溃
当系统出现崩溃、死锁或死机时,生产内核会触发 machine_kexec()
函数。这会启动捕获内核,并将生产内核的内存映像转储到 /proc/vmcore
文件中。
2.3.4. 捕获内核启动
捕获内核会从生产内核的内存中读取崩溃数据,并生成 /proc/vmcore
文件。捕获内核和 ramdisk 组成一个微环境,用于处理和存储内存转储数据。
2.3.5. 数据转储
捕获内核的 ramdisk 中的脚本会执行数据转储操作,将 /proc/vmcore
文件中的数据保存到磁盘或网络存储中。这些数据可以用于后续的分析和调试。
2.3.6. 数据分析
使用工具如 gdb
、crash
等分析工具对生成的 vmcore
文件进行分析。这些工具可以帮助用户定位系统崩溃的原因,并提供详细的崩溃报告。在系统发生崩溃时,vmcore
文件是分析和诊断问题的关键。这个文件包含了崩溃时的内存映像,提供了有关内核状态的重要信息。使用 gdb
和 crash
等工具,我们可以深入分析 vmcore
文件,找出系统崩溃的原因.
1. GDB
GDB(GNU Debugger)是一种强大的调试工具,广泛用于调试应用程序和内核。它支持查看内存、设置断点、执行代码等操作,适用于深入分析和诊断内核崩溃问题。
2. Crash
crash
是专门用于分析内核崩溃转储的工具,它提供了多种命令,用于查看内核数据结构、内存内容、线程状态等信息。相比于 GDB,crash
更加专注于内核级别的调试和分析。
使用 gdb
分析 vmcore
文件
1. 准备工作
首先,确保你已经安装了 gdb
和适用于你内核版本的调试符号(通常是内核的调试符号包)。将 vmcore
文件和内核映像(vmlinux
文件)放在同一目录下。
gdb /path/to/vmlinux /path/to/vmcore
2. 分析内存内容
使用 GDB,可以查看内存内容、内核数据结构等。以下是一些常用的命令:
-
查看内存:
(gdb) x/10x 0xc0000000
这个命令可以查看从地址
0xc0000000
开始的 10 个内存单元的内容。 -
查看内核符号:
(gdb) info symbol 0xc0000000
这个命令可以查看指定地址的符号信息。
-
设置断点并运行:
(gdb) break function_name (gdb) continue
设置断点并继续执行,用于调试内核崩溃时的代码执行路径。
3. 分析崩溃原因
-
查看内核调用栈:
(gdb) bt
打印调用栈信息,帮助了解崩溃发生时的调用路径。
-
检查特定的数据结构:
(gdb) p data_structure
打印特定数据结构的内容,帮助检查是否存在异常。
使用 crash
分析 vmcore
文件
1. 准备工作
确保你已经安装了 crash
工具,并且已经下载了与内核版本匹配的调试符号。
crash /path/to/vmlinux /path/to/vmcore
2. 使用 crash
命令
crash
提供了多种命令来分析内核崩溃数据:
-
查看系统信息:
crash> sysinfo
显示系统信息,包括内核版本、CPU 信息和内存布局。
-
查看内核线程列表:
crash> ps
列出系统中所有的内核线程,帮助识别崩溃时的活动线程。
-
查看内核堆栈:
crash> bt
打印内核调用栈,类似于 GDB 中的
bt
命令。 -
查看特定进程的信息:
crash> proc
显示系统中的进程信息,包括每个进程的状态和内存使用情况。
-
查看内存内容:
crash> x /10x 0xc0000000
显示从地址
0xc0000000
开始的 10 个内存单元的内容。
3. 经典场景分析案例
案例 1:内核崩溃由于内存损坏
假设在分析 vmcore
文件时发现系统因为内存损坏导致崩溃。以下是分析步骤:
-
查看内存内容:
crash> x /20x 0xc0000000
检查崩溃时的内存内容,寻找异常值。
-
检查调用栈:
crash> bt
确认崩溃发生时的调用路径,查找可能导致内存损坏的代码。
-
查看特定数据结构:
crash> p memory_structure
检查相关内存数据结构的内容,确认是否有损坏或异常情况。
案例 2:内核崩溃由于驱动程序问题
假设系统崩溃由于一个驱动程序引发的错误。以下是分析步骤:
-
查看系统信息:
crash> sysinfo
确认系统和内核版本,确保与驱动程序版本匹配。
-
查看内核调用栈:
crash> bt
分析调用栈信息,找到崩溃时涉及的驱动程序代码。
-
查看进程状态:
crash> ps
查找崩溃时活跃的进程,确认是否涉及问题驱动程序。
案例 3:内核崩溃由于系统资源耗尽
假设系统崩溃由于资源耗尽。以下是分析步骤:
-
查看系统资源使用情况:
crash> sysinfo
检查系统的内存和 CPU 使用情况,确认是否存在资源耗尽的情况。
-
查看内核线程:
crash> ps
查找系统崩溃时活跃的线程,确认是否有线程占用过多资源。
-
检查内存分配:
crash> kmem -i
查看内核内存分配情况,确认是否存在资源泄漏或异常分配。
2.4 Kdump 的应用场景
假设你在生产环境中运行一个关键应用,系统突然出现无响应的情况,没有明显的日志记录,且监控数据看起来正常。这时,Kdump 可以发挥重要作用:
-
配置 Kdump:首先,确保系统已配置 Kdump,并且
crashkernel
参数已正确设置。例如,crashkernel=128M
表示为捕获内核预留了 128MB 的内存。 -
触发崩溃:可以通过模拟崩溃(例如使用
sysrq
触发 panic)来测试 Kdump 是否能够正确捕获和转储内存。 -
分析崩溃数据:崩溃后,捕获内核会生成
/proc/vmcore
文件。使用crash
工具分析vmcore
文件,找出导致崩溃的原因。 -
故障排查:通过分析内存转储数据,可以找到崩溃的根本原因,比如某个驱动程序或内核模块的问题,并进行修复。
Kdump 的优势
- 实时数据捕获:Kdump 能够在系统崩溃时实时捕获内存数据,提供详细的崩溃信息。
- 高效转储:通过使用 ramdisk,可以大幅提高数据转储的速度。
- 详细分析:生成的
vmcore
文件可以通过gdb
和crash
等工具进行详细的分析,帮助开发者和管理员找到系统崩溃的原因。
三、解决方案
1. 方案一调整crashkernel(需重启系统)
通过上面分析,结合日志:
32489:Aug 5 19:51:35 dlp2-99-230 kernel: megaraid_sas 0000:5e:00.0: firmware crash dump#011: no
33775:Aug 5 20:00:45 dlp2-99-230 kernel: Command line: BOOT_IMAGE=/vmlinuz-3.10.0-1160.el7.x86_64 root=UUID=87afdba4-8e9d-4349-a068-23ac53d18164 ro crashkernel=768M biosdevname=0 net.ifnames=0 rhgb quiet
33894:Aug 5 20:00:45 dlp2-99-230 kernel: Reserving 256MB of low memory at 1264MB for crashkernel (System low RAM: 1539MB)
33895:Aug 5 20:00:45 dlp2-99-230 kernel: Reserving 768MB of memory at 132336MB for crashkernel (System RAM: 130563MB)
34180:Aug 5 20:00:45 dlp2-99-230 kernel: Kernel command line: BOOT_IMAGE=/vmlinuz-3.10.0-1160.el7.x86_64 root=UUID=87afdba4-8e9d-4349-a068-23ac53d18164 ro crashkernel=768M biosdevname=0 net.ifnames=0 rhgb quiet
34635:Aug 5 20:00:45 dlp2-99-230 kernel: crash memory driver: version 1.1
34919:Aug 5 20:00:46 dlp2-99-230 kernel: megaraid_sas 0000:5e:00.0: firmware crash dump#011: no
此处说明:
- Firmware Crash Dump: megaraid_sas 0000:5e:00.0: firmware crash dump#011: no
这行日志表明 megaraid_sas 控制器的固件不支持生成 crash dump 文件。固件设置中可能未启用相关功能或该控制器本身不支持该特性。
该相关问题再红帽知识库也曾复现(但当前还不能完全确认是 firmware crash dump#011: no导致crash文件未生成):
-
Reserving 256MB of low memory at 1264MB for crashkernel (System low RAM: 1539MB)
表示系统在低内存区域(从 1264MB 开始)预留了 256MB 内存。
-
Reserving 768MB of memory at 132336MB for crashkernel (System RAM: 130563MB)
表示系统在高内存区域(从 132336MB 开始)预留了 768MB 内存。
这里再说明下为什么需要高、低内存区域都要预留:
在 kdump
机制中,低内存和高内存的预留是为了确保系统在崩溃后能够成功启动捕获内核并生成内存转储文件。以下是低内存和高内存均需要预留的原因:
1.1 低内存预留的重要性
-
设备驱动和DMA内存:
- 许多设备驱动和DMA(直接内存访问)操作需要使用低内存(通常是低于 4GB 的内存区域)。这些设备在捕获内核启动时仍需要工作,以便在崩溃时能够正常操作。
-
中断处理和内存映射:
- 系统中的许多中断处理程序和内存映射操作都依赖于低内存。为了确保捕获内核能够正常处理中断和内存映射,低内存预留是必需的。
1.2高内存预留的重要性
-
内存转储空间:
- 高内存(高于 4GB 的内存区域)预留用于存储内核崩溃转储文件。这些转储文件可能非常大,因此需要大量的高内存来保存所有的崩溃数据。
-
内核数据结构:
- 捕获内核需要访问和使用大量的内核数据结构,这些数据结构通常分布在高内存区域。预留高内存确保这些数据结构在捕获内核启动时可用。
假设我们有一台具有 128GB 内存的服务器,设置 crashkernel=768M
来预留内存以备内核崩溃时使用。
-
低内存预留:
Reserving 256MB of low memory at 1264MB for crashkernel (System low RAM: 1539MB)
- 系统在低内存区域预留了 256MB,用于捕获内核启动时需要的设备驱动和DMA操作。
-
高内存预留:
Reserving 768MB of memory at 132336MB for crashkernel (System RAM: 130563MB)
- 系统在高内存区域预留了 768MB,用于存储内核崩溃转储文件和必要的内核数据结构。
1.3为什么两者都需要预留?
-
低内存需求:
- 捕获内核的引导和基础服务通常需要低内存支持,确保最基本的设备和中断处理功能正常。
-
高内存需求:
- 大量的崩溃数据需要在高内存中存储,避免占用低内存区域,导致设备和基础服务无法正常运行。
预留低内存和高内存的做法是为了确保在系统崩溃后,捕获内核能够成功启动并生成完整的内存转储文件。低内存用于设备驱动和基础服务,高内存用于存储崩溃数据和必要的内核数据结构。这种双重预留机制确保了捕获内核在各种硬件环境和崩溃情况下的可靠性。
有了上述分析, 进行调整操作:
[root@dlp2-99-230 log]# cat /etc/default/grub
GRUB_TIMEOUT=5
GRUB_DISTRIBUTOR="CentOS Linux"
GRUB_DEFAULT=saved
GRUB_DISABLE_SUBMENU=true
GRUB_TERMINAL_OUTPUT="console"
GRUB_CMDLINE_LINUX="crashkernel=768M biosdevname=0 net.ifnames=0 rhgb quiet" # 768M 或者 512M
GRUB_DISABLE_RECOVERY="true"
GRUB_GFXPAYLOAD_LINUX=text
您在 /var/spool/mail/root 中有邮件
[root@dlp2-99-230 log]# grub2-mkconfig -o /boot/grub2/grub.cfg
[root@dlp2-99-230 log]# reboot
[root@dlp2-99-230 log]# cat /proc/cmdline # 验证
BOOT_IMAGE=/vmlinuz-3.10.0-1160.el7.x86_64 root=UUID=87afdba4-8e9d-4349-a068-23ac53d18164 ro crashkernel=768M biosdevname=0 net.ifnames=0 rhgb quiet
[root@dlp2-99-230 log]#
1.4 模拟crash
什么是 sysrq?
sysrq 是 Linux 内核中的一个功能,通过它可以直接向内核发送特定的命令,进行如重启、内存转储、文件系统同步等操作。这个功能在调试和诊断系统问题时非常有用。
[root@dlp2-99-230 log]# systemctl status kdump # 确保kdump服务正常
● kdump.service - Crash recovery kernel armingLoaded: loaded (/usr/lib/systemd/system/kdump.service; enabled; vendor preset: enabled)Active: active (exited) since 一 2024-08-05 12:01:11 CST; 1h 31min agoProcess: 2638 ExecStart=/usr/bin/kdumpctl start (code=exited, status=0/SUCCESS)Main PID: 2638 (code=exited, status=0/SUCCESS)Tasks: 0Memory: 0BCGroup: /system.slice/kdump.service8月 05 12:01:06 dlp2-99-230 systemd[1]: Starting Crash recovery kernel arming...
8月 05 12:01:11 dlp2-99-230 kdumpctl[2638]: kexec: loaded kdump kernel
8月 05 12:01:11 dlp2-99-230 kdumpctl[2638]: Starting kdump: [OK]
8月 05 12:01:11 dlp2-99-230 systemd[1]: Started Crash recovery kernel arming.
您在 /var/spool/mail/root 中有邮件
[root@dlp2-99-230 127.0.0.1-2024-08-05-11:56:35]# cat /etc/kdump.conf | grep -v '#'path /var/crash
core_collector makedumpfile -l --message-level 1 -d 31
[root@dlp2-99-230 127.0.0.1-2024-08-05-11:56:35]#[root@dlp2-99-230 log]#
[root@dlp2-99-230 log]# echo 1 | sudo tee /proc/sys/kernel/sysrq # 该命令将 1 写入 /proc/sys/kernel/sysrq 文件中,启用所有 sysrq 功能。
[root@dlp2-99-230 log]# echo c | sudo tee /proc/sysrq-trigger # 一旦启用了 sysrq 功能,可以通过以下命令触发内核崩溃: 将 c 字符写入 /proc/sysrq-trigger 文件中,告诉内核立即触发崩溃 (Crash)。这将导致系统崩溃并重启。
查看生成的文件
[root@dlp2-99-230 127.0.0.1-2024-08-05-11:56:35]# ls
vmcore vmcore-dmesg.txt
[root@dlp2-99-230 127.0.0.1-2024-08-05-11:56:35]# pwd
/var/crash/127.0.0.1-2024-08-05-11:56:35
[root@dlp2-99-230 127.0.0.1-2024-08-05-11:56:35]# ls
vmcore vmcore-dmesg.txt
[root@dlp2-99-230 127.0.0.1-2024-08-05-11:56:35]# ll
总用量 1682440
-rw------- 1 root root 1722502368 8月 5 11:56 vmcore
-rw-r--r-- 1 root root 311479 8月 5 11:56 vmcore-dmesg.txt
[root@dlp2-99-230 127.0.0.1-2024-08-05-11:56:35]## 这里说明下:有可能不生成vmcore相关文件 是因为kdump时加载的 Modules 出现问题,可以罗列出module,把最可能有问题的三方模块进行屏蔽,使用blacklist命令,具体操作可以参考红帽的官方文档说明
[root@dlp2-99-230 127.0.0.1-2024-08-05-11:56:35]# tail -n 30 vmcore-dmesg.txt # 相关模块
[ 296.149234] Modules linked in: cfg80211 rfkill xt_multiport iptable_raw ip_set_hash_ip ip_set_hash_net veth ipip tunnel4 ip_tunnel xt_set ip_set_hash_ipportnet ip_set_hash_ipportip ip_set_bitmap_port ip_set_hash_ipport ip_set dummy nvidia_uvm(OE) ip6table_nat nf_conntrack_ipv6 nf_defrag_ipv6 nf_nat_ipv6 ip6_tables iptable_mangle xt_comment xt_mark ipt_MASQUERADE nf_nat_masquerade_ipv4 nf_conntrack_netlink nfnetlink iptable_nat nf_nat_ipv4 xt_addrtype iptable_filter xt_conntrack nf_nat br_netfilter bridge LeoFS(OE) nfsv3 nfs_acl rpcsec_gss_krb5 auth_rpcgss nfsv4 yrfs_693(OE) yrfs_610(OE) dns_resolver LeoNET(POE) yrfs_63x(OE) nfs yrfs_6641(OE) lockd grace fscache tcp_diag inet_diag overlay(T) yrfs(OE) uio_pci_generic uio vfio_pci vfio_iommu_type1 vfio cuse fuse 8021q garp mrp stp llc bonding rdma_ucm(OE)
[ 296.149555] rdma_cm(OE) iw_cm(OE) ib_ipoib(OE) ib_cm(OE) nf_conntrack_ipv4 nf_defrag_ipv4 ip_vs_sh ip_vs_wrr ip_vs_rr ip_vs nf_conntrack ib_umad(OE) sunrpc dm_mirror dm_region_hash dm_log dm_mod iTCO_wdt iTCO_vendor_support skx_edac coretemp intel_rapl iosf_mbi kvm_intel kvm irqbypass crc32_pclmul ghash_clmulni_intel aesni_intel lrw gf128mul glue_helper ablk_helper cryptd pcspkr sg i2c_i801 lpc_ich joydev mei_me mei ipmi_si ipmi_devintf ipmi_msghandler acpi_power_meter knem(OE) ip_tables xfs libcrc32c nvidia_drm(POE) nvidia_modeset(POE) mlx5_ib(OE) ib_uverbs(OE) ib_core(OE) nvidia(POE) sd_mod crc_t10dif crct10dif_generic ast i2c_algo_bit drm_kms_helper ttm syscopyarea sysfillrect sysimgblt fb_sys_fops mlx5_core(OE) ahci crct10dif_pclmul crct10dif_common crc32c_intel libahci drm i40e megaraid_sas
[ 296.149872] mlxfw(OE) psample libata auxiliary(OE) devlink mlx_compat(OE) ptp pps_core drm_panel_orientation_quirks wmi nfit libnvdimm xpmem(OE)
[ 296.149929] CPU: 20 PID: 11510 Comm: bash Kdump: loaded Tainted: P OE ------------ T 3.10.0-1160.el7.x86_64 #1
[ 296.149962] Hardware name: Inspur SA5212M5/YZMB-00882-102, BIOS 4.0.3 03/29/2018
[ 296.149985] task: ffff90eb19a46300 ti: ffff90eb456d4000 task.ti: ffff90eb456d4000
[ 296.150008] RIP: 0010:[<ffffffffad274856>] [<ffffffffad274856>] sysrq_handle_crash+0x16/0x20
[ 296.150039] RSP: 0018:ffff90eb456d7e58 EFLAGS: 00010246
[ 296.150056] RAX: ffffffffad274840 RBX: ffffffffadae74a0 RCX: 0000000000000000
[ 296.150078] RDX: 0000000000000000 RSI: ffff90fc8e4138d8 RDI: 0000000000000063
[ 296.150099] RBP: ffff90eb456d7e58 R08: ffffffffade0487c R09: 00000000ffffffff
[ 296.150120] R10: 0000000000000df2 R11: 0000000000000df1 R12: 0000000000000063
[ 296.150142] R13: 0000000000000000 R14: 0000000000000004 R15: 0000000000000000
[ 296.150164] FS: 00007f62dc667740(0000) GS:ffff90fc8e400000(0000) knlGS:0000000000000000
[ 296.150188] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 296.150207] CR2: 0000000000000000 CR3: 0000001eeefe0000 CR4: 00000000007607e0
[ 296.150228] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[ 296.150251] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
[ 296.150272] PKRU: 55555554
[ 296.150282] Call Trace:
[ 296.150296] [<ffffffffad27507d>] __handle_sysrq+0x10d/0x170
[ 296.150315] [<ffffffffad2754e8>] write_sysrq_trigger+0x28/0x40
[ 296.150337] [<ffffffffad0c6d40>] proc_reg_write+0x40/0x80
[ 296.150357] [<ffffffffad04db50>] vfs_write+0xc0/0x1f0
[ 296.150375] [<ffffffffad04e92f>] SyS_write+0x7f/0xf0
[ 296.150395] [<ffffffffad593f92>] system_call_fastpath+0x25/0x2a
[ 296.150414] Code: eb 9b 45 01 f4 45 39 65 34 75 e5 4c 89 ef e8 e2 f7 ff ff eb db 0f 1f 44 00 00 55 48 89 e5 c7 05 81 36 7d 00 01 00 00 00 0f ae f8 <c6> 04 25 00 00 00 00 01 5d c3 0f 1f 44 00 00 55 31 c0 c7 05 fe
[ 296.151439] RIP [<ffffffffad274856>] sysrq_handle_crash+0x16/0x20
[ 296.152316] RSP <ffff90eb456d7e58>
[ 296.153205] CR2: 0000000000000000
[root@dlp2-99-230 127.0.0.1-2024-08-05-11:56:35]#
2、方案二 (验证次数较少) 修改kdumpctl
该方案的优势,是无需重启操作系统,即可再下一次崩溃时,生成对应的crash文件.
kdumpctl 工具用于管理 kdump 服务,允许管理员启动、停止、检查 kdump 的状态,并重新加载配置。、
2.1 替换cmdline
修改 kdump 的 cmdline 参数可以通过编辑相关配置文件来实现。把remove_cmdline_param()和append_cmdline()方法,直接修改成直接输出方式:即$cmdline的值就是BOOT_IMAGE=/vmlinuz-3.10.0-1160.el7.x86_64 root=UUID=87afdba4-8e9d-4349-a068-23ac53d18164 ro crashkernel=768M biosdevname=0 net.ifnames=0 rhgb quiet
[root@dlp2-99-230 127.0.0.1-2024-08-05-11:56:35]# cat /proc/cmdline
BOOT_IMAGE=/vmlinuz-3.10.0-1160.el7.x86_64 root=UUID=87afdba4-8e9d-4349-a068-23ac53d18164 ro crashkernel=768M biosdevname=0 net.ifnames=0 rhgb quiet
[root@dlp2-99-230 127.0.0.1-2024-08-05-11:56:35]#
# remove_cmdline_param <kernel cmdline> <param1> [<param2>] ... [<paramN>]
# Remove a list of kernel parameters from a given kernel cmdline and print the result.
# For each "arg" in the removing params list, "arg" and "arg=xxx" will be removed if exists.
remove_cmdline_param()
{local cmdline=$1shiftfor arg in $@; docmdline=`echo $cmdline | \sed -e "s/\b$arg=[^ ]*//g" \-e "s/^$arg\b//g" \-e "s/[[:space:]]$arg\b//g" \-e "s/\s\+/ /g"`doneecho $cmdline
}#
# This function appends argument "$2=$3" to string ($1) if not already present.
#
append_cmdline()
{local cmdline=$1local newstr=${cmdline/$2/""}# unchanged str implies argument wasn't thereif [ "$cmdline" == "$newstr" ]; thencmdline="${cmdline} ${2}=${3}"fiecho $cmdline
}
[root@dlp2-99-230 127.0.0.1-2024-08-05-11:56:35]# cat /proc/cmdline
BOOT_IMAGE=/vmlinuz-3.10.0-1160.el7.x86_64 root=UUID=87afdba4-8e9d-4349-a068-23ac53d18164 ro crashkernel=768M biosdevname=0 net.ifnames=0 rhgb quiet[root@dlp2-99-230 127.0.0.1-2024-08-05-11:56:35]# current_cmdline=$(cat /proc/cmdline)
[root@dlp2-99-230 127.0.0.1-2024-08-05-11:56:35]# echo "Current cmdline: $current_cmdline"
Current cmdline: BOOT_IMAGE=/vmlinuz-3.10.0-1160.el7.x86_64 root=UUID=87afdba4-8e9d-4349-a068-23ac53d18164 ro crashkernel=768M biosdevname=0 net.ifnames=0 rhgb quiet[root@dlp2-99-230 127.0.0.1-2024-08-05-11:56:35]# new_cmdline=$(remove_cmdline_param "$current_cmdline" "crashkernel")
[root@dlp2-99-230 127.0.0.1-2024-08-05-11:56:35]# echo "Cmdline after removing crashkernel: $new_cmdline"
Cmdline after removing crashkernel: BOOT_IMAGE=/vmlinuz-3.10.0-1160.el7.x86_64 root=UUID=87afdba4-8e9d-4349-a068-23ac53d18164 ro biosdevname=0 net.ifnames=0 rhgb quiet[root@dlp2-99-230 127.0.0.1-2024-08-05-11:56:35]# updated_cmdline=$(append_cmdline "$new_cmdline" "crashkernel" "768M")
[root@dlp2-99-230 127.0.0.1-2024-08-05-11:56:35]# echo "Updated cmdline: $updated_cmdline"
Updated cmdline: BOOT_IMAGE=/vmlinuz-3.10.0-1160.el7.x86_64 root=UUID=87afdba4-8e9d-4349-a068-23ac53d18164 ro biosdevname=0 net.ifnames=0 rhgb quiet crashkernel=768M
2.2 模拟crash
参考1.4模拟crash
该方案更加便捷,但是缺点也非常明显,不利于统一管理,也有可能会带来其他kdumpctl周边问题。
四、总结
针对公司近期遇到的Centos7.9操作系统kdump crash文件vmcore未生成问题,可能也有多种原因,针对该现象最好的办法就是分析日志,根据日志的异常,和kdump的实现原理去分析推测可能卡住的地方。具体的crashkernel预留可参考调整 crashkernel 参数https://blog.csdn.net/qq_28513801/article/details/140925575 如有任何疑问或需要进一步的帮助,请随时留言讨论。
相关文章:

Centos7.9操作系统kdump crash文件vmcore未生成问题
Centos7.9操作系统kdump crash文件未生成问题 一、背景说明1、问题背景 二、排查思路1、先了解下crashkernelcrashkernel设置方式示例如何配置crashkernel验证crashkernel配置 2、再了解下kdump2.1 Kdump 的基本概念2.1.1. 生产内核(Production Kernel)2…...

找不到符号 javax.servlet.WriteListener
1、问题 找不到符号2、原因 JDK1.8升级到高版本后,需要手动引入包。 在打包时,需要注意一下是否是在父类打包,而不是在某个model打包。 3、解决 引入 <dependency><groupId>javax.servlet</groupId><artifactId>…...

智能仪表板DevExpress Dashboard v24.1 - 新增级联参数过滤
使用DevExpress Analytics Dashboard,再选择合适的UI元素(图表、数据透视表、数据卡、计量器、地图和网格),删除相应参数、值和序列的数据字段,就可以轻松地为执行主管和商业用户创建有洞察力、信息丰富的、跨平台和设…...

计算机网络-CSP初赛知识点整理
历年真题 [2016-NOIP-普及-第3题] 以下不属于无线通信技术的是( ) A. 蓝牙 B. Wifi C. GPRS D. 以太网 [2015-NOIP-普及-第10题] FTP 可以用于( )。 A. 远程传输文件 B. 发送电子邮件 C. 浏览网页 D. 网上聊天 [2019-CSP-J-第1题] 中国的国家顶级域名是( ). A. .cn B. .ch C.…...

MySQL第1讲--详细安装教程和启动方法
文章目录 安装教程打开或关闭方式方式1:方式2: 客户端连接方式客户端连接方式1:客户端连接方式2:MySQL环境变量的配置 安装教程 1、mysql官网下载最新的符合本系统的版本 2、点击.msi文件进入安装页面 选择默认的选项开发者安…...
SQL创建数据表的一些语句
SQL创建数据表 /*Navicat Premium Data TransferSource Server : dockermysqlSource Server Type : MySQLSource Server Version : 80023Source Host : localhost:3306Source Schema : nestleTarget Server Type : MySQLTarget Server Version…...

Spring Boot实战:拦截器
一.拦截器快速入门 1.1了解拦截器 什么是拦截器: 概念 :拦截器是Spring框架提供的核⼼功能之⼀, 主要⽤来拦截⽤⼾的请求, 在指定⽅法前后, 根据业务需要执⾏预先设定的代码。 也就是说, 允许开发⼈员提前预定义⼀些逻辑, 在⽤⼾的请求响应前后执⾏. 也…...

<数据集>战斗机识别数据集<目标检测>
数据集格式:VOCYOLO格式 图片数量:7903张 标注数量(xml文件个数):7903 标注数量(txt文件个数):7903 标注类别数:43 标注类别名称:[F16, Mig31, F35, F18, SR71, A10, A400M, AG600, J20, F4, C17, Tor…...

【python】Python中位运算算法详细解析与应用实战
✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,…...

vba 保存word里面的图片_1分钟批量处理100张图片,有Word在
天下苦Word久矣!Word不仅是个码字工具,还是个排版工具,而Word在排版方面经常遇到的问题,恐怕说个三天三夜都说不完! 好不容易做完了100页的活动方案,交到处女座上司那里,他告诉我:“…...

Android进阶之路 - 字体加粗,定制化字体粗度
在客户端中不论是PC端,还是移动端主要价值之一就体现在用户交互方面,也就是用户体验了,接下来讲的是很常见的字体加粗问题 UI大找茬 深入浅出字体、字体库TextView文本渐变字体阴影、文字阴影字体加粗 - 定制化字体粗度 在开发中经常会遇到…...
ForkJoin框架的解析
Java 的 Fork/Join 框架是 Java 7 中引入的一种强大并发框架,旨在简化多线程编程,特别是对那些可以被递归地拆分成更小任务的任务。Fork/Join 框架的核心思想是将大任务拆分为多个小任务,并行运行这些小任务,然后将结果合并起来得…...

使用IDEA2019.1.4创建“hello world”java程序
使用IDEA创建“hello world”java程序分为4步: 创建工程->创建模块->创建库->创建类 1.创建工程 修改工程名称及地址 上步骤点击finish后,2019.1.4版本会自动弹出创建模块的窗口 2.创建模块 可以在上述窗口的基础上创建模块,也可…...

学习vue3 五,传送,缓存组件以及过渡和过渡列表
目录 Teleport传送组件 keep-alive缓存组件 transition动画组件 1. 过渡的类名 2. 自定义过渡class名 3. transition的生命周期 4.appear transition-group 1. 过渡列表 2. 列表的移动过渡 3. 状态过渡 Teleport传送组件 Teleport Vue 3.0新特性之一。 Teleport 是一…...

MyBatis快速学习
目录 前言 MyBatis的具体使用 一些小工具:MyBatisX 常见问题: 1.表中字段名和实体属性名不一致 2.按条件查询(单条件)时的,查询条件怎么编写 3.按条件查询(多条件) 4.多条件查询时&…...

24.8.3数据结构|双向循环链表、静态链表
双向循环链表 节点类型与双链表的节点类型完全相同双向循环链表的操作也与双链表的操作基本一致。 例题 将自然数一到N按由小到大的顺序沿顺时针方向围成一个圈,然后以一为起点先沿顺时针方向数到第N个数将其划去,再沿逆时针方向数到第K个数将其滑去&a…...

C语言典型例题28
《C程序设计教程(第四版)——谭浩强》 习题2.5 输入一个华氏温度,要求输出摄氏温度。公式为C5/9(F-32),要求输出要有文字说明,取两位小数 数学知识: (1)华氏温度与摄氏温度&#x…...

PHP企业培训考试系统小程序源码
🚀企业培训考试系统,赋能员工成长新引擎📚 🌱 开篇:解锁企业培训新篇章 在快速变化的商业环境中,员工的能力提升是企业持续发展的关键。🚀 传统的培训方式已难以满足现代企业的需求࿰…...

进程状态(三)----- linux 中具体的进程状态(下)
目录 前言1. T && t 状态2. X 与 Z 状态3. 孤儿进程 前言 继上一篇文章 进程状态(二)----- linux 中具体的进程状态(上) 介绍了 linux 系统中具体的 R、S、D 状态,而这篇文章继续介绍 linux 系统中剩下的三种…...
关系型数据库(RDBMS,Relational Database Management System)
关系型数据库(RDBMS,Relational Database Management System)是一种结构化数据存储系统,它使用表(Tables)、行(Rows)和列(Columns)的结构来组织和管理数据。关…...

无法与IP建立连接,未能下载VSCode服务器
如题,在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈,发现是VSCode版本自动更新惹的祸!!! 在VSCode的帮助->关于这里发现前几天VSCode自动更新了,我的版本号变成了1.100.3 才导致了远程连接出…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端
🌟 什么是 MCP? 模型控制协议 (MCP) 是一种创新的协议,旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议,它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...

如何将联系人从 iPhone 转移到 Android
从 iPhone 换到 Android 手机时,你可能需要保留重要的数据,例如通讯录。好在,将通讯录从 iPhone 转移到 Android 手机非常简单,你可以从本文中学习 6 种可靠的方法,确保随时保持连接,不错过任何信息。 第 1…...
Java 加密常用的各种算法及其选择
在数字化时代,数据安全至关重要,Java 作为广泛应用的编程语言,提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景,有助于开发者在不同的业务需求中做出正确的选择。 一、对称加密算法…...

IT供电系统绝缘监测及故障定位解决方案
随着新能源的快速发展,光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域,IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选,但在长期运行中,例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...

使用LangGraph和LangSmith构建多智能体人工智能系统
现在,通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战,比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...
git: early EOF
macOS报错: Initialized empty Git repository in /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/.git/ remote: Enumerating objects: 2691797, done. remote: Counting objects: 100% (1760/1760), done. remote: Compressing objects: 100% (636/636…...

9-Oracle 23 ai Vector Search 特性 知识准备
很多小伙伴是不是参加了 免费认证课程(限时至2025/5/15) Oracle AI Vector Search 1Z0-184-25考试,都顺利拿到certified了没。 各行各业的AI 大模型的到来,传统的数据库中的SQL还能不能打,结构化和非结构的话数据如何和…...
鸿蒙(HarmonyOS5)实现跳一跳小游戏
下面我将介绍如何使用鸿蒙的ArkUI框架,实现一个简单的跳一跳小游戏。 1. 项目结构 src/main/ets/ ├── MainAbility │ ├── pages │ │ ├── Index.ets // 主页面 │ │ └── GamePage.ets // 游戏页面 │ └── model │ …...