Debian udev规则中的无条件转到(和Medion RC-0617)

Debian udev规则中的无条件转到(和Medion RC-0617),debian,hid,udev,Debian,Hid,Udev,我一直在逆向工程Medion RC-0617遥控器(带USB加密狗)在一些Debian 8.8衍生产品(antix16)下 它注册了3个不同的HID设备(/dev/hidraw*),我希望这些设备与/dev/mdremote0、1和2进行符号链接,与关联的hidraw设备的数量无关(大多数情况下是hidraw1、2和3,但这取决于插入的输入设备)以便使用脚本查询它们以执行遥控按钮的自定义操作。 (同时将其文件模式设置为666,以便作为普通用户访问) udevadm info-a/dev/hidr

我一直在逆向工程Medion RC-0617遥控器(带USB加密狗)在一些Debian 8.8衍生产品(antix16)下

它注册了3个不同的HID设备(/dev/hidraw*),我希望这些设备与/dev/mdremote0、1和2进行符号链接,与关联的hidraw设备的数量无关(大多数情况下是hidraw1、2和3,但这取决于插入的输入设备)以便使用脚本查询它们以执行遥控按钮的自定义操作。 (同时将其文件模式设置为666,以便作为普通用户访问)

udevadm info-a/dev/hidraw1的输出如下(缩短):

因此,我需要编写的udev规则需要:

  • 按idVendor和idProduct标识一个父设备
  • 检查另一个父设备中的bInterfaceProtocol属性
  • 为设备分配正确的符号链接/dev/mdremote*,并设置正确的权限
我的第一次尝试是这样的:

SUBSYSTEM=="hidraw", SUBSYSTEMS=="usb", ATTRS{idVendor}=="04f2", ATTRS{idProduct}=="0618", ATTRS{bInterfaceProtocol}=="01", SYMLINK="mdremote0", MODE="0666"
SUBSYSTEM=="hidraw", SUBSYSTEMS=="usb", ATTRS{idVendor}=="04f2", ATTRS{idProduct}=="0618", ATTRS{bInterfaceProtocol}=="00", SYMLINK="mdremote1", MODE="0666"
SUBSYSTEM=="hidraw", SUBSYSTEMS=="usb", ATTRS{idVendor}=="04f2", ATTRS{idProduct}=="0618", ATTRS{bInterfaceProtocol}=="02", SYMLINK="mdremote2", MODE="0666"
SUBSYSTEM=="hidraw", SUBSYSTEMS=="usb", ATTRS{idVendor}=="04f2", ATTRS{idProduct}=="0618", GOTO="match"
GOTO="end"
LABEL="match"
SUBSYSTEM=="hidraw", SUBSYSTEMS=="usb", ATTRS{bInterfaceProtocol}=="01", SYMLINK="mdremote0", MODE="0666"
SUBSYSTEM=="hidraw", SUBSYSTEMS=="usb", ATTRS{bInterfaceProtocol}=="00", SYMLINK="mdremote1", MODE="0666"
SUBSYSTEM=="hidraw", SUBSYSTEMS=="usb", ATTRS{bInterfaceProtocol}=="02", SYMLINK="mdremote2", MODE="0666"
LABEL="end"
# Test if the wanted dongle is a parent device
SUBSYSTEM=="hidraw", SUBSYSTEMS=="usb", ATTRS{idVendor}=="04f2", ATTRS{idProduct}=="0618", GOTO="match"
# If not, skip the next 3 rules. The test against SUBSYSTEM=="hidraw" is there to produce a rule match
SUBSYSTEM=="hidraw", GOTO="end"
LABEL="match"
# Those 3 rules actually assign the right symlink depending on the bInterfaceProtocol property.
# Note that ALL of those rules contain the SUBSYSTEM=="hidraw" check, because the GOTO in the second line
# does not get executed for non-hidraw devices and the rules get evaluated for any non-hidraw device.
SUBSYSTEM=="hidraw", SUBSYSTEMS=="usb", ATTRS{bInterfaceProtocol}=="01", SYMLINK="mdremote0", MODE="0666"
SUBSYSTEM=="hidraw", SUBSYSTEMS=="usb", ATTRS{bInterfaceProtocol}=="00", SYMLINK="mdremote1", MODE="0666"
SUBSYSTEM=="hidraw", SUBSYSTEMS=="usb", ATTRS{bInterfaceProtocol}=="02", SYMLINK="mdremote2", MODE="0666"
LABEL="end"
(预期bInterfaceProtocol属性的顺序)

