[SOLVED] USB device forwarding to Debian LXC

Jul 9, 2024
3
0
1
Hello, I know there's a lot of these out there, and I swear I've read through the first page or two of google results. I've been trying to set up a kodi container for a day or two. Amusingly enough, the complicated parts all went without a hitch, but I can not get the container to recognize my USB devices.
- Version is pve-manager/8.2.4/faa83925c9641325 (running kernel: 6.8.8-2-pve).
- The container is a debian template, with apt get xfce4 kodi + dependencies.
Hardware notes:
- 5600G on a deskmini x300, so an AMD iGPU worth noting.
- The keyboard is technially a wireless bolt receiver. I've used that in bios / busybox fallback shell on fresh installs, so it shouldn't need special drivers or pairing procedures to work. It works fine in the proxmox terminal.
- Mouse is a cheapo wired.

The current config is:
Code:
arch: amd64
cores: 2
features: nesting=1
hostname: deb-kodi-test
memory: 2048
net0: name=eth0,bridge=vmbr0,firewall=1,gw=192.168.69.1,hwaddr=BC:24:11:0D:16:15,ip=192.168.69.69/24,type=veth
ostype: debian
rootfs: node-b-data:105/vm-105-disk-0.raw,size=8G
swap: 512
unprivileged: 1
lxc.cgroup.devices.allow: c 189:* rwm
lxc.cgroup2.devices.allow: c 226:0 rwm
lxc.cgroup2.devices.allow: c 226:128 rwm
lxc.cgroup2.devices.allow: c 235:* rwm
lxc.mount.entry: /dev/bus/usb/001 dev/bus/usb/001 none bind,optional,create=dir
lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir
lxc.mount.entry: /dev/dri/renderD128 dev/renderD128 none bind,optional,create=file
lxc.mount.entry: /dev/kfd dev/kfd none bind,optional,create=file
and I'm using a udev rule to grant the container (and well, everyone) device access to the usb hub1 and the iGPU
Code:
KERNEL=="renderD128", MODE="0666"
KERNEL=="kfd", MODE="0666"
KERNEL=="kfd", GROUP="render", MODE="0666"
KERNEL=="card1", MODE="0666"
KERNELS=="usb1",SUBSYSTEMS=="usb",MODE="0666"

Good:
- GPU forwarding works. On container boot, the proxmox terminal is replaced and the container takes me all the way to the Kodi home page. Both the proxmox dev: /dev/dri/card1 + renderD128,gid=0 and the cgroups + udev method above get the same result. I can see kodi complaining about missing default / lavrate / samplerate / etc devices in the log, but that's a future problem, if it even is one.

