ZFS: zfs_alloc()/zfs_free() mismatch

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/