linux的崩溃转储-kdump的艺术

时间:2023-01-25 16:51:25

kdump是专门用来进行崩溃转储,我第一次看到它的时候可是吃了不少苦头,本文首先谈谈我吃的那些苦头,然后谈谈之后的事情。
记得有一次,那时还在长春,我们经理让我将linux内存映像转储到磁盘,我当时的第一反应就是grep内核源代码,查找dump,结果找到的除了注释就 是不相关的东西,我想这下可麻烦了,然后我就开始在网上找资料,后来还是查linux的内核Documents的时候找到了kdump,这个项目是专门进 行内核转储的,它是基于kexec的,之后的事情就很明了了,我迫不及待的想看看它是怎么实现的,办法呢?当然是查源代码了,当时我想实现肯定在源代码里面有所体现,不过这次我不再傻乎乎的grep了,我似乎“聪明”了一些,我知道内核崩溃的时候最后好多都是panic,于是我就在panic里面找 linux的转储代码,结果呢,当然是一无所获。
项目紧迫,索性不找了,先实现了再说,也做一次知其然不知其所以然了。一切做完之后,还是觉得不甘心,一定要把原理搞清楚不可,猛然间想到了 kexec,kdump用的就是kexec,而kexec我是嗷嗷熟悉的啦,就是用一个新内核覆盖原有的内核,然后启动这个新内核,当然也可以不覆盖原内 核,也就是新内核可以载入到不同的位置,这样的话两个内核就可以同时存在了。这些我都明白,明白得很,可是,kdump毕竟是一种转储机制,而机制是要在 内核中实现的,心想kdump一定会在内核中实现,放心不下于是再查内核代码,还是没有找到,我对内核代码结构已经非常熟悉了,前后除了驱动和体系相关的部分读了好几遍了,我几乎时刻在跟踪linux的内核发展,这怎么可能呢?怎么可能有我找不到的代码呢,心里十分崩溃,内核还没有崩溃我先崩溃了...
在继续崩溃之前,回头想想内核的架构,想想内核设计的多么完美,这最起码能使我不再把自己崩溃归罪于内核,只能怪自己没有悟道内核的真谛而已。linux 的内核确实实现了机制,然后把策略留给用户来完成,但是机制就一定用代码实现吗?我之所以这么认为一看我就很嫩,代码只是一种表达的方式而已,有的时候如果能用一句话说情的事情而又可以用别的机制实现的事情,内核就没有必要再提供一种机制了,linux的紧凑性也就在此体现。实际上,kexec完全实现了 kdump,只是因为kexec和linux内核本身设计得简直好的没得说。
既然kexec可以将新的内核加载到任何一个位置,那么完全可以在需要转储的系统上预留一块连续的内存,然后等到需要转储这个系统的时候,比如系统崩溃,比如手动转储,在这个时候,我们可以将一个新的干净的内核载入到预留的那块内存,新内核本身用不完这块预留的内存,这个新内核启动以后要用很多内存,特别 是启动到用户空间时也需要内存,实际上以新内核为系统内核的系统内存就是这块预留的内存,但是新内核可以访问整个系统物理内存,这当然指的是需要转储的系统的内存加上新的内核的系统内存,这样的话就可以用kexec机制启动一个新的内核到一个不同的预留的位置,然后转储整个物理内存,这比以前的内核崩溃转储好的多,以前是在崩溃的内核中进行转储的,这个内核已经崩溃了,它的内部状态以及硬件状态是极其不确定的,在这种不确定的情况下,专储的映像难道可靠 吗?新的kdump机制巧妙的利用了kexec机制进行了安全的内核转储,设计上巧妙至极,既实现了和kexec并列的内核机制,又利用了已有的 kexec机制的代码,避免了冗余,kdump纯粹是kexec在新的逻辑上的运用,但是对于用户而言,它确实是一种机制,我们来看一幅图,简单的说明了内核转储时的情形:
linux的崩溃转储-kdump的艺术 新的内核在需要转储的系统预留的内存启动以后,照样启动到/sbin/init程序,也就是到了用户空间,到了用户空间就等于解放了系统,因为内核只提供 机制,真正的策略是用户空间实现的,既然到了用户空间,那么就可以应用各种策略了,比如我们可以用自己的方式转储内核,也可以直接访问/dev /oldmem或者/proc/vmcore来访问转储的内核,这就可以随意了。
技术很多时候只是一种技术,如果一种技术可以称为艺术的话,那么你千万不要把研究它认为是在工作,浪费时间,更多的是,研究它或者说仅仅欣赏它是对你情操的一种陶冶,如果非要我举个例子的话,那么我首推linux