まえおき
最近RAIDを新たに構築した。せっかくなので、これまで使っていたXFSから耐障害性が高いと評判のbtrfsに切り替えた。
btrfsの特徴はこの記事が分かりやすかった。
ぜんぜんわからない俺達は雰囲気でbtrfs使っている
この記事ではディスクイメージの一部を破壊したらマウントもできなくなったと書いてあるが、実際にそうなると困るので追試を行った。
実験
10MB程度のtest.zipを作成し、ディスクイメージ内の該当データの先頭の2バイトをCC CC
に書き換えた。
test.zipにアクセスすると、I/Oエラーが出てくれる (バッドセクタではないのにちゃんとチェックサムが働いた)
% cp mountpoint/test.zip .
cp: error reading 'mountpoint/test.zip': Input/output error
dmesgを見るとチェックサムエラーが検知されたことが分かる
% sudo dmesg | tail -n 50
[ 7573.785169] BTRFS warning (device loop20): csum failed root 5 ino 261 off 0 csum 0xeedc5577 expected csum 0xbe9bdcc2 mirror 1
[ 7573.785190] BTRFS error (device loop20): bdev /dev/loop20 errs: wr 0, rd 0, flush 0, corrupt 4, gen 0
[ 7573.785358] BTRFS warning (device loop20): csum failed root 5 ino 261 off 0 csum 0xeedc5577 expected csum 0xbe9bdcc2 mirror 1
[ 7573.785376] BTRFS error (device loop20): bdev /dev/loop20 errs: wr 0, rd 0, flush 0, corrupt 5, gen 0
btrfs scrub
でファイルシステム全体のチェックもできる
% sudo btrfs scrub start -B mountpoint
scrub done for aa165469-63c6-4f62-9d04-5fa4e01f7e49
Scrub started: Mon Apr 3 13:41:21 2023
Status: finished
Duration: 0:00:00
Total to scrub: 91.00MiB
Rate: 0.00B/s
Error summary: csum=1
Corrected: 0
Uncorrectable: 1
Unverified: 0
ERROR: there are uncorrectable errors
scrub後にdmesgを見ると、破損したファイルの名前が分かる
% sudo dmesg | tail -n 50
[ 7446.061071] BTRFS info (device loop20): scrub: started on devid 1
[ 7446.065021] BTRFS warning (device loop20): checksum error at logical 93323264 on dev /dev/loop20, physical 122683392, root 5, inode 261, offset 0, length 4096, links 1 (path: test.zip)
[ 7446.065028] BTRFS error (device loop20): bdev /dev/loop20 errs: wr 0, rd 0, flush 0, corrupt 3, gen 0
[ 7446.065032] BTRFS error (device loop20): unable to fixup (regular) error at logical 93323264 on dev /dev/loop20
[ 7446.065446] BTRFS info (device loop20): scrub: finished on devid 1 with status: 0
最初のI/Oエラーの時点でinode番号が分かるので、findでも確認できる
(負荷がかかるため壊れかけているHDDでは行わない方がいいかも)
% find mountpoint -inum 261
test.zip
結果
実運用では、データ部分にバッドセクタが発生した程度ならこのように問題なさそうだ。原因不明のデータ化けも発見できそうで優秀。
参考記事と異なる結果になったのは、参考記事ではWorldをWORLDに書き換えたことでファイル名部分も破壊され、メタデータ領域の破損として扱われたためにマウントできなかったのかもしれない。
補足
チェックサムを無視してファイルを取り出したいときは、マウントオプションにrescue=ignoredatacsums,ro
を指定する。
% sudo mount -t auto -o rescue=ignoredatacsums,ro crash.img mountpoint
% cp mountpoint/test.zip .
%
もちろんデータは壊れているので、少しでもサルベージしたいときのための方法。