简而言之,这是行不通的,udev manpage说:

某些键还与父设备的属性相匹配 在sysfs中,不仅仅是生成事件的设备。如果 在单个设备中指定与父设备匹配的多个密钥 规则,所有这些密钥必须在同一个父设备上匹配

因此,我开始了另一种方法:首先对加密狗进行匹配,如果此检查不匹配,则跳过单个规则,如下所示:

SUBSYSTEM=="hidraw", SUBSYSTEMS=="usb", ATTRS{idVendor}=="04f2", ATTRS{idProduct}=="0618", ATTRS{bInterfaceProtocol}=="01", SYMLINK="mdremote0", MODE="0666"
SUBSYSTEM=="hidraw", SUBSYSTEMS=="usb", ATTRS{idVendor}=="04f2", ATTRS{idProduct}=="0618", ATTRS{bInterfaceProtocol}=="00", SYMLINK="mdremote1", MODE="0666"
SUBSYSTEM=="hidraw", SUBSYSTEMS=="usb", ATTRS{idVendor}=="04f2", ATTRS{idProduct}=="0618", ATTRS{bInterfaceProtocol}=="02", SYMLINK="mdremote2", MODE="0666"
SUBSYSTEM=="hidraw", SUBSYSTEMS=="usb", ATTRS{idVendor}=="04f2", ATTRS{idProduct}=="0618", GOTO="match"
GOTO="end"
LABEL="match"
SUBSYSTEM=="hidraw", SUBSYSTEMS=="usb", ATTRS{bInterfaceProtocol}=="01", SYMLINK="mdremote0", MODE="0666"
SUBSYSTEM=="hidraw", SUBSYSTEMS=="usb", ATTRS{bInterfaceProtocol}=="00", SYMLINK="mdremote1", MODE="0666"
SUBSYSTEM=="hidraw", SUBSYSTEMS=="usb", ATTRS{bInterfaceProtocol}=="02", SYMLINK="mdremote2", MODE="0666"
LABEL="end"
# Test if the wanted dongle is a parent device
SUBSYSTEM=="hidraw", SUBSYSTEMS=="usb", ATTRS{idVendor}=="04f2", ATTRS{idProduct}=="0618", GOTO="match"
# If not, skip the next 3 rules. The test against SUBSYSTEM=="hidraw" is there to produce a rule match
SUBSYSTEM=="hidraw", GOTO="end"
LABEL="match"
# Those 3 rules actually assign the right symlink depending on the bInterfaceProtocol property.
# Note that ALL of those rules contain the SUBSYSTEM=="hidraw" check, because the GOTO in the second line
# does not get executed for non-hidraw devices and the rules get evaluated for any non-hidraw device.
SUBSYSTEM=="hidraw", SUBSYSTEMS=="usb", ATTRS{bInterfaceProtocol}=="01", SYMLINK="mdremote0", MODE="0666"
SUBSYSTEM=="hidraw", SUBSYSTEMS=="usb", ATTRS{bInterfaceProtocol}=="00", SYMLINK="mdremote1", MODE="0666"
SUBSYSTEM=="hidraw", SUBSYSTEMS=="usb", ATTRS{bInterfaceProtocol}=="02", SYMLINK="mdremote2", MODE="0666"
LABEL="end"
这在第一学期看起来是正确的。但是,猜猜看,它也不起作用,mdremote*符号链接只是指向任何设置了bInterfaceProtocol密钥的设备。

事实上,第二行(GOTO=“end”)被忽略了。我花了一些时间才弄明白,但解决办法其实很简单:

如果没有要匹配的条件,udev将规则视为“始终不匹配”,因此根本不执行GOTO

我的工作udev规则文件如下所示:

