Managing LVM Storage with libvirt
By default, libvirt stores VM images as files in /var/lib/libvirt/images/. While functional, this approach limits flexibility. LVM (Logical Volume Management) provides better control over disk space, snapshots, and performance tuning. Using LVM volumes as libvirt storage pools lets you manage VM storage like block devices rather than files, giving you faster provisioning, atomic snapshots, and better resource allocation.
Prerequisites
You’ll need:
- A working libvirt installation (
libvirtdrunning) - An existing LVM volume group with available space
virshCLI tool- Appropriate permissions (typically root or libvirt group membership)
If you don’t have LVM set up yet, create a volume group first:
# Create physical volume
pvcreate /dev/sdb
# Create volume group
vgcreate vg-libvirt /dev/sdb
# Verify
vgs
Adding an LVM Volume Group as a Storage Pool
The cleanest approach is to define the LVM volume group as a libvirt storage pool using XML.
Via virsh
Create a pool definition file:
<pool type='logical'>
<name>vg-libvirt</name>
<target>
<path>/dev/vg-libvirt</path>
</target>
</pool>
Save this as lvm-pool.xml, then define it:
virsh pool-define lvm-pool.xml
virsh pool-start vg-libvirt
virsh pool-autostart vg-libvirt
Verify the pool is active:
virsh pool-list --all
virsh pool-info vg-libvirt
Via virt-manager GUI
If you prefer the GUI, open virt-manager and navigate to:
- File → Add Connection (if needed)
- Right-click the connection → Details → Storage
- Click the “+” button
- Select “Logical: LVM volume group”
- Choose your existing VG from the dropdown
- Confirm and the pool will be created
Creating VMs in the LVM Pool
Once the pool is defined, you can create volumes within it and launch VMs using those volumes.
Create a logical volume for a VM:
lvcreate -L 20G -n vm-disk1 vg-libvirt
Or let libvirt create the volume for you when defining a VM. In the VM XML, reference your pool:
<disk type='volume' device='disk'>
<driver name='qemu' type='raw'/>
<source pool='vg-libvirt' volume='vm-disk1'/>
<target dev='vda' bus='virtio'/>
</disk>
List volumes in your pool:
virsh vol-list vg-libvirt
Snapshots and Cloning
LVM snapshots are significantly faster with the logical pool type than with file-based storage.
Create a snapshot:
lvcreate -L 5G -s -n vm-disk1-snap /dev/vg-libvirt/vm-disk1
Clone an existing volume:
virsh vol-clone vg-libvirt vm-disk1 vm-disk1-clone
Monitoring and Maintenance
Check pool and volume usage:
virsh pool-info vg-libvirt
virsh vol-info vg-libvirt vm-disk1
Resize a logical volume if needed:
lvextend -L +10G /dev/vg-libvirt/vm-disk1
Note: VM filesystems won’t automatically grow with the LV. You’ll need to extend partitions/filesystems inside the guest separately using standard tools like growpart or parted.
Delete a volume:
virsh vol-delete --pool vg-libvirt vm-disk1
Removing the Storage Pool
If you need to stop using the pool:
virsh pool-destroy vg-libvirt # Stop the pool
virsh pool-undefine vg-libvirt # Remove the definition
This only removes the libvirt definition; your logical volumes remain intact on disk.
Performance Considerations
- Use
type='raw'for VM disks in LVM pools—it provides better performance thanqcow2 - Consider using
cache='directsync'orcache='none'for the disk cache mode if you’re not using filesystem-level caching - LVM snapshots consume space in your VG; monitor available space regularly with
vgsandlvs
LVM storage pools integrate seamlessly with libvirt and offer a robust alternative to file-based VM storage, especially for production environments where snapshot and cloning performance matter.
