Libvirt

From Segfault
Jump to navigation Jump to search

Installation

Debian

sudo apt-get install qemu-kvm libvirt-bin
sudo usermod -a -G kvm,libvirt alice

If necessary:[1][2]

sudo deb-systemd-invoke start virtlockd.socket virtlockd.service

Fedora

sudo dnf install virt-manager qemu-kvm libvirt                   # Fedora, RHEL Note: libvirt seems to be optional
sudo usermod -a -G libvirt alice

Permissions

For already existing VMs or disk images, grant access to everyone in the libvirt group:

sudo find /opt/vm/ -exec setfacl -m u:libvirt-qemu:rwX -m g:libvirt:rwX '{}' +

Network

Networking should already be enabled these days:

$ sudo virsh net-edit default
<network>
  <name>default</name>
  <uuid>cc3cf216-c5b0-4e0f-bb5c-94420b5054f6</uuid>
  <forward mode='nat'/>
  <bridge name='virbr0' stp='on' delay='0'/>
  <mac address='12:34:00:aa:bb:cc'/>
  <ip address='192.168.122.1' netmask='255.255.255.0'>
    <dhcp>
      <range start='192.168.122.2' end='192.168.122.254'/>
    </dhcp>
  </ip>
</network>

$ sudo systemctl restart libvirtd.service

Usage

Creation

After KVM has been installed, let's create a Debian virtual machine:

virt-install --name debian --description "Debian GNU/Linux" --ram 4096 --vcpus 2 \
   --disk path=/opt/vm/debian.qcow,size=4 --os-variant debian9 \
   --network bridge=virbr0 --graphics vnc,listen=127.0.0.1,port=5910 \
   --cdrom ../debian.iso

Use osinfo-query os for all --os-variant options.

As Fedora comes with SELinux enabled, we may have to grant extra permissions[3][4] to the locations above:

sudo setsebool -P virt_use_nfs 1
sudo chcon -R --type=virt_image_t /opt/vm/kvm
sudo setfacl -m u:$USER:rwx /opt/vm/kvm

General

The newly installed virtual machine can be controlled with virsh[5].

List virtual machines:

$ virsh list 
Id    Name                           State
----------------------------------------------------
2     debian                         running

Connect the virtual machine's serial console:

$ virsh console debian                                          # The guest needs to enable its Serial Console
Connected to domain debian
Escape character is ^]

Shutdown/reboot/start a virtual machine:

virsh shutdown debian
virsh reboot   debian
virsh start    debian

For the shutdown command to work, the system needs to support certain ACPI calls. Linux systems should run acpid. Windows systems should have the Shutdown: Allow system to be shut down without having to log on local security policy[6] enabled (via Computer Configuration => Windows Settings => Security Settings => Local Policies => Security Options). Also the Power Button should be configured to react to shutdown signals, even for a virtual system with no real power button.[7]

Core dump a virtual machine:

virsh dump debian --file debian.core                            # May not work due to non-migratable devices

Send a sysrq sequence to a guest:[8]

virsh send-key debian KEY_LEFTALT KEY_SYSRQ KEY_H

External disks

Temporarily attaching (and detaching) external disks to a (running) virtual machine can be cumbersome but can be simplified with a pre-configured XML file.[9] Let's connect for example an USB drive to our host machine:

$ dmesg | grep idVen | tail -1
usb 1-1: New USB device found, idVendor=0781, idProduct=5406, bcdDevice= 2.00

$ lsusb -s 008
Bus 001 Device 008: ID 0781:5406 SanDisk Corp. Cruzer Micro U3

Prepare our XML file:

$ cat sandisk.xml
<hostdev mode='subsystem' type='usb'>
 <source>
   <vendor id='0x0781'/>
   <product id='0x5406'/>
 </source>
</hostdev>

With that in place, we can now attach the disk via the XML file:

virsh attach-device debian sandisk.xml

We may have to give ourselves write permissions to that device first:

sudo setfacl -m u:${USER}:rw /dev/bus/usb/001/008

If needed, an udev rule could be created, but then the device will only be attached/detached to a particular machine:

$ cat /etc/udev/rules.d/90-libvirt-usb.rules
ACTION=="add", \
   SUBSYSTEM=="usb", \
   ENV{ID_VENDOR_ID}=="0781", \
   ENV{ID_MODEL_ID}=="5406", \
   RUN+="/usr/bin/virsh attach-device debian /usr/local/etc/sandisk.xml"

ACTION=="remove", \
   SUBSYSTEM=="usb", \
   ENV{ID_VENDOR_ID}=="0781", \
   ENV{ID_MODEL_ID}=="5406", \
   RUN+="/usr/bin/virsh detach-device debian /usr/local/etc/sandisk.xml"

To detach, run:

virsh detach-device debian sandisk.xml

Storage Pools

For some reason new storage pools are created when new machines are defined:

virt-install --name foobar --ram 2048 --vcpus 2 --os-type debian9 \
    --disk /opt/vm/debian9.qcow2 \
    --cdrom /mnt/nfs/debian-9.4.0-amd64-netinst.iso [...]

And once the VM is defined:

$ virsh pool-list 
Name      State    Autostart
-------------------------------
default   active   yes
nfs       active   yes
debian9   active   yes

$ for p in nfs debian9; do virsh pool-dumpxml ${p} | grep path; done
   <path>/mnt/nfs/</path>
   <path>/opt/vm/</path>

As a temporary workaround, let's destroy (and undefine) all non-default pools:

for p in $(virsh pool-list --name | grep -vw default); do virsh pool-destroy $p && virsh pool-undefine $p; done

Snapshots

After creating a disk-only snapshot we could not delete the same snapshot any more:

$ virsh snapshot-create --domain foobar --disk-only
Domain snapshot 1573619216 created

$ virsh snapshot-delete --domain foobar --snapshotname 1573619216
error: Failed to delete snapshot 1573619216
error: unsupported configuration: deletion of 1 external disk snapshots not supported yet

We first have to merge back the changes into the parent device[10] before we can delete the snapshot:

$ virsh domblklist foobar
Target   Source 
------------------------------------------------------------
vda      /opt/vm/foobar.1573619216
sda      -
$ virsh start foobar
Domain foobar started

$ virsh blockcommit foobar /opt/vm/foobar.1573619216 --verbose --pivot
Block commit: [100 %]
Successfully pivoted
$ virsh domblklist foobar
Target   Source 
-------------------------------------------------------
vda      /opt/vm/foobar.qcow2
sda      -

While the snapshot file is still present, it is no longer active and can be disassociated from the VM:

$ virsh snapshot-list --domain foobar
Name         Creation Time               State
---------------------------------------------------
1573619216   2019-11-12 20:26:56 -0800   shutoff

$ virsh snapshot-delete --domain foobar --snapshotname 1573619216 --metadata 
Domain snapshot 1573619216 deleted

The physical snapshot file itself can be removed too:

rm /opt/vm/foobar.1573619216

Bugs

  • Redhat #678555 - systemd should not purge application created cgroups, even if they contain no processes
  • Redhat #452422 - qemu: could not open disk image
  • Redhat #527736 - Storage driver can't create storage pool volumes on a FAT32 hard disk

Links

References