さて。弊社的には明日 (7/1) から新しい会計年度 (FY14) が始まります。というわけで FY13 最後の投稿なのですが、ひとつ前の記事に続いて Azure 上の Linux 仮想マシンについて書きます。
※ 現象の説明はいいから対処法だけ教えろ!という方は記事の最後へジャンプしてください。
kernel.panic
Windows では STOP エラー(所謂「ブルースクリーン」)が発生した場合、メモリダンプをページファイルに書き込んで、その後自動的に再起動するというのがデフォルトの設定になっています。
STOP エラー時の設定 (Windows Server 2012)
Linux にも当然同様の仕組みがあって、たとえば再起動に関してはカーネルパラメータ “kernel.panic” で制御できます。デフォルト値はディストリビューションによるのだとは思いますが、Azure のプラットフォームイメージにある CentOS 6.3 や Ubuntu Server では、 “kernel.panic = 0” つまり、パニック時に自動再起動しないようになっています。
これは以下のコマンドで確認できます。
# sysctl kernel.panic
kernel.panic = 0
あるいは
# cat /proc/sys/kernel/panic
0
自動再起動を有効にしてみる
パニック時の自動再起動を有効にするには、 kernel.panic パラメーターに 0 以外の値を設定すれば OK です。たとえばパニック後 5 秒で再起動させるためには、 “kernel.panic = 5” を設定すれば良いわけです。
方法としては、
1. 一時的な設定(一度再起動すると元に戻る)
# echo 5 > /proc/sys/kernel/panic
2. 恒久的に有効な設定
/etc/sysctl.conf に “kernel.panic = 5” を設定
# vi /etc/sysctl.conf
sysctl.conf を読み込んで内容を有効化。
# sysctl –p
そして試してみると、あれ?
では、強制的にカーネルパニックを起こして、自動再起動を試してみましょう。
こんなコマンドを実行すると、 [Enter] を押した瞬間にカーネルパニックが発生し、ターミナルの応答がなくなります。
# echo c > /proc/sysrq-trigger
SSH のコネクションも切れました。
さて、1,2 分で起動してきますから、再度接続してみましょう。
・・・
あれ?固まってる?
ダンプキャプチャカーネルと Hyper-V のドライバ
実はこれ、クラッシュダンプの出力処理のところで、固まっているんです。Linux のクラッシュダンプ生成の仕組み (kdump) と、Hyper-V の準仮想化ドライバが関係しています。
まず、Hyper-V 側から。Azure 上の Linux VM は、つまり Hyper-V 上の Linux VM です。Hyper-V 上の Linux には、仮想化のオーバーヘッドを回避して効率よくディスクやネットワークのアクセスを行う準仮想化ドライバ (VSC: Virtulization Service Consumer) が動いています。
この VSC は、ペアレントパーティションの VSP (Virtualization Service Provider) と、VMBus と呼ばれる通信経路で結ばれています。VSP と VSC は、デバイスドライバを真っ二つに分割して間をバス(共有メモリ)で繋いだものといって良いかもしれません。いわゆる “split device driver model” というやつです。 Xen の準仮想化ドライバと似てますね。 Hyper-V では VMBus が XenBus と同じ役割を担います。
次に、Linux のクラッシュダンプ取得方式について。Linux では、クラッシュダンプの生成を、パニックしたカーネル自身ではなく、ダンプ用の別カーネル(ダンプキャプチャカーネル)に再起動することで行っています。パニックするような状態だから、ダンプの生成処理自体が正しく行えると期待するのは楽観的である、という思想だと思います。
で、ダンプ生成時には kexec という仕組みでダンプキャプチャカーネルを起動しますが、元のカーネルのメモリイメージは残っているわけで(そもそもそれをダンプするのが目的)、そこにはペアレントパーティションの VSP とつながっている VSC があるわけです。
ということは、ダンプキャプチャカーネルにもストレージ用の VSC (storvsc) が組み込まれていると、
VSP とうまく繋がらず、ディスク I/O ができない
という事象が発生します。絵にするとこんな感じでしょうか↓ (2008 年の Tech Ed で使った絵をいじりました。懐かしい…)
対処方法
この問題、 Hyper-V 上の Linux に関する KB2858695と同じ現象だと思われます。対処方法もこの KB の通りです。要はダンプキャプチャカーネルで準仮想化ドライバを使わないようにすれば良いのです。
Azure 上の CentOS に関しては、この KB 内の ”Red Hat Enterprise Linux (RHEL) 6.4” という部分の対処が効きます。 /etc/kdump.conf がこんな感じになれば OK です。
path /var/crash
core_collector makedumpfile -c --message-level 1 -d 31
extra_modules ata_piix sr_mod sd_mod
blacklist hv_vmbus hv_storvsc hv_utils hv_netvsc hid_hyperv
options ata_piix prefer_ms_hyperv=0
disk_timeout 100
他の Linux は?
Azure 仮想マシンのプラットフォームイメージには、 CentOS の他にもいくつかの Linux ディストリビューションが存在しますが、 CentOS 以外にはこの問題は存在しないようです。
# CentOS のイメージはただいま修正依頼中です。
関連情報
“Documentation for Kdump - The kexec-based Crash Dumping Solution”
http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/plain/Documentation/kdump/kdump.txt
“Can't use kdump or kexec for Linux virtual machines on Hyper-V”
http://support.microsoft.com/kb/2858695/en-us
「Linux 仮想マシンでのスワップ領域設定」 (前回の記事)
http://blogs.technet.com/b/ksasaki/archive/2013/06/21/linux.aspx
__END__