Shrink a Qemu KVM virtual disk

Shrinking a virtual disk isn’t something that comes up often. Usually you tend to grow your virtual machines. I, however came across the requirement on my home workstation to shrink a Qemu virtual disk running Windows 10 as I wanted to enhance backup/deployment of the OS itself and externalise the games/other software therein. If you’re running a home system with contention for SSD space then you might have a similar issue. Information wasn’t readily available though I did find a very helpful response on Server Fault that gave me the basis for my method. You may want to cross reference that for further information.

If you already have an adequate amount of unallocated storage on your disk, skip to step 3. If you do not have storage unallocated to partitions on the virtual disk, you’ll need to shrink your partition/s. In Windows you can do this in Disk Management, even for an online boot partition. Press Windows key+R, type “diskmgmt.msc” and hit enter to open the utility. Identify the partition/s you wish to resize, right click and select “Shrink Volume”.

At this interface, you’ll want to play with the “amount of space to shrink” until your total size reaches the desired value. However, this did not work for me at all. For whatever reason (I suspect Windows’ lack of desire to re-arrange existing files) I was about 80GB short of the target shrink. My alternative method was to use GParted, an open source partitioner, running under Ubuntu. To do this I simply added an Ubuntu live ISO image as a boot device on my VM and rebooted. You can run it from the Alt+F2 dialogue, windows key search (current Ubuntu) or System>Administration>GParted under Ubuntu MATE (my preferred distro).

Right click the volume you wish to resize and use the resize option, you may also wish to delete any unnecessary partitions (make sure they’re definitely unnecessary!). I’ll have to trust you can work partition management in general, note it’s best practice to finalise as few changes as possible at a time.

I found it easiest to just adjust the New Size field to my desired size, ensure to leave some room for growth. You can also use the graphical slider. The green arrow pointing to a line in the toolbar is your finalise button. Let GParted do it’s thing (which is surprisingly rapid on an SSD).

2. Once you’ve accomplished your partition shrinkage (if required), then you can resize the disk. The only way to do this is to build the contents of your filesystems into a new disk . To do this you’ll need two sets of tools, under Ubuntu these are “qemu-utils” and “libguestfs-tools”. As luck would have it, these were broken for me on both my Ubuntu host system and my nearby Debian NAS so I resorted to using a Fedora VM to build the new disk image.

To install the tools on Debian/Ubuntu:

sudo apt-get update && sudo apt-get install qemu-utils libguestfstools

To install the tools on Fedora/Redhat/Centos and other Redhat derivatives, assuming you have sudo access (I didn’t out of the box, you can use “su -” to elevate to root or log directly into the root account otherwise):

sudo yum -y update && sudo yum -y install qemu-img libguestfs-tools

Make sure the VM with the disk you’re resizing attached is shut down.

3. Create a new disk image:

qemu-img create -f qcow2 /path/to/new/virtual_disk.qcow2 36G

Substitute your desired disk format after the -f (format) argument, if you want to change disk image formats this is a good opportunity. Where I’ve specified 36G, specify your desired disk image size, this must be larger than the combined partitioned space of the existing virtual disk.

4. Transfer contents to the new disk image, this works a lot like DD but with the contents of a virtual disk.

virt-resize /path/to/old_disk.qcow2 /path/to/new/virtual_disk.qcow2

I ran into an issue at this stage as well, which fortunately was extremely well described in the error provided by libguestfs-tools, so a huge thanks to the devs there. You too may need need to run

export LIBGUESTFS_BACKEND=direct

Now, if all your tools are playing nice and you’ve got the storage to spare it’s time for a beer while you wait on the I/O speed of your system to copy the disk.

5. Now, if we’ve got this far without any errors you should have a new disk image. Remove your original disk image in your VM configuration, add the new disk and check the boot order is correct. Power up the VM, cross your fingers very tightly.

If you’re having issues then feel free to leave me a message and I’ll try to get back to you. I ran into a lot of little gotchas on this mission, I’ve documented a couple here but there were more problems such as the logistics of working with a 220GB file and storage for the VM; I ended up passing through a read only Samba share from my host to the Fedora VM to access the virtual disk I was resizing and passing through a USB external HDD to receive the new disk image!