Linux ブートディスクの交換と環境移行

■突然の障害ととりあえずの対処[不良ブロックの書き出し]
■平和な日々
 こちらのページにまとめた方法で日常的に バックアップを取るようになり,データ消失の危険性は激減しました. しかし,マーフィーの法則(死語?)ではありませんが,何故かバックアップを 取っていないときに限ってクラッシュするくせに,定期的に取っているときには 事故は起きません.幸いにも現在のところ,バックアップの恩恵を受けるような ディスク障害は発生していません.そして気が付くと,24h稼働のサーバとして 運用し始めてから,夏の暑いシーズンを迎えるのも2回目に突入しようとしています.

 しかし,そんな平和な日々がある日突然終焉を迎えたのでした…

■それはある日突然やってくる
 とある日曜日,久しぶりにコンソールを見てみると,エラーがドカドカと 表示されています.戦慄を覚えつつ /var/log/messages を確認してみると…

terminator kernel: hda: dma_intr: error=0x84 { DriveStatusError BadCRC }

kernel: hda: dma_intr: error=0x40 { UncorrectableError },LBAsect=232389, high=0, low=232389, sector=103848

 上記のようなディスク関係のエーラーが大量に出ています.それも出所は hda と なっていますので,ブートディスクです.

 このエラーは IDE ケーブルの不良によって発生する場合もありますが,当初は 問題なく動いていたことから考えても,ディスクに不良セクタが出来はじめている と考えて間違いないでしょう(ケーブルの経年変化にしても短すぎます).問題を 根本的に解決するためにはディスクを交換し,現在の環境を再現する 必要があります

 しかし,これまでバックアップしていたのは /home のような自前のファイルのみ. メモを残さずに設定変更したり,ソフトをインストールしたことがあるため, Linux のクリーンインストール後に現在と同じ環境に戻すのはかなり骨 です.交換用の新しいディスクが手元に無かったことももあり,その労力 を考えて少々ブルーになりました.

■とりあえずの対処
 とは言え,手をこまねいて見ているだけでは,症状は悪化する一方です. 放置すれば起動不能になる可能性もあります.そこで当面の対処として 不良ブロックを書き出し,使用しないようにすることにしました.

 一般的な Linux 環境でディスク上の不良ブロックをチェックする場合, badblocks コマンドを使用します.例えば /dev/hda3 のパーティションの 不良ブロックをチェックし,/tmp/badblocks.txt に結果を書き出す場合, 以下のようにこのコマンドを使用します.

# badblocks -o /tmp/badblocks.txt -v /dev/hda3

 なお,上記のように badblocks コマンドを実行すると,ディスク上を 読み込みモードで検査しますので,マウント中のパーティションでもスキャン することができます.書き込みモードで検査を行う場合は "-w" オプション を付けて実行しますが,検査を行ったパーティションの内容が消去されてしまいます. つまり,利用中のパーティションにこのオプションは使用してはいけません.

 ちなみに私は badblocks コマンドを直接実行せずに,e2fsck で間接的に 使用しました.EXT2,EXT3 ファイルシステムを使用している場合,何らかの 起動手段(例えばブートCDでrescueモードで起動)でマシンを起動し,チェック をするパーティションをマウントしていない状態で実行します./dev/hda3 パーティションをチェックする場合は,以下のように実行します.

# e2fsck -c /dev/hda3

 "-c"オプションは, badblocks を呼び出してファイルシステム中に不良 ブロックが無いかを調べ,不良ブロックを『不良ブロックinode』に加えるという オプションです.ちなみに badblocks で不良ブロックを書き出した後に,e2fsck の "-l" オプションで直接不良ブロックを登録する手段もあります.詳しくは man ファイルを参照してください.

 上記の方法で対処を行って以降,毎日のように膨大な数レポートされていた エラーはピタリと収まりました.

■代替セクタに関する予備知識
 余談ですが,基本的にディスクは未使用の新品であっても,ディスク上の 全ての領域が正常に利用できるわけではありません.製造工程で不良セクタが 発生するのを回避するのは難しいからです(全く不良セクタの無いディスクを 作ろうとすると,莫大なコストがかかる.店頭で売られているディスクは, 工場出荷時に中身がチェックされ,欠陥セクタリストに不良セクタが登録され た状態で出荷されています).そしてディスクには,不良セクタの問題を カバーするために,代替セクタ(セクタスペアリング)と呼ばれる機構が 用意されています.

 この機構は,予め用意されている(ディスク上に確保されている)正常に 読み書き可能な代替セクタに,問題のあるセクタに対するアクセスを 代替させる機構です.ブロック再割り当てとも呼ばれており,ローレベル フォーマットを行うことによって,リマッピングを行うことが可能です (通常のフォーマッタでも,不良セクタのマッピングが行えるものもあります).

 不良セクタが出来る原因は多くのものがあります.その代表的な原因としては, ディスク面の物理的な障害の他,セクタの境界が磁気的に曖昧になるなどが あります.一般に上記の代替処理がきちんと動作し ている際にはユーザーレベルからは不良セクタの存在を意識することは殆ど ありません.しかし大容量ディスクの場合,一旦不良セクタが出来はじめると 急速に不良セクタが増加し,データ消失などのトラブルの原因になる傾向が多いようです

