Compacting VM Disk Images
Dynamically-allocated virtual disks grow when the guest writes data but don’t shrink when the guest deletes it — the hypervisor can’t tell a deleted file’s blocks from live ones. Compaction reclaims that space: convince the guest to zero its free space, then ask the hypervisor to drop (or compress) the zeroed regions. Two preconditions hold across platforms: the disk must not be part of a snapshot chain, and it must not be encrypted — encrypted blocks are high-entropy and neither sparsify nor compress.
libvirt / qcow2
virt-sparsify (libguestfs) does the whole job — it zeroes free space inside the filesystems and writes a sparse output image, without needing guest cooperation:
virt-sparsify --compress /path/to/image.qcow2 /path/to/new-image.qcow2It works on any disk image format libguestfs reads (--convert qcow2 changes format in the same pass) and cannot run in place — you need scratch space for the output file. Note the explicit exception: libguestfs can read encrypted disks but encrypted disks cannot be sparsified, which is the same precondition stated above.
VirtualBox (VDI)
VBoxManage only discards zeroed blocks, so the guest-side zeroing is on you.
Windows guest — prep thoroughly, then zero with Sysinternals SDelete:
- Disable the paging file (Settings → System → About → Advanced system settings → Performance → Advanced → Virtual memory) — pagefile blocks are un-zeroable churn
- Disk Cleanup on C: to remove temp files
- Defragment/consolidate free space:
defrag C: /FreespaceConsolidate /Verbose - Zero free space:
sdelete -z C:(-z= zero free space; distinct from-cwhich cleans free space with the DoD overwrite pattern — for compaction you want zeros)
Then on the host:
vboxmanage modifymedium /path/to/image.vdi --compactRemember to re-enable the paging file afterward.
Linux guest — same idea with dd:
sudo dd if=/dev/zero of=/temp.zeros bs=4096k # runs until disk full
sudo rm -f /temp.zerosthen vboxmanage modifymedium --compact on the host.
Notes
--compactonly works on VDI; for VMDK/VHD convert first.- On SSD-backed hosts with TRIM/discard enabled end-to-end (guest + controller + host), much of this happens continuously and manual compaction matters less.
- Keep the zero-fill step in mind when the VM is a sensitive artifact (e.g. an engagement box you’re archiving): compaction is a storage operation, not sanitization — but SDelete’s
-zpass does incidentally overwrite deleted guest data with zeros.
Related
- windows-services — the Windows guest prep (paging file, defrag) touches the same system knobs
- icacls — checking permissions on image files when archiving lab VMs