Using LVM-based storage pools for libvirt benefits from the extra features of LVM itself such as live snapshots and encryption and the scope of this guide is to illustrate the migration from image files to LVM storage pools.
In order to be able to migrate, you need at least a free partition and, at best, a new clean device that will be converted to a LVM physical volume. This guide assumes that /dev/sda2
is a partition that will be used to hold a libvirt storage pool for virtual machines.
The first step is to create a physical volume group:
pvcreate /dev/sda2
where:
/dev/sda2
is the partition you want to use.followed by the creation of a volume group:
vgcreate virt /dev/sda2
where:
virt
is a descriptive name for the entire volume group
Now libvirt
must be instructed to use the virt
volume group as a storage pool:
virsh pool-define-as \ --name virt \ --type logical \ --source-format lvm2 \ --target /dev/sda2
The next step is to mark the pool to autostart:
virsh pool-autostart virt
and finally start the pool:
virt pool-start virt
You can now list the storage pools you have using pool-list
:
virsh pool-list <code> should yield something along the lines of: <code> Name State Autostart ------------------------------------------- virt active yes
If you want more information on the pool, you can use pool-info
:
virsh pool-info virt
Images will need to be converted to the raw format in order to be able to copy them over easily with dd
. In order to do that, supposedly if your image format is qcow2
, you would issue:
qemu-img convert -f qcow2 -O raw \ /var/lib/libvirt/images/domain.qcow2 \ /var/lib/libvirt/images/domain.raw
where:
/var/lib/libvirt/images/domain.qcow2
is the image to convert from in qcow2
format and,/var/lib/libvirt/images/domain.raw
is the image to convert to.Make sure that the VM you wish to copy over is shutdown before proceeding. We are now going to create a volume within the volume group with the exact same size as the raw image file. First step is to find out how large your raw image file is:
qemu-img info /var/lib/libvirt/images/domain.raw
which should tell you the exact size:
image: domain.raw file format: raw virtual size: 8G (8589934592 bytes) disk size: 8G
Using the 8589934592
bytes size, we create the volume:
virsh vol-create-as virt domain 8589934592
where:
domain
is a descriptive name of the volume - can be anything but it would be tidy to use the name of the virtual machine8589934592
is the size in bytes (8GiB, in this case)
Now that the volume is created, you can query some info about it, for instance, using virsh
:
virsh vol-info domain --pool virt
Alternatively, you can use LVM tools directly:
lvdisplay
This task can take a while, so again, ensure that the virtual machine is fully powered off before proceeding. With the LVM volume in place and the RAW image, issue:
dd if=/var/lib/libvirt/images/domain.raw of=/dev/virt/domain bs=1M
where:
/var/lib/libvirt/images/domain.raw
is the path to the domain RAW image,/dev/virt/domain
is the device corresponding to the LVM volume - /dev/virt/
will be created depending on what name you chose when issuing lvcreate
in the first section.bs=1M
means to block copy in 1MiB chunks.This operation will take a while and there is no progress indicator - from time to time you can hit Ctrl+T in order to display some information about how much data was copied so far.
When the copying via dd
completes, you will need to adapt your virtual machine configuration. For instance, if your configuration previous to these steps was:
<disk type='file' device='disk'> <driver name='qemu' type='qcow2'/> <source file='/var/lib/libvirt/images/domain.qcow2'/> <target dev='vda' bus='virtio'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/> </disk>
you will need to adjust:
type='file
' to type='block
' since you are now using the LVM block device,type='qcow2
' to type='raw
', file='/var/lib/libvirt/images/domain.qcow2
' to dev='/dev/virt/domain
' to point to the LVM volume,
as well as remove the <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/>
because it will be automatically re-created when the domain is saved.
For instance, given the configuration above, the converted result would be:
<disk type='block' device='disk'> <driver name='qemu' type='raw'/> <source dev='/dev/virt/domain'/> <target dev='vda' bus='virtio'/> </disk>
with the address line removed.