自宅サーバのrootfsをbtrfsにした

Posted: 2023/12/02
Category: 知性

この記事は さくらインターネット Advent Calendar 2023 2日目の記事ですが、100%趣味の話だけで特にサービスに関係ある話は出てきません。

経緯

主に NAS 用途で使用しているサーバの / が壊れた。だいたい問題なく使用できるものの、特定のファイルにアクセスしようとしたときにエラーが出る感じで SSD の寿命のようだった。

SSD を交換して一件落着となればよかったのだが、思いのほか広範囲でファイルが壊れていたようでディスクをコピーしただけではいろんなコマンドが実行できないようになってしまった。壊れているファイルを見つけ次第直す方針でも良かったのだが、せっかくなので SSD を RAID1 構成で束ねることにした。

SSD の故障

SSD は HDD と違って物理的な問題でディスク全体が読めなくなるようなことは少ない。それはすなわち壊れるときには少しずつ壊れていくケースが多いということであり、一見正常に書き込めているようでもいざ読み込んでみると特定の部位だけ読めないということが往々にして発生する。

今回はまさにそのケースで、普段使っているコマンドが叩けなくなるまで問題が起きていることに気付かなかった。 dmesg 見ると読み込んだ時点で I/O エラーが起きている旨のログが出ていたのだが、 SMART の bad sector とか reallocated sector のカウントは増えていなかったので見落としていた。

再発防止策の検討

今回のような問題は、定期的にディスク全体が正常に読み取れるかどうかを確認することで早い段階で検出することができる。再発防止策として何かをするならこれをやるべきだろう。

これを実現するためには書き込んだデータのチェックサムがどこかに保管されていることが必要となる。この"どこか"はどこでもいいのだけど、ファイルシステムで良い感じに持っていてもらうと簡便で都合がいい。

一方で、書き込んだデータのチェックサムを保持しているファイルシステムは意外と少ないようで、自分が知る限りでは ZFS と btrfs のどちらかぐらいしかこの機能を持っていなそうであった。

rootfs に使用するファイルシステムの選定

ZFS は NAS のストレージ領域のファイルシステムとして使っているので操作には慣れており安心感がある。一方で ZFS と Linux がライセンス的に相性最悪なのはよく知られている通りで、ブートドライブとして利用するのはそれなりの面倒が伴う。

btrfs は Linux カーネルで標準サポートされており何も考えず使い始めることができ、 Ubuntu のインストーラーでポチポチやったらそのままブート可能なディスクのファイルシステムとして使用でき、全く触ったことがなく操作に慣れていないことまで含めて ZFS と正反対の特徴があるといった感じだ。比較的歴史が浅く Twitter で壊れた報告を見かけた記憶があるが、それももう10年ぐらい前だし、 公式の Status ページ によれば RAID56 組まない限りだいたい OK という感じらしい。

どちらもファイルシステムの管理コマンドで RAID が組めたり、マウントしたままの状態で整合性の確認(scrubと呼ばれることが多い)が行えたりと便利さという面ではほとんど変わらなさそうだ。

ごちゃごちゃ書いてきたが最終的に選んだのはタイトルの通りで btrfs で、 OS で標準サポートされているならアップデートの度に面倒なことが起きたりはしないであろうこと、触ったことがないので面白そうというのが理由だ。 安定性に対する不安さがないといえば嘘になるが、壊れるときは何やっても壊れるのでこの際気にしないこととした。

構成

この記事を書いている時点で作業を行ってから1ヶ月半程度経ってしまっているので、以下の作業ログは記憶と捏造に基づくものとなっていることを先にお断りしておく。

btrfs を使うことが決まった。せっかく便利なファイルシステムなのでどうせなら RAID1 でディスクを2本まとめてみようと思う。

インストール

Ubuntu 22.04のインストーラーで btrfs を使用するディスク構成とするだけで rootfs として btrfs を使い始められる。

btrfs からブートするシステムが出来上がったら、 / にスペアのディスクを追加する。

$ sudo btrfs filesystem show /
Label: none  uuid: a5d399e1-b301-41ef-87e7-147db767cf71
        Total devices 1 FS bytes used 44.22GiB
        devid    1 size 900.00GiB used 49.06GiB path /dev/sde3
$ sudo btrfs device add /dev/sdf1 /

