Reduce qcow2 size with `qemu-img convert -c -O qcow2`

Virtualisation works but we all know that images can will grow uncontrollably. In the client I run windows and schedule a cleanmgr /sagerun:1 frequently to keep windows hogging too much data. I see that the image grows but stay large.

# ls -lhs
total 47G
 14G -rw-r--r--. 1 root root  14G Mar 20 13:57 win11-active-compact.qcow2
 26G -rwxr-xr-x. 1 root root  30G Mar 20 13:51 win11-activ.qcow2
7.6G -rw-r--r--. 1 root root 7.7G Mar 20 13:45 win11.qcow2

In this case the smallest image win11.qcow2is a bare bones setup of windows without any application installed (and most of the bloat removed). The big active one is a clone of the same client after a using it for a couple of weeks. But the win11-active-compact.qcow is the same image after doing:

qemu-img convert -c -O qcow2 win11-activ.qcow2 win11-active-compact.qcow2

I wonder if I have to do this regularly by hand on a switched off client or if this is can be run automatically?

You’ve reminded me to take another look at this, as I recently ended up doing the qemu-img convert dance to reclaim some storage.

It turns out that qemu will handle it while a VM is running if the OS inside the VM that can issue TRIM commands (which includes Windows) as long as discard=unmap is set when that image is attached to that VM.

If you’re using virtual machine manager, go to the details page and look for “Discard mode” under advanced options for that disk image. You’ll then need to shut down and restart the virtual machine for the setting to take effect.

For a Windows guest, ask it to defragment/optimize the drive and you should see the image on disk size shrink on the host while it runs.

Shrink Qcow2 Disk Files - Proxmox VE and QEMU, KVM and trim | Anteru's Blog were helpful as a references - and also point out that you probably need to be using VirtIO as the storage driver for this to work.

You might look up the virt-sparsify command. I added the following to my VM backup script:

#Trim the source VM file now that it's backed up to reclaim unused disk space
virt-sparsify --in-place $path
echo "Source VM image after Trim/virt-sparsify"
qemu-img info $path

It seems it is:

Thanks for those!

On the win11 client:
image

Running Optimize-Volume C seems to have no discernible effect on the image size nor does Optimize-Volume C -Retrim

Running sdelete -z c: after installing it with winget install sdelete actually increased (doubled) the image size so that currently is bad advice.

I hadn’t tried that, but it makes sense as there’s a separate detect-zeros option that would be needed to pick up on that behaviour, and I didn’t seem to be able to set in virtual machine manager.