August 11, 2021

Expand NetBSD root partition

Expand NetBSD root partition

I already wrote how to expand LVM partition on NetBSD, however expanding root partition is not as easy as none root partition.

I've got schema prepared for small machines like firewalls and vpn terminators, which has only one 10GB disk, and whole filesystem is on one partition, and mount point is just / , so disklabel looks like this:

# disklabel xbd0
# /dev/rxbd0d:
type: unknown
disk: XenServer
label: 
flags:
bytes/sector: 512
sectors/track: 63
tracks/cylinder: 16
sectors/cylinder: 1008
cylinders: 20805
total sectors: 20971520
rpm: 3600
interleave: 1
trackskew: 0
cylinderskew: 0
headswitch: 0			# microseconds
track-to-track seek: 0	# microseconds
drivedata: 0 

16 partitions:
#        size    offset     fstype [fsize bsize cpg/sgs]
 a:  18874368         0     4.2BSD   2048 16384     0  # (Cyl.      0 -  18724*)
 b:   2097152  18874368       swap                     # (Cyl.  18724*-  20805*)
 c:  20971520         0     unused      0     0        # (Cyl.      0 -  20805*)
 d:  20971520         0     unused      0     0        # (Cyl.      0 -  20805*
Basic NetBSD disklabel

For those not familiar with FFS or UFS file systems used in *BSD. First you need to create slice for BSD on disk, then inside slice you can set partitions, becasue of this partition c and d are reserved on BSD systems, and partitions for users start with "a", then "b", and then "e" and so on. So above disklabel shows:

d - This is whole disk
c - This is whole slice on disk for NetBSD (in this case whole disk is dedicated to BSD)
b - this is swap disk. Notice fstype is swap
a - this is first partition normally assigned to /.  Notice  fstype is 4.2BSD
NetBSD Disklabel explanation

Disklabel is using sectors of disks instead of bytes, so 10GB is 20971520 sectors.

Disk size in template can't be changed during creation of VM, so only option is to create 10GB machine, then shutdown (or not even start) it, and alter disk size. Lets do it in Xen Orchestra.

Entering 20GB

And it worked on turned off machine

New size - 20 GB

Machine booted without any problem, but disklabel didn't change, however looking at dmesg showed new size in sectors which is basically previous size doubled.

# dmesg | grep xbd0
[     1.990051] xbd0 at xenbus0 id 51712: Xen Virtual Block Device Interface
[     1.990051] xbd0: using event channel 8
[     2.040073] xbd0: 20480 MB, 512 bytes/sect x 41943040 sectors
[     2.060060] boot device: xbd0
[     2.060060] root on xbd0a dumps on xbd0b
New sector size. From 20971520 to 41943040

Lets use this new size with disklabel. We can edit disklabel with disklabel -e xbd0 in vi.

I altered total sectors, partition c and d to new sizes:

New sizes

Now we need to do some math. We need to expand only root partition, without touching swap partition. Disklabel position of partitions are controlled by two variables size which is how big is partition, and offset which repesents when it starts. So first partition start at 0 sector (offset 0), and have size of 18874368 sectors), then swap start at sector when partition a ends (offset 18874368), and have size of 2097152 sectors. If we add one size to another we got total sectors of original disk size. So using built in calculator (bc) we can now count correct values.

Substract from total sectors size of swap:

# bc
41943040-2097152 
39845888
Swap space of same size now starts at sector 39845888

Then, if ne offset for swap is calculated and its size didn't change it means that all sectors down to 0 will be new size of partition a: as well. We can now update disklabel accordingly:

New size of a: - root partition (/) with new offset for same swap partition

Fear not if you mess something up when counting, disklabel will warn you that is too big, or overlap with another one partition.

One sector to much - warning

Not much surprise - no effect at all yet, still original 10GB layout:

Despite new disklabel, old layout remains

It is time to grow partition with resize_ffs. Remember to always use raw device when doing so, hence rxbd0a instead of xbd0a. I didn't run fsck and said yes, because it changes nothing to problem that will occur next.

Resize completed, but new size is still unusable, on this stage I decided maybe it will show up after reboot, so I did, aaand .... its gone:

Growing / partition ends up with error

This looks bad. This was clean shutdown, but fsck said that we need to fsck anyway. However fsck now is complaining about super blocks, and is not checking filesystem, because ... it is clean.

fsck failed

Fortunatelly there is option -f (force), you can add -y as well which automatically confirms every question:

# fsck_ffs -f -y /dev/rxbd0a
Filesystem repaired

Lets try to grow filesystem once again in single user mode just after fscking, then reboot to check if system boots properly and has new size

Same story again, after resize, reboot

To my surprise after that system booted without any problem, and df showed new correct size:

20GB of new root partition!

Now I only have to shut down this machine and create another template from it with new disk size.