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 -----------------