Shrink virtual disk (VDI) of a VirtualBox VM (Linux)

A lot of people are using VirtualBox to build their test or demo environments. In this blog post, I will demonstrate how to shrink an existing virtual disk of a Linux VM (Oracle Linux 7).

Motivation

When you are using your VM over several weeks or months and do a lot of stuff with it, the virtual disks (VDI) which are in use by the VM will increase in size. But after cleanups or deletion of data, the virtual disk size does not decrease.

For example, I use a dedicated virtual disk to store the Oracle software within my VM. Currently, the used size is 23 GB.

$> df -h /u00
Filesystem                    Size  Used Avail Use% Mounted on
/dev/mapper/vg_oracle-lv_u00   50G   23G   24G  50% /u00

But when I compare this size to the physical size (47 GB) of my virtual disk, I can see, that a lot of space is wasted.

$> ls -lah ora19c-oracle.vdi
-rwxr-xr-x   1 User  staff    47G 11 Jan 19:45 ora19c-oracle.vdi

Preparation

Before I can shrink my disk, I have to clean up the free space, by writing zeros to the free blocks. I use zerofree for this. Out of the box, zerofree is not shipped with Oracle Linux 7. To install it, the EPEL repository can be used or you can compile it from the sources.

$> yum install oracle-epel-release-el7
$> yum install zerofree

CAUTION: Zerofree will only work with the EXT filesystem. Oracle Linux 7 uses per default XFS.

After the installation, the disk has to be unmounted or mounted read-only. Otherwise, zerofree will raise an exception.

$> zerofree -v /dev/mapper/vg_oracle-lv_u00
zerofree: filesystem /dev/mapper/vg_oracle-lv_u00 is mounted rw

My test environment uses LVM, but it will work with “normal” disks too. You can use option -n of zerofree to perform a dry run.

$> umount /dev/mapper/vg_oracle-lv_u00
$> zerofree -v /dev/mapper/vg_oracle-lv_u00

CAUTION: If you want to cleanup a virtual disk belonging to the root mountpoint, you have to switch your Linux machine into single user runlevel (rescue mode). Then you can mount the root mountpoint read only.

$> init 1
$> mount -o remount,ro /dev/mapper/vg_system-lv_root
$> zerofree -v /dev/mapper/vg_system-lv_root

Shrink

After stopping the VM, we can use VBoxManage to shrink the disk.

$> VBoxManage modifymedium ora19c-oracle.vdi --compact

Location of VBoxManage:

  • MacOS: /Applications/VirtualBox.app/Contents/MacOS/VBoxManage
  • Linux: /usr/bin/VBoxManage
  • Windows: C:\Program Files\Oracle\VirtualBox\VBoxManage.exe

When I now check the physical size of the virtual disk, I can see that the size was decreased to 24 GB.

$> ls -lah ora19c-oracle.vdi
-rwxr-xr-x   1 User  staff    24G 11 Jan 19:45 ora19c-oracle.vdi