- stat /dev/bus/usb/001/* shows shows that the udev rule does assign 666 to everything in there.
- stat /dev/bus/usb/002-4/* shows shows that those are still 664, so the rule didn't misfire

lsusb inside the container is very promising. Entries also exist as expected under /dev/bus/usb/001/
Code:
Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 003 Device 003: ID 8087:0aa7 Intel Corp. Wireless-AC 3168 Bluetooth
Bus 003 Device 002: ID 05e3:0608 Genesys Logic, Inc. Hub
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 002: ID 05e3:0612 Genesys Logic, Inc. Hub
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 004: ID 17ef:608d Lenovo Optical Mouse
Bus 001 Device 003: ID 046d:c548 Logitech, Inc. Logi Bolt Receiver
Bus 001 Device 002: ID 05e3:0610 Genesys Logic, Inc. Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
I'm concerned that it's seeing stuff outside of Bus 001, but once again, future problem.

Bad:
- Keyboard and mouse have no response in kodi, or xfce desktop (so it's not just a kodi gui problem).
- Inside the container, there's no /dev/input, and using evtest on a specific device gives evtest: can't get version: Operation not permitted. I tried using js test with a gamepad at one point, and it basically logged half a line of reading before some kind of "permission denied", so I stilll strongly suspect a permissioning issue.

Alternatives:
- I've tried using dev0: /dev/bus/001/003,gid=0and dev0: /dev/bus/001/001,gid=0
- It's my understanding that gid=0 should let the container access them as root, bypassing the id mapping that's usually involved. The GPU passthrough worked fine with gid=0. Correct me if that's wrong.
- They both have the same symptoms. Device shows up in lsusb, but no actual inputs. The latter option is a root hub, since that's probably my ideal way to sidestep enumeration issues. It does actually show the devices under it when I lsusb from insidethe container, but still no dice on "actually working".
- I've seen some guides mention a /dev/ttyACM0. I don't see this, even when the container is off and I'm typing into the terminal. I assume it's a joystick specific thing.

I'm currently looking to just get any usb input working, one way or another. Forwarding the whole hub / clamping down on permissions can come later. Thanks for reading :)
 
If you expect a device at /dev/input within the container, you will have pass that through. For example:
Code:
pct set <container id> --dev0 path=/dev/input/mouse0

- It's my understanding that gid=0 should let the container access them as root, bypassing the id mapping that's usually involved. The GPU passthrough worked fine with gid=0. Correct me if that's wrong.
This only specifies which gid should be assigned to the device node within the container. No need to specify this explicitly. gid is already 0 by default.
 
I didn't see /dev/input explicitly mentioned on the guides I was following, so I was kind of hoping that the container would read off the usb device and make it's own /dev/input, which I suppose was wishful thinking. Anyways, neither adding /dev/input/mouse* as a set of devices nor mapping all of /dev/input worked. The container can see events in evtestunder both configurations, so definitely some forward progress. Unfortunately, still no response out of kodi / xfce. I also found this guide which does include /dev/input mapping, so I followed along and tried out the evdev driver, but still nothing. Current config: (Also added/dev/snd/ and /dev/fb0 as per the guide too)
Code:
lxc.cgroup2.devices.allow: c 189:* rwm
lxc.cgroup2.devices.allow: c 226:0 rwm
lxc.cgroup2.devices.allow: c 226:128 rwm
lxc.cgroup2.devices.allow: c 235:* rwm
lxc.cgroup2.devices.allow: c 13:* rwm
lxc.cgroup2.devices.allow: c 29:0 rwm
lxc.cgroup2.devices.allow: c 116:* rwm
lxc.mount.entry: /dev/bus/usb/001 dev/bus/usb/001 none bind,optional,create=dir
lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir
lxc.mount.entry: /dev/dri/renderD128 dev/renderD128 none bind,optional,create=file
lxc.mount.entry: /dev/kfd dev/kfd none bind,optional,create=file
lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file
lxc.mount.entry: /dev/snd dev/snd none bind,optional,create=dir
lxc.mount.entry: /dev/input dev/input none bind,optional,create=dir
and udev
Code:
KERNEL=="renderD128", MODE="0666"
KERNEL=="kfd", GROUP="render", MODE="0666"
KERNEL=="card1", MODE="0666"
SUBSYSTEMS=="graphics",KERNEL=="fb0",MODE="0666"
SUBSYSTEMS=="sound",MODE="0666"
KERNELS=="sound",SUBSYSTEMS="input",MODE="0666"
KERNELS=="usb1",MODE="0666"
Let me know if there are other logs I should be looking at. Xorg doesn't have anything too interesting, and nothing related to inputs.

Edit: Not sure what changed, but using the above, the container can see /dev/input, but none of the events under it are making it over, so no more evtest. The main change since that initial "almost working" phase was the evdev drivers and audio forwarding. whoops, dev/dev/input
 
Last edited:
Ah, I think this is it, specifically
Code:
# On the host, Xorg can often be run without an explicit xorg.conf, because udev provides Xorg with a list of devices.
# In a container udev does not enumerate devices which are bind-mounted into the container.
# Consequently:
#      -we need to set "AutoAddDevices" to "false" and list all devices.
#      -The libinput driver, which appears to depend upon udev, does not work in a container.
#      -InputClasses do not work.  (The lower-level InputDevices do work).
I'll try this later, but ideally, I'd rather find a way to forward udev events on Bus 001 to the container, rather than have to hardcode a set of recognized devices. Much prefer being able to just hotplug controllers / keyboards etc into a specific usb port, rather than keep track of "the one that works".

Solution, for google:
The alternative is to scan all of /dev/input on startup, and generate an xorg conf entry using those results. This is more work than I was willing to put in, but thankfully, someone already did this. Next step would just be to add a button in kodi to re-run the script on demand. Or stick a listener on /dev/input, but that might be overkill.
 
Last edited:

About

The Proxmox community has been around for many years and offers help and support for Proxmox VE, Proxmox Backup Server, and Proxmox Mail Gateway.
We think our community is one of the best thanks to people like you!

Get your subscription!

The Proxmox team works very hard to make sure you are running the best software and getting stable updates and security enhancements, as well as quick enterprise support. Tens of thousands of happy customers have a Proxmox subscription. Get yours easily in our online shop.

Buy now!