Initial Commit
This commit is contained in:
commit
c896225cbd
|
@ -0,0 +1,33 @@
|
|||
# Maintainer: David Thurstenson (thurstylark@gmail.com)
|
||||
pkgname=libvirt-usb-hotplug
|
||||
pkgver=0.1
|
||||
pkgrel=1
|
||||
pkgdesc="Attach and detach USB devices from libvirt guests based on udev rules"
|
||||
arch=(any)
|
||||
url="https://git.thurstylark.com/libvirt-usb-hotplug.git"
|
||||
license=('GPL')
|
||||
depends=('systemd'
|
||||
'udev'
|
||||
'libvirt')
|
||||
backup=()
|
||||
source=("libvirt-usb-hotplug.bash"
|
||||
"libvirt-usb-hotplug.conf"
|
||||
"libvirt-usb-hotplug.rules"
|
||||
"libvirt-usb-hotplug@.service"
|
||||
)
|
||||
sha256sums=()
|
||||
|
||||
package() {
|
||||
install -Dm755 \
|
||||
"${srcdir}"/libvirt-usb-hotplug.bash \
|
||||
"${pkgdir}"/usr/bin/libvirt-usb-hotplug
|
||||
install -Dm644 \
|
||||
"${srcdir}"/libvirt-usb-hotplug.conf \
|
||||
"${pkgdir}"/etc/libvirt-usb-hotplug.conf
|
||||
install -Dm644 \
|
||||
"${srcdir}"/libvirt-usb-hotplug.rules \
|
||||
"${pkgdir}"/usr/lib/udev/rules.d/99-libvirt-usb-hotplug.rules
|
||||
install -Dm644 \
|
||||
"${srcdir}"/libvirt-usb-hotplug@.service \
|
||||
"${pkgdir}"/usr/lib/systemd/system/libvirt-usb-hotplug@.service
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
#!/bin/bash
|
||||
|
||||
# libvirt-usb-hotplug.bash
|
||||
|
||||
# This script can be used to hotplug USB devices to libvirt virtual
|
||||
# machines from udev rules with systemd services.
|
||||
|
||||
# References:
|
||||
# - https://github.com/olavmrk/usb-libvirt-hotplug
|
||||
# - http://kicherer.org/joomla/index.php/en/blog/48-automatic-hotplugging-of-usb-devices-for-libvirt-managed-vms
|
||||
# - https://blog.tjll.net/systemd-for-device-activation-and-media-archiving/
|
||||
|
||||
|
||||
# Abort script execution on errors
|
||||
set -e
|
||||
|
||||
readvars() {
|
||||
PROG="$(basename "$0")"
|
||||
ACTION=$1
|
||||
IFS='_' read DOMAIN ID_VENDOR_ID ID_MODEL_ID <<< "$2"
|
||||
|
||||
if [ -z "${DOMAIN}" ]; then
|
||||
echo "Missing libvirt domain parameter for ${PROG}." >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
findmatch() {
|
||||
# Iterate through devlist to find match
|
||||
for i in "${devlist[@]}"; do
|
||||
# If we find a match, return successfully
|
||||
[ "${ID_VENDOR_ID}:${ID_MODEL_ID}" = "$i" ] && return 0
|
||||
# If a match can't be found, keep looping
|
||||
continue
|
||||
done
|
||||
# If no match was found, return unsuccessfully
|
||||
return 1
|
||||
}
|
||||
|
||||
case ${ACTION} in
|
||||
add)
|
||||
readvars
|
||||
COMMAND='attach-device'
|
||||
;;
|
||||
remove)
|
||||
readvars
|
||||
COMMAND='detach-device'
|
||||
;;
|
||||
match)
|
||||
# This section is responsible for determining if the corresponding udev rule
|
||||
# matches against the device in question. Udev watches exit code to determine
|
||||
# if a match was made.
|
||||
#
|
||||
# Ref: udev(7) manpage
|
||||
|
||||
# Read the config file
|
||||
source /etc/libvirt-usb-hotplug.conf
|
||||
|
||||
# If we should match against any usb device, just exit successfully
|
||||
[ "$matchall" = "true" ] && exit 0
|
||||
|
||||
# If the devlist array is empty, no matches can be made
|
||||
[ ${#devlist[@]} = 0 ] && exit 1
|
||||
|
||||
# If targetdomain is unset or empty, exit unsuccessfully
|
||||
[ ! -v targetdomain ] && exit 1
|
||||
[ "$targetdomain" = "" ] && exit 1
|
||||
# Print the targetdomain so it can be picked back up by the udev rule
|
||||
printf "%s" "$targetdomain"
|
||||
|
||||
case $listmode in
|
||||
whitelist)
|
||||
# findmatch() returns 0 if match found, and 1 if match not found
|
||||
findmatch
|
||||
exit $?
|
||||
;;
|
||||
blacklist)
|
||||
# Reverse the exit status of findmatch() for blacklist mode
|
||||
! findmatch
|
||||
exit $?
|
||||
;;
|
||||
*)
|
||||
# If listmode is unset, or set improperly, exit unsuccessfully
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
echo "Invalid script ACTION: ${ACTION}" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# Run the appropriate virsh-command, and ask it to read the update XML from stdin.
|
||||
echo "Running virsh ${COMMAND} ${DOMAIN} --persistent for USB vendor=0x${ID_VENDOR_ID} product=0x${ID_MODEL_ID}:" >&2
|
||||
(virsh "${COMMAND}" "${DOMAIN}" /dev/stdin --persistent || true) <<END
|
||||
<hostdev mode='subsystem' type='usb' managed='yes'>
|
||||
<source startupPolicy='optional'>
|
||||
<vendor id='0x${ID_VENDOR_ID}' />
|
||||
<product id='0x${ID_MODEL_ID}' />
|
||||
</source>
|
||||
</hostdev>
|
||||
END
|
|
@ -0,0 +1,25 @@
|
|||
# libvirt-usb-hotplug.conf
|
||||
|
||||
# Name of libvirt domain to which the device in question will be attached
|
||||
# Default if unset: <none> (disables matching)
|
||||
targetdomain=win10
|
||||
|
||||
# Match against every usb device
|
||||
# Valid values: true, false
|
||||
# Default if unset: false
|
||||
matchall=true
|
||||
|
||||
# Should the list be a whitelist, or blacklist?
|
||||
# Valid values: whitelist, blacklist
|
||||
# Default if unset: <none> (disables matching)
|
||||
listmode=blacklist
|
||||
|
||||
# List of devices to match against
|
||||
# Value format: '<vendor_id>:<device_id>'
|
||||
devlist=(
|
||||
'0b05:1872' # ASUSTek Computer, Inc. AURA LED Controller
|
||||
'0b05:185c' # ASUSTek Computer, Inc. Bluetooth Radio
|
||||
)
|
||||
|
||||
|
||||
# vim: set ft=bash:
|
|
@ -0,0 +1,13 @@
|
|||
# libvirt-usb-hotplug.rules
|
||||
|
||||
ACTION=="add", \
|
||||
SUBSYSTEM=="usb", \
|
||||
PROGRAM=="/usr/bin/libvirt-usb-hotplug match" \
|
||||
SYMLINK+="libvirt_%c_%E{ID_VENDOR_ID}_%E{ID_MODEL_ID}", \
|
||||
TAG+="systemd", \
|
||||
ENV{SYSTEMD_WANTS}="libvirt_%c_%E{ID_VENDOR_ID}_%E{ID_MODEL_ID}"
|
||||
|
||||
ACTION=="remove", \
|
||||
SUBSYSTEM=="usb", \
|
||||
ENV{PRODUCT}=="46d/c215/*", \
|
||||
TAG+="systemd"
|
|
@ -0,0 +1,15 @@
|
|||
[Unit]
|
||||
Description=Libvirt guest usb hotplug: %I
|
||||
After=libvirtd.service
|
||||
BindsTo=dev-libvirt_%i.device
|
||||
After=dev-libvirt_%i.device
|
||||
Requisite=dev-libvirt_%i.device
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStart=/usr/bin/libvirt-usb-hotplug add %I
|
||||
ExecStop=/usr/bin/libvirt-usb-hotplug remove %I
|
||||
|
||||
[Install]
|
||||
WantedBy=dev-libvirt_%i.device
|
Loading…
Reference in New Issue