Skip to content

Instantly share code, notes, and snippets.

@ivan
Last active June 5, 2018 09:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ivan/5f21fe0345bedc71fa3929a10ab65540 to your computer and use it in GitHub Desktop.
Save ivan/5f21fe0345bedc71fa3929a10ab65540 to your computer and use it in GitHub Desktop.
VFIO software KVM switch from hell to deal with unreliable mouse attachment
#!/bin/bash
set -eu
guest=$1
attached_to_file=~/.cache/keyboard-mouse-attached-to-guest
echo -n -E "$guest" > $attached_to_file
#!/bin/bash
set -eu
attached_to_file=~/.cache/keyboard-mouse-attached-to-guest
rm -f "$attached_to_file"
mouse=046d:c048
keyboard=0d3d:0001
if virsh --connect qemu:///system list | grep -qP 'windows10 +running$'; then
guest=windows10
else
guest=macos
fi
vm-usb-device detach "$guest" $mouse || true
vm-usb-device detach "$guest" $keyboard || true
set-input-device-settings
#!/bin/bash
# Deal with Logitech G9 initialization failure weirdness (caused by display
# input switch & ScpToolkit jank?) and handle the keyboard too while we're at it
mouse=046d:c048
mouse_name="Logitech G9 Laser Mouse"
keyboard=0d3d:0001
keyboard_name="USBPS2"
attached_to_file=~/.cache/keyboard-mouse-attached-to-guest
ensure_running() {
guest=$1
if [[ $(virsh --connect qemu:///system list | grep -P -c "$guest +running$") -eq 0 ]]; then
echo "[$(date)] $guest is no longer running, removing $attached_to_file"
rm -f "$attached_to_file"
return 0
else
return 1
fi
}
while true; do
if [[ -f "$attached_to_file" ]]; then
guest=$(<$attached_to_file)
if xinput list | fgrep -m 1 -q "$keyboard_name"; then
if ensure_running "$guest"; then
continue
fi
vm-usb-device detach "$guest" $keyboard 2> /dev/null && echo "[$(date)] detached keyboard from $guest" || true
vm-usb-device attach "$guest" $keyboard && echo "[$(date)] keyboard attached to $guest" || echo "[$(date)] failed to attach keyboard to $guest"
fi
# Logitech G9 has two entries in `xinput list` when attached at host; if there are 0 or 1, assume it's on guest
if [[ $(xinput list | fgrep -c "$mouse_name") -eq 2 ]]; then
if ensure_running "$guest"; then
continue
fi
# Wait for monitor input switch to calm down because the mouse is sensitive to failing initialization
# TODO: maybe use a better mechanism e.g. have guest request the mouse when it's sufficiently calm
sleep 2.5
vm-usb-device detach "$guest" $mouse 2> /dev/null && echo "[$(date)] detached mouse from $guest" || true
vm-usb-device attach "$guest" $mouse && echo "[$(date)] mouse attached to $guest" || echo "[$(date)] failed to attach mouse to $guest"
fi
fi
sleep 0.25
done
#!/bin/bash
set -eu
# Usage:
# vm-usb-device attach windows10 046d:c048
# vm-usb-device detach windows10 046d:c048
# (use lsusb to get vendor:product id)
action=$1
vmname=$2
device=(${3//:/ })
xml_name=/tmp/device-${device[0]}:${device[1]}.xml
echo "\
<hostdev mode='subsystem' type='usb'>
<source>
<vendor id='0x${device[0]}'/>
<product id='0x${device[1]}'/>
</source>
</hostdev>" > $xml_name
virsh --quiet --connect qemu:///system "$action"-device "$vmname" "$xml_name"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment