LinuxのHDDに不良セクタが発生したので修復してみた

NAS(Linux機)からファイルを読み出していたら、突然ハングアップしてしまい‥…dmesgを調べてみるとHDDに不良セクターと思しきI/O Errorが発生していました。

sda: Current: sense key=0x3
    ASC=0x0 ASCQ=0x0
Info fld=0x43c024d6
end_request: I/O error, dev sda, sector 1136665808
Buffer I/O error on device sda, logical block 142083226

確かに、このセクターをddで読み出してみると、延々カシャカシャ音を立てるばかり。しばらくするとI/O Errorで失敗します。

dd if=/dev/sda of=/dev/null skip=$((1136665808/8)) bs=4k count=1
(しばらく固まる)
dd: /dev/sda: Input/output error


こういう時は、このセクターに書き込みを行うと、HDDのファームウェア代替(だいたい)セクターに置き換えてくれるはず。
このセクターはファイルデータの一部であることが分かっているので、とりあえず0で埋めます。(ファイルシステムメタデータの一部だと厄介。と言っても0で埋めてあとでfsckをかけてみるくらいしか無いのですが)

注意点として、セクターは512Byte単位ですが、書き込みはLinuxのページサイズである4KB単位で行わないと、データをいったん読み出してから書き込もうとするので、またI/O Errorになってしまいます。
したがって、以下のようにbs=4kを指定して、セクタ番号を8で除算した値を指定します。間違うと別のデータを破壊してしまうので注意。

sudo dd if=/dev/zero of=/dev/sda seek=$((1136665808/8)) bs=4k count=1
1+0 records in
1+0 records out

書き込みに成功しました。

もう一度読んでみると

dd if=/dev/sda of=/dev/null skip=$((1136665808/8)) bs=4k count=1
1+0 records in
1+0 records out

正常に読み出せるようになっていました(というか、そう見えるように代替セクターに置き換えられていると思われます)。


前後のセクターを読んでみても正常そうなので、しばらくこれで様子を見てみます。