Root RAID HOWTO cookbook Michael A. Robinton, michael@bzs.org v1.08, April 02, 1998 藤原輝嘉, fjwr@mtj.biglobe.ne.jp 3 May 1998 この文書では RAID で構成したファイルシステムをルートディレクトリとして マウントするための方法と,Linux の initrd を使って対になる fallback 復 旧システムを作るための方法を述べます.RAID1 と RAID5 の md0 デバイスを 使用する完全な手順を示します.手順の各ステップと一緒にその目的も説明し ます.この版は RAID1 と RAID5 の設定向けの,3つの行で設定される ``/etc/raidboot.conf'' ファイルに合わせて設定した一般的な linuxrc ini- trd ファイルを含んでいます. ______________________________________________________________________ 目次 1. はじめに 1.1 本文書の最新版の入手 1.2 バグ 1.3 謝辞 1.4 著作権表示 2. 作業を始める前に必要な事項 2.1 必要なパッケージ 2.2 他の類似の実装系 2.3 ぜひ読んでおきたい文書 2.4 RAID 関連の情報 3. ルートディレクトリを RAID にする方法の概説 4. RAID をルートとしてマウントするための initrd の解説 4.1 セキュリティに関する注意事項 4.2 カーネルと RAID ツールの構築 4.3 initrd による復旧及び起動ファイルシステムの構築 4.4 ステップ・バイ・ステップの手順 4.5 ディストリビューションのインストール (Slackware の場合のみ) 4.6 Linux pthreads のインストール 4.7 RAID ツールのインストール 4.8 新しいファイルシステムからの不要なディレクトリとファイルの削除 4.9 /dev/mdx の作成 4.10 initrd のための裸のファイルシステム作成 4.10.1 起動/復旧用の initrd ファイルシステムの作成 4.10.2 復旧システムの修正 4.11 `initrd' で RAID デバイスから起動させる - linuxrc 4.12 シャットダウン用の rc スクリプトの修正 4.13 Configuring RAIDBOOT - raidboot.conf 4.14 復旧,RAID システムの 'loadlin と LILO' のカーネルパラメータ指定 5. 筆者の仕事用 RAID システムの設定 5.1 システムの仕様 同じマザーボードが入っている2つのシステムの設定を以下に示します. 5.2 ハードディスクのパーティション分割 6. RAID ファイルシステムの構築 6.1 /etc/raid5.conf 6.2 /etc/raid1.conf 6.3 仕事用 RAID ファイルシステムを構築するための具体的手順 7. 最後に注意する点 8. 付録 A. Bohumil Chalupa さんによる md0 のシャットダウン 9. シャットダウンスクリプトの例 9.1 Slackware - /etc/rc.d/rc.6 9.2 Debian bo - /etc/init.d/halt and /etc/init.d/reboot 9.2.1 /etc/init.d/halt 9.2.2 /etc/init.d/reboot 10. 付録 C: その他の設定ファイル 10.1 linuxrc ANAME CDATA linuxrc file(REF)REF 10.2 loadlin -- linux.bat file - boot.par ANAME CDATA linux.bat file - boot.par(REF)REF 10.3 linuxthreads Makefile.diff ANAME CDATA linuxthreads Makefile.diff(REF)REF 10.4 raid1.conf ANAME CDATA raid1.conf(REF)REF 10.5 raid5.conf ANAME CDATA raid5.conf(REF)REF 10.6 raidboot.conf ANAME CDATA raidboot.conf(REF)REF 10.7 rc.raidown ANAME CDATA rc.raidown(REF)REF 11. 付録 D: 古い linuxrc とシャットダウンスクリプト 11.1 古いファイル - linuxurc 11.2 古いファイル - シャットダウンスクリプト 12. 付録 E: Gadi 氏の RAID 停止に関するLinux カーネルパッチ 13. 付録 F: rc.raidown 14. 付録 G: linuxrc の動作原理 ______________________________________________________________________ 1. はじめに 読者は色々なタイプの RAID の実装とそれらの利点や欠点をよくわかっている ものと仮定します.本文書はチュートリアルではなく,Linux システムで RAID をルートにマウントする方法の手順だけを示すものです.Linux の RAID について知るために必要な情報は全て文書内で直接示すか,参考文献として示 しています.ですから私に質問のメールを送るのはそれらをよく調べた上で 行ってください. 1.1. 本文書の最新版の入手 Root-RAID-HOWTO LaTeX (DVI や PostScript を作れます),テキスト,HTML の各フォーマット で入手できます. sunsite.unc.edu/mdw/HOWTO/ SGML と HTML 形式で入手できます. ftp.bizsystems.com/pub/raid/ 1.2. バグ この文書を書いている時点で,ルートにマウントした RAID デバイスが停止す る問題は完全には解決されていません.Ed Welbon さんが提案し,Bohumil Chalupa さんが実装した回避方法はこの文書に含まれています.これは RAID1 と RAID5 デバイスの場合に,毎ブート時の長い ckraid コマンドが必要では なくなるというものです.この回避方法を行わないと,システムを再起動する 度に md デバイスに対して ckraid が必要となります.これだと大きなアレイ の場合には,システムの性能が大幅に低下してしまいます.筆者の Pentium 166, メモリ 128M のシステム上で動作している 6G の RAID1 デバイスでは, 再起動の度に ckraid に30分以上もかかってしまいます :-( 転送速度 20MB/ 秒の SCSI アダプタに接続している 15ギガバイトの RAID5 アレイの場合は1 時間以上かかります. 回避方法というのは,シャットダウン時にアレイの状態を実際のブートデバイ スに保存して,ここに置いてある最初にシステムを構築した時の参照ステータ スと比較するものです.ステータスが再起動のときに一致していればアレイの スーパーブロックは次のブート時に再構築され,そうでなければオペレータに ステータスエラーを通知し,全ての RAID ツールが使用可能な復旧システムが 残されます. スーパーブロックを再構築することで,全てのドライブにOKの印を付けられて しまい,mdstop を実行せずにアレイの電源が切られたことがシステムに無視 されることが起こります.これは全てのドライブのステータスがシャットダウ ン時にOKである場合しか正しく動作しません.異常があるドライブでアレイが 動いている場合には,md デバイスを再スタートさせる前に異常なドライブを 取り除く必要があり,そうでなければデータが壊れてしまうことがあります. RAID0 の場合はシャットダウン前に mdstop を行う必要が無いので,上記のこ とはいずれもあてはまりません. この問題に対して最終的に提案された解は,initrd に似た finalrd と,デバ イスがリードオンリーの時はシャットダウン中に clean フラグを書き込む mdrootstopを導入することです.他の方法もきっとはあることでしょう. とにかく,今のところは問題を避けることはできています.この問題をもっと うまく解決されたらぜひ私にお知らせください. 1.3. 謝辞 以下の方々の文書やメールのおかげでこの文書が完成しました.アイディアの ほとんどは他の人のものをもらってきたもので,私はこれらを COOKBOOKの形 にまとめ,すぐに使えるようにしただけです. o Linas Vepstas さん の RAID HOWTO でほとんどのことを勉強させていただきました. o Gadi Oxman さん には「素人」のくだらない質問に答えていただきました. o Ed Welbon さん の素晴らしい initrd.md パッケージがきっかけでこの文書を書くことに なりました. o Bohumil Chalupa さん が 再起動時の「問題回避」を実装してくださったおかげで, 仕事の環境 でRAID をルートにマウントして使えるようになりました. o この他に色々な点この作業を助けてくださった方々. 1.4. 著作権表示 This document is GNU copyleft by Michael Robinton michael@bzs.org . Permission to use, copy, distribute this document for any purpose is hereby granted, provided that the author's / editor's name and this notice appear in all copies and/or supporting documents; and that an unmodified version of this document is made freely available. This document is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY, either expressed or implied. While every effort has been taken to ensure the accuracy of the information documented herein, the author / editor / maintainer assumes NO RESPONSIBILITY for any errors, or for any damages, direct or consequential, as a result of the use of the information documented herein. 2. 作業を始める前に必要な事項 RAID を設定し,運用するために必要なパッケージや,ほとんどの疑問に答え てくれる文書を以下に示します.簡単にでも良いですからこれらの資料には目 を通してください. 2.1. 必要なパッケージ まずは以下のパッケージの最新のバージョンを入手する必要があります. o RAID, initrd, /dev/loopx をサポートしている Linux カーネル 筆者は linux-2.0.33 を sunsite から入手しました. o raid145-971022-2.0.31 RAID1/4/5 のサポート を追加するパッチです. o raidtools-pre3-0.42 RAID のデバイスを作成,管理するためのツール(と文書)です. o ``Gadi 氏の RAID 停止パッチ'' を付録 E に含めています. o linuxthreads-0.71 スレッドの パッケージが必要です.ウェブブラウザは使えないので FTP をつかってく ださい. o インストールできる Linux のディストリビューション 筆者は Slackware-3.4 を使っ ています. 必要ではないけれど,役立つもの o raidboot-0.01.tar.gz 予め作成 されている RAID 復旧/起動システム 本文書における具体的な手順は上記のパッケージを前提にしています.パッ ケージのバージョンが更新されていたり,私と異なる Linux のディストリ ビューションを使っている場合には,具体的な手順を異なるかもしれません. パッチやツール等はバージョン 2.1 のカーネルでは異なる場合があります. 最新の文書を以下で確認してください. ftp.kernel.org/pub/linux/daemons/raid/ 2.2. 他の類似の実装系 私はモジュールは使わないで,必要なものは全てカーネルに組み込むことにし ました.私のカーネルイメージの大きさは,圧縮して 300k と少しです. 起動可能な RAID デバイスを作る別の方法として,Ed Welbon 氏 の initrd.md.tar.gz を見てください.こちらの方 法ではモジュールを使っています.モジュールを使ってとても小さいカーネル を作りたい場合には,このパッケージに含まれる簡単なスクリプトを見れば, どうすればよいかわかります. http://www.realtime.net/~welbon/initrd.md.tar.gz 2.3. ぜひ読んでおきたい文書 まず /usr/src/linux/Documentation/initrd.txt は読んでください. それから raidtools パッケージに付属の文書やマニュアルも読んでくださ い.特に man mdadd と QuickStart.RAID には目を通してください. 以下のものにも目を通しておくと良いでしょう. o BootPrompt-HOWTO o man lilo o man lilo.conf 2.4. RAID 関連の情報 o sunsite.unc.edu/mdw/HOWTO/mini/Software-RAID o www.ssc.com/lg/issue17/raid.html o linas.org/linux/raid.html o ftp.kernel.org/pub/linux/daemons/raid/ o www.realtime.net/~welbon/initrd.md.tar.gz o luthien.nuclecu.unam.mx/~miguel/raid/ 関係があるメーリングリストを以下に列挙します. o majordomo@nuclecu.unam.mx へ subscribe raiddevの内容のメールを送れば参加できます. 投稿は raiddev@nuclecu.unam.mx へ メールを送ります. o majordomo@vger.rutgers.edu へ subscribe linux-raidの内容のメールを送れば参加できます. 投稿は linux-raid@vger.rutgers.edu へメールを送ります. (これが最も活発なメーリ ングリストのようです) 3. ルートディレクトリを RAID にする方法の概説 復旧システムを試したり,構築したり,デバッグしたくない場合は, Slackware-3.4 に基づいて作った一般的なシステムを以下で入手してくださ い. ftp.bizsystems.com/pub/raid/raidboot-0.01.tar.gz そして,次の手順を実行します. o 使用するディスクのサポートを組み込み,RAID を有効にしたカーネルを構 築します o RAID アレイが正しく設定,マウントできるかテストします o RAID システム上に OS をインストールします o ルートデバイスとして /dev/md0 を参照するように fstab の内容を修正し ます.起動に必要なパーティションが fstab に含まれていることを確認し ます. o Modify your shutdown halt and reboot script(s) (mine is /etc/rc.d/rc.6) as shown in ``Modifying the rc-scripts for SHUTDOWN'' の記述にしたがって,マシンの停止及び再起動のスクリプト( 筆者のシステムでは /etc/rc.d/rc.6 です)を修正します. o 以下の手順に示すように,ファイルを作業用システムから,復旧システム と新しい RAID システムの両方にコピーします. cd /root/raidboot mkdir mnt gzip -d rescue.clean losetup /dev/loop0 rescue.clean mount /dev/loop0 mnt 次のようにファイルをコピーします. cp -p /etc/* mnt/etc cp -p /etc/rc.d/* mnt/etc/rc.d {or as appropriate for your system} cp -a /lib/modules/* mnt/lib/modules Linux のディストリビューションによっては,ルートファイルシステムの ro/rw ステータスを調べます.initrd 復旧システムの rc 起動スクリプトか らは,これを調べる部分を取り除く必要があります.``復旧システムの修正'' の章の手順を参照してください. devmd0/ がルートデバイスfstab になるよう fstab を修正します.起動に必 要なパーティションが fstab に含まれていることを確認しましょう. RAID から起動する設定を記述する /etc/raidboot.conf を作成します.この ファイルの最初の3行にはコメントを入れてはいけません.それ以降ならば問 題ありません. raidboot.conf /dev/sda1 /dev/sda2 raidboot raid5.conf # comments may only be placed 'after' the three # configuration lines. # # This is 'raidboot.conf' # # line one, the partition(s) containing the 'initrd' raid-rescue system # It is not necessary to boot from these partitions, however, # since the rescue system will not fit on floppy, it is necessary # to know which partitions are to be used to load the rescue system # # line two, the path to the raidboot config information # Where the shutdown status, etc... is located at boot time # It does NOT include the mount point information, only 'path' # /mntpoint/'path' # # line -3-, name of the raid configuration file # Current raid configuration file i.e. raid1.conf, raid5.conf 後はいくつかの作業を行えば,RAID システムの起動準備ができます. 付録 F で説明する,``rc.raidown'' ファイルを # 作成し,これを復旧,作 業,RAID の各システムの /etc/rc.d ディレクトリ # にコピーします.復旧 システムをアンマウントした後,これを圧縮します. umount mnt losetup -d /dev/loop0 mv rescue.clean rescue gzip rescue 復旧ファイルを RAID 起動パーティションにコピーします. cp rescue.gz /mnt_point(1)/raidboot cp rescue.gz /mnt_point(2)/raidboot RAID アレイを有効にします. mdadd -ar RAID 起動パーティションの 正しい 参照ステータスを保存します. cat /proc/mdstat | grep md0 > /mnt_point(1)/raidboot/raidgood.ref cat /proc/mdstat | grep md0 > /mnt_point(1)/raidboot/raidgood.ref 最後に ``起動時の設定パラメータ'' の説明に従って起動プログラムを設定 し,RAID アレイ上のシステムを起動します. 4. RAID をルートとしてマウントするための initrd の解説 これは RAID の復旧ツール(rescue tools) を含む `initrd' RAMディスクを作 るための手続きです. 本文書では特に RAID1 と RAID5 の実装について説明を行います. 4.1. セキュリティに関する注意事項 復旧用のファイルシステムはスタンドアロンで使用できます.RAID アレイの マウントに失敗した場合,復旧システムがマウントされて動作します.ですか らセキュリティには十分注意してください! 4.2. カーネルと RAID ツールの構築 最初の作業は,パッチを当ててカーネルを再構築することと RAID 操作ツール に慣れることです.付録 E の ``Gadi 氏の RAID 停止パッチ'' を確認し, カーネルに含めてください.設定を行ってから RAID デバイスをマウント,テ ストします.詳細な手順は raidtools パッケージに含まれていますが,本文 書でも後で述べます. 4.3. initrd による復旧及び起動ファイルシステムの構築 私は復旧/起動用のファイルシステムと仕事用のマシンのファイルシステムを 構築する際に Slackware-3.4 ディストリビューションを使いました.です が,どの Linux ディストリビューションでも問題ないと思います.異なる ディストリビューションを使う場合には,手順のうち Slackware に特化した 部分を確認し,必要に応じて修正してください. 筆者は loadlin を使ってカーネルイメージとRAMディスクを DOS パーティ ションから起動していますが,これは,単に DOS の設定ソフトウェアを使う 困ったデバイスを使っているからです.LILO でもうまく動作しますし,RAID/ 起動ファイルと lilo レコードだけを含む小さい Linux パーティションも使 用できます. 筆者は最初に Slackware の `setup' スクリプトを使って最小限のRAMディス クシステムを作り,次にこのRAMディスク上の素のSlackware に `linuxthreads' パッケージと `raidtools' を上書きインストールすることに しました.私は仕事用のマシンを構築するときにも全く同じ手続きを用いまし た.ですから,復旧システムと仕事用システムはほぼ同じ構成になっていま す. このインストールによって`裸の'システムができます(ファイルのコピーを保 存しておきましょう).このシステムへ /lib/modules/2.x.x...... /etc .... with a modified fstab, mdtab, raidX.conf, raidboot.conf /etc/rc.d /dev/md* を現在使っているシステムから上書きコピーし,現在あるいはこれから動作さ せようとしているシステムに合わせてカスタマイズします. これにより,起動/復旧システムを現在動作している RAID デバイスをルート にマウントしたシステムと同じにできます.ライブラリ等のバージョンは常に 最新にできますが,少し小さいシステムになります. 4.4. ステップ・バイ・ステップの手順 ユーザ root のホームディレクトリ(/root)で以下のコマンドを実行します: cd /root mkdir raidboot cd raidboot マウントポイントを作成します. mkdir mnt mkdir mnt2 ファイルシステムをインストールするのに十分な大きさのファイルを作りま す.これは最終的な復旧ファイルシステムよりずっと大きくなります.16メガ バイトでは十分ではなかったので,私は24メガバイト使うことにしました. dd if=/dev/zero of=build bs=1024k count=24 ファイルを loop デバイスとし,ext2 ファイルシステムをこのファイル上に 作成します. losetup /dev/loop0 build mke2fs -v -m0 -L initrd /dev/loop0 mount /dev/loop0 mnt 4.5. ディストリビューションのインストール (Slackware の場合のみ) Slackware にしか通用しない話題なので,Slackware 以外のディストリビュー ションを使う場合には``次の章に進んで''ください. 現在は空のファイルシステムが作られてマウントされている状態です.ここ で"setup"を実行します. /root/raidboot/mnt を指定します.`source'には通常のインストール元を適宜指定します.パッ ケージ選択は自由に行ってかまいませんが,`configure' は行わないでくださ い. プロンプトのモードとしては `EXPERT' を選択します. 私はシステムの最小構成の `A', `AP', `N' に加え,使い慣れていてサイズも 小さいエディタ(vi, jed, joe)を選択しました. lqqqqqqqq SELECTING PACKAGES FROM SERIES A (BASE LINUX SYSTEM) qqqqqqqqk x lqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqk x x x [X] aaa_base Basic filesystem, shell, and utils - REQUIRED x x x x [X] bash GNU bash-1.14.7 shell - REQUIRED x x x x [X] devs Device files found in /dev - REQUIRED x x x x [X] etc System config files & utilities - REQUIRED x x x x [X] shadow Shadow password suite - REQUIRED x x x x [ ] ide Linux 2.0.30 no SCSI (YOU NEED 1 KERNEL) x x x x [ ] scsi Linux 2.0.30 with SCSI (YOU NEED 1 KERNEL) x x x x [ ] modules Modular Linux device drivers x x x x [ ] scsimods Loadable SCSI device drivers x x x x [X] hdsetup Slackware setup scripts - REQUIRED x x x x [ ] lilo Boots Linux (not UMSDOS), DOS, OS/2, etc. x x x x [ ] bsdlpr BSD lpr - printer spooling system x x x x [ ] loadlin Boots Linux (UMSDOS too!) from MS-DOS x x x x [ ] pnp Plug'n'Play configuration tool x x x x [ ] umsprogs Utilities needed to use the UMSDOS filesystem x x x x [X] sysvinit System V-like INIT programs - REQUIRED x x x x [X] bin GNU fileutils 3.12, elvis, etc. - REQUIRED x x x x [X] ldso Dynamic linker/loader - REQUIRED x x x x [ ] ibcs2 Runs SCO/SysVr4 binaries x x x x [X] less A text pager utility - REQUIRED x x x x [ ] pcmcia PCMCIA card services support x x x x [ ] getty Getty_ps 2.0.7e - OPTIONAL x x x x [X] gzip The GNU zip compression - REQUIRED x x x x [X] ps Displays process info - REQUIRED x x x x [X] aoutlibs a.out shared libs - RECOMMENDED x x x x [X] elflibs The ELF shared C libraries - REQUIRED x x x x [X] util Util-linux utilities - REQUIRED x x x x [ ] minicom Serial transfer and modem comm package x x x x [ ] cpio The GNU cpio backup/archiving utility x x x x [X] e2fsbn Utilities for the ext2 file system x x x x [X] find GNU findutils 4.1 x x x x [X] grep GNU grep 2.0 x x x x [ ] kbd Change keyboard mappings x x x x [X] gpm Cut and paste text with your mouse x x x x [X] sh_utils GNU sh-utils 1.16 - REQUIRED x x x x [X] sysklogd Logs system and kernel messages x x x x [X] tar GNU tar 1.12 - REQUIRED x x x x [ ] tcsh Extended C shell version 6.07 x x x x [X] txtutils GNU textutils-1.22 - REQUIRED x x x x [ ] zoneinfo Configures your time zone x x x mqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqj x `AP' シリーズからは私の好きなエディタ `JOE' とコンパクトで便利なファイ ル操作ツールである `MC' だけを選択しました.ここは必要に応じてユーティ リティを選択してください. lqqqqqqqqq SELECTING PACKAGES FROM SERIES AP (APPLICATIONS) qqqqqqqqqk x x [ ] ispell The International version of ispell x x x x [ ] jove Jonathan's Own Version of Emacs text editor x x x x [ ] manpgs More man pages (online documentation) x x x x [ ] diff GNU diffutils x x x x [ ] sudo Allow special users limited root access x x x x [ ] ghostscr GNU Ghostscript version 3.33 x x x x [ ] gsfonts1 Ghostscript fonts (part one) x x x x [ ] gsfonts2 Ghostscript fonts (part two) x x x x [ ] gsfonts3 Ghostscript fonts (part three) x x x x [ ] jed JED programmer's editor x x x x [X] joe joe text editor, version 2.8 x x x x [ ] jpeg JPEG image compression utilities x x x x [ ] bc GNU bc - arbitrary precision math language x x x x [ ] workbone a text-based audio CD player x x x x [X] mc The Midnight Commander file manager x x x x [ ] mt_st mt ported from BSD - controls tape drive x x x x [ ] groff GNU troff document formatting system x x x x [ ] quota User disk quota utilities x x x x [ ] sc The 'sc' spreadsheet x x x x [ ] texinfo GNU texinfo documentation system x x x x [ ] vim Improved vi clone x x x x [ ] ash A small /bin/sh type shell - 62K x x x x [ ] zsh Zsh - a custom *nix shell x x x mqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqj x `N' パッケージからは TCP/IP だけを入れました.これは必ずしも必要ではあ りませんが,非常に便利ですし,ルートに RAID アレイがマウントされていな い状態で復旧や更新の作業を行う際にネットワークにアクセスできるようにな ります.TCP/IP には `A' に含まれるアプリケーションのいくつかが使用する `biff' も含んでいます.`N' をインストールしなかったとしても,biff パッ ケージは入れたくなると思います. lqqqq SELECTING PACKAGES FROM SERIES N (NETWORK/NEWS/MAIL/UUCP) qqqqqk x lqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqk x x x [ ] apache Apache WWW (HTTP) server x x x x [ ] procmail Mail delivery/filtering utility x x x x [ ] dip Handles SLIP/CSLIP connections x x x x [ ] ppp Point-to-point protocol x x x x [ ] mailx The mailx mailer x x x x [X] tcpip TCP/IP networking programs x x x x [ ] bind Berkeley Internet Name Domain server x x x x [ ] rdist Remote file distribution utility x x x x [ ] lynx Text-based World Wide Web browser x x x x [ ] uucp Taylor UUCP 1.06.1 with HDB && Taylor configs x x x x [ ] elm Menu-driven user mail program x x x x [ ] pine Pine menu-driven mail program x x x x [ ] sendmail The sendmail mail transport agent x x x x [ ] metamail Metamail multimedia mail extensions x x x x [ ] smailcfg Extra configuration files for sendmail x x x x [ ] cnews Spools and transmits Usenet news x x x x [ ] inn InterNetNews news transport system x x x x [ ] tin The 'tin' news reader (local or NNTP) x x x x [ ] trn 'trn' for /var/spool/news x x x x [ ] trn-nntp 'trn' for NNTP (install 1 'trn' maximum) x x x x [ ] nn-spool 'nn' for /var/spool/news x x x x [ ] nn-nntp 'nn' for NNTP (install 1 'nn' maximum) x x x x [ ] netpipes Network pipe utilities x x x mqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqj x インストールが終了したら,それ以外の項目には全て `no' と答え(全ての設 定項目に `no' と答える),スクリプトを終了します. 4.6. Linux pthreads のインストール 次に`linuxthreads-0.71' ライブラリをインストールしなければなりません. ここでは手作業によるインストールを詳しく説明する代わりに,linuxthreads の Makefile に対する差分パッチを示します.元の Makefile を保存してから diff コマンドでパッチを当て,そして make を行います. cd /usr/src/linuxthreads-0.71 patch make make install -------------------diff Makefile.old Makefile.raid----------------- 2a3,13 > # If you are building "linuxthreads" for installation on a mount > # point which is not the "root" partition, redefine 'BUILDIR' to > # the mount point to use as the "root" directory > # You may wish to do this if you are building an 'initial ram disk' > # such as used with bootable root raid devices. > # REQUIRES ldconfig version 1.9.5 or better > # do ldconfig -v to check > # > BUILDIR=/root/raidboot/mnt > #BUILDIR= > 81,82c92,93 < install pthread.h $(INCLUDEDIR)/pthread.h < install semaphore.h $(INCLUDEDIR)/semaphore.h --- > install pthread.h $(BUILDIR)$(INCLUDEDIR)/pthread.h > install semaphore.h $(BUILDIR)$(INCLUDEDIR)/semaphore.h 84c95 < test -f /usr/include/sched.h || install sched.h $(INCLUDEDIR)/sched.h --- > test -f $(BUILDIR)/usr/include/sched.h || install sched.h $(BUILDIR)$(INCLUDEDIR)/sched.h 86,89c97,103 < install $(LIB) $(LIBDIR)/$(LIB) < install $(SHLIB) $(SHAREDLIBDIR)/$(SHLIB) < rm -f $(LIBDIR)/$(SHLIB0) < ln -s $(SHAREDLIBDIR)/$(SHLIB) $(LIBDIR)/$(SHLIB0) --- > install $(LIB) $(BUILDIR)$(LIBDIR)/$(LIB) > install $(SHLIB) $(BUILDIR)$(SHAREDLIBDIR)/$(SHLIB) > rm -f $(BUILDIR)$(LIBDIR)/$(SHLIB0) > ln -s $(SHAREDLIBDIR)/$(SHLIB) $(BUILDIR)$(LIBDIR)/$(SHLIB0) > ifneq ($(BUILDIR),) > ldconfig -r ${BUILDIR} -n $(SHAREDLIBDIR) > else 91c105,106 < cd man; $(MAKE) MANDIR=$(MANDIR) install --- > endif > cd man; $(MAKE) MANDIR=$(BUILDIR)$(MANDIR) install 4.7. RAID ツールのインストール インストールの次のステップは,RAID ツール raidtools-0.42 のインストー ルです. RAMディスクのファイルを構築するディレクトリを Makefile に教えるために "configure" スクリプトを実行します. cd /usr/src/raidtools-0.42 configure --sbindir=/root/raidboot/mnt/sbin --prefix=/root/raidboot/mnt/usr make make install ここで注意すべき点があります.インストールに使う Makefile は正しくない ので,これを直すために次の作業を行います.これは将来のリリースでは修正 され,再リンクは必要無くなる予定です. インストールエラーの修正 正しく操作するためには Makefile の `LINKS' で指定されているファイルの リンクを削除し,張り直さなければなりません. cd /root/raidboot/mnt/sbin ln -fs mdadd mdrun ln -fs mdadd mdstop 4.8. 新しいファイルシステムからの不要なディレクトリとファイルの削除 以下のディレクトリとファイルをファイルシステムから削除します. (注意: 誤って現在稼働中のシステムのファイルを消さないように.) このリストを見 てファイルを消すだけなら簡単ですが,私がこのリストをどうやって作ったの かも考えてください! cd /root/raidboot/mnt rm -r home/ftp/* rm -r lost+found rm -r usr/doc rm -r usr/info rm -r usr/local/man rm -r usr/man rm -r usr/openwin rm -r usr/share/locale rm -r usr/X* rm -r var/man rm -r var/log/packages rm -r var/log/setup rm -r var/log/disk_contents 4.9. /dev/md x の作成 最後のステップは,現在のファイルシステムから復旧ファイルシステムに /dev/md* デバイスをただコピーすることです.これは mknod でも行うことが できるでしょう. cp -a /dev/md* /root/raidboot/mnt/dev 4.10. initrd のための裸のファイルシステム作成 これでカスタマイズでき,再利用も可能なまっさらなファイルシステムができ ました.一度カスタマイズすると,復旧ディスクに使うことができるこのファ イルシステムは壊れてしまい,修正するためにはRAIDツールが必要となりま す.これは次の章で説明する linuxrc ファイルを追加することによって, ブートしてルートにマウントする RAID デバイスに使うこともできます. initrd ファイルのために小さいデバイスへシステムをコピーします.16メガ バイトもあれば十分でしょう. 小さいファイルシステムを作り,これをマウントします. cd /root/raidboot dd if=/dev/zero of=bare.fs bs=1024k count=16 ファイルを loop デバイスとし,このファイル上に ext2 ファイルシステム構 築します. losetup /dev/loop1 bare.fs mke2fs -v -m0 -L initrd /dev/loop1 mount /dev/loop1 mnt2 `build'ファイルシステムを`bare.fs'にコピーします. cp -a mnt/* mnt2 後の更新を容易にするため,カスタマイズの前に `bare.fs' システムを保存 します.`build' ファイルシステムはもう必要ありませんので,消しても構い ません. cd /root/raidboot umount mnt umount mnt2 losetup -d /dev/loop0 losetup -d /dev/loop1 rm build cp bare.fs rescue gzip -9 bare.fs 4.10.1. 起動/復旧用の initrd ファイルシステムの作成 次に,作業用のマシンからカーネルに適合するシステム依存のファイルをコ ピーするか,ターゲットのシステムに適合するように復旧ファイルシステムの ファイルを手で修正するかします. losetup /dev/loop0 rescue mount /dev/loop0 mnt etc ディレクトリに *~ ファイルや,core, ログファイルが無いことを確認し ます.次の2つのコマンドはいくつかウォーニングを出しますが,無視してく ださい. cp -dp /etc/* mnt/etc cp -dp /etc/rc.d/* mnt/etc/rc.d mkdir mnt/lib/modules cp -a /lib/modules/2.x.x mnt/lib/modules <--- your current 2.x.x 4.10.2. 復旧システムの修正 復旧システムの以下のファイルを修正します.ここで挙げるファイルの中には Slackware 特有のものもありますが,他のディストリビューションでも同等の ものがあるはずです. cd mnt ネットワーク関係でないもの etc/fstab etc/mdtab そのままで大丈夫でしょう ネットワーク関係 etc/hosts etc/resolv.conf etc/hosts.equiv 及び関連ファイル etc/rc.d/rc.inet1 IPアドレス,ネットマスク,ゲイトウェイの設定を修正します etc/rc.d/rc.S ファイルシステムのステータス関係の部分を全て削除します # Test to see if the root partition is read-only の部分から # remove /etc/mtab* so that mount will ..... を含まない部分までを削除します. これは RAMディスクが読み書き可能でマウン トされると出るうるさいウォーニングを出 ないようにします. etc/rc.d/rc.xxxxx 必要ならば他のファイルも.本文書で後述します root/.rhosts もし存在すれば home/xxxx/xxxx 必要ならば他のファイルも 警告: この作業で passwd と shadow のファイルは復旧システムに コピーされてしまいます!これはセキュリティ上の理由で好 ましくない場合もあるでしょう. 必要に応じて /dev/disk をマウントするためのディレクトリを作ります.こ れはシステムで一意に決まらなければなりません.これらはシステムを起動す るためのマウントポイント(起動パーティションと起動パーティションのバッ クアップ)になります.筆者のシステムは loadlin を利用して DOS から起動 するようになっていますが,Linux パーティションや LILO でもうまく動作し ます.筆者のシステムでは以下のようになっています. cd /root/raidboot/mnt <-- initrd のルート mkdir dosa DOS パーティションのマウントポイント mkdir dosb DOS のミラーのマウントポイント 復旧ファイルシステムはこれで出来上がりです! 復旧ファイルシステムのファイルを調べれば,まだ多くのファイルを消せるこ とが分かると思います.この作業は複雑すぎることと,ほとんどの RAID シス テムには十分なディスクとメモリがあることから,私はこれを行ってはいませ ん.ファイルシステムをもっとスマートにしたければ,ご自分でやってくださ い! 4.11. `initrd' で RAID デバイスから起動させる - linuxrc 復旧ディスクで RAID デバイスを起動するには,ただ次のスクリプトファイル linuxrc をデバイスのルートにコピーするだけです. この linuxrc ファイルの動作についての話は ``付録 G, linuxrc の動作につ いて''で議論します. もっと簡単で理解しやすい(動作もする) linuxrc は ``付録 D'' にあります が,これは古い linuxrc と停止スクリプトです.以下の部分を linuxrcとし て作業ディレクトリにコピーしておきましょう. -------------------- linuxrc ---------------------- #!/bin/sh # ver 1.13 3-6-98 # ################# BEGIN 'linuxrc' ################## # DEFINE FUNCTIONS # #################################################### # Define 'Fault' function in the event something # goes wrong during the execution of 'linuxrc' # FaultExit () { # correct fstab to show '/dev/ram0' for rescue system /bin/cat /etc/fstab | { while read Line do if [ -z "$( echo ${Line} | /usr/bin/grep md0 )" ]; then echo ${Line} else echo "/dev/ram0 / ext2 defaults 1 1" fi done } > /etc/tmp.$$ /bin/mv /etc/tmp.$$ /etc/fstab # point root at /dev/ram0 (the rescue system) echo 0x100>/proc/sys/kernel/real-root-dev /bin/umount /proc exit } # Define 'Warning' procdure to print banner on boot terminal # Warning () { echo '*********************************' echo -e " $*" echo '*********************************' } # Define 'SplitKernelArg' to help extract 'Raid' related kernel arguments SplitKernelArg () { eval $1='$( IFS=,; echo $2)' } #Define 'SplitConfArgs' to help extract system configuration arguments SplitConfArgs () { RaidBootType=$1 RaidBootDevice=$2 RaidConfigPath=$3 } ######################################################## ################### MAIN linuxrc ####################### ######################################################## # mount the proc file system /bin/mount /proc # Get the boot partition and configuration location from command line CMDLINE=`/bin/cat /proc/cmdline` for Parameter in $CMDLINE; do Parameter=$( IFS='='; echo ${Parameter} ) case $Parameter in Raid*) SplitKernelArg $Parameter;; esac done # check for 'required raid boot' if [ -z "${Raid_Conf}" ]; then Warning Kernel command line \'Raid_Conf\' missing FaultExit fi SplitConfArgs $Raid_Conf # tmp mount the boot partition /bin/mount -t ${RaidBootType} ${RaidBootDevice} /mnt # get etc files from primary raid system pushd /etc # this will un-tar into 'etc' (see rc.6) if [ ! -f /mnt/${RaidConfigPath}/raidboot.etc ]; then # bad news, this file should be here Warning required file \'raidboot.etc\' \ missing from ${RaidBootDevice}/${RaidConfigPath} \\n \ \\tUsing rescue system defaults else /bin/tar -xf /mnt/${RaidConfigPath}/raidboot.etc fi # get 'real' raidboot device for this boot # status path, and name of raidX.conf if [ ! -f /mnt/${RaidConfigPath}/raidboot.cfg ]; then # bad news, this file should be here Warning required file 'raidboot.cfg' \ missing from ${RaidBootDevice}/${RaidConfigPath}\\n \ \\tUsing rescue system defaults # Get the first raidX.conf file name in $RArg1 RaidBootDevs=$RaidBootDevice RaidStatusPath=$RaidConfigPath for RaidConfigEtc in $( ls raid*.conf ) do break; done else { read RaidBootDevs read RaidStatusPath read RaidConfigEtc } < /mnt/${RaidConfigPath}/raidboot.cfg fi popd /bin/umount /mnt # Set a flag in case the raid status file is not found # RAIDOWN="raidboot.ro not found" RAIDREF="raidgood.ref not found" echo "Reading md0 shutdown status." # search for raid shutdown status for Device in ${RaidBootDevs} do # these filesystem types should be in 'fstab' since # the partitions must be mounted for a clean raid shutdown /bin/mount ${Device} /mnt if [ -f /mnt/${RaidStatusPath}/raidboot.ro ]; then RAIDOWN=`/bin/cat /mnt/${RaidStatusPath}/raidboot.ro` RAIDREF=`/bin/cat /mnt/${RaidStatusPath}/raidgood.ref` /bin/umount /mnt break fi /bin/umount /mnt done # Test for a clean shutdown with array matching reference if [ "${RAIDOWN}" != "${RAIDREF}" ]; then Warning shutdown ERROR ${RAIDOWN} FaultExit fi # The raid array is clean, remove shutdown status files for Device in ${RaidBootDevs} do /bin/mount ${Device} /mnt /bin/rm -f /mnt/${RaidStatusPath}/raidboot.ro /bin/umount /mnt done # Write a clean superblock on all raid devices echo "write clean superblocks" /sbin/mkraid -f --only-superblock /etc/${RaidConfigEtc} # Activate raid array(s) if [ -z "$Raid_ALT" ]; then /sbin/mdadd -ar else /sbin/mdadd $Raid_ALT fi # If there are errors - BAIL OUT and leave rescue running if [ $? -ne 0 ]; then Warning some RAID device has errors FaultExit fi # Everything is fine, let the kernel mount /dev/md0 # tell the kernel to switch to /dev/md0 as the /root device # The 0x900 value is the device number calculated by: # 256*major_device_number + minor_device number echo "/dev/md0 mounted on root" echo 0x900>/proc/sys/kernel/real-root-dev # umount /proc to deallocate initrd device ram space /bin/umount /proc exit #------------------ end linuxrc ---------------------- `linuxrc' を initrd の起動デバイスに追加します. cd /root/raidboot chmod 777 linuxrc cp -p linuxrc mnt 4.12. シャットダウン用の rc スクリプトの修正 インストールの最後の手順は,シャットダウン時に md の状態を本当のルート デバイスに保存するさせるように rc スクリプトを修正することです. Slackware の場合は,rc.0 から rc.6 です.Debian `bo' の場合は,これは `halt' 及び `reboot' になります. もしこれ以外のディストリビューションで実行した場合は,この文書に追加す るため,手順とサンプルファイルを筆者にメールで送ってください. 私はRAID 停止時の問題回避のための Bohumil Chalupa さんの方法を少し変 更したものを使っています.彼の示した元の方法は ``付録A''で述べます. 私の仕事用システムには md0 以外の Linux パーティションは残っていないの で,raidOK readonly のステータスを保存するために起動パーティションを 使っています.筆者はシャットダウン時に md アレイのステータスを含む起動 パーティションとその複製の両方へファイルを書き込み,md デバイスがリー ドオンリーで再マウントされたことを記録することにしました.これはハード ディスクのどれかが壊れたときの障害対策となります. シャットダウンスクリプトは修正され,``rc.raidown'' という名前になりま す.これは,正しく再起動して, RAID デバイスをマウントするために必要な 情報を保存するためのものです.各ディストリビューション用のシャットダウ ンスクリプトの例は ``付録 B''で紹介します. RAID アレイのシャットダウン時ののステータスを得るために,全ての case 文(もしあれば)の後で,かつ,実際のシャットダウン(kill, 状態保存等)と ファイルシステムのアンマウントの前の部分において ``rc.raidown''を呼び 出します. ############ Save raid boot and status info ############## # if [ -x /etc/rc.d/rc.raidown ]; then /etc/rc.d/rc.raidown fi ################## end raid boot ######################### 全てのファイルシステムがアンマウントされた後(ルートファイルシステムは アンマウント「されません」)かつ,電源断のステータスチェックの前に次の コマンドを入れます. ################ for raid arrays ######################### # Stop all known raid arrays (except root which won't stop) if [ -x /sbin/mdstop ]; then echo "Stopping raid" /sbin/mdstop -a fi ########################################################## これによりルート以外の全ての RAID デバイスを安全に停止させることができ ます.ルートのステータスは raidstat.ro に記録され,次回の起動時に参照 されます. rc ファイルを新しい RAID アレイ,まだ /root/raidboot/mnt にマウントさ れている復旧ファイルシステム,(もし同じマシンならば) 作業用システムの それぞれにコピーします. 必要に応じて復旧ファイルシステムのetc/fstabの修正と,復旧ファイルシス テムの mdtab が正しいかどうかのチェックを行います. さて,復旧ディスクを DOS パーティションにコピーすれば,RAID デバイスを ルートファイルシステムとしてシステムを起動する準備は終わりです. umount mnt losetup -d /dev/loop0 gzip -9 rescue 起動パーティションに rescue.gz をコピーします. 残る作業は,設定ファイル raidboot.conf を作り,システムを再起動して新 しいファイルシステムをテストすることだけです. 4.13. Configuring RAIDBOOT - raidboot.conf 設定例の後のコメントは,設定ファイルの最初の3行のそれぞれについての説 明です.例は 4 ドライブの SCSI RAID5 アレイで,起動パーティションを sda1 と sdb1 ドライブに複製している場合のものです.実際に使用する場合 には,この代わりにファイルシステムに応じたパラメータを設定してくださ い. /dev/sda1 /dev/sdb1 linux raid5.conf # コメントは3つの設定行の「後」にのみ記述することができます. # # このファイルは 'raidboot.conf' です. # # 1行目, 'initrd' RAID-復旧システムのあるパーティション # これらのパーティションから起動する必要はありませんが,復旧シス # テムはフロッピーディスクには入らないでしょうから,復旧システム # をどのパーティションからロードするのかわからなければなりません. # # 2行目, raidboot の設定情報へのパス # シャットダウン時のステータス等が起動時にどこにあるのか示します. # これはマウントポイントの情報は含まず,'パス' # /マウントポイント/'パス'のみを含みます. # # 3行目, RAID 設定ファイルのファイル名 # 現在の RAID 設定ファイルですから,つまり raid1.conf, # raid5.conf になります. 4.14. 復旧,RAID システムの 'loadlin と LILO' のカーネルパラメータ指 定 復旧とRAIDの2つのカーネルパラメータがありますが,指定する必要があるの は前者のみです. o Raid_Conf=msdos,/dev/sda1,raidboot このパラメータは RAID 起動デバイスと設定ファイルを指定しま す.フロッピーディスクの復旧システムを起動する場合には,カー ネルのコマンドライン, loadlin あるいは LILO の起動ファイル にこの記述をします. 書式: 'ファイルシステムの種類,デバイス,マウントポイントから 設定ファイルへのパス' o Raid_ALT=-r,-p5,/dev/md0,/dev/sda3 /dev/sdb3 /dev/sdc3 /dev/sdd3 mdadd のパラメータの代わりになります.冗長でない RAID アレイ から起動するときに必要となります.mdadd のコマンドラインパラ メータをコンマ区切りで記述します.破損した/非冗長アレイを動 かす必要があるとき以外には,コメントアウトするか'ヌル文字列' を指定します. すなわち Raid_ALT= を指定します. いずれのパラメータも LILO や loadlin の起動パラメータファイルか, loadlin のカーネルコマンドラインで指定できます.しかし,コマンドライン で指定する場合には,行の最大の長さ(128文字)を越えないように注意してく ださい. LILO で起動する場合には,LILO の設定ファイルへの記述は次のようになりま す. append="Raid_Conf=msdos,/dev/sda1,raidboot" append="Raid_ALT=-r,-p5,/dev/md0,/dev/sda3 /dev/sdb3 /dev/sdc3 /dev/sdd3" より詳しくはman lilo.confを参照してください. 筆者は DOS の設定ユーティリティを必要とするハードウェアを持っているの で,システムに小さな DOS パーティションを作っています.したがって,対 になるディスク上にミラー(コピー)を持つ RAID5 システムを起動するのに loadlin を使っています.同じ方法を RAID1 システムでも使っています.以 下の例では loadlin を使っていますが,やり方は LILO とよく似ています. 必要に応じて loadlin の起動パラメータを編集したり,テスト中にスワップ ディスク上で Linux システムを起動できるように,DOS にルートを持つシス テムには小さいエディタを入れています. DOS システムには Linux のために以下のようなファイルを持っています. c:\raidboot.bat c:\raidboot\loadlin.exe c:\raidboot\zimage c:\raidboot\rescue.gz c:\raidboot\raidboot.cfg c:\raidboot\raidboot.etc c:\raidboot\raidgood.ref c:\raidboot\raidstat.ro (only at shutdown) ---------------------- linux.bat --------------------------- echo "Start the LOADLIN process:" c:\raidboot\loadlin @c:\raidboot\boot.par -------------------- end linux.bat ------------------------- boot.par の内容は以下です. # loadlin boot parameter file # # version 1.02 3-6-98 # linux kernel image c:\linux\zimage # target root device root=/dev/md0 #root=/dev/ram0 #root=/dev/sdc5 # mount root device as 'ro' ro # size of ram disk ramdisk_size=16384 # initrd file name initrd=c:\raidboot\rescue.gz #noinitrd # memory ends here mem=131072k # points to raid boot device, configuration file # for floppy rescue boot, you may want to specify # this on the command line instead of here # format 'filesystem-type,device,path-to-config-frm_mntpnt' Raid_Conf=msdos,/dev/sda1,raidboot # Alternate mdadd parameters # necessary when boot with non-redundant raid # otherwise, COMMENT OUT OR SPECIFY 'NULL' #Raid_ALT=-r,-p5,/dev/md0,/dev/sda3 /dev/sdb3 /dev/sdc3 /dev/sdd3 # ethernet devices ether=10,0x300,eth0 ***** >> 注意!! 復旧システムの起動と,RAID デバイスのマウントの場合で は,loadlin のパラメータが root=/dev/ram0 for the rescue system root=/dev/md0 for RAID のように異なるだけです.root=/dev/ram0 を指定すると,RAID デバイスはマウントされず,必ず復旧システムが起動されます. RAID アレイの認識に失敗すると,復旧システムはマウントされ,動作しま す. 5. 筆者の仕事用 RAID システムの設定 5.1. システムの仕様 同じマザーボードが入っている2つのシステムの設定を 以下に示します. Raid-1 Raid-5 マザーボード: Iwill P55TU IDE * 2 Adaptec SCSI プロセッサ: Intel P200 ディスク: 7G * 2 Segate 4.2G * 4 Maxtors Wide SCSI ディスクドライブは RAID5 のマシンでは 'sda' から 'sdd' と認識され, RAID1 のシステムでは 'hda', 'hdc' と認識されています. 5.2. ハードディスクのパーティション分割 再起動時の ckraid の問題があるため,ルートにマウント可能な RAID アレイ をテストすることは大変なので,筆者はスワップパーティションを切り直し, テスト用の小さい RAID パーティション(sda6,sdb6,sdc6,sdd6)をここに作 り,小さいルートパーティションと /usr/src パーティションの組を RAID 用 カーネルとツールの作業用とテスト用にそれぞれ作りました.これは便利な方 法だと思います. /dosx/raidboot/raidgood.ref shutdown -r now によって正常な再起動を行い,システムを復旧させます. 6. RAID ファイルシステムの構築 この記述は,システム仕様で述べた筆者の RAID1 システムに関してのもので す.あなたのシステムが異なる RAID のアーキテクチャを採用している場合 は,適宜修正してください.詳しくは raidtools-0.42 に付属しているオンラ インマニュアルか,QuickStart.RAID を参照してください. 6.1. /etc/raid5.conf # raid-5 configuration raiddev /dev/md0 raid-level 5 nr-raid-disks 4 chunk-size 32 # Parity placement algorithm parity-algorithm left-symmetric # Spare disks for hot reconstruction #nr-spare-disks 0 device /dev/sda3 raid-disk 0 device /dev/sdb3 raid-disk 1 device /dev/sdc3 raid-disk 2 device /dev/sdd3 raid-disk 3 6.2. /etc/raid1.conf # raid-1 configuration raiddev /dev/md0 raid-level 1 nr-raid-disks 2 nr-spare-disks 0 device /dev/hda4 raid-disk 0 device /dev/hdc4 raid-disk 1 6.3. 仕事用 RAID ファイルシステムを構築するための具体的手順 筆者の RAID5 システムでは,以下のものをインストールしています. Slackware-3.4 どのディストリビューションでも大丈夫でしょう linuxthreads-0.71 raidtools-0.42 linux-2.0.33 に raid145 パッチと Gadi 氏のパッチを当てたもの RAID デバイスを作成,フォーマットします. mkraid /etc/raid5.conf mdcreate raid5 /dev/md0 /dev/sda3 /dev/sdb3 /dev/sdc3 /dev/sdd3 mdadd -ar mke2fs /dev/md0 mkdir /md mount -t ext2 /dev/md0 /md reboot が使う参照ファイルを作成します.これは読者のシステムでは異なる かもしれません. cat /proc/mdstat | grep md0 > /dosa/raidboot/raidgood.ref cat /proc/mdstat | grep md0 > /dosb/raidboot/raidgood.ref Slackware-3.4 または別のパッケージを用いて,OS をインストールします. setup インストール先には `/md' を,インストール元には読者が普段使っているも のを指定します.カーネルを除く必要なディスクセットを選択,インストール します.(Slackware の場合)システム設定(Configure)を実行しますが,lilo とカーネルの起動の項目は飛ばします.最後に setup コマンドを終了しま す. `pthreads' をインストールします. cd /usr/src/linuxthreads-0.71 Makefile を編集し,環境変数を指定します. BUILDIR=/md make make install `raidtools' をインストールします. cd /usr/src/raidtools-0.42 configure --sbindir=/md/sbin --prefix=/md/usr raidtools の `make install' で発生するエラーを修正します. cd /md/sbin rm mdrun rm mdstop ln -s mdadd mdrun ln -s mdadd mdstop /dev/mdx を作ります. cp -a /dev/md* /md/dev 現在のシステムからシステム設定を追加します(エラーは無視します). cp -dp /etc/* mnt/etc cp -dp /etc/rc.d/* mnt/etc/rc.d (新しい rc.6 を含む) mkdir mnt/lib/modules cp -a /lib/modules/2.x.x mnt/lib/modules <-- 現在使っているカーネル 2.x.x のバージョン 以下のファイルを編集し,読者のファイルシステムに合わせて修正します. cd /md 非ネットワーク関係 etc/fstab 実際のルートファイルシステムと RAID デバイス用に修正します etc/mdtab うまく動作するはずです ネットワーク関係 etc/hosts etc/resolv.conf etc/hosts.equiv 及び関連ファイル etc/rc.d/rc.inet1 IP アドレス,ネットマスク,ゲートウェイ等 etc/rc.d/rc.S ファイルシステムのステータスについての部分を全て削除 # Test to see if the root partition isread-only の部分から # remove /etc/mtab* so that mount will ..... までを含まないようにします.これにより,RAM ディスクが 読み書き可能でマウントされると出るうるさいウォーニング が出なくなります. etc/rc.d/rc.xxxxx 必要ならば他のファイルも root/.rhosts もし存在すれば home/xxxx/xxxx 必要ならば他のファイルも 警告: この操作で,パスワードとシャドウパスワードのファイルも 新しいファイルシステムに移されます!これはセキュリティ の点からは,望ましくないかもしれません. システム上で一意であることが必要な /dev/disk... をマウントするための辞 書を作成します.筆者の場合は以下のようになりました. cd /md <-- 新しいファイルシステムのルート mkdir dosa DOSパーティションのマウントポイント mkdir dosb DOS ミラーパーティションのマウントポイント 新しいファイルシステムは完成です.md の参照ステータスを `実際の'ルート デバイスに確認・保存すれば,起動の準備は終わりです. DOS パーティションを dosa, dosb にマウントします. cat /proc/mdstat | grep md0 > /dosa/raidboot/raidgood.ref cat /proc/mdstat | grep md0 > /dosb/raidboot/raidgood.ref mdstop /dev/md0 7. 最後に注意する点 達人とは,ある話題についてあなたより少なくとも1%多くのことを知っている 人のことであることを忘れないでください.私に助けを求めるメールを出すと きにはこの点を忘れないでください.私は実験をしましたが,それは RAID1, RAID5 についてたった一度ずつだけなのです! Michael Robinton Michael@bzs.org 8. 付録 A. Bohumil Chalupa さんによる md0 のシャットダウン Bohumil Chalupa さんの Linux RAID メーリングリストへの投稿で,RAID1, 5 での mdstop の問題の回避方法です.この方法では,シャットダウンの時に RAID デバイスが壊れている可能性は想定していません.そこで,筆者がブー ト時の正常な参照ステータスを簡単に比較するようにしました.これにより, アレイに異常があるとき,オペレータが調整することができます.これについ ての詳細は本文中で述べています. > From: Bohumil Chalupa > > initrd と linuxrc を使ってRAID1 アレイを動かし,それから root を > /dev/md0 にうまく切替えることできました. > > しかし,アレイを正常に *止める* 方法はわかりません. それでは,私がお答えしましょう :-) > Date: Mon, 29 Dec 1997 02:21:38 -0600 (CST) > From: Edward Welbon > 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 ----------------- 9. シャットダウンスクリプトの例 o ``Slackware'' o ``Debian'' 9.1. Slackware - /etc/rc.d/rc.6 #! /bin/sh # # rc.6 This file is executed by init when it goes into runlevel # 0 (halt) or runlevel 6 (reboot). It kills all processes, # unmounts file systems and then either halts or reboots. # # Version: @(#)/etc/rc.d/rc.6 1.50 1994-01-15 # # Author: Miquel van Smoorenburg # Modified by: Patrick J. Volkerding, # # Modified by: Michael A. Robinton < michael@bizsystems.com > # to add call to rc.raidown # Set the path. PATH=/sbin:/etc:/bin:/usr/bin # Set linefeed mode to avoid staircase effect. stty onlcr echo "Running shutdown script $0:" # Find out how we were called. case "$0" in *0) message="The system is halted." command="halt" ;; *6) message="Rebooting." command=reboot ;; *) echo "$0: call me as \"rc.0\" or \"rc.6\" please!" exit 1 ;; esac ############ Save raid boot and status info ############## # if [ -x /etc/rc.d/rc.raidown ]; then /etc/rc.d/rc.raidown fi ################## end raid boot ######################### # Kill all processes. # INIT is supposed to handle this entirely now, but this didn't always # work correctly without this second pass at killing off the processes. # Since INIT already notified the user that processes were being killed, # we'll avoid echoing this info this time around. if [ "$1" != "fast" ]; then # shutdown did not already kill all processes killall5 -15 killall5 -9 fi # Try to turn off quota and accounting. if [ -x /usr/sbin/quotaoff ] then echo "Turning off quota." /usr/sbin/quotaoff -a fi if [ -x /sbin/accton ] then echo "Turning off accounting." /sbin/accton fi # Before unmounting file systems write a reboot or halt record to wtmp. $command -w # Save localtime [ -e /usr/lib/zoneinfo/localtime ] && cp /usr/lib/zoneinfo/localtime /etc # Asynchronously unmount any remote filesystems: echo "Unmounting remote filesystems." umount -a -tnfs & # 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 ################ for raid arrays ######################### # Stop all known raid arrays (except root which won't stop) if [ -x /sbin/mdstop ]; then echo "Stopping raid" /sbin/mdstop -a fi ########################################################## # See if this is a powerfail situation. if [ -f /etc/powerstatus ]; then echo "Turning off UPS, bye." /sbin/powerd -q exit 1 fi # Now halt or reboot. echo "$message" [ ! -f /etc/fastboot ] && echo "On the next boot fsck will be FORCED." $command -f ############### end rc.6 ################################# 9.2. Debian bo - /etc/init.d/halt and /etc/init.d/reboot The modifications shown here for Debian bo halt and reboot files are NOT TESTED. When you test this, please e-mail me so I can remove this comment. 9.2.1. /etc/init.d/halt #! /bin/sh # # halt The commands in this script are executed as the last # step in runlevel 0, ie halt. # # Version: @(#)halt 1.10 26-Apr-1997 miquels@cistron.nl # PATH=/sbin:/bin:/usr/sbin:/usr/bin ############ Save raid boot and status info ############## # if [ -x /etc/rc.d/rc.raidown ]; then /etc/rc.d/rc.raidown fi ################## end raid boot ######################### # Kill all processes. echo -n "Sending all processes the TERM signal... " killall5 -15 echo "done." sleep 5 echo -n "Sending all processes the KILL signal... " killall5 -9 echo "done." # Write a reboot record to /var/log/wtmp. halt -w # Save the random seed between reboots. /etc/init.d/urandom stop echo -n "Deactivating swap... " swapoff -a echo "done." echo -n "Unmounting file systems... " umount -a echo "done." mount -n -o remount,ro / ################ for raid arrays ######################### # Stop all known raid arrays (except root which won't stop) if [ -x /sbin/mdstop ]; then echo "Stopping raid" /sbin/mdstop -a fi ########################################################## # See if we need to cut the power. if [ -x /etc/init.d/ups-monitor ] then /etc/init.d/ups-monitor poweroff fi halt -d -f ############# end halt #################### 9.2.2. /etc/init.d/reboot #! /bin/sh # # reboot The commands in this script are executed as the last # step in runlevel 6, ie reboot. # # Version: @(#)reboot 1.9 02-Feb-1997 miquels@cistron.nl # PATH=/sbin:/bin:/usr/sbin:/usr/bin ############ Save raid boot and status info ############## # if [ -x /etc/rc.d/rc.raidown ]; then /etc/rc.d/rc.raidown fi ################## end raid boot ######################### # Kill all processes. echo -n "Sending all processes the TERM signal... " killall5 -15 echo "done." sleep 5 echo -n "Sending all processes the KILL signal... " killall5 -9 echo "done." # Write a reboot record to /var/log/wtmp. halt -w # Save the random seed between reboots. /etc/init.d/urandom stop echo -n "Deactivating swap... " swapoff -a echo "done." echo -n "Unmounting file systems... " umount -a echo "done." mount -n -o remount,ro / ################ for raid arrays ######################### # Stop all known raid arrays (except root which won't stop) if [ -x /sbin/mdstop ]; then echo "Stopping raid" /sbin/mdstop -a fi ########################################################## echo -n "Rebooting... " reboot -d -f -i 10. 付録 C: その他の設定ファイル 10.1. linuxrc``linuxrc file'' 10.2. loadlin -- linux.bat file - boot.par``linux.bat file - boot.par'' 10.3. linuxthreads Makefile.diff``linuxthreads Makefile.diff'' 10.4. raid1.conf``raid1.conf'' 10.5. raid5.conf``raid5.conf'' 10.6. raidboot.conf``raidboot.conf'' 10.7. rc.raidown``rc.raidown'' 11. 付録 D: 古い linuxrc とシャットダウンスクリプト 11.1. 古いファイル - linuxurc この linuxrc ファイルは次の節で示すシャットダウンスクリプトと組み合わ せれば正しく動作します. ---------------------- linuxrc -------------------- #!/bin/sh # ver 1.07 2-12-98 # linuxrc - for raid1 using small dos partition and loadlin # # mount the proc file system /bin/mount /proc # This may vary for your system. # Mount the dos partitions, try both # in case one disk is dead /bin/mount /dosa /bin/mount /dosc # Set a flag in case the raid status file is not found # then check both drives for the status file RAIDOWN="raidstat.ro not found" /bin/echo "Reading md0 shutdown status." if [ -f /dosa/raidboot/raidstat.ro ]; then RAIDOWN=`/bin/cat /dosa/raidboot/raidstat.ro` RAIDREF=`/bin/cat /dosc/raidboot/raidgood.ref` else if [ -f /dosc/raidboot/raidstat.ro ]; then RAIDOWN=`/bin/cat /dosc/raidboot/raidstat.ro` RAIDREF=`/bin/cat /dosc/raidboot/raidgood.ref` fi fi # Test for a clean shutdown with all disks operational if [ "${RAIDOWN} != ${RAIDREF}" ]; then echo "ERROR ${RAIDOWN}" # Use the next 2 lines to BAIL OUT and leave rescue running /bin/echo 0x100>/proc/sys/kernel/real-root-dev exit # leaving the error files in dosa/raidboot,etc... fi # The raid array is clean, proceed by removing # status file and writing a clean superblock /bin/rm /dosa/raidboot/raidstat.ro /bin/rm /dosc/raidboot/raidstat.ro /sbin/mkraid /etc/raid1.conf -f --only-superblock /bin/umount /dosa /bin/umount /dosc # Mount raid array echo "Mounting md0, root filesystem" /sbin/mdadd -ar # If there are errors - BAIL OUT and leave rescue running if [ $? -ne 0 ]; then echo "RAID device has errors" # Use the next 3 lines to BAIL OUT /bin/rm /etc/mtab # remove bad mtab /bin/echo 0x100>/proc/sys/kernel/real-root-dev exit fi # else tell the kernel to switch to /dev/md0 as the /root device # The 0x900 value the device number calculated by: # 256*major_device_number + minor_device number /bin/echo 0x900>/proc/sys/kernel/real-root-dev # umount /proc to deallocate initrd device ram space /bin/umount /proc /bin/echo "/dev/md0 mounted as root" exit #------------------ end linuxrc ---------------------- 11.2. 古いファイル - シャットダウンスクリプト このシャットダウンスクリプトは前に示した linuxrc と組み合わせれば正し く動作します. RAID アレイのシャットダウン時のステータスを得るために,ファイルシステ ムをアンマウントする直前に以下の行を挿入します. RAIDSTATUS=`/bin/cat /proc/mdstat | /usr/bin/grep md0` 全てのファイルシステムをアンマウントした後(ルートファイルシステムはア ンマウント「されません」)の部分に,以下を追加します. # root device remains mounted RO # mount dos file systems RW mount -n -o remount,ro / echo "Writing RAID read-only boot FLAG(s)." mount -n /dosa mount -n /dosc # create raid mounted RO flag in duplicate # containing the shutdown status of the raid array echo ${RAIDSTATUS} > /dosa/raidboot/raidstat.ro echo ${RAIDSTATUS} > /dosc/raidboot/raidstat.ro umount -n /dosa umount -n /dosc # Stop all the raid arrays (except root) echo "Stopping raid" mdstop -a これによって,ルート以外の全ての RAID デバイスが正常に終了します.ルー トのステータスは raidstat.ro に保存され,次回の起動時に参照されます. 筆者が以前に RAID1 の Slackware システムで使っていたシャットダウンスク リプトの全体を以下に示します.筆者は RAID1 から /etc/raidboot.conf ファイルを使う新しい方法に乗り換えています. #! /bin/sh # # rc.6 This file is executed by init when it goes into runlevel # 0 (halt) or runlevel 6 (reboot). It kills all processes, # unmounts file systems and then either halts or reboots. # # Version: @(#)/etc/rc.d/rc.6 1.50 1994-01-15 # # Author: Miquel van Smoorenburg # Modified by: Patrick J. Volkerding, # Modified by: Michael A. Robinton, for RAID shutdown # Set the path. PATH=/sbin:/etc:/bin:/usr/bin # Set linefeed mode to avoid staircase effect. stty onlcr echo "Running shutdown script $0:" # Find out how we were called. case "$0" in *0) message="The system is halted." command="halt" ;; *6) message="Rebooting." command=reboot ;; *) echo "$0: call me as \"rc.0\" or \"rc.6\" please!" exit 1 ;; esac # Kill all processes. # INIT is supposed to handle this entirely now, but this didn't always # work correctly without this second pass at killing off the processes. # Since INIT already notified the user that processes were being killed, # we'll avoid echoing this info this time around. if [ "$1" != "fast" ]; then # shutdown did not already kill all processes killall5 -15 killall5 -9 fi # Try to turn off quota and accounting. if [ -x /usr/sbin/quotaoff ] then echo "Turning off quota." /usr/sbin/quotaoff -a fi if [ -x /sbin/accton ] then echo "Turning off accounting." /sbin/accton fi # Before unmounting file systems write a reboot or halt record to wtmp. $command -w # Save localtime [ -e /usr/lib/zoneinfo/localtime ] && cp /usr/lib/zoneinfo/localtime /etc # Asynchronously unmount any remote filesystems: echo "Unmounting remote filesystems." umount -a -tnfs & # you must have issued # 'cat /proc/mdstat | grep md0 > {your boot vol}/raidboot/raidgood.ref' # before linuxrc will execute properly with this info RAIDSTATUS=`/bin/cat /proc/mdstat | /usr/bin/grep md0 # capture raid status` # Turn off swap, then unmount local file systems. # clearing mdtab as well 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 # root device remains mounted # mount dos file systems RW echo "Writing RAID read-only boot FLAG(s)." mount -n /dosa mount -n /dosc # create raid mounted RO flag in duplicate # containing the shutdown status of the raid array echo ${RAIDSTATUS} > /dosa/raidboot/raidstat.ro echo ${RAIDSTATUS} > /dosc/raidboot/raidstat.ro umount -n /dosa umount -n /dosc # Stop all the raid arrays (except root) echo "Stopping raid" mdstop -a # See if this is a powerfail situation. if [ -f /etc/power_is_failing ]; then echo "Turning off UPS, bye." /sbin/powerd -q exit 1 fi # Now halt or reboot. echo "$message" [ ! -f /etc/fastboot ] && echo "On the next boot fsck will be FORCED." $command -f 12. 付録 E: Gadi 氏の RAID 停止に関するLinux カーネルパッチ --- linux/drivers/block/md.c.old Fri Nov 21 13:37:11 1997 +++ linux/drivers/block/md.c Sat Dec 6 13:34:28 1997 @@ -622,8 +622,13 @@ return do_md_run (minor, (int) arg); case STOP_MD: - return do_md_stop (minor, inode); - + err = do_md_stop(minor, inode); + if (err) { + printk("md: enabling auto mdstop for %s\n", kdevname(inode->i_rdev)); + md_dev[minor].auto_mdstop = 1; + } + return err; + case BLKGETSIZE: /* Return device size */ if (!arg) return -EINVAL; err=verify_area (VERIFY_WRITE, (long *) arg, sizeof(long)); @@ -692,6 +697,10 @@ sync_dev (inode->i_rdev); md_dev[minor].busy--; + if (!md_dev[minor].busy && md_dev[minor].auto_mdstop) { + do_md_stop(minor, inode); + md_dev[minor].auto_mdstop = 0; + } } static int md_read (struct inode *inode, struct file *file, --- linux/include/linux/md.h~ Fri Nov 21 13:29:14 1997 +++ linux/include/linux/md.h Fri Nov 21 13:29:14 1997 @@ -260,6 +260,7 @@ int repartition; int busy; int nb_dev; + int auto_mdstop; void *private; }; 13. 付録 F: rc.raidown 以下のテキストを rc.raidown スクリプトとして,/etc/rc.d にセーブしま す. #! /bin/sh # # rc.raidown This file is executed by init when it goes into runlevel # 0 (halt) or runlevel 6 (reboot). It saves the status of # a root mounted raid array for subsequent re-boot # # Version: 1.08 3-25-98 Michael A. Robinton < michael@bizsystems.com > # ############ Save raid boot and status info ############## if [ -f /etc/raidboot.conf ] then { read RaidBootDevs read RaidStatusPath read RaidConfigEtc } < /etc/raidboot.conf # you must have issued # cat /proc/mdstat | grep md0 > # {your boot vol mnt(s)}/{RaidStatusPath}/raidgood.ref # before linuxrc will execute properly with this info # # capture raid status RAIDSTATUS=`/bin/cat /proc/mdstat | /usr/bin/grep md0` mkdir /tmp/raid$$ echo "Writing RAID read-only boot FLAG(s)." for Device in ${RaidBootDevs} do # get mount point for raid boot device or use tmp RBmount=$( cat /proc/mounts | /usr/bin/grep ${Device} ) if [ -n ${RBmounts} ]; then RBmount=$( echo ${RBmount} | cut -f 2 -d ' ' ) else RBmount="/tmp/raid$$" mount ${Device} ${RBmount} fi if [ -d ${RBmount}/${RaidStatusPath} ]; then # Create raid mounted RO flag = shutdown status of raid array echo ${RAIDSTATUS} > ${RBmount}/${RaidStatusPath}/raidboot.ro # Don't propagate 'fstab' from ramdisk if [ -f /linuxrc ]; then FSTAB= else FSTAB=fstab fi pushd /etc # Save etc files for rescue system /bin/tar --ignore-failed-read \ -cf ${RBmount}/${RaidStatusPath}/raidboot.etc \ raid*.conf mdtab* ${FSTAB} lilo.conf popd # Create new raidboot.cfg { /bin/echo ${RaidBootDevs} /bin/echo ${RaidStatusPath} /bin/echo ${RaidConfigEtc} } > ${RBmount}/${RaidStatusPath}/raidboot.cfg /bin/umount ${RBmount} fi done rmdir /tmp/raid$$ echo "Raid boot armed" fi ################## end raid boot ######################### 14. 付録 G: linuxrc の動作原理 これは RAID をルートファイルシステムにマウントするための,linuxrc ファ イルの複雑な形のものです.このファイルは `bash' か,それ以外のシェル関 数が利用できるシェル上で実行しなければなりません. この利点は,一般的であり,initrd イメージ内にあるスタートアップファイ ルやパラメータに依存しないことです. ブート時にカーネルによって LILO や loadlin からlinuxrc に渡された Raid_Conf パラメータは,linuxrc が必要とする起動デバイスや raidboot の2つの初期化ファイルの位置を示します(raidboot.etc と raidboot.cfg は シャットダウンスクリプトによって作られます). raidboot.etc は元となるシステムから以下に示すファイルを tar でまとめたもので,起動時に initrd の /etcディレクトリになり ます. raid* mdtab* fstab lilo.conf ( 利用可能ならば ) 注意すべき点は,このファイルはシステムが「本当に」クラッシュ したときには,必要に応じて編集される点です. raidboot.cfg は linuxrc が必要とする残りの RAID 起動ファイル のパスと,使用されているブートパーティション及び利用可能な バックアップパーティションの名前を持っています.このファイル は通常,シャットダウンファイルによって作成されますが,必要に 応じて手動で作ることもあります. raidboot.cfg は3行,コメント無しの形式です. /dev/bootdev1 /dev/bootdev2 [/dev/bootdev3 ... 等] raid-status/path name_of_raidX.conf_file raid-status/path はマウントポイントの名前は含みません. raidX.conf のファイル名は /etc ディレクトリ内のもので,通常 は ckraid と mkraid のために用いられます. 以下の追加ファイルは,ずっと使用する RAID 起動パーティションに置きま す.これは上で述べたのと同じものですが,非常事態には利用可能な任意の場 所(例えば起動フロッピーディスク)からロードすることができます. o raidgood.ref は次のコマンドによって作成されます. cat /proc/mdstat | grep md0 > /{raid_status_path}/raidgood.ref このファイルとこの次のファイルをセーブする場合は,``シャットダウン スクリプト''の章を参照してください. o raidstat.ro はシャットダウン時に毎回 rc スクリプトによって作成さ れ,RAID アレイの終了ステータスを保存します.