EDIT (2015-11-14): Please note that this post was made in 2011. At that time, this was the only solution. Comments suggest there are better ways now. I have not investigated.
Current project involves moving some KVM VMs from file storage to block storage. This is basically converting the .qcow2 files to LVM LVs. It was surprisingly simple.
First, we need to get an idea of how much space our VM uses. If you don’t know what you allocated, then inside the VM run
and add up the file system space. One of the steps requires converting the image to a raw format which creates a file that is the full size of all partitions.
Now shutdown your VM. You can’t make this change while it is running.
Next, convert the qcow2 file to a raw disk format. As mentioned previously, this is going to create a file that is the size of all of the VM partitions (including swap) combined. If you have 2 partitions, root of 20GB and a 2GB swap, it will create a file a little larger than 22GB. Make sure where you expand it has sufficient space.
Do the conversion
qemu-img convert disk0.qcow2 -O raw disk0.raw
Here is the output from one of my conversions.
user@example:/tmp/disk.nnbfn.net$ qemu-img convert tmp5GWO4q.qcow2 -O raw disk.raw user@example:/tmp/disk.nnbfn.net$ ls -lh total 42G -rw-r--r-- 1 user user 41G 2011-03-27 09:09 disk.raw -rwxrw-r-- 1 user user 117 2011-01-17 10:19 run.sh* -rwxrw-r-- 1 user user 21G 2011-03-26 12:04 tmp5GWO4q.qcow2*
Notice how the 21GB qcow2 file expanded to 41GB.
Now we need to get the exact size of the raw file.
user@example:/tmp/disk.nnbfn.net$ ls -l total 43103688 -rw-r--r-- 1 user user 44023414784 2011-03-27 09:09 disk.raw -rwxrw-r-- 1 user user 117 2011-01-17 10:19 run.sh -rwxrw-r-- 1 user user 22309240832 2011-03-26 12:04 tmp5GWO4q.qcow2
44023414784 is the size of the raw file in bytes.
Now, you need to create the LV. This command assumes you are naming the LV lv_disk and it is part of the Volume Group vgroup.
It is important to include the “b” following the size. This tells it you want the volume to be 44023414784 bytes. Without the “b” it would assume megabytes.
lvcreate -L 44023414784b -n lv_disk vgroup
You can verify the LV was created by running lvdisplay.
$ sudo lvdisplay /dev/vgroup/lv_disk --- Logical volume --- LV Name /dev/vgroup/lv_disk VG Name primary LV UUID 72PE7V-TYfq-sE0X-ue16-CFds-Jqbb-9rYKXi LV Write Access read/write LV Status available # open 1 LV Size 41.00 GiB Current LE 10496 Segments 2 Allocation inherit Read ahead sectors auto - currently set to 256 Block device 251:3
Or in bytes like so
$ sudo lvdisplay --units b /dev/vgroup/lv_disk --- Logical volume --- LV Name /dev/vgroup/lv_disk VG Name primary LV UUID 72PE7V-TYfq-sE0X-ue16-CFds-Jqbb-9rYKXi LV Write Access read/write LV Status available # open 1 LV Size 44023414784 B Current LE 10496 Segments 2 Allocation inherit Read ahead sectors auto - currently set to 256 Block device 251:3
Now to copy the raw image to the LV.
sudo dd if=disk.raw of=/dev/vgroup/lv_disk
Now you have to edit your VM definition.
The disk section when using the file looked like so:
<disk type='file' device='disk'> <driver name='qemu' type='qcow2' cache='none'/> <source file='/srv/virtual/vm_web/tmp5GWO4q.qcow2'/> <target dev='hda' bus='virtio'/> </disk>
After, it looks like this:
<disk type='block' device='disk'> <driver name='qemu' type='raw' cache='none'/> <source dev='/dev/vgroup/lv_disk'/> <target dev='vda' bus='virtio'/> </disk>
Overall, it is a simple and straight forward process. Convert, create, copy.