外付けUSBハードディスクドライブでRAIDを組む
Fedora 7が出たのを契機に自宅サーバのOSをFedora Core 5からDebian Etchに乗り換えたので、そのついでに色々と構成を変更することにした。
メインサーバは問題ないのだけど、サブサーバとして使っているマシン(NECのデスクトップ)の冷却性能が酷くて、内蔵ベイに二台以上HDDを突っ込むと温度が平気で60℃を超えてしまう。水冷なんてキワモノに手を出したのがいけなかったなあ。で、仕方ないので内蔵ベイに入れるHDDは一台にして、ちょうど余っていたUSB-IDE変換機を使ってもう一台のHDDを外付けにすることにした。
いつぞやの同時多発クラッシュを経験して以来RAIDでミラーを構成しないと精神的に落ち着かなくなってきたので、HDDを二台とも内蔵ベイに入れておいてRAIDを構成してからその上にOSをインストールしておいた。ちゃんとRAIDが動いているのを確認して電源を一旦落とし、一台を取り出して外付けに接続してから電源オン。
起動して
$ cat /proc/mdstat
してみたところ、外付けにしたHDDがRAIDに参加していないことが判明。なんでだー、と思いつつ、手動でre-addしてみる:
# mdadm --re-add /dev/md0 /dev/sda1
と、普通に参加してくれた。
いちおう、起動のたびに手動でre-addしてやればなんとかなるのだけど、いちいちやるのは面倒だということと、re-addのたびにresyncが始まってHDD全体のコピーが行われるのが良くないように思う。
いろいろ調べてみたところ(Linuxには不慣れなので、まずブートの仕組みから勉強しなおすことになった)、原因はブート時にmdadmが走るとき、USB storageがまだ認識されていないからみたいだ。mdadmによるRAIDの認識は当然ながらルートファイルシステムのマウントの前に行われるので、initramfsの中をいじらなければならない。
まず、USB HDDを認識するために必要なカーネルモジュールがinitramfs内でロードされているかチェック。
$ mkdir initramfs $ cd initramfs $ zcat /boot/initrd.img-2.6.18-4-686 | cpio -i 22930 blocks $ find lib/modules | grep usb lib/modules/2.6.18-4-686/kernel/drivers/usb lib/modules/2.6.18-4-686/kernel/drivers/usb/core lib/modules/2.6.18-4-686/kernel/drivers/usb/core/usbcore.ko lib/modules/2.6.18-4-686/kernel/drivers/usb/storage lib/modules/2.6.18-4-686/kernel/drivers/usb/storage/usb-storage.ko lib/modules/2.6.18-4-686/kernel/drivers/usb/input lib/modules/2.6.18-4-686/kernel/drivers/usb/input/usbhid.ko lib/modules/2.6.18-4-686/kernel/drivers/usb/host lib/modules/2.6.18-4-686/kernel/drivers/usb/host/ehci-hcd.ko lib/modules/2.6.18-4-686/kernel/drivers/usb/host/uhci-hcd.ko lib/modules/2.6.18-4-686/kernel/drivers/usb/host/ohci-hcd.ko
あるっぽい。うーん、なんでだめなんだ。
と思ったら、実はusb_storageは接続からマウントまで5秒ほど間をおくらしい。
毎日が撤退戦 - usb_storageマウント失敗
http://llama.logos.k.u-tokyo.ac.jp/~yokoyama/diary/archives/001966.php
これだー。というわけで、/etc/initramfs-tools/scripts/init-premountにsleep 10するスクリプトを置くことにしてみる。
# cd /etc/initramfs-tools/scripts/init-premount # vi usbstorage # chmod +x usbstorage # cat usbstorage #!/bin/sh PREREQS="" prereqs() { echo "$PREREQS"; } case "$1" in prereqs) prereqs exit 0 ;; esac . /scripts/functions log_begin_msg "Probing USB storage modules" sleep 10 log_end_msg
書き込んだら、
# update-initramfs -u
でinitramfsを再作成して再起動。これでめでたく起動時からRAIDが走ってくれた。