Q: How can I reduce the size of a dynamic VDI on disk?
A: There are two approaches to cleaning up and reducing the size of the file system stored on a dynamic VDI. The first is what I call in-place and the second is by doing a file system copy. This answer addresses the first of these.
You must prepare the file system before you attempt to reduce its size, otherwise the benefit will be minimal. First, clear out any obvious garbage files that are lying around; for example empty your wastebasket and Internet caches; clean up any temporary folders and files that you no longer need. In the case of NTFS and FAT file systems, you should run a defragment utility, because this not only reduces file fragmentation but also free space fragmentation.
You then need to use a utility to zero the free space within the file system (remember that in general free space will not be zero, because it will contain data blocks that have been used and recycled to the file system). This utility must understand the structure of the file system and in particular its free-space maps, and be able to bypass the high level file-system I/O functions to write directly to the disk at a block level, without compromising its integrity. It is therefore OS specific.
The best tool to use for NTFS under a Windows guest OS is the System Internals (now part of Microsoft) tool
sdelete (
Microsoft SysInternals File Utillities). You run this at the command prompt with the
-c option to tell
sdelete to clear the unused space, hence the following command cleans out the
C and
D partitions:
In the case of Linux, a good utility for ext2, ext3 and ext4 file systems is
zerofree written by Ron Yorston and available on his website:
zerofree. The easiest way to use this utility is to keep a copy in
/usr/bin on each system image. Some distributions such as Ubuntu now include this so you can install it in your Ubuntu guest by running
sudo apt-get install zerofree. To zero out the file systems, you boot your system in
init 1 mode (typically the second option on most grub-loader menus); then remount your file systems read-only (as zerofree will only clear out read-only file systems); and then run zerofree on each partition, for example the following clears my system and application disks:
Code: Select all
mount -n -o remount,ro -t ext2 /dev/sda1 /
mount -n -o remount,ro -t ext2 /dev/sdb1 /var
zerofree /dev/sda1
zerofree /dev/sdb1
The safest thing to do immediately following these commands is to shutdown / reboot your VM after scheduling a boot-time file system check. Then shutdown your VB. You can then execute
VBoxManage modifyvdi xxxx.vdi --compact command from your host OS where
xxxx.vdi is your dynamic VDI. (I find that the easiest thing to do is to
cd to my
VDI directory first so I don't have to bother with pathnames in the command).
Compacting a dynamic VDI is done in place in a two pass algorithm. First all blocks are scanned and any that are entirely zero are freed; this creates holes in the physical allocation. So if the image contained 110 blocks and 10 were tagged as zero, then the new image should contain 100 blocks. The second phase copies any blocks above the 100 high-water mark into the now vacant blocks below the mark. The block map is then updated and the VDI file truncated to the new length. This process minimises the amount of temporary disk required, but it does have the disadvantage that the compaction process further shuffles block order.
Note: mpack's unofficial CloneVDI tool (see sticky in Windows Hosts) can also be used to compact VDIs, and does not require that first sdelete/zerofree preprocessing pass, hence is normally considerably quicker in use, in addition to being able to compact e.g. unpartitioned areas of the disk which sdelete can't reach. Although a 32bit Windows app, it is known to run well in the Wine GUI platform for Linux and OS X.