2012年 11月 15日
SUSE Linux での dd_rescue
ということで「何か」ありました。ディスクのI/Oエラーです。
こういうときに役立つのが dd_rescue で、よく knoppix のライブCDで起動して使うケースが多いようです。以前「それでもお前はサーバーか」というような安物サーバーを修復するために使ったことがあります。それも方法の一つですが、どうせなら SUSE でやるのが粋というものです。なぜ粋なのかは聞かないでください。ライブCDで起動したのでは、ログファイルの保存ができません。シャットダウンする前にUSBメモリなどのどこかに保管する必要があります。
もっとも、救えるものは「救えるファイル」だけなので、そこは諦めるしかありません。セクタエラーが出て、/ (root)パーティション がマウントできない、と言った事態には対処できないのでご注意ください。
ちなみに Linux だけではなく Windows もディスク丸ごとバックアップできるので、修復用マシンに用意しておいてもいいかも知れません。
もし、サーバに空きパーティションがあれば、そこに New Install でインストールします。ブートローダーが書き換わりましたら、救済用パーティションから起動します。
CUI のYaST ではスペースキーで 'ddrescue' を選ぶとインストールされます。
※ コメントにもご指摘ありましたが SUSE でのパッケージは ddrescue ですが、インストールされるプログラム名、コマンドは /bin/dd_rescue です。一応 GNU GPL2.0 で配布されているものですが一般的な GNU 版とは微妙に違う様です。
これでインストールできたので、ddescue の学習です。コマンドを叩くと次のようなヘルプが出ます。これが全てですので、救済中にあまりにもすることがないので、意訳してみました。
※あくまでも SUSE での ddrescue です。
※補足
opensuse の"ソフトウェア検索"からブラウザで 1 Click Install も出来ます。YaST のインストーラが立ち上がるので、指示に従ってインストールします。SUSE 版
ここでは SUSE 版を説明しています(多分.....)
よく使いそうなオプションは太字で記します。
--ここから
options:
-s ipos 開始位置 ipos入力ファイル(def=0)
-S opos 開始位置中の出力ファイル (def=ipos)
-b softbs コピーブロック・サイズ、(def=65536)
-B hardbs エラーが出たときfallback するブロックサイズ (def=512)、
-e maxerr、maxerrエラー数の後、終了 (def=0=無限大:つまり終了しない)
-m maxxfer 転送される量の最高値 (def=0=inf)
-y syncfrq 出力ファイルに fsync する呼び出し頻度 (def=512*softbs)
-l logfile エラーと要約を記録するファイル(def="")
-o bbfile 不良ブロックを記録するファイル(def="")
-r 逆方向コピー(def=前から) ※くどいけど注意 - 後ろのブロックからコピーするオプションです。他のディストリビューションの GNU 版では "retry 数"になるようです。
-t 出力ファイルを切り詰める、(def=no)
-d/D 入出力用O_DIRECT使用(def=no)
-w 書き込みエラーで異常終了(def=no)
-a spArseファイル記述(def=no)
-A zeroed のエラーでも常にブロックを書く(def=no)、
-i 対話型:データを上書きする前に尋ねる(def=no)
-f 強制モード: いくつかの Sanity check(まともかどうか)をスキップする(def=no)
-p 維持モード: 所有権などの維持(def=no)
-q quiet モード: 表示なし
-v verbose モード: 表示あり
-V バージョン表示して終了
-h このヘルプを表示して終了
注:
サイズは、ユニットb(=512)、k(=1024)、M(=1024^2)あるいはG(1024^3)バイトの中で与えられるかもしれません。
それが必ずしも異常終了しないか、出力を切り詰めないので(Trancate)、このプログラムはI/Oエラーの場合にはデータを救うのに有用です。
--ここまで
あとは、増設ディスクをつけたり、NASをCIFSマウントするなりして、パーティションを丸ごとファイルにバックアップしてみます。もっとも、その場合、「rescue 用ディスク」と「再リカバリ用ディスク」の2台が、しかも、壊れたディスクより容量の大きなものが必要になるので、懐が痛むところです。
次の例は、 sdb1 のパーティションを rescue.img にバックアップする時に実行したものです。通常は sda を sdb にバックアップするのですが、sda より sdb の方がサイズが大きいものを用意するので、残りがもったいない。ということで、パーティション>パーティションではなく、パーティション>ファイル で実行しました。もし、LAN内に空き容量の大きな NAS があれば、マウントしてターゲットとして考えてみるのも手段でしょう。USB 接続も良いのですが、あまり転送速度が出ません。
# dd_rescue -v /dev/sdb1 /rescure-dir/rescue.img -l "dd.log"
※実際には -b 655360 を付けて実施しました。
-v をつけないとダンマリとします。必ず付けておきましょう。 -l の後のログファイルは "file" と必ずダブルクォーテーションで囲みます。もし dd_rescue が失敗したり、^C を間違って押してもログファイルがあれば引き続き操作をしてくれるようです。
※ くどいようですが SUSE Linux での例です。他のディストリビューションではかなり「方言」があります。オプションを確認してください。
※ 転送元と転送先を間違えると「がっかり」な悲惨な結果になります。一旦マウントしてみて内容を確認するなり fdisk -l でディスクのサイズや mount コマンドなどで確認するなりの作業をしっかり行ってください。実行する前に、同僚に確認してもらうという事も重要です。
なお、SATA ディスクの場合、エラーの頻度にもよりますが、一時間あたり 30Gb ほど処理してくれるようです。これは、-b オプションをつけないでデフォルトの 65536 で行った場合です。 -b 655360 と十倍にしてみるとかなり速度は上がるようです。大体2~3倍くらいは向上するようです。syncfrq に影響してログがなかなか作成されないようなので、ここまでサイズを大きくする必要はなさそうです。
※ 通常のエンタープライズ向けの SAS Raid のシステムだと I/O エラーはハードウェアが代替してくれるので、タマが壊れない限りお世話にならないかもしれません。
ls -lh コマンドでrescue.img ファイルのサイズが増えていくことで確認します。途中ログが書かれますので、これも cat してみてください。
このような感じで log が作成されます。エラーがぼろぼろ出てきます。デフォルトではすぐに作成されますが、 -b オプションでブロックサイズを大きく取ると、ログの同期 fsync まで数時間かかる場合があるようです。
sles11:/rescue/ # cat dd.log
dd_rescue: (info): about to transfer 0.0 kBytes from /dev/sdc1 to /share/wd3t/rescue1.img
dd_rescue: (info): blocksizes: soft 655360, hard 512
dd_rescue: (info): starting positions: in 0.0k, out 0.0k
dd_rescue: (info): Logfile: dd1.log, Maxerr: 0
dd_rescue: (info): Reverse: no , Trunc: no , interactive: no
dd_rescue: (info): abort on Write errs: no , spArse write: if err
dd_rescue: (info): about to transfer 0.0 kBytes from /dev/sdc1 to /share/wd3t/rescue1.img
dd_rescue: (info): about to transfer 0.0 kBytes from /dev/sdc1 to /share/wd3t/rescue1.img
dd_rescue: (info): blocksizes: soft 655360, hard 512
dd_rescue: (info): blocksizes: soft 655360, hard 512
dd_rescue: (info): starting positions: in 0.0k, out 0.0k
dd_rescue: (info): starting positions: in 0.0k, out 0.0k
dd_rescue: (info): Logfile: dd1.log, Maxerr: 0
dd_rescue: (info): Logfile: dd1.log, Maxerr: 0
dd_rescue: (info): Reverse: no , Trunc: no , interactive: no
dd_rescue: (info): Reverse: no , Trunc: no , interactive: no
dd_rescue: (info): abort on Write errs: no , spArse write: if err
dd_rescue: (info): abort on Write errs: no , spArse write: if err
dd_rescue: (info): ipos: 307510400.0k, opos: 307510400.0k, xferd: 307510400.0k
errs: 0, errxfer: 0.0k, succxfer: 307510400.0k
+curr.rate: 2089kB/s, avg.rate: 20609kB/s, avg.load: 1.4%
dd_rescue: (info): ipos: 307510848.0k, opos: 307510848.0k, xferd: 307510848.0k
* errs: 0, errxfer: 0.0k, succxfer: 307510848.0k
+curr.rate: 657kB/s, avg.rate: 20608kB/s, avg.load: 1.4%
dd_rescue: (warning): /dev/sdc1 (307510848.0k): Input/output error!
Bad block: 615021728
dd_rescue: (info): ipos: 307510880.0k, opos: 307510880.0k, xferd: 307510880.0k
* errs: 1, errxfer: 0.5k, succxfer: 307510848.0k
+curr.rate: 1176kB/s, avg.rate: 20608kB/s, avg.load: 1.4%
dd_rescue: (warning): /dev/sdc1 (307510880.0k): Input/output error!
Bad block: 615021729
dd_rescue: (info): ipos: 307510880.0k, opos: 307510880.0k, xferd: 307510880.0k
* errs: 2, errxfer: 1.0k, succxfer: 307510848.0k
+curr.rate: 1393kB/s, avg.rate: 20608kB/s, avg.load: 1.4%
:
: 中略
:
dd_rescue: (warning): /dev/sdc1 (1805216000.0k): Input/output error!
Bad block: -684535289
dd_rescue: (info): ipos:1932731520.0k, opos:1932731520.0k, xferd:1932731520.0k
errs: 568, errxfer: 284.0k, succxfer:1932731264.0k
+curr.rate: 21527kB/s, avg.rate: 19519kB/s, avg.load: 1.7%
dd_rescue: (info): /dev/sdc1 (1932731904.0k): EOF
Summary for /dev/sdc1 -> /rescue/rescue1.img:
dd_rescue: (info): ipos:1932731904.0k, opos:1932731904.0k, xferd:1932731904.0k
errs: 568, errxfer: 284.0k, succxfer:1932731648.0k
+curr.rate: 4533kB/s, avg.rate: 19519kB/s, avg.load: 1.7%
568個のエラーが出ているようです。
後はこのファイルを mount -o loop コマンドで「読めるかどうかでしょう。
.... うまく行くかどうかは to be continue....
.... -b オプションでブロック数を増やして、30時間後 .....
sles11:/rescuet # ls *.img -lh
-rw-r----- 1 root root 1.8T Nov 14 16:13 rescue1.img
sles11:/rescuet # ls dd1.log -lh
-rw-r----- 1 root root 188K Nov 14 16:13 dd1.log
sles11:/rescuet # mount -t ext3 -o loop rescue1.img /mnt
sles11:/rescuet # ls /mnt
disk2 lost+found
sles11:cd /mnt
sles11:/mnt # ls -alh
total 28K
drwxr-xr-x 4 root root 4.0K Jun 24 17:21 .
drwxr-xr-x 23 root root 4.0K Nov 13 07:08 ..
drwxrwxrwx 48 nobody users 4.0K Oct 12 19:37 disk2
drwx------ 2 root root 16K Feb 28 2011 lost+found
sles11:/mnt #
無事マウントできました。この中からデータを救出するのにまた何日かかるか....
-Key word-
SUSE SLES11 Linux dd_rescue ddrescue
その他の情報はこちら
islandcenter.jp
コメントありがとうございます。
突然の非礼失礼いたしました。また修正してくださいましてありがとうございました。
大分古い、過去のお話になりますが、昔、先輩にsendmailについて相談した際、CFについて聞いたことがありました。
その際「CFっていうツールの使い方なんですけど・・・」と聞いたところどうも話が食い違うので情報を確認すると、cfとCF、小文字と大文字で違うツール(ほぼ同じ機能ですが)だったんです。
http://fhuman.esys.tsukuba.ac.jp/StaffOnly/system/turbolinux/sendmail/sendmail.html
このことから、プログラム名の表記に非常に気を使うようになりました。
一般的な感覚では細かすぎるようにも思えますが、UNIX系OSを使う人間としては、この辺の区別はしっかりしておかないといけないと思います。
釈迦に説法となってしまうかもしれませんが、お気に留めていただければ誠に幸いです。
有難うございました。
今、20年ぶりにプログラムを書いていますが、ご指摘のように世の中には間違えの多い資料や書籍が多いですね。
できるだけリアルな操作リストを合わせて公開するように心がけています。参考になって良かったです。今後もご指摘よろしくお願いします。