SUBSYSTEM=="hidraw", SUBSYSTEMS=="usb", ATTRS{idVendor}=="04f2", ATTRS{idProduct}=="0618", ATTRS{bInterfaceProtocol}=="01", SYMLINK="mdremote0", MODE="0666"
SUBSYSTEM=="hidraw", SUBSYSTEMS=="usb", ATTRS{idVendor}=="04f2", ATTRS{idProduct}=="0618", ATTRS{bInterfaceProtocol}=="00", SYMLINK="mdremote1", MODE="0666"
SUBSYSTEM=="hidraw", SUBSYSTEMS=="usb", ATTRS{idVendor}=="04f2", ATTRS{idProduct}=="0618", ATTRS{bInterfaceProtocol}=="02", SYMLINK="mdremote2", MODE="0666"
SUBSYSTEM=="hidraw", SUBSYSTEMS=="usb", ATTRS{idVendor}=="04f2", ATTRS{idProduct}=="0618", GOTO="match"
GOTO="end"
LABEL="match"
SUBSYSTEM=="hidraw", SUBSYSTEMS=="usb", ATTRS{bInterfaceProtocol}=="01", SYMLINK="mdremote0", MODE="0666"
SUBSYSTEM=="hidraw", SUBSYSTEMS=="usb", ATTRS{bInterfaceProtocol}=="00", SYMLINK="mdremote1", MODE="0666"
SUBSYSTEM=="hidraw", SUBSYSTEMS=="usb", ATTRS{bInterfaceProtocol}=="02", SYMLINK="mdremote2", MODE="0666"
LABEL="end"
# Test if the wanted dongle is a parent device
SUBSYSTEM=="hidraw", SUBSYSTEMS=="usb", ATTRS{idVendor}=="04f2", ATTRS{idProduct}=="0618", GOTO="match"
# If not, skip the next 3 rules. The test against SUBSYSTEM=="hidraw" is there to produce a rule match
SUBSYSTEM=="hidraw", GOTO="end"
LABEL="match"
# Those 3 rules actually assign the right symlink depending on the bInterfaceProtocol property.
# Note that ALL of those rules contain the SUBSYSTEM=="hidraw" check, because the GOTO in the second line
# does not get executed for non-hidraw devices and the rules get evaluated for any non-hidraw device.
SUBSYSTEM=="hidraw", SUBSYSTEMS=="usb", ATTRS{bInterfaceProtocol}=="01", SYMLINK="mdremote0", MODE="0666"
SUBSYSTEM=="hidraw", SUBSYSTEMS=="usb", ATTRS{bInterfaceProtocol}=="00", SYMLINK="mdremote1", MODE="0666"
SUBSYSTEM=="hidraw", SUBSYSTEMS=="usb", ATTRS{bInterfaceProtocol}=="02", SYMLINK="mdremote2", MODE="0666"
LABEL="end"
结果证明这很有效。它仍然可以通过为GOTO=“end”语句提供更好的匹配规则来改进,但我没有这样做。

事实上,第二行(GOTO=“end”)被忽略了。我花了一些时间才弄明白,但解决办法其实很简单:

如果没有要匹配的条件,udev将规则视为“始终不匹配”,因此根本不执行GOTO

我的工作udev规则文件如下所示:

