/akeydo

A systemd service that sends a D-Bus signal when the QEMU evdev hotkey is triggered.

Primary LanguagePythonMIT LicenseMIT

vfio-kvm

A systemd service that sends a D-Bus signal when the QEMU evdev hotkey is triggered.

When using a virtual machine with evdev passthrough QEMU allows the devices to be switched between the host and the virtual machine by pressing the left and right control keys at the same time. This service detects that press and sends a D-BUS signal allowing the computer to trigger and actions the user may want, including changing the input of one or more monitors.

When a virtual machine is started, the service reads the XML configuration for the virtual machine and scans for any passthrough input devices that start with the name of the virtual machine and creates them.

The service reads events from the source device and forwards them to the newly created device. When the QEMU hotkey is pressed the events will be forwarded to the next virtual machine or the host, allowing control to be cycled between any number of virtual machines.

Installation

Arch Linux

yay -Sy vfio-kvm
systemctl enable vfio-kvm.service --now

Manual Installation

cp config/libvirt/qemu /etc/libvirt/hooks/
cp config/dbus/vfio-kvm.xml /etc/dbus-1/system.d/
cp vfio-kvm.py /usr/bin/vfio-kvm
chmod +x /usr/bin/vfio-kvm
cp config/systemd/vfio-kvm.service /usr/lib/systemd/system/
systemctl enable vfio-kvm.service --now

Using the Service

For each device to toggle between the host and virtual machine(s) add the following XML segment to the libvirt XML for the virtual machine.

...
<devices>
  ...
  <input type="passthrough" bus="virtio">
    <source evdev="/dev/input/by-id/<VM NAME>-<DEVICE NAME>"/>
  </input>
  ...
</devices>
...

For example, to passthrough the device keyboard1 to the virtual machine named vm1 add the following XML segment to the <devices> section of the virtual machine configuration:

<input type="passthrough" bus="virtio">
  <source evdev="/dev/input/by-id/vm1-keyboard1"/>
</input>

The service will grab /dev/input/by-id/keyboard1 and forward events from it to the device specified in the evdev attribute of the <source> tag.

Switching Monitors on Hotkey

This service sends a D-Bus signal that can be monitored in order to run custom commands when the QEMU hotkey is pressed. To monitor the signal from a shell script use the program dbus-monitor.

dbus-monitor --system "type='signal',sender='vfio.kvm'"

To see a complete example that triggers ddccontrol, look in the examples folder.

Adding Custom Hotkeys

The service can be configured to look for additional hotkeys and reroute device input.

Adding a Custom Hotkey to Switch to the Host

To add a custom hotkey that will switch directly to the host, edit the file /etc/vfio-kvm.yaml to add the following section:

host:
  hotkey:
    - KEY_LEFTCTRL
    - KEY_LEFTALT
    - KEY_KP0

This hotkey will switch to the host when the left control, left alt, and the number zero on the keypad are pressed together.

Adding a Custom Hotkey to Switch to a Virtual Machine

To add a custom hotkey that will switch directly to a specific virtual machine, update the <metadata> block of the virtual machine XML configuration to include settings specific to VFIO-KVM.

The following sample shows how to set a hotkey that will switch directly to the specific virtual machine when the left control, left alt, and the number one on the keypad are pressed together:

...
<metadata>
  ...
  <vfiokvm:settings xmlns:vfiokvm="https://kvm.vfio/xmlns/libvirt/domain/1.0">
    <vfiokvm:hotkey>
      <vfiokvm:key value="KEY_LEFTCTRL"/>
      <vfiokvm:key value="KEY_LEFTALT"/>
      <vfiokvm:key value="KEY_KP1"/>
    </vfiokvm:hotkey>
  </vfiokvm:settings>
  ...
</metadata>
...

Adding a Custom Hotkey to Release Control of Devices without Toggling

To add a custom hotkey that will release all devices to the host without sending out a D-BUS signal or updating the active target, edit the file /etc/vfio-kvm.yaml to add the following section:

release_hotkey:
  - KEY_LEFTCTRL
  - KEY_LEFTALT
  - KEY_PAUSE

This hotkey will release all devices to the host when the left control, left alt, and the pause key are pressed together. Pressing this hotkey again will cause the active virtual machine to re-grab the devices.

Troubleshooting

  • The VM won't start when configured to use the guest devices
    • The vfio-kvm.service must be started in order for the guest devices to exist; verify that the service has started successfully before the VM loads.