QEMU - incorrect real disk size of a virtual drive

Solution 1:

qemu-img and du both report the actual allocated space from host point of view. They can not know/understand if the guest OS is really using that space or if, as in you case, it was freed by the user.

To inform the host that your guest has a ton of free space you need to fstrim your guest filesystem and you must be sure that your qemu/guest block device stack correctly passes down TRIM/discard requests. In order to do that, you need to:

  • use a qemu block device driver with TRIM/discard support. Example of such drives are virtio-scsi, scsi and sata/ahci. All these drivers expose block devices using the classical /dev/sd[abcd...] nomenclature. On the other hand it appears that your guest is using a plain virtio driver (with /dev/vd[abcd...] names), which does not support TRIM/discard. You can check if your driver support discards by issuing lsblk -D;

  • enable the relative libvirt domain discard=unmap option;

Finally, your host must be using a filesystem with hole_punching support as ext4 (which you are using) and xfs.

You can read here for some more information.

If all prerequisites are true, issuing fstrim <mount_point> inside your guest will automatically de-allocate unused space on host also. Be sure to understand that the logical/apparent file size will remain unchanged (ie: it will show 2.0 TB ever after fstrim), but using qemu-img or du will reveal the true (smaller) allocated file size.

If the prerequisites are not met, you need to offline compact your image file via virt-sparsify or qemu-img convert after cleaning your guest free space with zeroes (ie: dd if=/dev/zero of=bigfile bs=1M count=<almost_all_free_space>; rm bigfile).

Be sure to understand what the above steps means: doing any error can irremediably corrupt your image file. And be sure to have a know-good backup before attempting any operation on your disk image file!*

Solution 2:

It’s expected behavior. As you wrote, “after I deleted some files and reduced the used space from 1.9T to 761G” - raw virtual image cannot “collect garbage” automatically and the real space will remain written and allocated even for removed files. Workaround is to perform (double)conversion raw>qcow2(>raw).

More detailed explained here - https://balau82.wordpress.com/2011/05/08/qemu-raw-images-real-size/ and here - https://techpiezo.com/tech-insights/raw-vs-qcow2-disk-images-in-qemu-kvm/