转自:http://www.ibm.com/developerworks/cn/linux/l-cn-kdump1/index.html
Kdump是一种基于 kexec的
Linux内核崩溃捕获机制,将 kernel崩溃前的内存镜像保存,程序员通过分析该文件找出 kernel崩溃的原因,从而进行系统改进。本文首先介绍了
kdump的基本概念,其次以 RHE6.2和 SLES11为例介绍如何安装和配置
kdump。
Kdump 的基本概念
什么是 kexec ?
Kexec
是实现 kdump 机制的关键,它包括 2个组成部分:一是内核空间的系统调用 kexec_load,负责在生产内核(production
kernel或 first kernel)启动时将捕获内核(capture kernel或
sencond kernel)加载到指定地址。二是用户空间的工具 kexec-tools,他将捕获内核的地址传递给生产内核,从而在系统崩溃的时候能够找到捕获内核的地址并运行。没有 kexec就没有
kdump。先有 kexec实现了在一个内核中可以启动另一个内核,才让 kdump有了用武之地。kexec原来的目的是为了节省
kernel开发人员重启系统的时间,谁能想到这个“偷懒”的技术却孕育了最成功的内存转存机制呢?
什么是 kdump ?
Kdump
的概念出现在 2005
左右,是迄今为止最可靠的内核转存机制,已经被主要的 linux™厂商选用。kdump是一种先进的基于 kexec的内核崩溃转储机制。当系统崩溃时,kdump使用
kexec启动到第二个内核。第二个内核通常叫做捕获内核,以很小内存启动以捕获转储镜像。第一个内核保留了内存的一部分给第二内核启动用。由于 kdump利用 kexec启动捕获内核,绕过了
BIOS,所以第一个内核的内存得以保留。这是内核崩溃转储的本质。
kdump
需要两个不同目的的内核,生产内核和捕获内核。生产内核是捕获内核服务的对像。捕获内核会在生产内核崩溃时启动起来,与相应的 ramdisk一起组建一个微环境,用以对生产内核下的内存进行收集和转存。
如何使用 kdump
构建系统和 dump-capture内核,此操作有 2种方式可选:
1)构建一个单独的自定义转储捕获内核以捕获内核转储;
2)或者将系统内核本身作为转储捕获内核,这就不需要构建一个单独的转储捕获内核。
方法(2)只能用于可支持可重定位内核的体系结构上;目前 i386,x86_64,ppc64和
ia64 体系结构支持可重定位内核。构建一个可重定位内核使得不需要构建第二个内核就可以捕获转储。但是可能有时想构建一个自定义转储捕获内核以满足特定要求。
如何访问捕获内存
在内核崩溃之前所有关于核心映像的必要信息都用 ELF格式编码并存储在保留的内存区域中。ELF头所在的物理地址被作为命令行参数(fcorehdr=)传递给新启动的转储内核。
在 i386体系结构上,启动的时候需要使用物理内存开始的 640K,而不管操作系统内核转载在何处。因此,这个
640K的区域在重新启动第二个内核的时候由 kexec备份。
在第二个内核中,“前一个系统的内存”可以通过两种方式访问:
1.
通过 /dev/oldmem
这个设备接口。
一个“捕捉”设备可以使用“raw”(裸的)方式
“读”这个设备文件并写出到文件。这是关于内存的 “裸”的数据转储,同时这些分析
/ 捕捉工具应该足够“智能”从而可以知道从哪里可以得到正确的信息。ELF文件头(通过命令行参数传递过来的
elfcorehdr)可能会有帮助。
2.
通过 /proc/vmcore。
这个方式是将转储输出为一个 ELF格式的文件,并且可以使用一些文件拷贝命令(比如 cp,scp等)将信息读出来。同时,gdb可以在得到的转储文件上做一些调试(有限的)。这种方式保证了内存中的页面都以正确的途径被保存
(注意内存开始的 640K被重新映射了 )。
kdump 的优势
- 高可靠性
崩溃转储数据可从一个新启动内核的上下文中获取,而不是从已经崩溃内核的上下文。
- 多版本支持
LKCD(Linux Kernel Crash Dump),netdump,diskdump已被纳入
LDPs(Linux Documen-tation Project)内核。SUSE和 RedHat都对
kdump有技术支持。
Kdump 实现流程
图 1. RHEL6.2 执行流程
图 2. sles11 执行流程
配置 kdump
安装软件包和实用程序
Kdump
用到的各种工具都在 kexec-tools中。kernel-debuginfo则是用来分析 vmcore文件。从
rhel5 开始,kexec-tools已被默认安装在发行版。而 novell也在 sles10发行版中把
kdump集成进来。所以如果使用的是 rhel5和 sles10之后的发行版,那就省去了安装
kexec-tools的步骤。而如果需要调试 kdump生成的 vmcore文件,则需要手动安装
kernel-debuginfo包。检查安装包操作:
uli13lp1:/ # rpm -qa|grep kexec
kexec-tools-2.0.0-53.43.10
uli13lp1:/ # rpm -qa 'kernel*debuginfo*'
kernel-default-debuginfo-3.0.13-0.27.1
kernel-ppc64-debuginfo-3.0.13-0.27.1
参数相关设置
系统内核设置选项和转储捕获内核配置选择在《使用 Crash工具分析 Linux dump文件》一文中已有说明,在此不再赘述。仅列出内核引导参数设置以及配置文件设置。
修改内核引导参数,为启动捕获内核预留内存
通过下面的方法来配置 kdump使用的内存大小。添加启动参数"crashkernel=Y@X",这里,Y是为
kdump 捕捉内核保留的内存,X是保留部分内存的开始位置。
· 对于 i386和 x86_64,编辑
/etc/grub.conf,在内核行的最后添加"crashkernel=128M"。
· 对于 ppc64,在 /etc/yaboot.conf最后添加"crashkernel=128M"。
在 ia64,编辑 /etc/elilo.conf,添加"crashkernel=256M"到内核行。
kdump配置文件
kdump的配置文件是 /etc/kdump.conf(RHEL6.2);/etc/sysconfig/kdump(SLES11
sp2)。每个文件头部都有选项说明,可以根据使用需求设置相应的选项。
启动 kdump 服务
在设置了预留内存后,需要重启机器,否则 kdump是不可使用的。启动 kdump服务:
Rhel6.2:
#chkconfig kdump on
#service kdump status
Kdump is operational
#service kdump start
SLES11SP2:
#chkconfig boot.kdump on
# service boot.kdump start
测试配置是否有效
可以通过 kexec加载内核镜像,让系统准备好去捕获一个崩溃时产生的 vmcore。可以通过
sysrq强制系统崩溃。
#echo c > /proc/sysrq-trigger
这造成内核崩溃,如配置有效,系统将重启进入 kdump内核,当系统进程进入到启动 kdump服务的点时,vmcore将会拷贝到你在
kdump配置文件中设置的位置。RHEL的缺省目录是 : /var/crash;SLES的缺省目录是
: /var/log/dump。然后系统重启进入到正常的内核。一旦回复到正常的内核,就可以在上述的目录下发现 vmcore文件,即内存转储文件。可以使用之前安装的 kernel-debuginfo中的
crash 工具来进行分析(crash的更多详细用法将在本系列后面的文章中有介绍)。
#crash /usr/lib/debug/lib/modules/2.6.17-1.2621.el5/vmlinux
/var/crash/2006-08-23-15:34/vmcore
crash> bt
...
载入“转储捕获”内核
需要引导系统内核时,可使用如下步骤和命令载入“转储捕获”内核:
kexec -p <dump-capture-kernel> \
--initrd=<initrd-for-dump-capture-kernel> --args-linux \
--append="root=<root-dev>init 1 irqpoll"
装载转储捕捉内核的注意事项:
- 转储捕捉内核应当是一个 vmlinux格式的映像(即是一个未压缩的
ELF映像文件),而不能是 bzImage格式; - 默认情况下,ELF文件头采用 ELF64格式存储以支持那些拥有超过
4GB内存的系统。但是可以指定“--elf32-core-headers”标志以强制使用
ELF32格式的 ELF文件头。这个标志是有必要注意的,一个重要的原因就是:当前版本的
GDB不能在一个 32位系统上打开一个使用 ELF64格式的
vmcore文件。ELF32格式的文件头不能使用在一个“没有物理地址扩展”(non-PAE)的系统上(即:少于
4GB 内存的系统); - 一个“irqpoll”的启动参数可以减低由于在“转储捕获内核”中使用了“共享中断”技术而导致出现驱动初始化失败这种情况发生的概率
; - 必须指定 <root-dev>,指定的格式是和要使用根设备的名字。具体可以查看
mount 命令的输出;“init 1”这个命令将启动“转储捕捉内核”到一个没有网络支持的单用户模式。如果你希望有网络支持,那么使用“init
3”。
后记
Kdump
是一个强大的、灵活的内核转储机制,能够在生产内核上下文中执行捕获内核是非常有价值的。本文仅介绍在 RHEL6.2和 SLES11中如何配置
kdump。望抛砖引玉,对阅读本文的读者有益。
参考资料
学习
- 参考 kdump 项目网站 Kdump。
- 参考 Linux 内核源代码下的 Documentation/kdump 文件获得更多关于 kdump 的信息。