I made a funny mistake in one of my clients when installing FreeBSD 15.1-RELEASE on their server … I have chosen wrong disk for the installation. The server had 4 local disks – 2 of them were some really low end SATA SSD drives (ada0 and ada1) and the server also had 2 fast NVMe disks (nda0 and nda1). I used Auto (ZFS) option in the bsdinstall(8) installer and chosen (wrongly) the ada1 disk.This is how my ZFS pool looked like after installation.freebsd # zpool status zroot pool: zroot state: ONLINEconfig:NAME STATE READ WRITE CKSUMzroot ONLINE 0 0 0 ada1p4 ONLINE 0 0 0… but this is the ZFS world – nothing stops You from adding as many drives to ZFS mirror as You want – so for a start I used FreeBSD gpart(8) tool to copy the partitions from ada1 disk to the NVME nda0 and nda1 drives.freebsd # gpart backup ada1 | gpart restore nda0freebsd # gpart backup ada1 | gpart restore nda1Then as FreeBSD was installed with BIOS+UEFI option I cloned the freebsd-boot partition and the UEFI partition.freebsd # dd bs=1m if=/dev/ada1p1 of=/dev/nda0p1 status=progressfreebsd # dd bs=1m if=/dev/ada1p1 of=/dev/nda1p1 status=progressfreebsd # dd bs=1m if=/dev/ada1p2 of=/dev/nda0p2 status=progressfreebsd # dd bs=1m if=/dev/ada1p2 of=/dev/nda1p2 status=progressNext I added these nda0 and nda1 as mirror devices for ada1 disk. For the record – the ada1p3 is a SWAP device – no need to clone it for obvious reasons.freebsd # zpool attach zroot ada1p4 nda0p4freebsd # zpool attach zroot ada1p4 nda1p4This is when ZFS decided to do the resilvering process immediately (which is good).freebsd # zpool status zroot pool: zroot state: ONLINEstatus: One or more devices is currently being resilvered. The pool willcontinue to function, possibly in a degraded state.action: Wait for the resilver to complete. scan: resilver in progress since Thu Aug 13 18:47:35 2026199G / 199G scanned, 15.5G / 199G issued at 428M/s31.0G resilvered, 7.76% done, 00:07:20 to goconfig:NAME STATE READ WRITE CKSUMzroot ONLINE 0 0 0 mirror-0 ONLINE 0 0 0 ada1p4 ONLINE 0 0 0 nda0p4 ONLINE 0 0 0 (resilvering) nda1p4 ONLINE 0 0 0 (resilvering)errors: No known data errorsWe can even track the status of that replication.freebsd # zpool iostat -v zroot 5 capacity operations bandwidth pool alloc free read write read write---------- ----- ----- ----- ----- ----- -----zroot 199G 229G 25 758 3.11M 42.6M mirror-0 199G 229G 3.21K 95.9K 402M 5.38G ada1p4 - - 25 693 3.11M 36.5M nda0p4 - - 0 4.15K 281 403M nda1p4 - - 0 4.41K 305 413M---------- ----- ----- ----- ----- ----- ----- capacity operations bandwidth pool alloc free read write read write---------- ----- ----- ----- ----- ----- -----zroot 199G 229G 2.89K 8.29K 369M 850M mirror-0 199G 229G 2.89K 8.29K 369M 850M ada1p4 - - 2.89K 383 369M 37.1M nda0p4 - - 0 4.00K 0 406M nda1p4 - - 0 3.91K 0 406M---------- ----- ----- ----- ----- ----- ----- capacity operations bandwidth pool alloc free read write read write---------- ----- ----- ----- ----- ----- -----zroot 199G 229G 2.99K 7.30K 378M 827M mirror-0 199G 229G 2.99K 7.30K 378M 827M ada1p4 - - 2.99K 185 378M 19.9M nda0p4 - - 0 3.54K 7.20K 404M nda1p4 - - 0 3.58K 0 404M---------- ----- ----- ----- ----- ----- -----After resilvering process is finished we can detach the ada1 drive from the ZFS mirror.freebsd # zpool detach zroot ada1p4… and after all these quite simple and predictable operations – everything when the system was still running – we have FreeBSD installation migrated from ada1 disk to ZFS mirror on two NVMe nda0 and nda1 disks as shown below.freebsd # zpool status zroot pool: zroot state: ONLINE scan: scrub repaired 0B in 00:00:08 with 0 errors on Thu Aug 13 23:20:152026config:NAME STATE READ WRITE CKSUMzroot ONLINE 0 0 0 mirror-0 ONLINE 0 0 0 nda0p4 ONLINE 0 0 0 nda1p4 ONLINE 0 0 0errors: No known data errorsIts kinda short article (for my standards) but it shows what was needed and possible with ZFS and other FreeBSD tools to do the job.EOF