How to resize a virtual hard disk

Have you ever been too conservative estimating how much space a VM is going to need? Even though the disk space on the host system is dynamically allocated I still end up aiming too low with the maximum disk size. I had an Arch Linux VM with an 8 GiB virtual hard disk which needed more space. It was only ever intented as an experiment in installing Arch Linux but I ended up sticking with the machine as a playground for testing out things.

So, um... I'll just make it bigger a couple of GiBs. It turned out it was not quite that easy. But here is how to do it, with the most basic CLI utilities. I ran into a problem with expanding my partition, because the disk was configured with a GPT. Which I also kindo forgot since I created this machine. This assumes a GPT formated disk with two partitions (One for /boot and the other one for /). I had an ext4 file system, but resize2fs should work the same with ext2/ext3. You'll need a live medium, I used the Arch install image, which I had laying around. It needs to include the tools gdisk (fdisk for GPT), e2fsck and resize2fs.

The basic procedure is to first increase the maximum "physical" disk size through VBoxManage. Then increase the size of the partition and then the file system.

$ VBoxManage modifyhd --resize 12288 Arch.vdi
This sets the maximum disk size to 12 GiB. Now you should boot the VM into he live system to increase the partition and file system size.
root@archiso ~ # gdisk /dev/sda
GPT fdisk (gdisk) version 0.8.5
Partitiontable scan:
  MBR: protective
  GPT: present

Command (? for help): p
Disk /dev/sda: 25165824 sectors, 12.0 GiB
First usable sector is 34, last usable sector is 16275634

Command (? for help): v
Problem: The secondary header's self-pointer indicates that it doesn't reside
at the end of the disk. If you've added a disk to a RAID array, use the 'e'
option on the experts' menu to adjust the secondary header's and partition
table's locations.
Notice what the problem is here. The additional space we added is not usable right now, because there are some data structures (which were and should be at the end of the disk) now in the middle of the disk. You should fix that with 'x' and then 'e'.
Expert command (? for help): e
Relocating backup data structures to the end of the disk
Gdisk doesn't support partition resizing, but you can delete (d) and recreate the partition (n) to get the same result. The new partition must begin at the same sector as the old one! (No data will be lost when you delete and recreate a partition. But if something goes wrong it might become unaccessible, so tread carefully.)
Command (? for help): p
Disk /dev/sda: 25165824 sectors, 12.0 GiB
First usable sector is 34, last usable sector is 25165824
2       258048         25165790   11.9 GiB    8300   Linux filesystem

When everything looks alright, write the changes (w) and quit (q) gdisk.

Now check the file system. This is required for resize2fs to work. Then resize2fs can automatically expand the file system to the new partition size.

root@archiso ~ # e2fsck -f /dev/sda2
root@archiso ~ # resize2fs /dev/sda2
resize2fs 1.42.6 (21-Sep-2012)

For questions, corrections or suggestions send me an email to marcus@<this_domain>.