1. kdump基本原理
1.1 内核崩溃处理机制
当 Linux 系统内核发生崩溃时,通常会触发 panic,系统停止正常运行。Kdump 在这种情况下:
- 使用一个备用的内核(称为 crash kernel)来启动最小化的环境。
- 从崩溃的主内核中复制内存内容(转储文件)。
- 将转储文件保存到预定义的存储位置(如本地磁盘、网络服务器等)。
1.2 Crash Kernel 的作用
Kdump 的核心是依赖 Crash Kernel,这是一段预留的内存和独立的内核,用于在主内核崩溃后接管系统。
- 主内核崩溃后,控制权切换到 Crash Kernel。
- Crash Kernel 通过访问主内核的内存(物理地址)生成转储文件。
2 Kdump 的工作流程
2.1 内存预留
在系统启动时,通过内核参数(crashkernel)为 Crash Kernel 预留一部分内存(通常是 128M 或更多)。
编辑 GRUB 配置文件,添加 crashkernel 参数预留内存:
GRUB_CMDLINE_LINUX="crashkernel=256M"
2.2 Crash Kernel 加载
系统启动时,Crash Kernel 和主内核一起加载到内存中,但 Crash Kernel处于非活动状态。
2.3 触发崩溃
- 主内核发生崩溃(如 panic)
- 或人为触发崩溃(通过 echo c > /proc/sysrq-trigger)
2.4 Crash Kernel 启动
系统重启到 Crash Kernel 环境。
Crash Kernel 通过访问崩溃的主内核内存区域,捕获内存内容并保存。
2.5 保存转储文件
Crash Kernel 将捕获的内存转储文件(vmcore)保存到本地磁盘、NFS、或其他预定义路径。
3. Kdump 的配置
3.1 内核支持
Kdump 的关键组件是 kexec,它允许系统在内核崩溃时直接加载并启动一个新的内核(Crash Kernel)。因此,标准内核必须启用 kexec 功能。
检查是否启用了 kexec
可以通过以下命令检查是否启用了 kexec:
$ grep CONFIG_KEXEC /boot/config-$(uname -r)
CONFIG_KEXEC=y
如果没有启用,您需要重新编译内核并启用该功能,或者安装一个启用了该功能的预编译内核。
检查是否支持 crashkernel
通过检查内核配置文件(如 /boot/config-$(uname -r))确认是否启用支持:
$ grep CONFIG_CRASH_KEXEC /boot/config-$(uname -r)
CONFIG_CRASH_KEXEC=y
## 或者
CONFIG_CRASH_DUMP=y
CONFIG_CRASH_CORE=y
必须启用 CONFIG_DEBUG_INFO
CONFIG_DEBUG_INFO 配置项允许内核生成符号信息。启用此选项后,内核调试符号将被包含在内核映像中,这有助于分析 crash 工具生成的转储文件。
grep CONFIG_DEBUG_INFO /boot/config-$(uname -r)
CONFIG_DEBUG_INFO=y
3.1 下载工具
在基于 Ubuntu/Debian 或 RHEL/CentOS 的系统上,需要安装以下工具:
# Ubuntu/Debian
sudo apt install kdump-tools crash linux-crashdump
# RHEL/CentOS
sudo yum install kexec-tools crash
安装Kdump 时,弹出的GUI 界面都要选是。
3.2 确认内核参数
一般安装后,都会默认配置好内核参数。
确保grub 配置好了下面参数,如果没有配置,需要手动添加。
GRUB_CMDLINE_LINUX="crashkernel=256M"
同时另外一种确认方法是,重启后查看/proc/cmdline 中是否包含对应参数。
3.3 确认Kdump 服务是否启动
systemctl status kdump-tools
or
service kdump status
如果没有启动,请正常启动它。
sudo systemctl enable kdump-tools
sudo systemctl start kdump-tools
至此就完成了对应的配置。
4. 分析kdump 生成的vmcore 文件
4.1 触发崩溃
为了测试,我们可以手动触发奔溃, 如下命令:
## 如果 sysrq 被禁用,需要手动启用它以触发内核崩溃:
#echo 1 > /proc/sys/kernel/sysrq
echo c > /proc/sysrq-trigger
该指令会导致系统奔溃,并重启。
4.2 验证转储文件
不同系统会有不同的转储文件存储路径,我这边的机器是在下面着该路径:
ls /var/crash/202411261446
dmesg.202411261446 dump.202411261446
有dmesg 和 dump 文件, 器中dump 文件就是要分析的转储文件vmcore。 使用file 查看
$ file dump.202411261446
dump.202411261446: Kdump compressed dump v6, system Linux, node aa, ..., machine x86_64, domain (none)
4.3 查看vmcore 文件
crash /usr/lib/debug/boot/vmlinux-5.4.0-150-generic /var/crash/202411261446/dump.202411261446
crash> bt # 查看栈回朔信息
crash> log #打印系统消息缓冲区,如log | tail -n 30。
crash> ps #显示进程的状态,>表示活跃的进程,如ps | grep RU。
crash> sym #转换虚拟地址为符号。
crash> dis #对给定函数或者地址进行反汇编,如dis -l [func | addr]
5. 其它
5.1 关于/proc/sys/kernel/panic
生产环境:设为 5 或 10,快速恢复。
将 /proc/sys/kernel/panic 的值设置为 0 时,系统在发生 内核 panic 后不会自动重启,而是保持崩溃状态。这种行为适用于调试和分析内核崩溃问题,因为系统会保留现场,开发人员可以查看崩溃时的内存、寄存器和其他状态信息。
调试环境:设为 0,保留崩溃现场。
将 /proc/sys/kernel/panic 的值设置为 0 时,表示 系统在发生内核 panic 后,输出 panic 相关的日志信息到控制台(如堆栈回溯、错误原因等);会等待 1 秒钟,然后自动重启。
永久设置
$ sudo nano /etc/sysctl.conf
kernel.panic = 0
#重新加载配置
$ sudo sysctl -p
5.2 关于/proc/sys/kernel/sysrq
这一功能允许系统管理员通过特定的键盘组合或命令,向 Linux 内核发出紧急命令来执行一些低级操作,如重启、同步磁盘、杀死进程等,即使系统处于某种无法正常操作的状态时也能使用。
默认情况下,Linux 系统可能会禁用这一功能,出于安全考虑或为了防止误操作。
常见的 SysRq 操作
- Reboot (重启):Alt + SysRq + b 立即重启系统。
- Sync (同步磁盘):Alt + SysRq + s 将所有的文件系统缓存数据同步到磁盘,防止数据丢失。
- Unmount (卸载文件系统):Alt + SysRq + u 将所有挂载的文件系统标记为只读,确保在重新启动时不会发生数据损坏。
- Kill (杀死进程):Alt + SysRq + k 杀死当前用户的所有进程。
- Emergency Sync (紧急同步):Alt + SysRq + o 关闭系统并同步数据。
SysRq 级别
SysRq 的行为可以通过文件 /proc/sys/kernel/sysrq 中的值来控制。具体值如下:
- 0:禁用 SysRq。
- 1:启用基本的 SysRq 操作(例如重启、同步磁盘)。
- 2:启用更多高级操作(如卸载文件系统、杀死进程)。
- 3:启用所有 SysRq 操作,包括完整的内核调试命令等。
- 255: 全部功能都打开;
该值的不同位域表示不同的功能:
位Bit)位置 | 值/十进制 | 功能描述 |
---|---|---|
0 | 1 | 允许重启系统(b)。 |
1 | 2 | 允许控制控制台日志级别(0-9)。 |
2 | 4 | 允许同步磁盘(s)。 |
3 | 8 | 允许将文件系统切换为只读模式(u)。 |
4 | 16 | 允许内存信息转储(m)。 |
5 | 32 | 允许进程终止(f、k)。 |
6 | 64 | 允许显示任务列表(t)。 |
7 | 128 | 允许立即关闭系统(o)。 |
永久设置
sudo nano /etc/sysctl.conf
kernel.sysrq = 1
#重新加载配置
$ sudo sysctl -p
这将确保 kernel.sysrq 的值在每次系统启动时都被设置为 1。
方法 2:创建一个 sysctl.d 配置文件
sudo nano /etc/sysctl.d/99-sysrq.conf
kernel.sysrq = 1
## 重新加载 sysctl 设置
sudo sysctl --system
麒麟系统位于/etc/sysctl.d/10-magic-sysrq.conf.
5.3 关于/proc/sysrq-trigger使用
使用help 帮助
echo h > /proc/sysrq-trigger
dmesg #查看可以输入的参数
sysrq: HELP : loglevel(0-9) reboot(b) crash(c) terminate-all-tasks(e) memory-full-oom-kill(f) kill-all-tasks(i) thaw-filesystems(j) sak(k) show-backtrace-all-active-cpus(l) show-memory-usage(m) nice-all-RT-tasks(n) poweroff(o) show-registers(p) show-all-timers(q) unraw(r) sync(s) show-task-states(t) unmount(u) force-fb(V) show-blocked-tasks(w) dump-ftrace-buffer(z)
5.4 配置内核参数
当内核发生一些死锁,系统并不会重启,只会卡死。这种情况下并不会造成内核
panic,需要构造条件使内核panic,这样才能生成vmcore文件。
内核提供了多种场景构造panic
## 进程出现挂起时引发panic
echo 1 > /proc/sys/kernel/hung_task_panic
## 进程hangtask机制超时时间
echo 60 > /proc/sys/kernel/hung_task_timeout_secs
## 软锁(soft lockup)触发panic
echo 1 > /proc/sys/kernel/softlockup_panic
## 设置Kernel遇到OOM触发panic
echo 1 > /proc/sys/vm/panic_on_oom
## 设置内核中出现警告产生panic
echo 1 > /proc/sys/kernel/panic_on_warn
对应的sysctl.conf
kernel.hung_task_panic=1
kernel.hung_task_timeout_secs=60
kernel.softlockup_panic=1
vm.panic_on_oom=1
kernel.panic_on_warn=1