S.M.A.R.TでUncorrectable error in data(Offline Uncorrectable)が発生したので,ファイルを特定してHDD(ext4)からデータを救出
背景
4.0TのHDDを長いこと使っていた.
Seagate BarraCuda 3.5(SMR)
ST4000DM004-2CV104
で,たまたまgsmartctl
を走らせてみたらError Logが真っ赤ではないか.
しかもUncorrectableとか書いてあるしもうヤバい.
具体的にはこんなエラー
Uncorrectable error in data at LBA = 0x2e7ff908 = 780138760
なんて脅してきた.
LBAだけ与えられてもどのファイルか分からないとどうしようもない.
というわけで早速チェックしていく.
そんな長いこと使っていたといってもSpindle Motor Power-on Hoursだけでいうと17,476だったので,728日およそ2年ぐらい.
そこそこ起動させっぱなしにしていたとはいえ,24時間365日付けていたわけではない.
Statisticsを見た限り,
Number of Reallocation Canditate Logical Sectorsが16あって,
Number of Reported Uncorrectable Errosが4
そして,Time in Under-Temperature(C)が1,360だ.
Time in Under-Temperature(C)の意味が分からないのだが,冷えすぎるとダメなの?
の前に
こんなエラーが出るってことはHDDは壊れかけなので,
できるだけ余計な負荷を与えないようにしたい.
ファイルの書き込みや削除なんか.
ゴミ箱を絡にしたりrmしたりも注意だ.
そして新しいHDDの購入手続きを進めておくこと.
私はバックアップをとらない過激派(HDDはどうしても常時可動させたくなっちゃう)なのでストックはない.
ファイルの特定の流れ
本当はS.M.A.R.T.が出してくれたエラーをそのまま使えるといいんだけれど,
LBAからファイルの位置を特定する方法が見つからなかったので,
badblocks
を使ってもう一度チェックする.
ここでbadblocks
のデフォルトのセクタサイズは1024になっているので,
sudo fdisk -l
とでもして,セクタサイズを調べておく.
購入時にフォーマットしたのがデフォルトの4096なのでこれを-b
オプションで指定する.
sudo badblocks -v /dev/sdxx -b 4096
ちなみにこの時はパーティションを区切った後のを指定しておいた方が楽だ.(/dev/sdaではなく/dev/sda1ということ)
でないとsda1のパーティションの始まりの場所を引く必要が出てくる.
というわけでこのコマンドを実行すると数字が出てくる.
この数字がエラーの発生した箇所を示してくれている.
次にこの場所にファイルがあるかどうかを確認する.
これ以降はdebugfs
を使う
私の環境ではこれ以降のコマンドは返ってくるまでにかなり時間がかかった.
遅くても我慢強く待つのがよいだろう.
sudo debugfs /dev/sdxx
debugfs: testb <block num>
ここで使用中でなければ救出の必要はない.
こんな風に返ってくる
使用されている場合
Block <block num> marked in use
使用されていない場合
Block <block num> not in use
今回はなんとmarked in use.ファイルが壊れてしまった.
まあまだ何とかなるかもしれないと思い,
ブロック番号からinode番号を調べる.
debugfs: icheck <block num>
これでファイルがあれば二つの数字が帰ってくる.
一つ目がブロック番号で2つ目がinode番号だ.
debugfs: ncheck <inode num>
これでファイル名が特定できる.
ファイルを救出する
この時点でファイルが壊れているので,後はどこまで読めるかだ.
致命的な場所さえ壊れていなければ,最近の優秀なソフトでは以外とそのまま読み込めたりするので,まだ諦めてはいけない.
ここでcpコマンドはディスクの読み込みエラーを起こすと途中で止まる
cp: error reading <file>: Input/output error
というわけで,それでも無理矢理読んでくれるコマンドddrescue
を使う.
使い方はcp
と同じだ.
ddrescue <src> <dst>
コマンドの詳細は残っていないが
今回は512byteつまり4096の1セクタ分が壊れてしまったようだった.
ファイル自体はzipで画像1ファイルだけ解凍に失敗したが,画像としては読み出せた.
ただ画像の途中から色は変わっていたが,上出来だ.
新機HDDに移行する
というわけで壊れかけのHDDから新しいHDDにデータを移行する.
パーティショニングやフォーマットについては割愛.
今回はHDDはまだ元気そう?だったのでcpコマンドでいった.
ただ,もっと自体が深刻であればddrescue
を使った方がよいだろう.
途中でcpが失敗しても分かるように,そして途中経過が分かるように次のようにした.
cp -r -v /mnt/<src>/* /mnt/<dst>
-r
で再帰的に-v
で途中経過を表示するようにした.