具有少量父设备属性的 udev 规则

Posted

技术标签:

【中文标题】具有少量父设备属性的 udev 规则【英文标题】:udev rule with few parent device attributes 【发布时间】:2015-01-16 23:49:03 【问题描述】:

我需要复杂且通用的udev 规则来确定插入任何 USB 集线器的某个端口的 USB 设备。所以,我必须结合设备树不同层的父属性...

我有这个:

$udevadm info --query=all --name=/dev/ttyUSB0 --attribute-walk

  looking at device '/devices/platform/bcm2708_usb/usb1/1-1/1-1.2/1-1.2.4/1-1.2.4:1.0/ttyUSB0/tty/ttyUSB0':
    KERNEL=="ttyUSB0"
    SUBSYSTEM=="tty"
    DRIVER==""

            . . .

  looking at parent device '/devices/platform/bcm2708_usb/usb1/1-1/1-1.2/1-1.2.4':
    KERNELS=="1-1.2.4"
    SUBSYSTEMS=="usb"
    DRIVERS=="usb"
            ...

  looking at parent device '/devices/platform/bcm2708_usb/usb1/1-1/1-1.2':
    KERNELS=="1-1.2"
    SUBSYSTEMS=="usb"
    DRIVERS=="usb"
    ATTRSdevpath=="1.2"
    ATTRSidVendor=="0835"
            ...
    ATTRSidProduct=="8500"
    ATTRSbDeviceClass=="09"
    ATTRSproduct=="USB2.0 Hub"

            . . .

然后我构造了类似这样的 udev 规则来识别某个 USB 集线器的某个端口:

KERNEL=="ttyUSB[0-9]*", KERNELS=="1-1.2.4", ATTRSidVendor=="0835", ATTRSidProduct=="8500", SYMLINK+="port1"

但是当我尝试使用来自不同父层的属性时它不起作用。

我知道 udev 仅支持来自一个特定父设备的附加属性。但我真的需要从我的设备的 2 个父节点获取组合属性的规则

有人可以提出解决方案吗?有什么技巧可以得到吗?

【问题讨论】:

【参考方案1】:

经过多次不成功的经验,我找到了解决办法!

它的主要特点是设置环境变量:

    在插入事件时,我们查看 vendor:id 对并将其记住在环境变量中。 在同一事件中,我们比较保存的变量和 USB 设备树节点 ID,以指定特定 USB 集线器端口的确切名称。

这份文件帮助了我http://www.reactivated.net/writing_udev_rules.html

KERNEL=="ttyUSB[0-9]*", SUBSYSTEM=="tty", SUBSYSTEMS=="usb", ATTRSidVendor=="05e3", ATTRSidProduct=="0610", ENVUSB_HUB_TYPE="05e3:0610"
KERNEL=="ttyUSB[0-9]*", SUBSYSTEM=="tty", SUBSYSTEMS=="usb", ATTRSidVendor=="0835", ATTRSidProduct=="8500", ENVUSB_HUB_TYPE="0835:8500"
#
ENVUSB_HUB_TYPE=="0835:8500", KERNEL=="ttyUSB[0-9]*", SUBSYSTEM=="tty", KERNELS=="1-1.[2-3].4:1.0", SYMLINK+="port1"
ENVUSB_HUB_TYPE=="0835:8500", KERNEL=="ttyUSB[0-9]*", SUBSYSTEM=="tty", KERNELS=="1-1.[2-3].3:1.0", SYMLINK+="port2"
ENVUSB_HUB_TYPE=="0835:8500", KERNEL=="ttyUSB[0-9]*", SUBSYSTEM=="tty", KERNELS=="1-1.[2-3].2:1.0", SYMLINK+="port3"
ENVUSB_HUB_TYPE=="0835:8500", KERNEL=="ttyUSB[0-9]*", SUBSYSTEM=="tty", KERNELS=="1-1.[2-3].5.5:1.0", SYMLINK+="port4"
ENVUSB_HUB_TYPE=="0835:8500", KERNEL=="ttyUSB[0-9]*", SUBSYSTEM=="tty", KERNELS=="1-1.[2-3].5.2:1.0", SYMLINK+="port5"
ENVUSB_HUB_TYPE=="0835:8500", KERNEL=="ttyUSB[0-9]*", SUBSYSTEM=="tty", KERNELS=="1-1.[2-3].5.3:1.0", SYMLINK+="port6"
ENVUSB_HUB_TYPE=="0835:8500", KERNEL=="ttyUSB[0-9]*", SUBSYSTEM=="tty", KERNELS=="1-1.[2-3].5.4:1.0", SYMLINK+="port7"
#
ENVUSB_HUB_TYPE=="05e3:0610", KERNEL=="ttyUSB[0-9]*", SUBSYSTEM=="tty", KERNELS=="1-1.[2-3].1.1:1.0" SYMLINK+="port1"
ENVUSB_HUB_TYPE=="05e3:0610", KERNEL=="ttyUSB[0-9]*", SUBSYSTEM=="tty", KERNELS=="1-1.[2-3].2:1.0", SYMLINK+="port2"
ENVUSB_HUB_TYPE=="05e3:0610", KERNEL=="ttyUSB[0-9]*", SUBSYSTEM=="tty", KERNELS=="1-1.[2-3].1.2:1.0", SYMLINK+="port3"
ENVUSB_HUB_TYPE=="05e3:0610", KERNEL=="ttyUSB[0-9]*", SUBSYSTEM=="tty", KERNELS=="1-1.[2-3].3:1.0", SYMLINK+="port4"
ENVUSB_HUB_TYPE=="05e3:0610", KERNEL=="ttyUSB[0-9]*", SUBSYSTEM=="tty", KERNELS=="1-1.[2-3].1.3:1.0", SYMLINK+="port5"
ENVUSB_HUB_TYPE=="05e3:0610", KERNEL=="ttyUSB[0-9]*", SUBSYSTEM=="tty", KERNELS=="1-1.[2-3].4:1.0", SYMLINK+="port6"
ENVUSB_HUB_TYPE=="05e3:0610", KERNEL=="ttyUSB[0-9]*", SUBSYSTEM=="tty", KERNELS=="1-1.[2-3].1.4:1.0", SYMLINK+="port7"

也许,它对某人有用。

【讨论】:

太棒了。优秀作品。我们必须跳过的箍是吗?【参考方案2】:

在我的 openh*** 系统上为我工作得很好。我有两个相同的 usb/modbus 适配器,现在我可以给它们不同的符号链接: 在我的 /etc/udev/rules.d/99-com.rules 中添加了这些行:

KERNEL=="ttyUSB[0-9]*", SUBSYSTEM=="tty", ATTRSidVendor=="1a86", ATTRSidProduct=="7523", ENVUSB_HUB_TYPE="1a86:7523"
#
ENVUSB_HUB_TYPE=="1a86:7523", KERNEL=="ttyUSB[0-9]*",SUBSYSTEM=="tty", KERNELS=="1-1.3:1.0", SYMLINK+="tty4800"
ENVUSB_HUB_TYPE=="1a86:7523", KERNEL=="ttyUSB[0-9]*",SUBSYSTEM=="tty", KERNELS=="1-1.2:1.0", SYMLINK+="tty9600"

【讨论】:

以上是关于具有少量父设备属性的 udev 规则的主要内容,如果未能解决你的问题,请参考以下文章

udev规则以及编写

如何使用 udev 规则识别断开连接的 USB 设备?

为啥我的 udev 规则在运行的 docker 容器中不起作用?

Linux┊详解udev

使用UDEV SCSI规则在Oracle Linux上配置ASM

udev规则以及编写