我有一个USB GPIO设备,其中有一些我想在容器中进行交互的3rd party drivers。编译,在主机上工作正常。如果我通过--device=/dev/bus/usb/001/$NUM
,其中$ NUM是插入设备时自动生成的路径,则也可以在容器中编译,并且工作正常;我想udev会分配这个。但是,我需要确定性的绑定点,因此我修改了udev rules来分配符号链接:
SUBSYSTEM=="usb", ATTR{idVendor}=="09db",
ATTR{idProduct}=="0075", MODE="0666",
TAG+="uaccess", TAG+="udev-acl",
SYMLINK+="mcc_daq"
这给了我/dev/mcc_daq
到/dev/bus/usb/whatever
的符号链接。在主机上仍然可以正常运行。
但是,如果我使用:
docker run --rm -it \
--device=/dev/mcc_daq \
mcc_daq1
我知道
usb_device_find_USB_MCC: libusb_open failed.: No such file or directory
Failure, did not find a USB 2408 or 2408_2AO!
test program spits out找不到设备时(使用libusb_get_device_descriptor)。
在容器udevadm info -q all /dev/mcc_daq
中运行时,以udevadm info -q all /dev/bus/usb/001/004
启动容器时,得到的输出与--device=/.../004
相同。但是,如果我将符号链接路径传递给docker,则无法查询绝对路径。
在主机系统上,udev输出更加详细,我不确定这是否是问题或预期行为的一部分。我的直觉是,缺少这些额外的条目意味着libusb可以找到设备,但找不到产品的供应商ID。但是,udev输出在容器中是相同的(无论是符号链接还是硬路径),这使我提出了疑问。
更新:一个有趣的新事实:当我在测试程序上运行strace时,我发现:
open("/dev/bus/usb/001/004", O_RDWR) = -1 ENOENT (No such file or directory)
因此,即使我安装了../004
,这也意味着驱动程序正在寻找---device=/dev/mcc_daq
。我不确定从哪里获得此信息。
简而言之,我认为使用docker run --device=/dev/symlink
不会引入与使用硬路径相同的udev上下文,即使udevadm info
的输出是相同的。
主持人:udevadm info -q all /dev/mcc_daq
P: /devices/pci0000:00/0000:00:14.0/usb1/1-8/1-8.2
N: bus/usb/001/004
S: mcc_daq
E: BUSNUM=001
E: DEVLINKS=/dev/mcc_daq
E: DEVNAME=/dev/bus/usb/001/004
E: DEVNUM=004
E: DEVPATH=/devices/pci0000:00/0000:00:14.0/usb1/1-8/1-8.2
E: DEVTYPE=usb_device
E: DRIVER=usb
E: ID_BUS=usb
E: ID_FOR_SEAT=usb-pci-0000_00_14_0-usb-0_8_2
E: ID_MODEL=USB-2408-2AO
E: ID_MODEL_ENC=USB-2408-2AO
E: ID_MODEL_ID=00fe
E: ID_PATH=pci-0000:00:14.0-usb-0:8.2
E: ID_PATH_TAG=pci-0000_00_14_0-usb-0_8_2
E: ID_REVISION=0101
E: ID_SERIAL=MCC_USB-2408-2AO_01DA523C
E: ID_SERIAL_SHORT=01DA523C
E: ID_USB_INTERFACES=:ffff00:
E: ID_VENDOR=MCC
E: ID_VENDOR_ENC=MCC
E: ID_VENDOR_FROM_DATABASE=Measurement Computing Corp.
E: ID_VENDOR_ID=09db
E: MAJOR=189
E: MINOR=3
E: PRODUCT=9db/fe/101
E: SUBSYSTEM=usb
E: TAGS=:uaccess:seat:udev-acl:
E: TYPE=255/255/0
E: USEC_INITIALIZED=19197013
Docker:udevadm info -q all /dev/mcc_daq
P: /devices/pci0000:00/0000:00:14.0/usb1/1-8/1-8.2
N: bus/usb/001/004
E: BUSNUM=001
E: DEVNAME=/dev/bus/usb/001/004
E: DEVNUM=004
E: DEVPATH=/devices/pci0000:00/0000:00:14.0/usb1/1-8/1-8.2
E: DEVTYPE=usb_device
E: DRIVER=usb
E: MAJOR=189
E: MINOR=3
E: PRODUCT=9db/fe/101
E: SUBSYSTEM=usb
E: TYPE=255/255/0
Docker:udevadm info -q all /dev/bus/usb/001/004
P: /devices/pci0000:00/0000:00:14.0/usb1/1-8/1-8.2
N: bus/usb/001/004
E: BUSNUM=001
E: DEVNAME=/dev/bus/usb/001/004
E: DEVNUM=004
E: DEVPATH=/devices/pci0000:00/0000:00:14.0/usb1/1-8/1-8.2
E: DEVTYPE=usb_device
E: DRIVER=usb
E: MAJOR=189
E: MINOR=3
E: PRODUCT=9db/fe/101
E: SUBSYSTEM=usb
E: TYPE=255/255/0
答案 0 :(得分:1)
从this discussion得出的结论是,如果您的docker run
命令是您的实际使用方式,则可以在工具“ readlink”的帮助下,使用下面的bash替换项来解决此问题:
docker run --rm -it \
--device=$(readlink -f /dev/mcc_daq) \
mcc_daq1
但是,如果您像我一样使用docker-compose,则此解决方法会变得更加尴尬,因为您可能需要对environment variables做一些准备工作。
此解决方法的问题之一当然是,如果您重新插入设备,路径将无效。因此,您必须重新启动容器。