ZFS root の再構築でちょっと苦労した

zpool でエラーが出た

ちょっと zpool status してみたらエラーがあるぞと言われ、zpool statux -vx してみということなのでやった結果が以下。 <0xc729>:<0xf1b5> となっているのは、エラーがあるスナップショットを消したらなくならないかと思ってやったけど消えませんねというやつ。

  pool: dim
 state: ONLINE
status: One or more devices has experienced an error resulting in data
    corruption.  Applications may be affected.
action: Restore the file in question if possible.  Otherwise restore the
    entire pool from backup.
   see: https://openzfs.github.io/openzfs-docs/msg/ZFS-8000-8A
  scan: scrub repaired 0B in 00:09:05 with 0 errors on Fri Jan 19 04:06:21 2024
config:

    NAME        STATE     READ WRITE CKSUM
    dim         ONLINE       0     0     0
      raidz2-0  ONLINE       0     0     0
        ada0p3  ONLINE       0     0     8
        ada1p3  ONLINE       0     0     8
        ada2p3  ONLINE       0     0     8
        ada3p3  ONLINE       0     0     8

errors: Permanent errors have been detected in the following files:

        dim/ezjail/alphanor@daily-2024-02-17:/usr/local/include/boost/url/grammar/variant_rule.hpp
        <0xc729>:<0xf1b5>
        dim/ezjail/alphanor@daily-2024-02-16:/usr/local/include/boost/url/grammar/variant_rule.hpp
        dim/ezjail/alphanor@daily-2024-02-18:/usr/local/include/boost/url/grammar/variant_rule.hpp

親切にも https://openzfs.github.io/openzfs-docs/msg/ZFS-8000-8A を読んでみなと言っているので読んでみたところ、

Unfortunately, the data cannot be repaired, and the only choice to repair the data is to restore the pool from backup. Applications attempting to access the corrupted data will get an error (EIO), and data may be permanently lost.

とか言われる。 その下を読んでみるとファイルのデータがおかしいだけなら上書きするだけでよさそうだけれども、どうも最悪のケースぽいので pool を再構築することにした。

データ移行

新しい pool を用意してデータを移すのはわりと楽な話で、 別のPCでバックアップを格納しているガチャベイ を借りてきてHDDを4台突っ込んで zraid2 で pool を作成し、 ZFS のバックアップ - Cugel’s Saga で書いたように取ってあるバックアップからデータを移せば済む。 今回は pool は一応生きているので、壊れていない snapshot を zfs send で転送した。 エラーが出ているファイルシステムだけは、1月頭の snapshot まで2か月弱遡らないと転送できなかったが、 幸いそこはしばらく触っていなかったのでログが少し失われたくらいで済んだ。

起動ではまる

boot しない

さて、新しい pool の作成はそんなに苦労せずに済んだのだが、 この pool の ROOT から起動するのができなくて時間をとってしまった。

bectl

これは私が最近の ZFS root 事情を知らなかったせいで、 いまどきは bectl で起動するファイルシステムを指定する必要があるのであった。 新しい pool は当然 Boot Environment が登録されていないので、 -r オプションで beroot を指定する。-t オプションは「次回起動時より」の指定である。

# bectl -r mar/ROOT activate -t default