Bump… anyone else trying to do USB passthrough in jailmaker (nspawn jails) and/or Electric Eel Docker apps?
To give a concrete example, I’m trying to use apcupsd
within a jlmkr container. lsusb
isn’t available in TrueNAS, but it is in my container:
root@usbreader:~# lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 002: ID 0764:0501 Cyber Power System, Inc. CP1500 AVR UPS
Bus 001 Device 003: ID 0557:7000 ATEN International Co., Ltd Hub
Bus 001 Device 004: ID 0557:2419 ATEN International Co., Ltd Virtual mouse/keyboard device
Bus 001 Device 005: ID 0c45:7401 Microdia TEMPer Temperature Sensor
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
That second device, “Cyber Power System…” is the UPS.
There is a simple program to check UPS connectivity included with the apcupsd package, apctest
. However, it hangs for a while then emits an error:
root@usbreader:~# apctest
2024-09-28 18:09:26 apctest 3.14.14 (31 May 2016) debian
Checking configuration ...
sharenet.type = Network & ShareUPS Disabled
cable.type = USB Cable
mode.type = USB UPS Driver
Setting up the port ...
apctest FATAL ERROR in apctest.c at line 319
Unable to open UPS device.
If apcupsd or apctest is already running,
please stop it and run this program again.
apctest error termination completed
If I run apctest through strace, it’s trying to access device files that don’t even exist on the host:
root@usbreader:~# strace apctest
execve("/usr/sbin/apctest", ["apctest"], 0x7ffd04204720 /* 23 vars */) = 0
brk(NULL) = 0x55ccaacd0000
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fd878691000
...
openat(AT_FDCWD, "/dev/bus/usb/001/002", O_RDWR|O_CLOEXEC) = 4
read(4, "\22\1\20\1\0\0\0\10d\7\1\5\1\0\3\1\0\1", 18) = 18
close(4) = 0
...
openat(AT_FDCWD, "/dev/usb/hiddev1", O_RDWR|O_NOCTTY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/dev/usb/hiddev2", O_RDWR|O_NOCTTY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
...
openat(AT_FDCWD, "/dev/usb/hiddev14", O_RDWR|O_NOCTTY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/dev/usb/hiddev15", O_RDWR|O_NOCTTY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/dev/usb/hid/hiddev0", O_RDWR|O_NOCTTY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/dev/usb/hid/hiddev1", O_RDWR|O_NOCTTY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
...
openat(AT_FDCWD, "/dev/usb/hid/hiddev14", O_RDWR|O_NOCTTY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/dev/usb/hid/hiddev15", O_RDWR|O_NOCTTY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/dev/hiddev0", O_RDWR|O_NOCTTY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/dev/hiddev1", O_RDWR|O_NOCTTY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
...
openat(AT_FDCWD, "/dev/hiddev14", O_RDWR|O_NOCTTY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/dev/hiddev15", O_RDWR|O_NOCTTY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
...
In the config for this jail, I have
systemd_nspawn_user_args=--resolv-conf=bind-host
--bind='/dev/bus/usb/001/002:/dev/bus/usb/001/002'
As the strace shows, apctest
is able to open /dev/bu/usb/001/002
. But none of the hid* devices exist on the host, so there is nothing to bind.
However, I have a Raspberry Pi connected to a different UPS, and on that system, in addition to the /dev/bus/usb/… file, there is also a /dev/usb/hiddev0
device file, and that is successfully opened and apctest
(as well as overall apcupsd
monitoring) work as expected.