btrfs send receive のエラー

btrfs send receiveでエラー発生して、外付けのHDDにbackupのsnapshotをコピー出来無くて悩んでいます。 原因を調査中です。もしかしたらバックアップ対象のfsにエラーがあるのかもしれません。

snapshotはsubvolume単位で取得します。 コマンドは

btrfs subvolume -r snapshot [src] [dest]

で取得できます。 なんとなく予想できると思いますが、-rはREAD_ONLYという意味です。 どういう訳かはわかりませんが、READ_ONLYじゃないとbtrfs sendでエラーが発生して実行できません。 今は/のみ取得していますが、リストアには/bootも必要なので、 最終的には両方取得するスクリプトを書くことになると思います。 どうやってリストアするのかはこれから調べます。

dmesgでエラーが確認できます。

BTRFS warning (device sda3): csum failed root 747 ino 91831861 off 9555968 csum 0xedd5c6f1 expected csum 0x5126b9cd mirror 1

いくら btrfs scrub しても uncorrectable errorは消えませんでした。

何度かググってみて、

find / -inum

で壊れたファイルが検索できる事がわかりました。

inode番号が番号に一致したファイルを検索するという意味らしいです。

# find / -inum 91831861
./var/log/messages-20200428

壊れたファイルが見つかったので削除し、 うーん、削除していいんでしょうか? もう一度scrubをかけてみます。

# btrfs scrub start /

やった、これでエラーが出なければsend receiveうまくいくと思ったら、バーってエラーが出ました。

scrubのログは/var/lib/btrfs/にある。 しかし、読みづらいし、エラーが出たファイルのinode番号を記録してくれない様なので、あまり使い道がないかもしれません。

dmesgを見ると、エラーが出たファイルのinode番号が分かります。

[ 5801.359663] BTRFS warning (device sda3): csum failed root 5 ino 91831989 off 1015808 csum 0xbdcc0186 expected csum 0x52118d64 mirror 1

inode番号からエラーになっているファイルを特定します。

# find / -inum 91831989
/var/log/debug.log-20200503

特定したファイルを削除します。

つまり、エラーがなくなるまで以下のループを繰り返します。

1.btrfs scrub start /

2.btrfs scrub status / で たまにチェックし、エラー発生したら3へ。

3.btrfs scrub cancel /

4.inode番号からファイルを特定し、削除します。

# btrfs scrub status /
UUID:             ce760fa2-8e25-4e7e-89d8-18329003541e
Scrub resumed:    Thu Jul 23 16:48:50 2020
Status:           finished
Duration:         0:39:03
Total to scrub:   309.57GiB
Rate:             135.72MiB/s
Error summary:    no errors found

btrfs_scrub_end

この後、btrfs send receiveは無事成功しました。

btrfs_send_receive_end

コマンドの終了ステータスを取得しようとしたんですが、$?を#?と間違えてしまったため、空白が出力されてしまいましたが、 コマンドが何の異常もなく終了しているので、問題なしとしました。