Convert KVM qcow2 to LVM raw partition

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

df -h

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.

10 thoughts on Convert KVM qcow2 to LVM raw partition

  1. I spent few hours playing with qcow2 conversion to iSXSI LUN. I had hedaches because dd reported read/write errors periodicaly. Then I discovered, You can use this command instead:

    qemu-img convert disk0.qcow2 -O raw /dev/vgroup/lv_disk

    Raw size of qcow2 image can be read from:

    qemu-img info disk0.qcow2

    Reply
  2. Tomas, I’ve tried your shortcut on Ubuntu 10.04, but it produced an error:
    qemu-img: Error while formatting ‘/dev/VG0/VM1’
    (obviously /dev/VG0/VM1 was where I tried to copy my qcow2 image).
    Any comments?

    Reply
  3. Update: using -O host_device instead of -O raw (as man qemu-img says) helped.

    Reply
  4. Is it possible to caliculate the raw image size formed from qcow2, if we know qcow2 size?

    Reply
  5. qemu-img info displays the virtual size, etc.
    And found out the cause of my generic error formatting:
    virtual size: 64G (68719476736 bytes)
    ryzomlv nakvmvg mwa-a- 32.00g

    Oops

    Reply
  6. You don’t need to convert from qcow2 to raw to put your data on a vm. Leave it in qcow2 format- why the change? I have my qcow2-based images running on LVM right now:

    qemu-img info /dev/kvm_temp/pxetest
    image: /dev/kvm_temp/pxetest
    file format: qcow2

    Reply
    1. qemu-img info /dev/kvm_temp/pxetest –> That’s not a LVM disc. That it’s a qcow file on a LVM partition.
      That not get benefits of LVM (more speed, best snapshots,…)

      Reply
  7. Not sure why you are converting the qcow image at all…. Why not just use the QEMU Disk Network Block Device Server?

    Try this (as root)
    modprobe nbd max_parts=16
    qemu-nbd -c /dev/nbd0 /foo/bar.qcow2
    dd if=/dev/nbd0 of=/path/to/lv bs=64k

    when dd finishes,
    qemu-nbd -d /dev/nbd0
    rmmod nbd

    Reply
    1. @Mike Schwager @GBK – This was originally posted in 2011. Things have apparently improved since then.

      Reply

Leave a Reply

Your email address will not be published.