さて、私のまわりでは最近ディスククラッシュが相次いでいる、 という話でしたが、今度はあまり関係ない方面から、 重要なデータが入っていてバックアップを取っていなかったディスクが壊れた、 なんとかならないか、 という依頼があったらしい。 で、調べてみると、BIOS からも認識しないわで、かなりの重症らしい。 ということで、ダメでも文句いわないから…、 などという感じで私のところに流れ着いてきました。
OS は Windows XP、NTFS フォーマット、 120GB を 100GB と 20GB の 2 パーティションにフォーマット、ただし 重要なデータはすべて 100GB の C: ドライブ…、だそうです。 というか、こういう状態になったディスクは、 「ダメでも」というよりは「データが戻ってきたらその方が奇跡」と思ってほしいものなのですが (^^;、 とにかくやってみましょう。 結論からいうと、かなり多くのファイルを救出することができました。 以前の壊れた FreeBSD ディスクのクラッシュ救出ノウハウもいろいろな場所で死んだディスクを救ったようですので、 今回もいろいろと公共の役に立ちそうなノウハウかと思われます (しかも圧倒的にユーザが多そうな Windows XP の NTFS だし…)。 というわけで、知識を共有してしまいましょう。
さらにこの辺によると、最近は dd(1) の ibs と obs を使い分けると速くなる話や、 -current の /usr/src/tools/recoverdisk や ports に dd_rescue (ports/sysutils/dd_rescue) などがあるようで、いろいろ便利になっているようです。 (2005/04/13 追記)
壊れたのは Windows XP のディスクですが、救出には FreeBSD を用います。 既に適当なマシンがあればそれでも良かったのですが、 今回はそのような目的に使える FreeBSD マシンが手近になかったので、 一から作業しました。
まず、ディスク内容を潰しても良い適当な PC を用意して、 そこに FreeBSD 4.9-RELEASE を入れました。 インストールに使った CD-ROM は外し、 ディスク構成を次のようにします。
BIOS から認識されるディスクの場合は、 「ATA バスを PIO モードに設定する」まで飛ばして OK です。
BIOS から認識しないディスクは当然 FreeBSD 起動時も認識されません。 しかし、FreeBSD ならば atacontrol(8) の必殺コマンドがあります (X Window System を入れずに文字コンソール画面からやった方が便利です)。 CD-ROM をセカンダリ ATA から抜いてあるのはこれをやりたかったためです (detach, attach ができるのはバス単位)。
# atacontrol detach 1 # atacontrol attach 1
一度で結果が出なくても諦めるなよ。ここで何度か繰り返すうちに、 次のようなカーネルからの表示がやってくることがあります。
ad2: 117246MB <Maxtor 6Y120P0> [238216/16/63] at ata1-master UDMA33
このメッセージが出ればまず第一戦の勝利だ! (当然、メッセージの詳細はディスクの種類によって異なる) 完全に回路が死んだわけではなく、 不安定になっているだけ。
クラッシュしたディスクは一般に不安定な状態なので、 UDMA でアクセスすることは避けたいものです。 超基本の初期 IDE 方式でもっとも遅い PIO 転送を設定しよう。
# atacontrol mode 1 BIOSPIO BIOSPIO
ATA の規格には PIO に関してもいくつもの規格がありますが、 もっとも保守的で低速な初期の規格が atacontrol(8) で言うところの BIOSPIO (PIO0) です。
ここで、fdisk を確認してみましょう。
# fdisk ad2
ここで、目的の NTFS がパーティションに存在していることが確認できれば、 第二戦の勝利! やった!
ところが、このディスクのイメージが読めるか試すために、 軽く dd してみると、やはりエラーが出るようです。
# cd /usr # dd if=/dev/ad2 of=broken.img bs=512 ad2: hard error reading fsbn XXXX (ad2 bn XXXX; cn XX tn XX sn XX) status=59 error=40
つまり、このディスクは回路方面が飛んでいる感じの上に、 さらにディスクの表面も腐っていると思われる、 しかし幸いながら fdisk データは生きているという状態です。 ブロック番号は記録がないのですが、 かなり若い番号だったので、ファイルシステムの重要な部分が飛んでいる可能性もあり、 油断できません。
さて、ここでお買い物です。 120GB のディスクを吸い取るには 120GB 以上のディスクが必要です。 作業の安全性、安定性、進行状況の確認のためには、 120GB を越えるサイズのディスクが必要です。 ここで、ここからの作業手順を説明します。
Windows XP 標準機能にある NTFS のデータ修復はあてになりません。 特に今回のようなファイルシステムの重要な部分が壊れている可能性が高い場合はなおさらです。 必ず専用ソフトを使いましょう。 高くても我慢しましょう。イヤなら今度からバックアップをちゃんと取りましょう (^^;。
つまり 120GB を越えるサイズのディスクが 2 本必要です。 160GB を 2 本買ってきましょう。
接続は以下のような構成とします。
160GB(1) には先ほどと同様、FreeBSD 4.9-RELEASE をインストールし、 必ず 120GB 以上空きを持つ BSD パーティションを 1 個作ります。 そこにイメージファイルを格納します。 インストーラから Auto で Disklabel エディタを設定すれば、 /usr が 150GB 以上になりますので、 それで良いと思います。
イメージ抽出に関して、詳しい情報は前回のノウハウを参考にして下さい。 基本的には dd(8) の conv=sync,noerror オプションで、 壊れたブロックをゼロパディングして吸い出すのです。 この際気をつけてほしいのは、いくら時間がかかっても必ず bs=512 とすることです。 dd(8) は bs 単位でゼロパディングします。bs の値を増やすことは、 生きているデータまで殺すことです。絶対にやってはいけません (念のためですが、512 未満に設定することはハードウェア的に意味がありません)。
まず、先ほどの要領で、atacontrol attach/detach を繰り返して、 バスリセットをかけ、ディスクを認識させます。この際、次のように表示されたとします。
# atacontrol detach 1 # atacontrol attach 1 ad2: 117246MB <Maxtor 6Y120P0> [238216/16/63] at ata1-master UDMA33
dd(8) は conv=sync,noerror するとディスクの終りで自動停止しなくなるため、 ディスクのブロック数を与える必要があります。 238216×16×63=240121728 なので、240121728 ブロックであることが分かります。 まず、先ほどと同様に問題のディスクを BIOSPIO モードに設定しましょう。
# atacontrol mode 1 BIOSPIO BIOSPIO
そして、いよいよ dd(8) による吸出しです。 count オプションに与えているのが先ほど計算したブロック数です。 バリバリエラーが発生し、そのたびにタイムアウトを待つため、 エラーがでたブロックが多いとひたすら時間がかかります (今回は習慣的に /dev/rad2 を使っていますが、 FreeBSD 5.x ではすでに /dev/rad2 は存在しないこともあり、 4.x でも /dev/ad2 でもよいでしょう)。
# cd /usr # dd if=/dev/rad2 of=broken.img bs=512 count=240121728 conv=sync,noerror
今回はだいたい 20 時間ほどで 120GB のイメージ吸出しが可能でした。
[注意!] dd(8) は非常に強力なコマンドですが、 間違えた操作をしたときのシステムに対する破壊力も抜群です。 私が人為ミスでシステムを再起不能なまでに破壊した経験のうち 1 件は、 dd(8) のタイプミスです。 十分に内容を理解した上で、dd(8) は実行するようにしてください。
次はこのイメージファイル broken.img をプライマリスレーブに接続したディスクに貼ります。 こちらは bs のサイズを大きくして大丈夫です。
# dd if=broken.img of=/dev/rad1 bs=65536
bs が大きい上に、UltraDMA も効いているため、 こちらは 2 時間未満で終わりました。
ここまで来たら、もう FreeBSD マシンを shutdown して構いません。 先ほどのプライマリスレーブのディスクを Windows に接続します。 今回は IEEE1394 の外付け BOX にこのディスクを入れ、 Windows XP の健全なマシンに接続し、 ファイナルデータを起動します。 そして、クラスタスキャンをかけ、壊れたディレトリツリーやディレクトリエントリの修復などをかけると、これまた数時間かかりますが、待ちます。
今回、健全なまま残っていたのはトップディレクトリでもフォルダ数個でした。 かなり深刻にメタデータが破壊されたようです。 ファイル名も壊れたものが多数ありましたが、 とにもかくにも、かなり必要なファイルが救出できました。 全く救出できないのと、8 割方のファイルを救出できたのは大きな違いです。 やっほー。
……ていうか、バックアップ取れ (^^;。