Resize ZFS Storage Pool on FreeBSD/TrueOS

Updated on November 21, 2023
Resize ZFS Storage Pool on FreeBSD/TrueOS header image

When upgrading a VPS instance on Vultr, a Linux file system is automatically resized. When running FreeBSD with the advanced ZFS file system, some manual work is required. This guide assumes our account has just been upgraded to include more storage space and walks through the steps of resizing a ZFS volume. In this example, we assume an installation of FreeBSD or TrueOS with ZFS as the root file system. This tutorial should work for similar operating systems, such as FreeNAS.

First, we will get an idea of the size and layout of the hard drive. From here forward, we will assume that our hard drive is device "vtbd0", the first hard drive in a FreeBSD installation. To discover the size and layout of vtbd0, we use the gpart command.

gpart show

We will see one line indicating the size of the drive and its status. The status that we will see at the end of the first line following the drive being resized is "corrupted". After this status line, there will be three lines telling us what partitions are on the drive, which file systems are in use, and the size of each partition. The first partition will likely be a "BIOS-boot" partition, the second is our ZFS volume, and the third is often swap space. This is the layout that we will assume for the purposes of this example. Each partition is assigned an index number. In this case, the index numbers are "1" for the BIOS-boot partition, "2" for the ZFS volume, and "3" for swap. Your layout and index numbers may differ.

The next thing we need to do is to recover the drive's layout so that it is no longer showing as "corrupted". Run the following command:

gpart recover vtbd0

We should immediately see a message saying "vtbd0 recovered". Double-check the drive status by running gpart show again. Next step is to handle the swap partition. If our swap partition comes after our ZFS pool on the drive, it may get in the way of the growing ZFS volume. We will take swap off-line and remove the swap partition by running:

swapoff -a
gpart delete -i 3 vtbd0

These commands turn off swap space and delete partition "3" (the swap partition). Be sure to run gpart show before running gpart delete to ensure that you are removing the correct partition.

Our next step is to resize the ZFS partition. We can take one of two approaches here. If we decide that we do not need swap space at all, then we can take over all free space on the drive and assign it to our ZFS partition by running:

gpart resize -i 2 vtbd0

Alternatively, if we want to continue using swap space, then we can modify the resize command a little. Let us assume that the ZFS partition is currently 10GB and we want to resize it to be 20GB. We would execute:

gpart resize -i 2 -s 20g vtbd0

The "-s 20g" parameter tells gpart to resize the second partition to 20GB. We can confirm that this action completed successfully by running gpart show. The gpart show command will also show us how much space is available at the end of the drive for a new swap partition.

At this point, checking the size of our ZFS storage pool will still display the previous size.

zpool list

To tell the file system to expand and take over the entire second partition of our drive, execute the following:

zpool online -e tank vtbd0p2

The above command resizes the ZFS storage pool named "tank" and takes over the entire second partition of the hard drive. The "p2" at the end of the line indicates we are working with the second partition and, if the layout of your drive is different, the number after the "p" will need to match the ZFS partition index. Remember, you can display the partition index with gpart show.

At this point, we are nearly done. If you don't need swap space, then your setup is complete. Run zpool list to confirm that the storage pool is the proper, larger size.

Otherwise, you have left space at the end of the drive for a swap partition. We can re-add swap space by running a few commands. First, we create a new swap space:

gpart add -t freebsd-swap -s 1g -i 3 vtbd0

This command creates a swap partition 1GB in size. The new partition is added to our hard drive and given the index number "3". Our next move is to enable the swap space so that our operating system may make use of the new partition.

swapon /dev/vtbd0p3

Once again, the "p3" at the end of the line indicates that our swap partition was assigned to index "3". If we used a different index, then the number should be changed to reflect the swap index number in the output generated by gpart show. We can confirm that swap space is enabled and working by running the command:

swapctl -l -h

This will show that 1GB of swap space is in use.

Finally, a word of caution. Removing/re-adding swap space changes the label of the swap partition. This means that the swap entry in the /etc/fstab file will no longer be considered valid. Therefore, swap space will not be enabled after the operating system reboots. To avoid this problem, open the /etc/fstab file and find the line which mounts swap space. Make sure the beginning of the line lists the partition that we just created, /dev/vtbd0p3, as the swap device.