2010年12月8日水曜日

kdump on gentoo linux

Redhat や Ubuntu にはクラッシュダンプを取得できる仕組みが用意されている.
しかし,Gentoo Linux にはもちろんそんなものは用意されていないので自前で作ってみる.

クラッシュダンプを取得する仕組みは,だいたい以下のような感じ.

  1. Crash する
  2. CrashDump 取得用のカーネルの起動
  3. /proc/vmcore をコピー

CrashDump 取得用カーネルは kexec の仕組みを利用するので,まず kexec-tools をインストールします.

$ sudo emerge -av sys-apps/kexec-tools
あと,通常使用するカーネルのオプションで下記のものを有効にしておきましょう.

  • CONFIG_KEXEC=y
  • CONFIG_SYSFS=y
  • CONFIG_DEBUG_INFO=y
この設定でコンパイルしたものを準備しておき,起動オプションに crashkernel=128M を追加します.

kernel /kernel-x86_64-2.6.36-gentoo root=/dev/sda2 crashkernel=128M

なんで 128MB なのかは今後調べる.物理メモリがデカいとこの値も大きくしないと動作しないかも.
このオプションを追加して起動すると dmesg に次のメッセージがでるはずです.

Reserving 128MB of memory at 32MB for crashkernel

次のログが出てた場合は何かが失敗してます.
crashkernel reservation failed

次に CrashDump 取得用のカーネルの準備を行います.
このカーネルは余計な機能は使わないようにできるだけ最小構成にした方がいいと思われます.

とりあえず,下記のオプションが必要らしいです.
(全アーキテクチャ共通)

  • CONFIG_CRASH_DUMP=y
  • CONFIG_PROC_VMCORE=y

(for i386, x86_64)

  • CONFIG_HIGHMEM4G or CONFIG_HIGHMEM64G=y
  • CONFIG_SMP=n
  • CONFIG_RELOCATABLE=y
他のアーキテクチャで必要なオプションは Documentation/kdump/kdump.txt を参照してください.

カーネルの準備が終わったところで,クラッシュダンプを取得するスクリプトを作ります.

/etc/init.d/kdump
#!/sbin/runscript
LOGGER="/usr/bin/logger -p info -t kdump"
start() {
    if [ -s /proc/vmcore ]; then
        coredir="/var/crash/`date +"%Y-%m-%d-%H:%M"`"
        mkdir -p $coredir
        cp --sparse=always /proc/vmcore $coredir/vmcore-incomplete
        exitcode=$?
        if [ $exitcode == 0 ]; then
            mv $coredir/vmcore-incomplete $coredir/vmcore
            $LOGGER "saved a vmcore to $coredir"
        else
            $LOGGER "failed to save a vmcore to $coredir"
        fi
        reboot
    fi
}

CrashDump を取得するための runlevel を作ります.
別に runlevel にしなくてもいいんですが,なんとなくです.

 $ sudo install -d /etc/runlevels/crash
 $ sudo rc-update add syslog-ng crash
 $ sudo chmod +x /etc/init.d/kdump
 $ sudo rc-update add kdump crash

最後に CrashDump kernel をロードします.

 $ sudo kexec -p /boot/crashdump-kernel-x86_64-2.6.36-gentoo \
   --append='root=/dev/sda2 softlevel=crash'


これで用意が完了です.テストしてみます.

 $ echo -n c | sudo tee /proc/sysrq-trigger

しばらくすると,マシンがリブートします.
リブート後,/var/crash を確認すると vmcore というファイルができているはずです.

 $ ls -lh /var/crash/2010-12-08-12\:00
 -r-------- 1 root root 3.7G 11月 19 23:25 vmcore

これをデバッグするには,こんな感じです.
デバッグの仕方とかは DEBUG HACKS とかが参考になるんじゃないでしょうか.
 $ gdb /boot/kernel-x86_64-2.6.36-gentoo vmcore