Reducing (sparsifying) qcow2 image of Windows10

Since joining Fujitsu I am permanently running a VM (kvm/qemu) with Windows 10 (unfortunately necessary). While the usaged disk space is about 50G, the actual qcow2 file had grown to over 180G, not good.

Searching the web the very promising virt-sparsify is mentioned again and again, and the man page gives hope, but as it turns out it is broken and calls qemu-img with incorrect/not-working arguments (see this bug).

Another problem seems to be that by default the discard mode seems not to be set to unmap.

So here are the stages how I reduced the size of the qcow2 image back down to around 60G.

  1. Turn off the VM
  2. Make sure you are using VirtIO for the disk, select Discard mode: unmap
  3. Boot into Windows, and from an elevated prompt run: Optimize-Volume -DriveLetter C -ReTrim -Verbose
  4. Shut down the VM
  5. Run a dummy conversion which sparsifies the image: qemu-img convert -O qcow2 orig.qcow2 sparse.qcow2
  6. Rename/Backup the images and boot back into Windows.

That helped in my case, without any consequences (till now) for the Windows installation.

7 Responses

  1. Moltke says:

    Nice tip! Didn’t know about that. Have two questions:
    1. You seem to be running your VM from the command line, is that correct? So, where do you do this:
    > select Discard mode: unmap
    2. What would be the equivalent in a Linux VM for this:
    > Boot into Windows, and from an elevated prompt run: Optimize-Volume -DriveLetter C -ReTrim -Verbose
    What I usually do is create a raw image and use that as the base, then just create derived images from that one, that way I can keep my VMs to a certain size. Just as explained here https://doc.opensuse.org/documentation/leap/virtualization/html/book-virtualization/cha-qemu-guest-inst.html#cha-qemu-guest-inst-qemu-img-effect which is a very valuable source of information when it comes to create and manage VMs. 🙂

    • No, I am using virt-manager to do this. There, in the setting for VirtIO disk you can choose th discard mode. The resulting qemu command line is far too long to be reasonably done by a human.

      For Linux VMs that would be fstrim with some arguments, I guess.

      • Moltke says:

        Ah, I see. So, I guess you ran this
        > qemu-img convert -O qcow2 orig.qcow2 sparse.qcow2
        in a terminal afterwards, or does virt-manager can do that too? It’s been ages since I last used it. Thanks for the reply.

  2. Paul Wies says:

    I bookmarked your article! Until now I worked with SysInternals sDelete to zero out windows space.

    I tried to follow your steps and stumbled two times, maybe I save somebody else the time:
    1.) “make sure you are using VirtIO for the disk…”
    When i switched (=deleting the disk and creating a new one with the other bus-type) from Bus “SATA” to Bus “VirtIO” , windows refused to start.
    I had to switch back to SATA, add a virtIO-disk so windows knows about this kind of device (RedHAT VirtIO SCSI disk) and loads/installs the driver.
    Then shutdown, remove the extra virt-io disk and switch back to virtIO for the windows.
    Boot as nothing ever happened 🙂
    2.) “from elevated prompt run…” this has to be powershell, not cmd.exe

    Before I remembered the trick with the other harddrive I ran the “optimize…”-command with the SATA bus and sDelete for good measure. Now, with the drive attached as VirtIO the “optimize-…”-command errors out.

    • Hi Paul,
      thanks for your comments. Yes, you are right, switching to VirtIO disks requires first getting them loaded into Windows, otherwise it doesn’t boot as you saw. The method you used is well documents (I did the same when I switched ;-).

      Concerning the Powershell command versus the sdelete, I think both are doing the same (when you do sdelete -z).

  1. 2021/09/03

    […] Norbert Preining: Reducing (sparsifying) qcow2 image of Windows10 […]

Leave a Reply to Moltke Cancel reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>