印刷用表示へ切り替え 通常表示へ切り替え 更新履歴を表示 更新履歴を隠す
LinuxWindows 障害のあるハードディスクのコピー

Windows XP のノートパソコンのハードディスクで chkdisk が走ることが多くなってきたので,ハードディスクのまるごとコピーを行った。結果は,中途半端に成功といったところ。

■ ■ ■

Windows XP で動作しているノートパソコンのハードディスクがそろそろダメっぽい。ハードウェアは ThinkPad T42。起動時に chkdisk が走ることが多くなってきた。ルートディレクトリに tmp.* というフォルダもいくつかできている。そこで,ディスクをまるごとコピーすることにした。ThinkPad にはセカンダリディスク用のアダプタを装着してあるので,もう1つディスクを積むことができる。条件は次の通り。

  • ディスクAには障害がある
  • ディスクAは2パーティション構成で,第1パーティションはNTFS,第2パーティションはFAT32
  • ディスクAの第2パーティションは隠しドライブで,ディスク・トゥー・ディスク (D2D) によるリカバリ情報が入っている
  • ディスクBは新規で,ディスクAと同型で同容量
  • ディスクBには,ディスクAの情報をできるだけ同じ状態でコピーしたい (D2D 領域も含めて)

使用したのは,KNOPPIX Japanese edition バージョン 5.3.1 CD 版。Linux の dd コマンドを使ってコピーしてしまおうという腹である (Manpage of DD)。お金はできるだけかけない方向で。お,同じようなことを違う方法でやっている人を発見。Fenrir さんのは,以下でやるのとは違って,ディスクを大容量にする場合である (Fenrir's BLog: Thinkpad X60s HDDの換装 (移行ソフトにお金かけない))。お金をかけないというところは同じ。

簡単だと思っていたが

KNOPPIX は USB の外付け DVD ドライブから起動させた。起動はするが,フルの起動には失敗するようで,シングルユーザモードに落ちてしまう。ただし,それでもコマンドは使えるので,作業を進めることにした。

Linux を使うと,ディスクに障害がない場合,次の方法をとれば一発でコピーが済む 。セクタ単位でコピーが行われるため,同一内容のディスクができあがる。ThinkPad 本体のハードディスクは /dev/hda,アダプタに取り付けたハードディスクは /dev/hdc と認識される。これを確認するには,例えば /dev/hda1 を適当なディレクトリにマウントして,中身を見てみればよい。

# mkdir /mnt/win
# mount -t vfat /dev/hda1 /mnt/win
# ls /mnt/win

コピーする際,dd の実行にかかった時間を計測するために,前後を date コマンドで挟んだ。

# date; dd if=/dev/hda of=/dev/hdc; date
Thu Dec  4 05:49:47 UTC 2008
/etc/hda: Input/output error
Thu Dec  4 06:43:17 UTC 2008

朝っぱらから起きだしてやったのに,途中でエラーで終わっていた。dd コマンドにはディスクエラーを無視するオプションがある。しかし,それを指定すると,何をしても dd コマンドが終了しなくなってしまう欠点があるのだ。Ctrl-C でも Ctrl-Z でもダメである。

# dd if=/dev/hda of=/dev/hdc conv=noerror,sync
...
同じエラー表示が繰り返される (終われない)

KNOPPIX がシングルユーザモードで起動しているので,再起動しかない。

不良セクタの手動回避方法

上でみたように,エラーの自動スキップの方法は,回避できないエラーに当たるとどうしようもない。そこで,手動でエラーをスキップすることにした。

# dd if=/dev/hda of=/dev/hdc conv=sync
hda: dma_intr: status=0x51 { DriveReady SeekComplete Error }
hda: dma_intr: error=0x40 { UncorrectableError }, LBAsect=5866783, sector=5866776
ide: failed opcode was: unknown
end_request: I/O error, dev hda, sector 5866776
Buffer I/O error on device hda,  logical block 733347
dd: /dev/hda: Input/output error
#

上のようなエラーで止まる。dd コマンドには skip オプションがあるので,これを使ってエラーのあるセクタである 5866776 の場所を確認してみる。出力先は /dev/null に向けている。

# dd if=/dev/hda of=/dev/null skip=5866776 count=1
(上と同じエラー)

試してみると,LBAsect=5866783 の場所まではエラーになる。そこで,これの次のセクタからのコピーをすることにした。出力側は seek オプションで読み飛ばせるので,これを skip と同じ値にしてやる。

# dd if=/dev/hda of=/dev/null skip=5866784 seek=5866784 conv=sync

これで不良セクタの次のセクタからのコピーが始まる。エラーが出たら,同様に skip と seek に LBAsect+1 を与えて dd を実行する。これを繰り返したところ,40 個の不良の後,ディスクコピーが終了した。

一部は失敗,一部は成功

上の方法でコピーして出来上がった新しいディスクの情報を見ると,2つのパーティションができていた。ここまでは成功。第1パーティションのフォーマット情報は不明 (つまり失敗),第2パーティションはFAT32で確保されていた(成功)。ディスクにエラーがある場合,コピーがどうしても飛び飛びになってしまうため,フォーマット情報に抜けが出てしまうようなのだ。D2D 領域には障害がなかったようで,丸ごとコピーに成功している。

そこで,第1パーティションのみNTFSでフォーマットして,もう一度「dd コマンド+不良セクタ手動回避」を試みることにした。

第1パーティションのみのコピー

すでに第2パーティションのコピーは終了しているので,第1パーティションだけのコピーだけでよい。したがって,/dev/hda の代わりに /dev/hda1,/dev/hdc の代わりに /dev/hdc1 を指定する。

# dd if=/dev/hda1 of=/dev/hdc1 conv=sync

ディスクに障害があるだけあって,エラーの場所は,最初にエラーのあったところと同じ場合と違う場合が発生。最終的にはエラー箇所は20個で,最初にやったときよりも少ない手間で済んだ。

何とか成功と言えるか

出来上がったディスクを再び Windows で認識させると,フォーマット情報は NTFS と正しく認識され,中のファイルも読めることが分かった。成功か! とぬか喜びをして,調子に乗ってそのディスクで起動してみることにした。Windows XP のロゴが表示され,chkdisk が走った。しばらく待つと,最終的な起動には至らず,リブートを繰り返すようになったのだった。NTFS パーティションのファイルも読めるので,一応は成功したと言えるかといったところ。

考えてみれば,ハードディスクに障害がありながら普通に Windows XP が起動していたのが奇跡的なことだったのかも知れない。

まとめ

同型・同容量のディスクの場合,Linux の dd コマンドを使えば D2D 領域を含めてコピーができる。元ディスクに障害がある場合は,新規ディスク (パーティション) をあらかじめフォーマットしておく方がよい。不良セクタの手動回避もある程度は有効である。

D2D 領域 (HPA, Hidden Protected Area) を DOS から操作するなら,X31 - ThinkPad X60s/X40/X31 メモ が参考になる。

Posted by n at 2008-12-09 04:47 | Edit | Comments (0) | Trackback(0)
Trackbacks

  • 「手違いで複数トラックバックを送ってしまった!」という場合でも気にしないでください (重複分はこちらで勝手に削除させていただきます)
  • タイムアウトエラーは,こちらのサーバの処理能力不足が原因です (詳細は トラックバック送信時のエラー をご覧ください)
  • トラックバックする記事には,この記事へのリンクを含めてください(詳細は 迷惑トラックバック対策 をご覧ください)
Comments
Post a comment
  • 電子メールアドレスは必須ですが,表示されません (気になる場合は「メールアドレスのような」文字列でもOKです)
  • URL を入力した場合はリンクが張られます
  • コメント欄内ではタグは使えません
  • コメント欄内に URL を記入した場合は自動的にリンクに変換されます
  • コメント欄内の改行はそのまま改行となります
  • 「Confirmation Code」に表示されている数字を入力してください (迷惑コメント対策です)


(必須, 表示されます)


(必須, 表示されません)


(任意, リンクされます)


Confirmation Code (必須)


Remember info (R)?