どうやらハードディスクが壊れているらしいので、新しいハードディスクを買ってきました。
Windowsを新規インストールする時間と手間が惜しいので、FreeBSDのddコマンドで、ハードディスクのパーティションをまるごとコピーすることにしました。初心者には、あんまりお勧めできない方法なんですが。
Windowsの場合、というかどのOSでも普通はそうなんですけど、OSとして使用中のパーティションの内容(Windowsなら、Cドライブなど)を、別ディスクに正確にコピーすることはできません(昔、Macintoshでは、当たり前のようにできたんですけど・・・)。
別の起動ディスクでブートさせて、コピーする場合でも、ブートローダがきちんとコピーできない場合があったり、それに、ファイル単位でコピーするので、ランダムアクセスに近い挙動をするので、それなりに時間がかかります。
一方、ddでセクタ単位でコピーする場合は、シーケンシャルアクセスになるので、データ転送速度は、ドライブの限界までだせるので、短時間でコピー作業が完了します。
ただし、ddでコピーする場合の欠点としては、もしもコピー元ディスクに不良セクタ(bad sector)があるときは、どのファイルが壊れたのかわからないままコピーされる、という、なんだかなぁ~、な結果になります。壊れてるんだから仕方ないですが。
作業手順としては、だいたいこんな感じでしょうか。
- コピー先の新HDDに、コピー元とまったく同じ大きさのパーティションを切る
- ddで、パーティションをまるごとコピーする
- コピー先の新HDDのMBRにブートローダをインストールする。
・・・という感じですが、なんだか、今回、いろいろとはまったので、失敗したことのメモを残しておきます。あんまり参考にならない話です。
● sysinstallコマンドでパーティションを切ろうとしたら、うまくいかなかった。なぜ?
sysinstallを実行して、Configureを選択、Fdiskを選択します。そして、コピー先の、新しいディスクを選択。
いつもそうなんですが、ジオメトリが変だから無視してそれっぽい値を使うよ、といわれます。とりあえず今は、まあいいや、と思うことにします。
おっと、その前に、あらかじめ、コピー元のディスクのパーティションを、fdiskコマンドで調べておきます。「fdisk ディスク名」、たとえば、「fdisk ad0」とかで、表示されます。
1つめのパーティションサイズは、32772537セクタでした。
そこで、sysinstallのFDISK Partition Editorで、このセクタ数、32772537を入力してやります。
つづいてパーティションタイプを指定しますが、コピー元のタイプが7だったので、7を指定します。
これで新たにパーティションが作成されるのですが(実際には、まだディスクに書き込まれていない)、なぜか、サイズが32756472になっていて、さっき指定したサイズとは違っています。
昔からのUnixユーザーなら、すぐに、「ははぁ~ん、シリンダ境界にあわせて、パーティションサイズを自動的に調整したんだな」とか思うんでしょうが、
32756472 / 63 / 255 = 2038.9960784313
・・・割り切れないじゃないですか。ぜんぜんシリンダ境界になってません。
ちなみに、
32756472 / 63 = 519944
なので、トラックあたりのセクタ数でなら割り切れるんですが、それなら、
32772537 / 63 = 520199
でもあるので、もともと入力した数も割り切れます。これ、何なんでしょうね?
いまどきのHDDの場合、トラックごとにセクタ数が違ってたりするらしいので、シリンダ境界に合わせるのは、たぶん、あまり意味ないと思います。だいたい、ヘッド数が255なわけないですし。
ということで、sysinstallを使うのはあきらめて、fdiskコマンドで、全部、数値を手入力して、まったく同じサイズのパーティションを作ってやりました。
ようするに、「fdisk -i ad0」とかやって、ちまちまと、全部の数値を、コピー元パーティションとまったく同じになるように、入力してやりました。
sysinstallがうまく使えなかった件は、ちょっと悔しいです。今度、sysinstallのソースでも眺めてみようか。
● ddでコピーしたのに、なぜか正常にコピーされなかった
基本的に、ddでコピーするときは
dd if=コピー元パーティション of=コピー先パーティション bs=ブロックサイズ
みたいな書式で指定するようになっていて、ブロックサイズは、本当は512(バイト)なんですが、大きめの値を指定すると、データ転送速度が上がるので、今回の場合、1Mバイトとして、
dd if=/dev/ad10s1 of=/dev/ad14s1 bs=1m
みたいにやってみたのですが、これは、今回の場合、ダメでした。
なぜなら、コピー元に不良セクタがある場合、ddコマンドは、読み出しエラーが起きた時点で、コピーを終了してしまうから、パーティションの内容の途中までしかコピーしてくれません。
そういうときは、ddに、convオプションを指定します。
conv=noerrorと指定すると、読み出しエラーがあっても処理を継続するようになります。ただし、読み出しエラーがあった箇所をすっとばして書き込むので、コピー先で、だんだんと、セクタの位置がずれていってしまいます。こういうときは、conv=noerror,syncと指定します。
えーと、以前、こんなのを書いたことがあって、その中で、ddでパーティション丸ごとコピーする話も入れておいたのですが・・・
今回、これが、なぜか、うまくいきませんでした。どういうわけか、途中から、セクタがずれていってしまうのです。
ちなみに、セクタのずれがないかどうかは、ddに、iseekオプションを指定して、適当な位置を無作為に指定して(ずれていないことを確認するだけなら、パーティションのおしまいのほうを選んで、同じデータか確認すれば、基本的にはいいはず)、ちまちまと調べてみました。きっと、もっとうまく方法はあるんでしょうけど。
コピー元のデータを確認
dd if=/dev/ad10s4 bs=1m iseek=90000 count=1 | hd | head
コピー先のデータを確認
dd if=/dev/ad14s4 bs=1m iseek=90000 count=1 | hd | head
てゆうなことを繰り返しながら、試行錯誤しているうちに気がついたんですが、bs=1mではなくて、bs=16kとか、もっと小さい値を指定すれば、ずれなくなりました。え~?!って感じですが、なんか、そうなりました。
bs=512なら、たぶん一番正確にコピーされるとは思うのですが、データ転送速度が1MBytes/sec程度しかでなくて、あまりにも遅すぎて、お話にならないので、やめておきました。
bsを大きくしていけば、最大で、40MBytes/sec以上でてました。「iostat 1」コマンドで確認できます。
しかし、セクタのずれる現象が気になったし、bs=16kにしても30MBtes/sec程度だったので、よしとすることにしました。
なぜずれちゃうんでしょうか? bsで指定したサイズ内でだけ、ずれてたのでしょうかね? どうも、そうとは思えなかったんですが。まあいいや。
● ブートローダは、個人的に気に入ってるMBMを入れた
これはとくにトラブルもなく、うまくいきました。
なにはともあれ、これで、やっとWindowsのCドライブの内容を、そっくりそのままコピーできて、新しいHDDでブートすることに成功しました。
0 件のコメント:
コメントを投稿