docker --device使用绝对设备路径,使用符号链接失败

时间:2018-12-19 14:58:26

标签: docker usb symlink udev libusb-1.0

我有一个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

1 个答案:

答案 0 :(得分:1)

this discussion得出的结论是,如果您的docker run命令是您的实际使用方式,则可以在工具“ readlink”的帮助下,使用下面的bash替换项来解决此问题:

docker run --rm -it \
        --device=$(readlink -f /dev/mcc_daq) \
        mcc_daq1

但是,如果您像我一样使用docker-compose,则此解决方法会变得更加尴尬,因为您可能需要对environment variables做一些准备工作。

此解决方法的问题之一当然是,如果您重新插入设备,路径将无效。因此,您必须重新启动容器。