在之前看到lkcd的时候看到说一般的unix内核都有“崩溃转储”机制,比如bsd,sloaris等等都有。这个崩溃转储机制可以在内核panic的时候生成一个内核转储文件,以便于内核开发维护人员通过这个“内核转储”文件分析问题所在。而说是linux没有这个机制。
一个sourceforge上的项目叫做lkcd的就是在做这个补空的工作。也在持续关注中,之后有了结果再总结吧。
今天无聊的时候想给本本配一个“基准”内核配置文件,以后升级内核的时候直接就可以用,至于添加新功能什么的再加。然后就一项一项的看的时候就发现一个所谓的kdump在内核配置里面出现了。位置在:Processor type and features->kernel crash dumps这个选项,虽然标明了是experimental,但是还是值得一看了。
所以看看内核文档先的结果就是有了下面的这篇蹩脚的翻译,自己看看罢,有空再改。以作存档。
如果转载,请注明出处。
内核文档:2.6.18.1/Documentation/kdump/kdump.txt
kdmp相关的文档-基于kexec的崩溃转储机制
================================================================
设计
======
当一个内核转储发生的时候Kdump使用kexec启动一个备份的内核。这个备份启动的内核只是使用少量的内存,并且这些内存由第一个内核提供。这样设计保证了第一个内核启动且正在运行中的DMA不会破坏第二个内核的运行。
在内核崩溃之前所有有关于核心映像的必要信息都用ELF格式编码并春出在保留的内存区域中。ELF头所在的物理地址被作为命令行参数(fcorehdr=)传递给新启动哦你过得内核。
在i386体系结构上,启动的时候需要使用物理内存开始的640K,而不管操作系统内核转载在何处。因此,这个640K的区域在重新启动第二个内核的时候由kexec备份。
在第二个内核中,“前一个系统的内存”可以通过两种方式访问:
- 第一种方式是通过/dev/oldmem这个设备接口。一个“捕捉”设备可以使用“raw”(裸的)方式“读”这个设备文件并写出到文件。这是关于内存的 “裸”的数据转储,同时这些分析/捕捉工具应该足够“智能”从而可以知道从哪里可以得到正确的信息。ELF文件头(通过命令行参数传递过来的 elfcorehdr)可能会有帮助。
-第二种方式就是通过/proc/vmcore。这个方式是将转储输出为一个ELF格式的文件,并且可以方便使用一些文件拷贝命令(比如cp,scp等等)将信息读出来。同时,gdb可以在得到的转储文件上做一些调试(有限的)。这种方式保证了内存中的页面都以正确的途径被保存。(注意内存开始的640K被重新映射了)
安装/设置
=====
1)使用root用户登录系统。
2)下载upstream kexec-tools用户空间包,下载地址:
3)解包:
tar xvpzf kexec-tools-1.101.tar.gz
4) 从下列地址得到最新的Kdump补丁。
如果所有关于用户空间支持kdump的补丁都已经集成到了upstream kexec-tools中那么这一步可以被省略。
5) cd到解包得到的目录:
cd kexec-tools-1.101
6)使用patch命令应用补丁:
patch -p1 < /path-to-kdump-patch/kexec-tools-1.101-kdump.patch
(注意使用正确的补丁目录和补丁文件)
7)配置这个包,使用如下命令:
./configure
8) 编译包:
make
9) 安装这个包:
make install
下载并构建系统内核和“转储-捕捉”内核
------------------------------------------------------
下载内核主版本树上的源码(从),注意选择合适版本的内核(高于2.6.13-rc1版本)。
需要编译两个内核:一个“系统内核”和一个“转储捕捉”内核。
要使这个特性得以实现并工作需要相应的编译两个内核。
遵照以下的步骤以配置内核使用合适的kexec和Kdump功能:
系统内核
---------
1)编译内核时要确认选中了“kexec system call”选项(在“处理器类型和功能”区域)。
CONFIG_KEXEC=y
2)编译内核时要确认选中了“s)ysfs file system support”(在“文件系统”->“伪文件系统”区域)。这通常是默认选中的。
CONFIG_SYSFS=y
注意:在“Configure standard kernel features (for small systems)”没有被使能(在“General Setup”区域)时“sysfs file system support”可能出现在“Pseudo filesystems"菜单中。在这种情况下,检查.config文件以确保sysfs被打开。可以参考:
grep 'CONFIG_SYSFS .config
3) 在“kernel hacking”区域中选中“Compile the kernel with debug info”:
CONFIG_DEBUG_INFO=Y
这样就可以使编译内核的时候带上调试用的符号,转储分析工具需要一个带有调试信息的vmlinux(内核文件)来调试分析转储文件。
4)编译内核和模块并安装之。更新启动管理器(比如grub,lilo,yaboot等等)的配置文件。
5)引导系统内核时使用引导参数:crashkernel=Y@X。
注意要使用合适的X和Y的值。Y的值表示要为第二个内核保留多少内存,X的值表示保留的内存区开始的物理地址。例如:crashkernel= 64M@16M 告诉系统内核保留64MB内存给“转储捕捉内核”使用,这64MB内存从物理地址0x01000000开始。
在x86和x86_64平台上,使用"crashkernel=64M@16M"。
在ppc64平台上,使用"crashkernel=128M@32M"。
转储捕获内核
-----------------------
1)在“general setup”选项下,附加“-kdump”到“Local version”后面。
2)在x86平台上,在“Processor type and features”选项下使能高端内存支持:
CONFIG_HIGHMEM64G=y
或者:
CONFIG_HIGHMEM4G=y
3)在x86平台上,去掉对称多处理器的支持,在“Processor type and features”:
CONFIG_SMP=n
(如果不小心设置成了y,那么在启动转储捕获内核的时候给内核传递:maxcpus=1这样的命令行参数,参见“Load the Dump-capture Kernel”)
4)在ppc64平台上,去掉NUMA的同时加上EMBEDDED支持:
CONFIG_NUMA=n
CONFIG_EMBEDDED=y
CONFIG_EEH=N for 转储捕获内核
5)加上“kernel crash dumps”支持,位置在“Processor type and features”:
CONFIG_CRASH_DUMP=y
6)为“Processor type and features”->“Physical address where the kernel is loaded”设置合适的值。注意,这个选项只可能在选中了“kernel crash dumps”选项之后出现。默认值是0x1000000(16MB)。这个值应当和上面讨论到的命令行选项“crashkernel=Y@X”中的“X” 的值相对应。
在x86和x86_64平台上,使用“CONFIG_PHYSICAL_START=0x1000000”
在ppc64平台上,当CONFIG_CRASH_DUMP被设置了那么就会自动给这个值赋值为32MB
7)可选择的使能“/proc/vmcore support”(在“Filesystems”->“Pseudo
filesystems”选项下)。
CONFIG_PROC_VMCORE=y
(CONFIG_PROC_VMCORE 是在打开“CONFIG_CRASH_DUMP”选项时自动打开的一个选项。)
8)编译并安装内核和模块。但是:__不要__将这个内核加入到启动管理器可管理的内核列表中。
载入“转储捕捉”内核
====================
当载入系统内核之后,使用如下步骤和命令载入“转储捕捉”内核:
kexec -p \
--initrd= --args-linux \
--append="root= init 1 irqpoll"
关于装载“转储捕捉”内核的注意事项:
*<转储捕捉内核>应当是一个vmlinux格式的映像(即就是一个未压缩的ELF映像文件)而不能是bzImage格式。
* 默认情况下,ELF文件头采用ELF64格式存储以支持那些拥有超过4GB内存的系统。但是可以指定“--elf32-core-headers”标志以强制使用ELF32格式的ELF文件头。这个标志是有必要注意的,一个重要的原因就是:当前版本的GDB不能在一个32位系统上打开一个使用ELF64格式的vmcore文件。ELF32格式的文件头不能使用在一个“没有物理地址扩展”(non-PAE)的系统上。(即是说,少于4GB内存的系统)
*一个“irqpoll”的启动参数可以减低由于在“转储捕获内核”中使用了“共享中断”技术而导致出现驱动初始化失败这种情况发生的概率。
*必须指定,指定的格式是和要使用根设备的名字。具体可以查看mount命令的输出。
*“init 1”这个命令将启动“转储捕捉内核”到一个没有网络支持的单用户模式。如果你希望有网络支持,那么使用“init 3”。
内核失败
========
当使用上面提到的步骤成功地载入了“转储捕捉内核”之后,“系统崩溃”事件被触发之后系统将重启到“转储捕捉内核”。触发点将被放置到内核的“panic()”函数,“die()”函数,“die_nmi()”函数和sysrq(ALT+SysRq+c)处理句柄中。
如下所列的一些情况将会触发“系统崩溃事件”:
如果一个硬锁定被探测到并且“NMI watchdog”配置了,那么系统将会重启到“转储捕捉内核”。(die_nmi())
如果die()函数被调用,并且调用die()函数的线程恰好是pid为0或1;或者die()函数在一个中断处理上下文中被调用;或者die()函数被调用且“panic_on_oops”被设置了,那么系统都将重启到“转储捕捉内核”。
在一个powerpc的系统上,当一个“软重启”产生,die()函数将在所有的cpu上被调用并且系统将重启动到“转储捕捉内核”。
如果是为了测试,有三种方式可以采用:
a)使用“ALT+SysRq+c”组合键;
b)使用如下命令:echo c > /proc/sysrq-trigger;
c)自己写一个内核模块强制产生“内核失败”;
读出转储文件
============
在“转储捕捉内核”启动完毕之后,使用如下命令以读出并保存“转储文件”:
cp /proc/vmcore
除此之外,也可以通过线性的访问/dev/oldmem这个设备从“转储的内存”中得到“裸数据”,参考如下命令:
mknod /dev/oldmem c 1 12
使用dd命令,加上适当的count参数,bs参数,跳到特定的产生dump的点。
使用如下命令可以看到整个内存:
dd if=/dev/oldmem of=oldmem.001
分析
==========
在开始分析“转储文件”之前,应该确定重启到一个稳定的内核。
可以使用GDB在“从/proc/vmcore拷贝得到的‘转储文件’”上做有限的分析。分析的时候需要“带有调试信息的vmlinux文件”(编译的时候带有-g选项),运行如下命令:
gdb vmlinux
追踪处理器0上的任务的栈调用,显示寄存器,显示内存内容等可以工作的很好。
注意:GDB不能分析x86平台上以ELF64格式产生的“内核转储文件”。在一个最大内存为4GB的系统上,可以通过在“转储捕捉内核”上指定“--elf32-core-headers”标志来使用ELF32格式的文件头。
也可以使用Crash工具集来分析Kdump产生的“内核转储文件”。Crash可以在Dave
Anderson的网站上找到,通过如下链接:
下一步工作
==========
1)提供内核页面过滤机制,这样可以通过去掉内存中的空白页面有效的减小“内核转储文件”的大小,
2)可重定位的内核可以有助于“崩溃转储”机制维护多个内核,并且“系统内核”就可以支持“捕捉转储”。
联系人
=======
Vivek Goyal (vgoyal@in.ibm.com)
Maneesh Soni (maneesh@in.ibm.com)
商标
========
Linux 是Linus Torvalds在美国或其他国家的一个商标。
Kdump
Kdump is a kexec based crash dumping mechansim for Linux. Kdump functionality is broken mainly in two components, user space and kernel space. Kernel space patches are already part of main line kernel tree. User space component is nothing but a patch on top of existing kexec tools.
Currently i386, x86_64 and ppc64 ports of kdump are available.
This site has been designed to provide an easy access to kdump documentation, patches and test reports.
Documentation:
Following are few links which can help in understanding kexec/kdump.
1.
2. Reboot Linux Faster using kexec, Hariprasad Nellitheertha
3. Kdump - A kexec based dumping mechanism (Paper) - Vievek Goyal et al, OLS 2005
4. Kdump - A kexec based dumping mechanism (Presentation slides) - Vievek Goyal et al, OLS 2005
5. Documentation/kdump.txt in kernel source tree
Patches:
The latest kexec-tools tarball,
And kdump support is available in kexec-tools-testing git tree, available at
OR
git://git.kernel.org/pub/scm/linux/kernel/git/horms/kexec-tools-testing.git
The older pre-git patches can be found
How to Test:
Please refer to document for possbile steps to test kexec/kdump
Test Reports:
Please look at the various test reports
Automation Support:
A prototype is developed by for providing ease of use for kdump. It is always helpful if user need not be bothered to manually load the dump capture kernel and save the kdump manually. These prototypes are done for various distros as below
Debian:
The following set of patches made on mkinitrd (from initrd-tools package:version 0.1.82), forms a prototype for automation for kdump on Debian unstable. As these are not the only things needed for kdump integration, please refer the kdump documentations for more details about kdump setup.
This first patch (to be applied on the mkinitrd ver 0.1.82), would enable the generation of a special initrd for the dump capture kernel. This allows the dump capture kernel to automatically save the dump to the specified disk filesystem before the root file system is mounted. After copying the kdump, it will reboot the system back to a regular kernel. Thus it can solve the problem of not able to access the login prompt because of corrupted root filesystem.
Usage:
mkinitrd -c [dump_dev] -f [file_system] -o [out-file] [kernel-version]
The second patch would enable the user to generate the initrd for the first or the regular kernel. This initrd will package the second kernel or the dump capture kernel along with its initrd, the kexec-tools user space application (needed to load the dump capture kernel).
Usage:
mkinitrd -i [capture_initrd] -v [capture_kernel] -o [out_file] [kernel-version]
The user would then need to boot to the first kernel with this initrd. Incase of a panic/crash, the system will automatically boot to the capture kernel. The capture kernel's initrd will copy the dump and reboot the system back to regular kernel.
FC4:
This patch can provide auto capture for kdump to the specified disk file system
Usage:
mkinitrd [--dump-dev=
] [--dump-fs=] image kernel-version
RHEL4 U2:
This patch can provide auto capture for kdump to the specified disk file system
Usage:
mkinitrd [--dump-dev=] [--dump-fs=] image kernel-version
SLES9 SP2
This patch can provide auto capture for kdump to the specified disk file system
Usage:
mkinitrd [-v ] [-f ] -k kernel -i image