追加しただけだと元のディスクに書かれたデータがそのまま置かれているだけなので、 RAID1 指定でバランス処理を行い、新しく追加したディスクにデータをコピーする。

バランス処理が終わると2つのディスクの used の値が同じになり、良い感じにミラーリングされてることが確認できる。

$ sudo btrfs balance start -dconvert=raid1 -mconvert=raid1 /
$ sudo btrfs filesystem show /
Label: none  uuid: a5d399e1-b301-41ef-87e7-147db767cf71
        Total devices 2 FS bytes used 44.22GiB
        devid    1 size 900.00GiB used 49.06GiB path /dev/sde3
        devid    2 size 900.00GiB used 49.06GiB path /dev/sdf1

scrub してみる

良い感じにミラーリングできたところで、導入した目的の1つであるところの scrub をかけてみてエラーがないかチェックしてみる。

といっても scrub を開始するのに必要なのはコマンドを1つ叩くだけなので何も難しいことはない。

$ sudo btrfs scrub start /
scrub started on /, fsid a5d399e1-b301-41ef-87e7-147db767cf71 (pid=1871487)

終わったかどうかは btrfs scrub status <mountpoint> を叩けば確認できる。

$ sudo btrfs scrub status /
UUID:             a5d399e1-b301-41ef-87e7-147db767cf71
Scrub started:    Sat Dec  2 10:27:21 2023
Status:           running
Duration:         0:00:05
Time left:        0:02:57
ETA:              Sat Dec  2 10:30:23 2023
Total to scrub:   88.45GiB
Bytes scrubbed:   2.42GiB  (2.74%)
Rate:             495.82MiB/s
Error summary:    no errors found
$ sudo btrfs scrub status /
UUID:             a5d399e1-b301-41ef-87e7-147db767cf71
Scrub started:    Sat Dec  2 10:27:21 2023
Status:           finished
Duration:         0:03:35
Total to scrub:   88.43GiB
Rate:             421.26MiB/s
Error summary:    no errors found

btrfs の壊し方

これで無事に btrfs 環境が構築できたわけだが、自分はこのとき作業をミスってブートできない状況になってしまった。

何を間違えたかというと、追加するディスクを間違えて、新品ではなく故障品のディスクをアレイに追加してしまった。この状態で RAID1 へのバランス処理を始めてしまった結果、I/Oエラーが多発して処理が進まなくなった。こうなると再起動する以外手は無いが、 btrfs はバランス処理中のファイルシステムからブートさせようとするとエラーを吐くらしく 1 、 initramfs 環境で skip_balance オプション付きでマウント後、どうにかして raid1 でのバランス指定を解除し single 構成に戻した後再起動させる必要があった。

また、正常に RAID1 として運用できてるファイルシステムで、片側のディスクを引っこ抜いた状態でブートさせようとするとエラーを吐いて止まってしまう。これを解決するにはカーネルに rootflags=degraded というオプションを付けて起動させればとりあえず起動させることができる 2 3

遭遇した問題を見てると、どれもファイルシステムが壊れているわけではなくどうしようもない状態を検出して btrfs が処理を停めているという感じなので、何かあったら安全側に倒す設計なのだな~という気分になった。

おわり

なんやかんやとありつつ無事に自宅サーバのファイルシステムが btrfs になった。1ヶ月半程度動かし続けているが当然問題はなく快調に動き続けてくれている。 雑に OS 入れて動かし続けていたサーバだったが、今回環境が綺麗になったのでまあ良い機会だったかなと思っている。

1つ問題があるとすれば、なんかディスク入れてるエンクロージャーもダメ?らしく、たまにI/Oエラーを吐いていたり SATA 3Gbps でしかリンクが上がってないことだ。ケーブル新品に替えたりしたんだけど改善しないので、悪いとすればエンクロージャーかマザーかなという感じ。

マザーよりはエンクロージャーが怪しいと思うので交換したいが、 3.5inch ベイに 2.5inch ディスク2発入れるやつがほとんど滅びかけててよさげなのがないので困っている。なんかいいやつないですかね…


  1. うろおぼえなので間違ってたらごめんなさい ↩︎

  2. https://wiki.archlinux.org/title/btrfs#:~:text=You%20will%20get,kernel%20parameters↩︎

  3. https://www.nslabs.jp/linux-btrfs-raid1.rhtml ↩︎