Debian guest on Windows host using discard/TRIM.
This isn't a direct answer per se, as I'm addressing the problem, not the question. Instead of periodically compacting the image, this solution uses discard to automatically remove unused blocks in the host's VM disk image.
This solution requires a guest filesystem that supports continuous TRIM.
The Arch Linux wiki has a list of filesystems supporting TRIM operations.
FDE and cryptoroot are specifically not covered, as there are security concerns and none of the other solutions to this question would allow compacting either. The Arch Linux wiki has information about TRIM and dm-crypt devices.
In theory, this will work for all Linux guests on VBox hosts using VDI storage.
With VBox exited and no VMs running, add discard support to your disks by setting both
nonrotational for each disk in the config file for the VM. At this time
discard is not in the GUI, but
nonrotational is exposed as the "Solid-state Drive" checkbox. (ref: vbox forums, discard support)
<AttachedDevice discard="true" nonrotational="true" type="HardDisk" [..other options..] >
Boot the VM up, and verify that TRIM support is enabled:
sudo hdparm -I /dev/sda | grep TRIM
If LVM is in use, change the discard setting in
/etc/lvm/lvm.conf. (ref: debian wiki, lvm.conf example)
issue_discards = 1
In fstab, add the
discard option to the filesystems you wish to auto-discard (ref: debian wiki, fstab example)
UUID=8db6787f-1e82-42d8-b39f-8b7491a0523c / ext4 discard,errors=remount-ro 0 1
UUID=70bfca92-8454-4777-9d87-a7face32b7e7 /build ext4 discard,errors=remount-ro,noatime 0 1
Remount the filesystems to have them pick up their new options.
sudo mount -o remount /
sudo mount -o remount /build
Manually trim free blocks now with
fstrim uses the mounted filesystem, not the block device backing it. Instead of setting continuous discard in
fstab, this could be done on a weekly cron. (The weekly cron is recommended for physical SSDs which may have questionable support for TRIM, but this is not relevant here since underlying SSDs are handled by the host OS. see: ssd trim warning).
At this point, the size of the filesystems inside the VM and the size of the VM images should be pretty close in value.
- Guest1: Debian 8.7, kernel: linux 4.8 grsec from backports, filesystem: ext4
- Guest2: Debian 9 RC2, kernel: linux 4.9, filesystem: ext4
- Host1: VBox 5.1.14, Win7, image fmt: VDI
- Host2: VBox 5.1.14, Win8.1, image fmt: VDI