Bohumil Chalupa さんの Linux RAID メーリングリストへの投稿で,RAID1, 5 での mdstop の問題の回避方法です.この方法では,シャットダウンの時に RAID デバイスが壊れている可能性は想定していません.そこで,筆者がブー ト時の正常な参照ステータスを簡単に比較するようにしました.これにより, アレイに異常があるとき,オペレータが調整することができます.これについ ての詳細は本文中で述べています.
> From: Bohumil Chalupa <bochal@apollo.karlov.mff.cuni.cz> > > initrd と linuxrc を使ってRAID1 アレイを動かし,それから root を > /dev/md0 にうまく切替えることできました. > > しかし,アレイを正常に *止める* 方法はわかりません.
それでは,私がお答えしましょう :-)
> Date: Mon, 29 Dec 1997 02:21:38 -0600 (CST) > From: Edward Welbon <welbon@bga.com> > Subject: Re: dismounting root raid device > > RAID0 以外の md デバイスについては,全ての書き込みが終了していること > を知るためにステータスを保存すると思います.もちろん,このようなステー > タスはリードオンリーでマウントされるルートファイルシステムについては > 保存されません.このような場合,リードオンリーのルートファイルシステ > ムに書き込み可能なファイルシステム "X" をマウント可能で,"X" に書き > 込みができなくてはなりません("復旧"の操作でもこれを行いますが,こち > らは自動処理ではありません). > > ファイルシステム "X" は RAID(initrd 経由で linuxrc が実行)が初期ステー > タスを取得するブートデバイスと仮定します.幸い raid0 はステータス書 > き込みの必要がありません(mdstop の後に mdtab にチェックサムを書き出 > すことができれば嬉しいのですが). > とりあえずこれをいじってみますが,"devil" が常に "details" に含まれ > ますが,難しくはなさそうです.
そうですね. 私も同じアイディアを考えていたのですが,試す時間がありませんでした. それで,昨日やってみたところ,うまく動きました.
うちの RAID1(ミラー)では,チェックサムやRAIDのスーパーブロックのデータ の保存は行っていません."実際"のブートパーティションの情報,つまりルー トに割り当てた md ボリュームがシャットダウン時にリードオンリーで再マウ ントされたことだけを保存しています.そして,起動時に linuxrc スクリプ トがこの情報を見つければ mkraid --only-superblock を実行し,これが見つ からなければ ckraid を実行します. つまり,RAID のスーパーブロック情報はシャットダウン時には更新されず, 起動時に更新されます. あまりすっきりした方法でないのですが, :-( 動いてはいます.
私はRAIDデバイスをルートにして起動するために Edward Welbon さんの initrd.md と Slackware の組合せを使っています. 私の覚えている限りでは,修正したファイルは mkdisk, linuxrc とシャット ダウン用のスクリプト /etc/rc.d/rc.6 だけです. もちろん, lilo.conf は修正しました. 重要な部分をメールに添付しておきます. Bohumil Chalupa --------------- my.linuxrc follows ----------------- #!/bin/sh # we need /proc /bin/mount /proc # start up the md0 device. let the /etc/rc.d scripts get the rest of them # we should do as little as possible here # ________________________________________ # root raid1 shutdown test & recreation # /start must be created on the rd image in my.mkdisk echo "preparing md0: mounting /start" /bin/mount /dev/sda2 /start -t ext2 echo "reading saved md0 state from /start" if [ -f /start/root.raid.ok ]; then echo "raid ok, modyfying superblock" rm /start/root.raid.ok /sbin/mkraid /etc/raid1.conf -f --only-superblock else echo "raid not clean, runing ckraid --fix" /sbin/ckraid --fix /etc/raid1.conf fi echo "unmounting /start" /bin/umount /start # _________________________________________ # echo "adding md0 for root file system" /sbin/mdadd /dev/md0 /dev/sda1 /dev/sdb1 echo "starting md0" /sbin/mdrun -p1 /dev/md0 # tell kernel we want to switch to /dev/md0 as root device, the 0x900 value # is arrived at via 256*major_device_number + minor_device number. echo "setting real-root-dev" /bin/echo 0x900>/proc/sys/kernel/real-root-dev # unmount /proc so that the ram disk can be deallocated. echo "unmounting /proc" /bin/umount /proc /bin/echo "We are hopefully ready to mount /dev/md0 (major 9, minor 0) as root" exit --------------- end of my.linuxrc ---------------------------------- ----------- extract from /etc/rc.d/rc.6 follows ----------------- # Turn off swap, then unmount local file systems. echo "Turning off swap." swapoff -a echo "Unmounting local file systems." umount -a -tnonfs # Don't remount UMSDOS root volumes: if [ ! "`mount | head -1 | cut -d ' ' -f 5`" = "umsdos" ]; then mount -n -o remount,ro / fi # Save raid state echo "Saving RAID state" /bin/mount -n /dev/sda2 /start -t ext2 touch /start/root.raid.ok /bin/umount -n /start -------------- end of excerpt from rc.6 ------------------------ ------------------ part of my.mkdisk follows ---------------------- # # now we have the filesystem ready to be populated, we need to # get a few important directories. I had endless trouble till # I created a pristine mtab. In my case, it is convenient that # /etc/mdtab is copied over, this way I can activate md with # a simple "/sbin/mdadd -ar" in linuxrc. # cp -a $ROOT/etc $MOUNTPNT 2>cp.stderr 1>cp.stdout rm -rf $MOUNTPNT/etc/mtab rm -rf $MOUNTPNT/etc/ppp* rm -rf $MOUNTPNT/etc/termcap rm -rf $MOUNTPNT/etc/sendmail* rm -rf $MOUNTPNT/etc/rc.d rm -rf $MOUNTPNT/etc/dos* cp -a $ROOT/sbin $ROOT/dev $ROOT/lib $ROOT/bin $MOUNTPNT 2>>cp.stderr 1>>cp.stdout # _____________________________________________________________________ # RAID: will need mkraid and ckraid cp -a $ROOT/usr/sbin/mkraid $ROOT/usr/sbin/ckraid $MOUNTPNT/sbin 2>>cp.stderr 1>>cp.stdout # --------------------------------------------------------------------- # it seems that init wont come out to play unless it has utmp. this can # probably be pruned back alot. no telling what the real bug was 8-). # mkdir $MOUNTPNT/var $MOUNTPNT/var/log $MOUNTPNT/var/run $MOUNTPNT/initrd touch $MOUNTPNT/var/run/utmp $MOUNTPNT/etc/mtab chmod a+r $MOUNTPNT/var/run/utmp $MOUNTPNT/etc/mtab ln -s /var/run/utmp $MOUNTPNT/var/log/utmp ln -s /var/log/utmp $MOUNTPNT/etc/utmp ls -lstrd $MOUNTPNT/etc/utmp $MOUNTPNT/var/log/utmp $MOUNTPNT/var/run/utmp # # since I wanted to change the mount point, I needed this though # I suppose that I could have done a "mkdir /proc" in linuxrc. # mkdir $MOUNTPNT/proc chmod 555 $MOUNTPNT/proc # # ------------------------------------------------------ # we'll mount the real boot device to /start temporarily # to check the root raid state saved at shutdown time # mkdir $MOUNTPNT/start # ------------------------------------------------------- # # need linuxrc (it is, after all, the point of this exercise). # if [ -x ./my.linuxrc ]; then cp -a ./my.linuxrc $MOUNTPNT/linuxrc chmod 777 $MOUNTPNT/linuxrc else ln -s /bin/sh $MOUNTPNT/linuxrc fi # ----------------- part of my.mkdisk ends -----------------