SUBSYSTEM=="hidraw", SUBSYSTEMS=="usb", ATTRS{idVendor}=="04f2", ATTRS{idProduct}=="0618", ATTRS{bInterfaceProtocol}=="01", SYMLINK="mdremote0", MODE="0666"
SUBSYSTEM=="hidraw", SUBSYSTEMS=="usb", ATTRS{idVendor}=="04f2", ATTRS{idProduct}=="0618", ATTRS{bInterfaceProtocol}=="00", SYMLINK="mdremote1", MODE="0666"
SUBSYSTEM=="hidraw", SUBSYSTEMS=="usb", ATTRS{idVendor}=="04f2", ATTRS{idProduct}=="0618", ATTRS{bInterfaceProtocol}=="02", SYMLINK="mdremote2", MODE="0666"
SUBSYSTEM=="hidraw", SUBSYSTEMS=="usb", ATTRS{idVendor}=="04f2", ATTRS{idProduct}=="0618", GOTO="match"
GOTO="end"
LABEL="match"
SUBSYSTEM=="hidraw", SUBSYSTEMS=="usb", ATTRS{bInterfaceProtocol}=="01", SYMLINK="mdremote0", MODE="0666"
SUBSYSTEM=="hidraw", SUBSYSTEMS=="usb", ATTRS{bInterfaceProtocol}=="00", SYMLINK="mdremote1", MODE="0666"
SUBSYSTEM=="hidraw", SUBSYSTEMS=="usb", ATTRS{bInterfaceProtocol}=="02", SYMLINK="mdremote2", MODE="0666"
LABEL="end"
# Test if the wanted dongle is a parent device
SUBSYSTEM=="hidraw", SUBSYSTEMS=="usb", ATTRS{idVendor}=="04f2", ATTRS{idProduct}=="0618", GOTO="match"
# If not, skip the next 3 rules. The test against SUBSYSTEM=="hidraw" is there to produce a rule match
SUBSYSTEM=="hidraw", GOTO="end"
LABEL="match"
# Those 3 rules actually assign the right symlink depending on the bInterfaceProtocol property.
# Note that ALL of those rules contain the SUBSYSTEM=="hidraw" check, because the GOTO in the second line
# does not get executed for non-hidraw devices and the rules get evaluated for any non-hidraw device.
SUBSYSTEM=="hidraw", SUBSYSTEMS=="usb", ATTRS{bInterfaceProtocol}=="01", SYMLINK="mdremote0", MODE="0666"
SUBSYSTEM=="hidraw", SUBSYSTEMS=="usb", ATTRS{bInterfaceProtocol}=="00", SYMLINK="mdremote1", MODE="0666"
SUBSYSTEM=="hidraw", SUBSYSTEMS=="usb", ATTRS{bInterfaceProtocol}=="02", SYMLINK="mdremote2", MODE="0666"
LABEL="end"

结果证明这很有效。它仍然可以通过为GOTO=“end”语句提供更好的匹配规则来改进,但我没有这样做。

@orwell我偶然发现了这一点,有点困惑为什么这对您不起作用。我尝试过做类似的事情,在无条件的GOTO和debian扩展以及Arch Linux上都没有问题。选中此项:

[c0d3@z3r0 tmp]$ cat /etc/udev/rules.d/45-test.rules
GOTO="end"
IMPORT{program}=="/bin/touch /tmp/noend"
LABEL="end"
IMPORT{program}=="/bin/touch /tmp/end"
[c0d3@z3r0 tmp]$ sudo udevadm control --reload 
[c0d3@z3r0 tmp]$ sudo udevadm trigger
[c0d3@z3r0 tmp]$ ls /tmp/*end
/tmp/end
[c0d3@z3r0 tmp]$ 

@奥威尔,我偶然发现了这一点,有点困惑为什么这对你不起作用。我尝试过做类似的事情,在无条件的GOTO和debian扩展以及Arch Linux上都没有问题。选中此项:

[c0d3@z3r0 tmp]$ cat /etc/udev/rules.d/45-test.rules
GOTO="end"
IMPORT{program}=="/bin/touch /tmp/noend"
LABEL="end"
IMPORT{program}=="/bin/touch /tmp/end"
[c0d3@z3r0 tmp]$ sudo udevadm control --reload 
[c0d3@z3r0 tmp]$ sudo udevadm trigger
[c0d3@z3r0 tmp]$ ls /tmp/*end
/tmp/end
[c0d3@z3r0 tmp]$ 

是的,听起来很有用。谢谢。是的,听起来很有用。谢谢。谢谢你发这个帖子!48小时过去了,所以你现在可以自己接受这个答案了。谢谢你发布这个!48小时过去了,所以你现在可以自己接受这个答案了。嗯,我已经写了一个不起作用的例子。。。但是我不想再摆弄这个了,谢谢,我已经写了一个不起作用的例子。。。但我不想再摆弄这个了,谢谢