Compacting VirtualBox disk images

01 Mar 2014

VirtualBox is a super-handy and free virtualization solution that is now owned by Oracle. Its disk image files are dynamically allocated by default, and as they’re used, they accumulate free blocks that can be compacted to save space.

I’m going to describe how to compact an Ubuntu Linux guest, because there’s plenty of info about how to do it for Windows, and plus, I just don’t care about Windows.

Install secure-delete on the guest

The secure-delete package was intended to help you wipe your disk of any data that is sensitive in nature, but it works just fine to help us in compacting the image too. This is because we need to write zeroes (0x00) to all the areas of the disk image that are currently unused, so that the VBoxManage tool can find and compact them.

So, install the secure-delete package on the guest:

apt-get install secure-delete

Put the VM into single-user mode

We need to have the guest OS be as inactive as possible when zeroing the free blocks, because if services are running and stuff is being written to the disk, that would be kind of counterproductive, wouldn’t it? So, make sure nothing critical is happening inside the VM, then tell it to switch to single-user mode:

telinit 1

This shuts down all multi-user services (including the X display server) and drops you into a root shell. The problem is that sometimes you have to hunt around to find which virtual terminal it has decided to run the root shell on. So try any of them (using alt/option-1 through alt/option-7, usually, although on a Mac host you might have to use the Fn key as well, to keep from triggering your brightness or volume controls or whatever.)

Run sfill

sfill is the actual utility we’ll use to zero the free, unused areas of the disk. By default it writes many passes of carefully tuned random data to completely obliterate sensitive files. But we only need one pass of plain zeroes for compacting. So we tell it to limit its firepower to one pass, and write zeroes, using the following command:

sfill -l -l -z /

It’s very important to use -l (lowercase L) twice; this limits the writes to one pass. The -z parameter switches on the use of zeroes. The slash, as you might guess, tells sfill to do the root partition (i.e., everything.) If the disk image you want to compact is mounted somewhere else, then use the path to that mount point (e.g., /extra-data or whatever.)

NOTE: this command will take quite a long while to run.

Shut down the VM

Now that the free blocks have been zeroed, we need to shut down the VM so that the VirtualBox tools can operate directly on the disk image without scrambling it. So tell Ubuntu to shutdown:

shutdown -h now

Use VBoxManage to compact the disk image

Now we need to actually do the compacting. But first we have to know where the disk image file lives on your host machine. Usually VirtualBox puts the VDI files (the disk images) right with the rest of the files for each VM, usually in a directory called “VirtualBox VMs” in your home directory. So poke around until you find the right place, and then it’s time to run the actual compaction command:

VBoxManage modifyhd /path/to/disk/image/file.vdi --compact

This won’t take as long as the sfill command did, but it still may be a few minutes. Fortunately the VirtualBox developers have instructed the command to print a nice progress bar so we can keep track of its… progress.

Once you’re done, the VDI file should be somewhat smaller. How much smaller depends on how much free space was lounging around inside the image. It could be a lot or not much. So, as always, your mileage may vary. I usually do this whole process after I’ve deleted a bunch of stuff inside the VM when I finish a project or do a significant upgrade.

Thanks for reading!