How to reduce the size of your VMs


As the host OS I use Windows 8 (just upgraded to 8.1), well why ? one might ask.Is rather simple: Steam and after some dreadful searching and configuring tools I managed to install the basics for writing and deploying code: Vim, Git, PuTTy and a decent console replacement like Console2 [0].

Of course those aren't enough as 90% of my coding is *nix dependent and I wouldn't run it on anything else; actually I'm still thinking of dropping Windows for something like ArchLinux [1] I fiddled with it and enjoyed all the low level stuff that just doesn't exist in Ubuntu Desktop.

Needless to say I use lots of VMs: I currently have three images that I use daily: Ubuntu Desktop, Ubuntu Server and an old Windows XP (well, I don't use it daily more like monthly). The problem of using just a few VMs with many projects is that it involves a lot of hdd trashing (i.e. git, deleting and creating lots of files).

What I did not realize is that my VMs were growing bigger and bigger by the day while their internal hdd space usage stayed mostly the same as I deleted old files and cleaned them up. For reference these were the initial sizes:

  • Ubuntu desktop: 19.7 GB
  • Ubuntu server: 8.0 GB
  • Windows XP : 7.9 GB

While trashing the SSD with all the writes and deletes I was expanding the VHDs despite the fact that I deleted the files in the VM. The cause: the actual blocks weren't nil so running a VM compact wouldn't yield any results.

With the --compact option, can be used to compact disk images, i.e. remove blocks that only contains zeroes. This will shrink a dynamically allocated image again; it will reduce the physical size of the image without affecting the logical size of the virtual disk. Compaction works both for base images and for diff images created as part of a snapshot.

The fix was clear: one needs from time to time to nullify the free space. After doing some quick research I've found easy ways to do it on every platform.

On Linux

The first version is using a tool like secure delete but with a very fast run:

sudo apt-get install secure-delete
sfill -f -z -l -l -I -v /


-f  fast (and insecure mode): no /dev/urandom, no synchronize mode.
-z  last wipe writes zeros, not random data.
-l  lessens the security (use twice for total insecure mode)
-I  just wipe space, not inodes
-v  is verbose mode.

Or a much simpler way:

sudo dd if=/dev/zero of=/bigemptyfile bs=4096k
sudo rm -rf /bigemptyfile

This will fill the entire empty space with a null file that is erased at the end. I haven't tested this too much, it might yield issues but is faster than the first version.

On Windows

On Windows Xp one just has to download SysinternalsSuite [2] and run sdelete –z from the command prompt.

OK once all of this is over: shutdown the VMs and run compact on the VHD. Using VirtualBox just run from the console VBoxManage modifyhd thedisk.vdi --compact, using VMware, well just click around till you find it.

OK time for results:

  • Ubuntu desktop: 11.0 GB ~ -45%
  • Ubuntu server: 4.3 GB ~ -47%
  • Windows XP : 6.6 GB ~ -16%

That's a whopping 13.7 GB out of my main SSD 128G drive that I use as the system drive, not bad, not bad at all !


Marian Posăceanu