From b34f4ef72cdf1d8cc14679044ef364f0a90f5191 Mon Sep 17 00:00:00 2001 From: Florian RICHER Date: Mon, 24 Jan 2022 23:25:15 +0100 Subject: [PATCH] [KVM] Add hotplug --- .../usb-libvirt-hotplug.sh | 113 ++++++++++++++++++ .../udev/90-usb-libvirt-hotplug.rules | 1 + 2 files changed, 114 insertions(+) create mode 100755 configs/kvm/usbhotplug/opt/usb-libvirt-hotplug/usb-libvirt-hotplug.sh create mode 100644 configs/kvm/usbhotplug/udev/90-usb-libvirt-hotplug.rules diff --git a/configs/kvm/usbhotplug/opt/usb-libvirt-hotplug/usb-libvirt-hotplug.sh b/configs/kvm/usbhotplug/opt/usb-libvirt-hotplug/usb-libvirt-hotplug.sh new file mode 100755 index 0000000..40e00b7 --- /dev/null +++ b/configs/kvm/usbhotplug/opt/usb-libvirt-hotplug/usb-libvirt-hotplug.sh @@ -0,0 +1,113 @@ +#!/bin/bash + +# +# usb-libvirt-hotplug.sh +# +# This script can be used to hotplug USB devices to libvirt virtual +# machines from udev rules. +# +# This can be used to attach devices when they are plugged into a +# specific port on the host machine. +# +# See: https://github.com/olavmrk/usb-libvirt-hotplug +# + +# Abort script execution on errors +set -e + +PROG="$(basename "$0")" + +if [ ! -t 1 ]; then + # stdout is not a tty. Send all output to syslog. + coproc logger --tag "${PROG}" + exec >&${COPROC[1]} 2>&1 +fi + +DOMAIN="$1" +VENDOR_ID=$ID_VENDOR_ID +PRODUCT_ID=$ID_MODEL_ID + +if [ -z "${DOMAIN}" ]; then + echo "Missing libvirt domain parameter for ${PROG}." >&2 + exit 1 +fi + + +# +# Do some sanity checking of the udev environment variables. +# + +if [ -z "${SUBSYSTEM}" ]; then + echo "Missing udev SUBSYSTEM environment variable." >&2 + exit 1 +fi +if [ "${SUBSYSTEM}" != "usb" ]; then + echo "Invalid udev SUBSYSTEM: ${SUBSYSTEM}" >&2 + echo "You should probably add a SUBSYSTEM=\"USB\" match to your udev rule." >&2 + exit 1 +fi + +if [ -z "${DEVTYPE}" ]; then + echo "Missing udev DEVTYPE environment variable." >&2 + exit 1 +fi +if [ "${DEVTYPE}" == "usb_interface" ]; then + # This is normal -- sometimes the udev rule will match + # usb_interface events as well. + exit 0 +fi +if [ "${DEVTYPE}" != "usb_device" ]; then + echo "Invalid udev DEVTYPE: ${DEVTYPE}" >&2 + exit 1 +fi + +if [ -z "${ACTION}" ]; then + echo "Missing udev ACTION environment variable." >&2 + exit 1 +fi +if [ "${ACTION}" == 'add' ]; then + COMMAND='attach-device' +elif [ "${ACTION}" == 'remove' ]; then + COMMAND='detach-device' +else + echo "Invalid udev ACTION: ${ACTION}" >&2 + exit 1 +fi + +if [ -z "${BUSNUM}" ]; then + echo "Missing udev BUSNUM environment variable." >&2 + exit 1 +fi +if [ -z "${DEVNUM}" ]; then + echo "Missing udev DEVNUM environment variable." >&2 + exit 1 +fi + + +# +# This is a bit ugly. udev passes us the USB bus number and +# device number with leading zeroes. E.g.: +# BUSNUM=001 DEVNUM=022 +# This causes libvirt to assume that the numbers are octal. +# To work around this, we need to strip the leading zeroes. +# The easiest way is to ask bash to convert the numbers from +# base 10: +# +BUSNUM=$((10#$BUSNUM)) +DEVNUM=$((10#$DEVNUM)) + +# +# Now we have all the information we need to update the VM. +# Run the appropriate virsh-command, and ask it to read the +# update XML from stdin. +# +echo "Running virsh ${COMMAND} ${DOMAIN} for USB bus=${BUSNUM} device=${DEVNUM} vendor_id=${VENDOR_ID} product_id=${PRODUCT_ID}:" >&2 +virsh "${COMMAND}" "${DOMAIN}" /dev/stdin < + + + +
+ + +END diff --git a/configs/kvm/usbhotplug/udev/90-usb-libvirt-hotplug.rules b/configs/kvm/usbhotplug/udev/90-usb-libvirt-hotplug.rules new file mode 100644 index 0000000..5ebc137 --- /dev/null +++ b/configs/kvm/usbhotplug/udev/90-usb-libvirt-hotplug.rules @@ -0,0 +1 @@ +SUBSYSTEM=="usb",RUN+="/opt/usb-libvirt-hotplug/usb-libvirt-hotplug.sh win10"