一、kernel crash简介
内核崩溃是Linux系统中最严重的错误之一,通常会导致系统完全停止响应。可能的原因包括功能问题,内核运行异常,性能问题,软件bug,soft lockup,hard lockup等。
linux内核崩溃,会通过kdump机制生成一个内核转储文件vmcore,通过vmcore可分析出内核崩溃的原因。
二、kdump机制
Kdump 提供了一种机制在内核出现故障的时候把系统的所有内存信息和寄存器信息 dump出来成一个文件,后续通过 gdb/crash 等工具进行分析和调试。
Kdump使用kexec系统调用引导到第二个内核(捕获内核),而不需要重新引导,然后捕获崩溃内核内存的内容(崩溃转储或vmcore),并将其保存到一个文件中。第二个内核驻留在系统内存的保留部分中。
三、kdump的安装配置测试
3.1 kdump安装
yum install kexec-tools #安装kdump
systemctl enable kdump.service #使能kdump
systemctl status kdump #查看kdump服务器是否启动
3.2 kdump配置
3.2.1 预留内存配置方法
设置第二内核的预留内存,是通过crashkernel=参数来的,具体配置方法:
1.编辑/etc/default/grub文件,找到类似下面的这行,修改crashkernel=为期望的值
GRUB_CMDLINE_LINUX="net.ifnames=0 biosdevname=0 console=tty0 crashkernel=auto console=ttyS0,115200n8"
2.根据系统启动方式更新grub:
grub2-mkconfig -o /boot/grub2/grub.cfg #bios
grub2-mkconfig -o /boot/efi/EFI/redhat/grub.cfg #uefi
3.重启系统生效
4.查看当前的内核命令行:cat /proc/cmdline
3.2.2 预留内存设置方式
crashkernel=的参数设置方式:
crashkernel设置方式 |
示例 |
示例含义 |
auto |
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 |
3.2.3 auto预留内存:
根据体系架构和总的内存大小,自动预留内存的大小:
自动预留内存的最小阈值,如果系统的内存小于如下表中指定的内存,则需要手动预留内存:
3.2.4 估计kdump大小:
在规划和构建kdump环境时,有必要知道在生成转储文件之前需要多少空间。makedumpfile命令可以估计该大小:
# makedumpfile -f --mem-usage /proc/kcore
3.2.5 vmcore文件存储位置
默认情况下vmcore文件保存在本地文件系统中,通常在/var/crash目录下,可以通过在/etc/kdump.conf 文件中修改该路径path /xx/xxx。
如果希望vmcore文件存储在不同的分区,可以修改#ext4开头的某一行,且去掉注释。
如果希望vmcore文件直接写到设备上,使用#raw这一行 。
vmcore文件也可以不保存在本地,可配置为通过nfs或者ssh协议在网络上发送文件。相应的配置#nfs或者#ssh对应的行。
3.2.6 core收集器
为了减少vmcorew文件大小,可以允许指定一个外部应用程序(core collector)用于压缩数据和省略不相关的信息。目前,唯一完全支持的核心收集器是makedumpfile。对应到kdump.conf就是#core_collector这一行。
core_collector makedumpfile -l --message-level 7 -d 31
--message-level指定了信息收集的级别,1为只打印process indicator 日志信息,默认值为7,具体见下表:
Message | progress common error debug report
Level | indicator message message message message
---------+------------------------------------------------------
0 |
1 | X
2 | X
4 | X
* 7 | X X X
8 | X
16 | X
31 | X X X X X
-d 指定了kdump的过滤级别,具体见下表:
| cache cache
Dump | zero without with user free
Level | page private private data page
-------+---------------------------------------
0 |
1 | X
2 | X
4 | X X
8 | X
16 | X
31 | X X X X X
31表示过滤掉以上五种全部信息,这样kdump生成的速度就会更快,生成的vmcore文件也会较小。如果此处使用值0 ,表示不过滤任何信息,在kdump生成时,会记录主机当前的所有信息。这就是为什么在kdump生成时,有些主机只有几十M大小生成,有些主机确有几十 G大小的原因。
3.2.7 默认动作
kdump将直接保存coredump到特定的类型中,默认情况下,kdump将重启系统:default reboot,
在/etc/kdump.conf中可以进行配置,可选有:
- dump_to_rootfs: 尝试将核心转储保存到根文件系统。此选项与网络目标结合使用时特别有用:如果网络目标不可访问,此选项将配置 kdump 以在本地保存核心转储。系统随后重新启动。
- reboot: 重新启动系统,在此过程中丢失核心转储。
- halt: 停止系统,在此过程中丢失核心转储。
- poweroff: 关闭系统电源,在此过程中丢失核心转储。
- shell: 从 initramfs 中运行 shell 会话,允许用户手动记录核心转储。
3.3 测试kdump
查看kdump是否激活:
systemctl is-active kdump
手动触发crash:
echo 1 > /proc/sys/kernel/sysrq
echo c > /proc/sysrq-trigger