Convert an unsparse vm image to sparse vm image

Few weeks ago, I needed to convert qcow2 image to raw image. So, I executed this command:

qemu-img convert -f qcow2 -O raw vm-foo.qcow2 vm-foo.raw

After that, I had an unsparse image because qemu-img don't output sparse file. I saw this by running this command:

qemu-img info vm-foo.img

or

ls -lksh vm-foo.img

So now, I want to convert this new vm-image to a sparse file, because I want to free space in my file system. As you could know, in sparse file, zero-data, don't takes place in your file system instead of unsparse file.

Moreover, when files are deleted, their data stay in place on the disk (just indexes was deleted).

In my case, i want to optimize my future sparse file vm-image, and I decide to force zero-data in my vm-image.

So, on my started guest, I wrote zero-data as far as possible, using this command:

root@foo# dd if=/dev/zero of=/tmp/zerotxt bs=1M
root@foo# sync
root@foo# rm /tmp/zerotxt

Now, I shutdown the guest, and convert unsparse file to sparsed file by using cp command:

cp --sparse=always vm-foo.raw vm-foo.raw-sparse

Well done, I got a clean sparse file!

  qemu-img info vm-foo.raw-sparse
image: vm-foo.raw-sparse
file format: raw
virtual size: 40G (42949672960 bytes)
disk size: 6.3G
This article on my blog.