2006年07月11日

Linuxでクラッシュダンプを採取(4) 〜 セカンドカーネルがやるべきこと 〜

はてなブックマークに登録

前回はセカンドカーネルの起動オプションに init=[シェルスクリプト] をつけてクラッシュダンプを採取してみましたが、クラッシュしたシステムの制御をそのシステムディスク上のコマンド群に委ねるのは非常に危険です。なぜなら、シェルコマンド自体が正常に動く保証もなければ、ディスクをマウントできる保証もどこにもないからです。ファーストカーネルがこけてセカンドカーネルが起動したのはいいけれど、ディスクのマウントに失敗して止まってしまっては身も蓋もありませんよね。「じゃあどうすればいいの?」というのが今回の話題です。

kexec コマンドには initrd オプションがあります。initrd というのは皆様ご存じのあの仕組みです。
起動時にルートマウントするために必要なドライバを事前に読み込んでくれるあの仕組みです。
Linux 二段階ブートのファーストステップとなるあの仕組みです。(しつこい?)

通常は、カーネル起動時に initrd.gz もディスクからロードされて RamDisk に展開されるわけですが、kexec コマンドで initrd オプションを指定すると、セカンドカーネルと一緒に initrd イメージをメモリ上にロードしてくれます。そのため、ディスクコントローラがハングアップしたりして、ディスクアクセスが一切出来なくなった状態でカーネルパニックが発生したとしても、セカンドカーネルのブートシーケンスは正常に処理を続行することができます。(メモリが壊れたらどうすんねんって突っ込みは無しね(^^;

で、セカンドカーネルがやるべき事はたった一つ、「クラッシュダンプを確実に記憶媒体に書き込むこと」だけなので、ディスクが利用できる状況であればディスクに書き込み、そうでなければNICを初期化してDHCPでアドレスを取得し、サーバにファイル転送するような処理を書いてあげれば良さそうです。
それでもだめな場合は・・・・・どうすればいいんだろうなあ(^^;;

まあ、とりあえず initrd のイメージを作ってみたいと思います。


# dd if=/dev/zero of=initrd.second bs=512 count=8192
# mkfs -t ext2 -F initrd.second
# mount -o loop initrd.second /initrd
# wget http://busybox.net/downloads/busybox-1.2.0.tar.gz
# tar zxvf busybox-1.2.0.tar.gz
# make -C busybox-1.2.0 menuconfig
# make PREFIX=/initrd install
# vi /initrd/linuxrc
# chmod +x /initrd/linuxrc
# mkdir /initrd/sysroot
# umount /initrd
# gzip initrd.second
# mv initrd.second.gz /boot/



これでセカンドカーネル用に /boot/initrd.second.gz ができ上がりました。
これをロードするための kexec コマンドは以下のようになります。


kexec -p \
--args-linux \
--elf32-core-headers \
--initrd=/boot/initrd.second.gz \
--append="sysroot=/dev/sda3" \
/boot/vmlinuz-second



余談ですが、initrd のイメージを作る際には busybox がとても便利です。
busyboxmenuconfig では static リンクで必要な機能を組み込んでおきます。
今回書いてみた linuxrc で使ってるコマンドは、全て busybox の中に含まれています。

最後に linuxrc の内容を貼り付けますが、このスクリプトは少々動作確認が不完全(というか作りかけのテストスクリプト)なので、参考程度にとどめておいて下さい。(FTPPUT できなかった場合はどんな処理をするのがいいんだろうなあ・・・・ってまだ悩んでます(^^;


#!/bin/ash

echo "### Starting crash.initrd ###"
mount -t proc /proc /proc
for i in `cat /proc/cmdline`;do
e=`echo $i | egrep '\w+=.*'`
[ -z "$e" ] || eval export $e
done
COREFILE=vmcore.`date +"%Y%m%d%H%M%S"`

NET_UP() {
ETHDEV=`/sbin/ifconfig -a | /bin/grep ^eth | /bin/cut -f1 -d" "`
for nic in $ETHDEV; do ifconfig $nic up;done
sleep 5
for retry in 0 1 2;do
for nic in $ETHDEV; do
echo "[DHCP Request On $nic]"
udhcpc -i $nic -qn -s /etc/udhcpc.script > /dev/null 2>&1
status=$?
if [ "$status" != "0" ]; then
echo "DHCP Error - Status Code: $status"
sleep 5
else
return 0
fi
done
done
for nic in $ETHDEV; do ifconfig $nic down;done
return 1
}

NET_DOWN() {
ETHDEV=`/sbin/ifconfig -a | /bin/grep ^eth | /bin/cut -f1 -d" "`
for nic in $ETHDEV; do ifconfig $nic down;done
}

SendToServer() {
echo "Configuring Network......."
NET_UP || /bin/ash
SERVER=`cat /etc/dhcp_server`
echo "Send vmcore to $SERVER"
ftpput -u user -p passwd $SERVER $COREFILE /proc/vmcore
NET_DOWN
}

CopyToDisk() {
echo "### Mounting $sysroot......."
mount $sysroot /sysroot
if [ "$?" -eq "0" ]; then
sleep 5
echo "### vmcore -> $sysroot/$COREFILE"
cp /proc/vmcore /sysroot/$COREFILE && SendToServer
umount /sysroot
return 0
fi
SendToServer
}

if [ -z "$sysroot" ]; then
SendToServer
else
CopyToDisk
fi

echo "### Reboot Server"
echo s > /proc/sysrq-trigger;sleep 5
echo b > /proc/sysrq-trigger;sleep 5



klab_gijutsu2 at 07:47│Comments(0)TrackBack(0)

トラックバックURL

この記事にコメントする

名前:
URL:
  情報を記憶: 評価: 顔   
 
 
 
Blog内検索
Archives
このブログについて
DSASとは、KLab が構築し運用しているコンテンツサービス用のLinuxベースのインフラです。現在5ヶ所のデータセンタにて構築し、運用していますが、我々はDSASをより使いやすく、より安全に、そしてより省力で運用できることを目指して、日々改良に勤しんでいます。
このブログでは、そんな DSAS で使っている技術の紹介や、実験してみた結果の報告、トラブルに巻き込まれた時の経験談など、広く深く、色々な話題を織りまぜて紹介していきたいと思います。
最新コメント