■ブートディスクの交換と環境のコピー
■とりあえずの対処とその効果
 とりあえずの対処として不良ブロックをリマッピングしたわけですが,この 処理を行った後,一ヶ月程はエラー無しで正常に動いていました.しかしその後, 『一旦不良セクタが出来始めると急速に不良セクタが増加する』の例に漏れず, 1週間に5,6回ディスクエラーが発生し,ログに記録されるようになりました. 幸いにしてKernelパニックに陥ってシステム停止という重篤な症状には陥りません でしたが,やはりその場しのぎの対処は所詮その程度といった所でしょうか.

 そのため,新しいディスクに現在の環境をコピーし,ブートディスクを入れ替える という根本的な対処を行うことにしました.

■マシンを落とすにあたっての手続き
 ブートディスクを交換する場合,どうしてもマシンを落とさなければなりま せん.なにがしかのサービスを提供しているマシンの場合,落とす時間が 短時間で済むのであれば,ちゃちゃっと行ってしまうという手もあります.しかし, データコピーを伴う作業の場合,サービスが停止している時間がかなり長時間に なることが予想されます.

 会社で一時もサービスを停止できないマシンの管理をしている人にとっては, この手の話はとても頭の痛い問題だと思います.一般に無停止システムの場合, 同じマシンを2台用意しておき,片側に障害が発生したりメンテナンスの際には もう片側に代替させるという方法をとります.

 普通の家で使っているマシンの場合,せいぜい『あ,落ちてるね』と,言われ るだけなのでそこまで気を遣わなくても良いとは思います.しかし,この Terminator TU は Web のアクセス解析にも使用していることもあり,不都合が 生じるのは私や身内だけではありません.tadachi-net.com のコンテンツを閲覧 した際に,「○○に接続できませんでした」のようなメッセージが表示されるのは あまり印象が良くあませんし,1日あたり('03/06現在) 1500 page view くらい ありますので,かなりの人の目に触れることになってしまいます.

 そこで,Windows ベースの別のマシン(Terminator K7DDR)に Virtual PC for Windowsをインストールし,Linux環境+Webアクセスログ取得環境を構築し, サービスレベルでの仮想バックアップマシンとしました.そしてルータ側の設定 として,外部からhttpアクセスがあった際に,K7DDR の仮想マシンに飛ばすように 切り替え,作業を始めました.

■ブートディスクのデータ移動の方法
 お金をかけても良いのであれば,DriveImage や Norton Ghost,B's recorder のようなソフト を使用し,ディスクの内容を別のディスクにコピーしたり,リカバリーCDを作成 することが比較的簡単に行えます. また,フリーで同様のことを行う場合, Partition Imageを使うという手も あります.このソフトはネットワーク経由でもバックアップ可能であり,市販ソフト にも見劣りのしない非常に高機能なものです.

 しかし,今回はお金をかけず,時間も節約しつつ,出来るだけ手軽に行う方法を 採ることにしました.具体的には,新規ディスクを IDE 接続し,パーティションを 切った後,データ領域は tar でコピーし,MBR は dd でコピーするという方法です.

■データ領域コピーの前準備
 まずは障害を抱えているディスクをそのままにした状態(プライマリ・マスター) で,新しいディスクをプライマリのスレーブに接続し,シングルユーザーモードで Linux ブート後,パーティション分けをしました.当然ながら,各パーティションの 容量は現在利用中のディスクのデータ量が収まるサイズにしておきます.(swap パーティションはmkswapしておくのも忘れずに)

 なお,コピー作業はシングルユーザーモードで行う必要があり,可能であれば ブートCD等で起動して作業を行った方が良いでしょう.これは,データのコピー 中に元データが更新されるとトラブルを引き起こす可能性があるからです.ちなみに Vine の場合, 起画面が表示された状態で CTRL+x を押すとキャラクタモードになります.ここで "linux" というラベルで表されるカーネル(と環境)で起動し,かつ,シングル ユーザーモードにしたい場合は,"linux -single"のように実行します.

※シングルユーザーモードで起動すると最低限のサービスしか起動せず,root がメンテナンスなどを行うために適切な環境で起動します.ちなみに私は (障害を抱えたディスクで「とりあえず」起動できる状態であったため& 面倒なので :-))ブートCDで起動して作業を行わず,シングルユーザー モードで作業を行いました.

