FreeBSD13で運用中のマシンのraidzの1つ(6TB)が壊れて、 ついでなので8TBにしてしまえと、順にリプレースする算段を立てた。
壊れたデバイスを外して新しい8TB HDDを取り付けて 同じようにGPTを切る。
gpart create -s gpt ada1 gpart add -a4k -t efi -s 200m -l efi1 ada1 gpart add -a4k -t freebsd-boot -s 512k -l boot1 ada1 gpart add -a4k -t freebsd-swap -s 2g -l swap1 ada1 gpart add -a4k -t freebsd-zfs -l zfs1 ada1
みたいな感じ。EFIとブートパーティションは面倒だから健全な ada0からもらってこよう(良い子は真似しちゃだめ)。
dd if=/dev/ada0p1 of=/dev/ada1p1 bs=1m dd if=/dev/ada0p2 of=/dev/ada1p2
これがまずかった。
普段ada2から起動していたようで、ada0のブートコードは 最初にFreeBSDインストールしたときの古いコードのままだった。
これでブートするとブートコードを読みに行くところでこんなエラーが出る。
ZFS: zfs_alloc()/zfs_free() mismatch
そのメッセージですぐ検索すればよかったのだが、実はリプレース作業の途中 外付けSATAスタンドで zpool replace をしていたら 外付けデバイスがエラーを吐いてコケることを繰り返し、 データが壊れたと早合点してしまった。そこで、 全データのバックアップを取ってから復旧せねばーとかやっていたので 2,3日かかってしまった。実際には
gpt bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 2 ada1
するだけでよかった(-i 2は freebsd-boot のパーティション)。
【教訓】 RAIDを組んでいるストレージは、普段起動しない ドライブのブートブロックの更新も忘れるな!
https://forums.freebsd.org/threads/zfs-zfs_alloc-zfs_free-mismatch-problem-with-8-2-stable.31215/