RESIZING UFS/ZFS PARTITIONS ON FREEBSD

2017-05-28
In this guide I will show you how to resize the root partition of a FreeBSD VPS using gpart(8). This is quite convenient since it allows us to increase the disk's size of a virtual machine without needing to reinstall the whole operating system. Even if this process is safe and well tested, I strongly recommend you to try this procedure in a development server and to create multiple snapshot of the target virtual machine before proceeding. Since the resize procedure is a bit different while using ZFS, I will cover that case in the last part of the tutorial.

Resize UFS partitions

First, let's figure out which disk we want to resize. Use # gpart show to get a list of available drives. Since I only have one disk, this is the output:
                
root@bsdvm4:~ gpart show
=>      40     52428720    vtbd0  GPT           (25G)
    40     1024        1      freebsd-boot  (512K)
    1064   48234496    2      freebsd-ufs   (23G)
48235560   4193200     3      freebsd-swap  (2.0G)
                
            
You should see the free space at the end of the disk now.

Since partitions can only be resized into contiguous chunk of space, to resize the second partition(i.e., the root partition) we need to delete the third one(which is safe since swap partitions only holds temporary data), resize the second one and then, recreate the swap partition.
  1. Disable swap partition:
  2.                     
    root@bsdvm4:~ swapoff /dev/vtbd0p3
                        
                    
  3. Delete swap partition:
  4.                     
    root@bsdvm4:~ gpart delete -i 3 vtbd0
    vtbd0p3 deleted
    root@bsdvm4:~ gpart show
    =>      40  94371760  vtbd0  GPT  (45G)
        40      1024      1  freebsd-boot  (512K)
      1064  48234496      2  freebsd-ufs  (23G)
    48235560  46136240         - free -  (22G)
                        
                    
  5. Resize partition:
  6.                     
    root@bsdvm4:~ gpart resize -i 2 -s 43G -a 4k vtbd0
    vtbd0p2 resized
    root@bsdvm4:~ gpart show
    =>      40  94371760  vtbd0  GPT  (45G)
        40      1024      1  freebsd-boot  (512K)
      1064  90177536      2  freebsd-ufs  (43G)
    90178600   4193200         - free -  (2.0G)
                        
                    
  7. Recreate swap partition:
  8.                     
    root@bsdvm4:~ gpart add -t freebsd-swap -a 4k vtbd0
    vtbd0p3 added
    root@bsdvm4:~ gpart show
    =>      40  94371760  vtbd0  GPT  (45G)
        40      1024      1  freebsd-boot  (512K)
      1064  90177536      2  freebsd-ufs  (43G)
    90178600   4193200      3  freebsd-swap  (2.0G)
                        
                    
  9. Grow UFS partition:
  10.                     
    root@bsdvm4:~ growfs /dev/vtbd0p2
    Device is mounted read-write; resizing will result in temporary write suspension for /.
    It is strongly recommended to make a backup before growing the file system.
    OK to grow filesystem on /dev/vtbd0p2, mounted on /, from 23GB to 43GB? [yes/no] yes
    super-block backups (for fsck_ffs -b #) at:
    48657216, 49937664, 51218112, 52498560, 53779008, 55059456, 56339904, 57620352, 58900800, 60181248, 61461696, 62742144, 64022592, 65303040, 66583488, 67863936,
    69144384, 70424832, 71705280, 72985728, 74266176, 75546624, 76827072, 78107520, 79387968, 80668416, 81948864, 83229312, 84509760, 85790208, 87070656, 88351104,
    89631552
                        
                    
  11. Activate swap partition:
  12.                     
    root@bsdvm4:~ swapon /dev/vtbd0p3
                        
                    
The disk is now resized.

Resize ZFS partitions

In this last part of the tutorial we will redo the same thing but using ZFS instead of UFS. While the process is quite similar, there are some aspects related to ZFS pools that may lead to confusion. So let's get started by listing available disks in our system:
                
root@bsdvm4:~ gpart show
=>      40  52428720  vtbd0  GPT  (25G)
    40      1024      1  freebsd-boot  (512K)
  1064   4194304      2  freebsd-swap  (2.0G)
4195368  48233392      3  freebsd-zfs  (23G)
                
            
We want to extend the last partition of the disk(i.e., the root partition) but first, let's extend the physical disk image. As always, shutdown your virtual machine and then use your hypervisor's tools to edit the disk. Since I'm using QEMU/KVM, I will use qemu-img(1):
                
$> qemu-img resize bsdvm04.qcow2 +20G
                
            
Now start your machine and run # gpart show, you should get something like this:
                
root@bsdvm4:~ gpart show
=>      40  52428720  vtbd0  GPT  (45G) [CORRUPT]
    40      1024      1  freebsd-boot  (512K)
  1064   4194304      2  freebsd-swap  (2.0G)
4195368  48233392      3  freebsd-zfs  (23G)
                
            
Like before, since I'm using a GPT partition scheme and since the GPT partition scheme backup is no longer at the end of the disk, the disk is flagged as corrupted. To fix this, simply run:
                
root@bsdvm4:~ gpart recover vtbd0
vtbd0 recovered
root@bsdvm4:~ gpart show
=>      40  94371760  vtbd0  GPT  (45G)
    40      1024      1  freebsd-boot  (512K)
  1064   4194304      2  freebsd-swap  (2.0G)
4195368  48233392      3  freebsd-zfs  (23G)
52428760  41943040         - free -  (20G)
                
            
Now we can extend the last partition using
                
root@bsdvm4:~ gpart resize -i 3 -s 44031M vtbd0
vtbd0p3 resized
root@bsdvm4:~ gpart show
=>      40  94371760  vtbd0  GPT  (45G)
    40      1024      1  freebsd-boot  (512K)
  1064   4194304      2  freebsd-swap  (2.0G)
4195368  90175488      3  freebsd-zfs  (43G)
94370856       944         - free -  (472K)
                
            
Since no error were shown, the partition is successfully resized.

Let's now see if the ZFS pool has been informed about this change:
                
root@bsdvm4:~ zpool list
NAME    SIZE  ALLOC   FREE  CKPOINT  EXPANDSZ   FRAG    CAP  DEDUP    HEALTH  ALTROOT
zroot  22.5G   939M  21.6G        -         -     0%     4%  1.00x    ONLINE  -
                
            
As you can see the size has not been automatically updated. To do so manually, we can use the following command:
                
root@bsdvm4:~ zpool online -e zroot vtbd0p3
                
            
If we check again
                
root@bsdvm4:~ zpool list
NAME    SIZE  ALLOC   FREE  CKPOINT  EXPANDSZ   FRAG    CAP  DEDUP    HEALTH  ALTROOT
zroot  42.5G   940M  41.6G        -         -     0%     2%  1.00x    ONLINE  -
                
            
We can see that the size is what we were expecting.