■データ領域のコピー
 次にデータ領域をコピーします.フロッピーディスクであれば dd コマンドを 使用して中身をそっくりそのままコピーできるのですが,ディスクでこれを行う のは危険です.tar コマンドを使用する方が良いでしょう.

 例えば,コピー元のディスクが hda,新しい(コピー先)のディスクが hdb であるとし,/dev/hda1 を /mnt/hda1,/dev/hdb1 を /mnt/hdb1 にマウントした状態 でこのパーティションの中身をコピーする場合,以下のように実行します.

# cd /mnt/hda1 # tar cpf - ./ | (cd /mnt/hdb1; tar xpfv -)

 私の環境の場合,/dev/hda1 が /boot,/dev/hda2 は swap,/dev/hda3 は / にマウントするようにしています.そのため,上記の方法で /dev/hda1を /dev/hdb1 へ.そして /dev/hda3 を /dev/hdb3 へコピーしました.

■MBRのコピー
 ブートディスクの場合,データ領域をコピーするだけでは起動できません. MBR(Master Boot Record)をコピーすると共に,OSがブート可能に設定する 必要があります.ただし実際の作業は,環境によって異なります.私の 場合,LILO(Linuxのブートローダー)をMBRにインストールし,マルチブート にせず(例えばWindows/Linuxを切り替えてブート可能にせず),OS は Linux のみで運用しています.そのため,Linux をブート可能にする設定は MBR をコピーするだけで基本的にOKです.なお,OSのブートシーケンスや LILO に関しては, こちらのページ を参照してください.

# dd if=/dev/hda of=/dev/hdb bs=446 count=1

 上記のコマンドを実行することにより,LILO の使用しているブートセクタを コピーすることができます.なお,何かあったときのために,ブートFDをここで 作成しておくことを強くお勧めします.ブートFDは, /sbin/mkbootdisk コマンドで簡単に作成することができます.LILO はディスク の構成が変更になると,エラーで起動しなくなる場合が多いのですが,最悪この ブートFDがあれば対処することができます.

■/etc/fstabの内容を確認
 新しいディスク上の,起動した際に /etc/fstab として利用することになる ファイルの内容を確認してください.ここで,パーティション名を /dev/hda1 のようなデバイス名で記述しておらず,LABELで指定している場合は,デバイス名 に書き換えておくと問題が少ないでしょう.
■ディスクの入れ替えとLILOの再インストール
 これでほぼ一通りの作業は終わりです.障害を抱えたディスクを外し,データ をコピーしたディスクに入れ替えます.そして運が良ければ(まず無いと思います :-), 電源投入後何も無かったかのように立ち上がると思います.

 もしここで,"LI"のようなメッセージが表示されて LILO が起動しない場合, 先程作成したブートFDで起動しましょう(私もこのパターンでした).そして 起動後,lilo コマンドを実行し,LILO を再インストールします.

# lilo

 LILO を再インストールした後は,普通にディスクからブートできるはずです.

■まとめ
 今回はたまたまエラーが発生したディスクが『とりあえずは』普通に稼働 する状態のため,最悪の状態は回避することが出来ました.しかし,ヘッド クラッシュ等のハード的障害が急に発生し,全くディスクの内容が見えなく なったとしたら…と,思うと,ちょっとぞっとしました.

 現在私が定期的にバックアップを行っているのは,自分で作成したデータ のみです.そのため,ブートディスクがクラッシュした際の環境修復 (OSを含む)には用いることができません.時間さえかければ スクラッチからであっても同等の環境を復活させることが可能ですが,その 労力を考えるとげんなりします.今後はこの点も含めてバックアップ計画を 練り直し,一通りのものをバックアップするようにしようと考えています.

 何年か前までは,ディスクがクラッシュしたときには『良い機会なので 新しい OS でも入れてみようかなぁ』と,逆にワクワクしたものです.しかし, 色々なもの(大量のデータ等)を抱えて来るようになると,絶対的な拠り所 としての安定環境を守りたいと思うようになります.

 私の場合は Terminator TU 1号機に全てのものを集中させている関係で, これが障害を抱えると非常に困った状態になります.ある意味,危機管理的な 話になりますが,サービスとして止めたくない部分,そしてデータとして 保全したい部分を切り離し,サービスに関しては別マシンでも簡単に実現 できるような環境を構築しておく方が良いのかもと思っています.


『Asus Terminator 活用メモ』 へ戻る