Migrating ZFS from mirrored pool to raidz1 pool

I have a few FreeBSD servers I want to virtualise. They all use ZFS for storage, so I figured a zfs send/receive operation would suffice.

The tricky part is estimating how large the disks on the receiving end must be. The raidz1 pool will be comprised of three (virtual) disks, After trial and error, I arrived at this equation:

ceil(((2*d)+10+3.33)/3)

d is the current amount of data stored in the mirrored pool, measured in gibibytes (GiB). Empirically, the factor 2 could easily be 1.5, but the extra space is hardly a problem and will come handy at some point. Plus, you don’t want your zpool to rise beyond the 70 % marker.

I added 10 GiB for additional poolspace and 3.33 GiB for boot and swap partitions. The sum is divided by 3 to determine the disk size. Create three virtual disks of the size given by the equation.

Each disk has a freebsd-boot partition set to 512 KiB, and a freebsd-swap partition set to 1 GiB. The remaining space is used for the freebsd-zfs partitions, one per disk.

Once the receiving pool is up and running, prepare the receiving computer:

nc -6l 1234 | zfs recv -Fduv poolname

Next, prepare the mirrored pool for transfer:

zfs snap -r poolname@transfer
zfs send -Rev poolname@transfer | nc -6N 2001:db8:d00d:1::2 1234

Remove the transfer snapshot from each contestant:

zfs destroy -Rv poolname@transfer

Set the bootfs property to point to the correct boot environment, if applicable:

zpool set bootfs=poolname/some/bootenv poolname

Shutdown the old computer, and restart the new one. Fingers crossed.