I've seen, a number of times, users asking about how to resize a FFS partition on NetBSD, and getting no reply in return.
The gpt(8)
utility, which I'm notoriously fan of, will easily allow to resize disks and partition, but what about resizing the actual filesystem, in order to match the new disk layout?
Other BSDs and Solaris provide a growfs
command to address such need, as far as the UFS/FFS filesystem is concerned.
NetBSD instead comes with resize_ffs(8).
So, let's see how to resize a FFS partition on NetBSD (GPT disk).
■ Shrinking
I have a 64G USB flash device with a GPT partition layout. The disk contains a 56G CGD-encrypted virtual device, which in turn hosts a single FFS partition.
$ gpt show sd1
start size index contents
0 1 PMBR
1 1 Pri GPT header
2 32 Pri GPT table
34 4062 Unused
4096 120954880 1 GPT part - NetBSD Cryptographic Disk
120958976 4063 Unused
120963039 32 Sec GPT table
120963071 1 Sec GPT header
Resize partition 1
- which here is the CGD disk - to half of its size, in this case 28G, using a 4M alignment:
$ gpt resize -i 1 -a 4m -s 28g sd1
/dev/rsd1: Partition 1 resized: 4096 58728448[code]
$ gpt show sd1
start size index contents
0 1 PMBR
1 1 Pri GPT header
2 32 Pri GPT table
34 4062 Unused
4096 58728448 1 GPT part - NetBSD Cryptographic Disk
58732544 62230495 Unused
120963039 32 Sec GPT table
120963071 1 Sec GPT header
Flush all configured wedges on sd1 and force autodiscovering them over:
$ dkctl sd1 makewedges
successfully scanned /dev/rsd1.
$ dmesg | grep sd1 | cut -d']' -f2
dk3 at sd1: "flash64", 120954880 blocks at 4096, type: cgd
( 2.1 configure the CGD disk )
$ cgdconfig cgd1 /dev/dk3
$ cgdconfig -l
cgd0: dk2
cgd1: dk3
cgd2: not in use
cgd3: not in use
Check the size in sectors of the partition to shrink, using disklabel
:
$ disklabel -iI cgd1
Enter '?' for help
partition>P
4 partitions:
* size offset fstype [fsize bsize cpg/sgs]
a: 120954880 0 4.2BSD 0 0 0 # (Cyl. 0 - 59059)
d: 120954880 0 unused 0 0 # (Cyl. 0 - 59059)
partition>Q
Shrink the partition to half off its size in sectors (-p
prints a progress bar):
$ resize_ffs -s 60477440 -pv /dev/cgd1a
It's required to manually run fsck on file system before you can resize it
Did you run fsck on your disk (Yes/No) ? Yes
Shrinking fs from 30238720 blocks to 15119360 blocks
mount the partition to verify the news size:
$ mount /dev/cgd1a /mnt
$ df- hg
/dev/cgd1a 28 0 26 0% /mnt
■ Growing
Now, let's bring back the partition to its original size.
- Move the partition boundaries to their former state:
$ gpt resize -i1 -a 4m -s 56g sd1
/dev/rsd1: Partition 1 resized: 4096 117448704
- Grow the fileystem inside the enlarged partition.
$ resize_ffs -pv /dev/cgd1a
Growing fs from 15119360 blocks to 30238720 blocks.
- check the new size:
$ mount /dev/cgd1a /mnt
$ df- hg
/dev/cgd1a 56 0 54 0% /mnt
One thing to notice when growing partitions is that the new partition should always start at the same sector as the old one, similarly to our example. If you want to free up space to grow a partition, you should delete any partition coming after the one to resize, leaving the starting sector intact.
■ Expanding disks
If you want to grow a partition in a virtual disk beyond the original disk's size you'll also need:
$ gpt resizedisk -a 4m -s *g <dev>
Which shall move the GPT backup copy to the new end of the disk, update all size fields for the new media size, and adjust the pointer to the secondary GPT header.
If you accidentally enlarge a partition past the disk's end, you can recover the secondary GPT header with:
$ gpt recover <dev>
gpt: <dev>: recovered secondary GPT table from primary