libvirt notes

This is a living document containing notes, howtos and lessons-learned about installing and running VMs in libvirt I started for the purpose of keeping what I’ve learned committed to memory. I’ve published it so maybe other can also get use from it.

Table of Contents

Host Configuration

Installing libvirt

By default, this gives a functioning baseline install on Debian Trixie (still 'testing' as of 2024-11-29):

sudo apt install \
    libvirt-clients \
    libvirt-daemon-system \
    qemu-system \
    qemu-system-modules-spice \
    qemu-utils \
    virt-manager

Note: Fedora has the @virtualization group to encapsulate the installation of all these; does Debian have something similar?

DHCP Reservations

From VMM, go to Edit > Connection Details > Virtual Networks and stop the network. Edit XML to add this tag to <dhcp/> block, then restart the network (ref):

<host mac="52:54:00:13:ef:bc" ip="192.168.122.33"/>

Routing to VMs from host machine’s LAN peers

By changing the default network type to routed instead of nat, VMs are automatically routable on the LAN as long as the main router has a static route pointing to the host machine, set to 10.20.30.0 in this case. Did not need to mess with ufw on the host machine.

Also learned that the libvirt network IP has a DNS server dangling off of it so dig <vmname> @10.20.30.1 resolves correctly.

Hooks

These live at /etc/libvirt/hooks/<hookname> (ref). I like to add this to the top of the hooks for easier troubleshooting and monitoring via journalctl:

# simplest one-liner
logger -t 'some-descriptive-tag' "$0 $*"

# -OR- if you're feeling like capturing a WHOLE bunch of output
exec > >(logger -t 'nope-logspam-doesnt-bother-me-one-bit')
exec 2>&1

SELinux issues blocking hooks from running in Fedora 39+(?)

I had an issue getting hooks to run in later versions of Fedora because somewhere between F38 and F40, they introduced an selinux context check that broke my network hook script:

root@strago:/etc/libvirt/hooks# virsh net-start default || journalctl -e -g avc --lines 1 | audit2why
error: Failed to start network default
error: Hook script execution failed: internal error: Child process (LC_ALL=C PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin USER=root /etc/libvirt/hooks/network default start begin -) unexpected exit status 126: libvirt:  error : cannot execute binary /etc/libvirt/hooks/network: Permission denied

Nov 14 07:57:43 strago.narshe audit[113078]: AVC avc:  denied  { execute } for  pid=113078 comm="rpc-virtnetwork" name="network" dev="dm-0" ino=2491327 scontext=system_u:system_r:virtnetworkd_t:s0 tcontext=system_u:object_r:virt_hook_t:s0 tclass=file permissive=0

  Was caused by:
  The boolean virt_hooks_unconfined was set incorrectly.
  Description:
  Allow virt to hooks unconfined

  Allow access by executing:
  # setsebool -P virt_hooks_unconfined 1

root@strago:/etc/libvirt/hooks# ll -aZ
total 12
drwx------. 2 root root system_u:object_r:virt_hook_t:s0 4096 Oct 29 13:28 .
drwx------. 7 root root system_u:object_r:virt_etc_t:s0  4096 Oct 23 20:30 ..
-rwx------. 1 root root system_u:object_r:virt_hook_t:s0  914 Oct 29 13:28 network

I didn’t want to just make any permanent change to selinux so I asked at Fedora’s forums and someone said there’s no way to chcon/restorecon your way out of this error, you just have to change the selinux setting with the setsebool command provided by audit2why above.

Guest Configuration

Clipboard sharing, keyboard/mouse capture and screen resizing

spice-agent running on the guest machine is what provides the ability for virt-viewer to capture keyboard (e.g., Meta+R) shortcuts without disturbing the machine you’re running virt-viewer on, scroll using trackpad gestures on a laptop, share clipboard contents between the virt-viewer machine and the guest and rescale the guest screen resolution to the size of the virt-viewer window (ref).

Requirements for getting this to work are:

  • Windows: guest has virtio-win-guest-tools installed and service spice-agent running (sc.exe start spice-agent)
  • Linux: guest has spice-vdagent installed (sudo apt install spice-vdagent or sudo dnf install spice-vdagent) and service spice-vdagentd running (systemctl enable --now spice-vdagentd)
  • guest has Video QXL defined
  • guest has Display/Graphics Spice server defined
  • guest has Channel spicevmc at com.redhat.spice.0 defined

Note 1: This is where I’ve sunk HOURS configuring things trying to get things working. I’ve gotten Windows and Fedora’s spice functionality working but I have not been able to get Debian KDE to successfully rescale or share the clipboard and not for a lack of trying. Update 2024-12-01: it looks like the spice-vdagent of Debian 13 (testing) works for screen resolution scaling, but clipboard (arguably the most important feature) is still broken.

Note 2: There exists what I’ve started calling the “legacy spice guest agent for Windows” hosted at www.spice-space.org which hasn’t been updated since 2018. If I remember correctly, it only works for BIOS-based guests and will not work if the guest is set up as UEFI (which I don’t think can be changed after creating the guest).

Purpose of qemu-guest-agent

If I understand correctly, qemu-ga enables sending certain hypervisor-relevant commands and interrogating the guest for system details (ref), e.g.,:

10:34:27 [~]$ virsh guestinfo win11
user.count          : 1
user.0.name         : David
user.0.domain       : DESKTOP-9C24BAJ
user.0.login-time   : 1732904616072
os.id               : mswindows
os.name             : Microsoft Windows
os.pretty-name      : Windows 10 Pro
os.version          : Microsoft Windows 11
os.version-id       : 11
os.machine          : x86_64
.
.
.
if.0.addr.1.addr    : 172.16.0.249
if.0.addr.1.prefix  : 24
if.1.name           : Loopback Pseudo-Interface 1
if.1.hwaddr         :
if.1.addr.count     : 2
if.1.addr.0.type    : ipv6
if.1.addr.0.addr    : ::1
if.1.addr.0.prefix  : 128
if.1.addr.1.type    : ipv4
if.1.addr.1.addr    : 127.0.0.1
if.1.addr.1.prefix  : 8

[~]$ virsh shutdown --mode agent win11
Domain 'win11' is being shutdown

Requires:

  • Windows: guest has virtio-win-guest-tools installed and service qemu-ga running (sc.exe start qemu-ga)
  • Linux: guest has qemu-guest-agent installed (sudo apt install qemu-guest-agent or sudo dnf install qemu-guest-agent) and service qemu-guest-agent running (systemctl enable --now qemu-guest-agent)
  • guest has Channel qemu-ga at org.qemu.guest_agent.0 defined

Share directory between host and guest

Requires:

  • Windows: guest has virtio-win-guest-tools and winfsp installed and service virtiofssvc running (sc.exe start VirtioFsSvc)
  • Linux: TODO
  • guest has Filesystem defined with some name, e.g., lolwut pointing at some directory on the host machine (example).

If the install is successful, the directory should be automatically available as a mounted shared in Explorer: successful

loading blog data