次のページ 前のページ 目次へ

8. 付録 A. Bohumil Chalupa さんによる md0 のシャットダウン

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


次のページ 前のページ 目次へ