使用udev根据设备响应创建设备符号链接,而不是udev设备信息



我有三个不同的串行设备连接到三个usb-串行转换器(FTDI USB-RS232)。如果我将它们连接起来,就会得到一般的设备名称/dev/ttyUSBx。当我尝试编写一些udev规则时,udevadm为我显示了三个设备的相同输出,除了一些设备串行id属性。

这些串行id将在每个设备上改变,所以如果我使用不同的usb串行转换器,我的规则将不再工作。所以,我需要一种方法与连接到串行转换器的特定设备进行通信,并通过其响应识别它。

"编写udev规则"HOWTO,关于使用PROGRAM功能调用外部程序来命名设备:

PROGRAM用于运行产生设备名称的程序(它们不应该做其他任何事情)。当这些程序正在执行时,设备节点尚未创建,因此以任何方式对设备进行操作都是不可能的,

规则的例子:SUBSYSTEM=="usb", PROGRAM="/bin/device_namer %k", SYMLINK+="%c"

所以我不能从那里写/dev/ttyUSBx来识别设备。然后,我有RUN功能,但它似乎不能创建一个新的SYMLINK,因为udev不会得到RUN的输出。

规则的例子:SUBSYSTEM=="usb", RUN="/bin/program"

我可以指示udev从那个RUN脚本创建符号链接吗?或者我可以从这里手工创建符号链接吗?

谢谢

一连接到计算机就盲目地在串行端口上自动聊天是一件非常可怕的事情。你确定要这么做吗?首先,这将花费一些时间,如果udev在创建设备节点之前必须等待结果,这将延迟设备节点的出现。如果设备碰巧断电或其串行端口断开连接,那么您将无法正确命名它(并且您需要有一个超时来检测这一点)。最后,如果您期望的设备之外的另一个设备已连接,您可能会向它发送垃圾,从而产生意想不到的后果。

您可以考虑依靠适配器的序列号来区分它们,并以一致的方式将每个适配器与外部设备关联起来。如果您的适配器甚至具有实际序列号,而不是像00000000这样的占位符字符串,那么您已经很幸运了!

无论如何,这就是你要做的。

正如您所怀疑的,您不能使用RUN,因为为时已晚,设备节点已经创建。你必须用PROGRAM。在您的程序中,您将不得不使用mknod自己创建设备节点,因为udev还没有这样做。您应该在临时位置创建一个临时节点,并在程序退出之前销毁它。

### Create the temporary device node in /tmp
device="/tmp/udev_device_guesser.$$"
# Note: mknod does not appear to be vulnerable to a symlink attack
mknod "$device" c "$MAJOR" "$MINOR"
### Use this device node to query what's attached to the serial port
insert your code here
### Get rid of the temporary node
rm -f "$device"
exit 0

实际上可以使用PROGRAM创建基于设备响应的设备符号链接,尽管文档中说。它只用于符号链接,不用于设备名称。

请注意,每个匹配AFTER并指定SYMLINK的规则都应该像这样,

SYMLINK+=

,因此您的SIMLINK规范将与新规范相连接。在其他情况下,您的符号链接将被擦除。

了解udev中发生的事情的最好方法是将日志级别设置为debug:

sudo udevadm control --log-priority=debug

您可以在/var/log/messages/var/log/syslog中找到这些日志,具体取决于您的发行版。

最新更新