[SOLVED] LXC USB Passthrough Hot-Plug Permissions

Elliott Partridge

Well-Known Member
Oct 7, 2018
57
11
48
Pittsburgh, PA
I have two systems with a UPS connected via USB, which I pass-through to an LXC container with the corresponding management software (apcupsd, pwrstatd). However, on both systems, I have a problem if the USB connection is ever disconnected - the LXC container can no longer read the USB endpoint. I have to reboot the container, and the permissions are restored. Any idea how to retain/restore permissions without a reboot?

On a fresh start of the container, I can see the USB endpoint:
Bash:
# ls -al /dev/usb/hiddev0
crw-rw-rw- 1 nobody root 180, 0 Jan 10 10:35 /dev/usb/hiddev0

However, after removing and re-inserting the USB connector:
Bash:
# ls -al /dev/usb/hiddev0
c--------- 0 nobody nogroup 180, 0 Dec 30 08:08 /dev/usb/hiddev0

System Configuration​

On the host:

Bash:
# ls -al /dev/usb/hiddev0
crw-rw-rw- 1 root 100000 180, 0 Jan 10 10:35 /dev/usb/hiddev0

LXC .conf:
Code:
arch: amd64
cores: 1
hostname: ups1
memory: 512
net0: name=eth0,bridge=vmbr0,firewall=1,hwaddr=<MAC>,ip=dhcp,type=veth
onboot: 1
ostype: debian
rootfs: vm-prod:subvol-###-disk-0,mountoptions=noatime,size=8G
swap: 512
unprivileged: 1
lxc.cgroup2.devices.allow: c 180:* rwm
lxc.mount.entry: /dev/usb/hiddev0 dev/usb/hiddev0 none bind,optional,create=file

udev rule for permissions:
/etc/udev/rules.d/50-apcups.rules
Code:
SUBSYSTEMS=="usb", KERNEL=="hiddev*", ATTRS{idVendor}=="051d", ATTRS{idProduct}=="0002", SYMLINK+="ups0", GROUP="100000", MODE="0666"
 
I think I figured this out, thanks to some more searching and finding these posts:
https://www.reddit.com/r/Proxmox/comments/i9xfoj/hotplugging_passthrough_usb_devices_to_lxc/
https://monach.us/automation/connecting-zwave-stick-under-lxc/
https://discuss.linuxcontainers.org...rite-on-re-connected-dev-ttyusb0-modem/1227/2

The trouble, as far as I can tell, is that the bind mount gets broken when the source (/dev/usb/hiddev0) goes away on the host. The solution is to make a persistent character device using mknod that then gets bind-mounted into the LXC container. This will weather any disconnection events, resulting in preserved permissions/bind-mount when the device is restored.

What I ended up doing on the host (nothing changed in the container):
Bash:
mkdir /var/lib/lxc/<id>/devices
cd /var/lib/lxc/<id>/devices
mknod -m 660 hiddev0 c 180 0
chown root:100000 hiddev0

Then, I modified the LXC .conf, replacing the /dev/usb/hiddev0 source path with /var/lib/lxc/112/devices/hiddev0.

Reboot the container and voilá! I can unplug/replug my device to my heart's content.
 
One year later, is this still the way to handle hotplugging? It seems simply like a bug that the permissions in LXC are not set up perfectly after re-connecting a device. Did anyone look into it?
 
Last edited:
  • Like
Reactions: GleraK