Compacting VirtualBox disk images
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.
secure-delete
on the guest
Install 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.)
sfill
Run 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!