How to shrink raw qemu / kvm images
If you allocated to much hard disk space to your virtual machines and you’re running out of free space on your storage device, here’s how to reclaim space from your existing virtual machines.
First, shrink and realign the partitions on the image file as you see fit. In Linux, you may use a liveCD and the command resize2fs to shrink the root partition. Starting with Windows 2008, this is easily possible using the Management Console.
When you’re done, shutdown the machine.
On your virtualization platform, setup the image as loopback device:
# losetup -fv /path/to/image.raw Loop device is /dev/loop0
Then, find out the sector size and last used sector of the last partition(marked in red):
# fdisk -cul /dev/loop0 Disk /dev/loop0: 32.2 GB, 32212254720 bytes 255 heads, 63 sectors/track, 3916 cylinders, total 62914560 sectors Units = sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk identifier: 0x1449bcb0 Device Boot Start End Blocks Id System /dev/loop0p1 * 2048 11452502 5725227 7 HPFS/NTFS /dev/loop0p2 11452503 42432503 15490000 7 HPFS/NTFS
You’ve got all the information you need, so you can detach the loopback device.
# losetup -d /dev/loop0
dump the needed part of the old image into a new one, adding 2 to the last sector:
# dd if=/path/to/image.raw of=/path/to/shrinked_image.raw bs=512 count=42432505
Additionally, you may compress the new image with the native qcow2 compression:
# qemu-img convert -c -O qcow2 /path/to/shrinked_image.raw /path/to/shrinked_image.qcow2
Edit the configuration of your virtual machine to reflect the new path and image type and boot.
Doing a dd like this doesn’t actually free up any space at all, because it’s making a direct copy of the old virtual disk.
To make it free up space, you have to make a sparse disk and then recreate all the partitions, make the filesystems, and copy in the data with cp. Something like this:
dd if=/dev/zero of=newdisk.raw bs=512 seek=42432505
losetup -fv /path/to/newdisk.raw
fdisk /dev/loop0
mkfs.ext4 /dev/loop0p1
mount /dev/loop0p1 /mnt/
cp -a /olddisk/root/ /mnt/
Hi paul,
Thanks for your addition.
You’re doing it the other way round. But sometimes, you cannot just copy in the files from one filesystem to another (e.g. Windows partitions). Then you have to shrink and realign the partitions from within the virtual machine (see second paragraph). Afterwards, you can shrink the physical size of the image file by using my method.
Daimon