swap gpt labels for zfs
so i have an issue. i have a 36 bay nas running freebsd and i want to move disks around. i use gpt labeling in order to know where disks are. this is way better because you can label them into a grid and if one fails then you don’t have to go easter egg hunting for a failed disk. even worse you won’t accidentally yank the wrong disk out and cause an even bigger issue.
although this is about moving disks i’ll do the basic initial setup for reference. consider that you are creating a pool from scratch and take note what /dev it is using when you put the drive in (dmesg or /var/log/messages should show this). in my example i am going to use /dev/da4 because that’s what i have available right now to “play” with.
# gpart show da4
=> 40 7814037088 da4 GPT (3.6T)
40 88 - free - (44K)
128 4194304 1 freebsd-swap (2.0G)
4194432 7809842696 2 freebsd-zfs (3.6T)
before we move on. while this isn’t too important and zfs will use whatever you throw at it but if you want to add another disk to a pool (with raidz expansion or create a mirror it’s probably a good idea to make sure they are the same sized disks and have the same partition table). in this example assume you added a disk that is now /dev/da5
# gpart backup da4|gpart restore -F da5
# gpart show da5
=> 40 7814037088 da5 GPT (3.6T)
40 88 - free - (44K)
128 4194304 1 freebsd-swap (2.0G)
4194432 7809842696 2 freebsd-zfs (3.6T)
you can also copy one partition table to multiple disk by just stringing them along.
# gpart backup da4|gpart restore -F da5 da6 da7 da8 da9
back to labeling da4
# gpart modify -i 2 01-WD_REDPLUS-SERIALNUMBER da4
i have 36 bays in my ancient isilon. i used to add F01-02 and do it in a grid but i find it easier to just number them like a typewriter nowadays. my isilon is 4 across and 6 down in the front and 4 across 3 down in the back (it has 12 hotswap bays in the rear of it).
the command above modifies the even further above partition table to make partition 2 (the one that says freebsd-zfs and is the bulk of the drive) to use the label 01-WD_REDPLUS-SERIALNUMBER. you may want to get all this information from the drive before you put it in or you can just put it in and grab it from smartctl -a /dev/da4.
after this is done you SHOULD be able to add the partition to a zfs pool by adding /dev/gpt/WD_REDPLUS-SERIALNUMBER to it. if you have problems you can confirm that the label is correct.
# gpart show -l da4
=> 40 7814037088 da4 GPT (3.6T)
40 88 - free - (44K)
128 4194304 1 - (2.0G)
4194432 7809842696 2 01-WD_REDPLUS-SERIALNUMBER (3.6T)
it should look something like that. the gpt labeling is not unique to zfs and you can rename the swap partition too if you want to use the label for that in fstab or something. there’s quite a bit you can do with it but the labeling is exactly that: labeling partitions so you know what they are.
moving onto what i need to do… i actually need to rename quite a few of the disks in order to use the new numbering system and because i am removing an old pool and want to use raidz expansion so i don’t want disks staggered all over the place (ocd).
just a quick note: shut down before moving a bunch of disks around. zfs doesn’t care so much if you’ve moved disks to different bays. it definitely will not like it if you yank four disks out at once while it’s running.
remember. in my case i am just trying to move and rename. so i already have existing gpt labels on all the partitions. this is a good place holder to know what to do after you rename them with gpart…
# zpool set path=/dev/gpt/NEWLABEL pool gpt/OLDLABEL
now to the nitty gritty. i’m going to just show this in code format and i’m sure most people will just jump to this part… i may put this on top in a tl;dr section. i already did 2 of these and reboot to make sure this works.
# gpart show -l da3
=> 40 15628053088 da3 GPT (7.3T)
40 88 - free - (44K)
128 4194304 1 R01-03_REDACTED-SWAP (2.0G)
4194432 15623858696 2 R01-03_Seagate_BarraCuda_REDACTED (7.3T)
# gpart modify -i 2 -l 27-Seagate_BarraCuda_REDACTED da3
da3p2 modified
# gpart modify -i 1 -l 27-Seagate_BarraCuda_REDACTED-SWAP da3
da3p1 modified
# gpart show -l da3
=> 40 15628053088 da3 GPT (7.3T)
40 88 - free - (44K)
128 4194304 1 27-Seagate_BarraCuda_REDACTED-SWAP (2.0G)
4194432 15623858696 2 27-Seagate_BarraCuda_REDACTED (7.3T)
# zpool set path=/dev/gpt/27-Seagate_BarraCuda_REDACTED pool gpt/R01-03_Seagate_BarraCuda_REDACTED
# zpool status pool -v
pool: pool
state: ONLINE
scan: scrub repaired 0B in 16:27:08 with 0 errors on Thu Dec 11 10:20:43 2025
expand: expanded raidz2-0 copied 69.2T in 2 days 11:33:54, on Wed Dec 10 17:53:35 2025
config:
NAME STATE READ WRITE CKSUM
pool ONLINE 0 0 0
raidz2-0 ONLINE 0 0 0
...
gpt/27-Seagate_BarraCuda_REDACTED ONLINE 0 0 0
...
errors: No known data errors
there you have it. this seems to have worked for me. luckily if you mess up your labeling then zfs will know there’s a problem because it tags the partitions so things like this can’t mess it up and will fall back to the typical /dev/da3p2 name in zpool status. you can probably just fix it from there if need be.