Qcow2 - Recover Disk Space on Linux
Sparse qcow2 images can be convenient for allowing you to over-subscribe your disk for your KVM guests in case they might need that space later. For example, you could provision 3 guests each with 400 GB of storage, on a single 500 GB drive. To begin with, the guests will only use a few GB of space each and use more as and when they need it.
Unfortunately, this can also have the opposite effect, causing the sparse image to use more space than was actually allocated to the guest. This is especially noticeable on smaller guests. I noticed that my 20 GB guest was using over 3 times that. The screenshot below shows the storage required of the image before and after I performed the recovery operation I am about to describe.
Steps
Method 1 - Virt-sparsify
One can use the virt-sparsify
tool to essentially perform all the steps I used to do manually as outlined in the "Method 2" section below.
All one needs to do make sure the guest is shutdown and then run:
$FILENAME="root-disk.qcow2"
mv -i $FILENAME old.qcow2.bak
sudo virt-sparsify old.qcow2.bak $FILENAME
Then check that your guest will start up again and everything is fine. If not, then you can remove the newly created file, and rename old.qcow2.bak
to be the original file again.
If everything is fine, then don't forget to remove the original (now backup) disk image to save space on the server:
rm old.qcow2.bak
trash-put
, just in case...
Optional - Using In-Place
If space is severely limited, and you don't have enough space to create a copy of the disk for the operation, then you can do this in-place with the --in-place
parameter like so:
virt-sparsify --in-place $FILENAME
Please note that the virt-sparsify wil write 0's to fill the empty space of the guest filesystem as part of this operation. If you need to not do this then you can
use the --ignore
parameter against the name of the internal filesystem or the volume group. However this behaviour changes based on whether you have also
specified in-place or not. I would recommend reading the man pages if you are considering doing this.
Method 2 - Manual
Log into the guest with SSH.
Fill the remaining space in the guest with 0's before be filling the guest with an empty file before deleting it. This will allow an operation we use later to know that this area is free.
# Create a temporary file of empty blocks. Uses 1MB blocks to speed things up.
dd if=/dev/zero of=mytempfile bs=1M
# Ensure file is synced to persistant storage and not in memory cache.
sync
# remove the temporary file
rm mytempfile
You should see output similar to below:
dd: error writing 'mytempfile': No space left on device
14538105+0 records in
14538104+0 records out
7443509248 bytes (7.4 GB) copied, 23.6383 s, 315 MB/s
Now shutdown the guest.
sudo shutdown
Now log into your KVM server and move your file to another location, before converting it back to the original location again.
mv guest-image.qcow2 guest-image.qcow2.bak
qemu-img convert -O qcow2 -p \
guest-image.qcow2.bak \
guest-image.qcow2
-p
flag will result in showing a percentage progress of the conversion.
Now you can boot your guest back up.
sudo virsh start my.guest.org
When you are all happy with everything and there are no issues, you can delete the original image that you had been using.
rm guest-image.qcow2.bak
References
- jamescoyle.net - Reclaim disk space from a sparse image file (qcow2/ vmdk)
- access.redhat.com - 21.14. virt-sparsify: Reclaiming Empty Disk Space
First published: 16th August 2018