深入探索 Kdump,第 1 部分:帶你走進 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 執行流程
圖 1. RHEL6.2 執行流程 

圖 2. sles11 執行流程
圖 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。望拋磚引玉,對閱讀本文的讀者有益。


參考資料

學習

發佈了81 篇原創文章 · 獲贊 61 · 訪問量 25萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章