让 udev 识别一组具有相同 uuid 和标签的唯一 USB 驱动器?RHEL7

让 udev 识别一组具有相同 uuid 和标签的唯一 USB 驱动器?RHEL7

我正在尝试在 RHEL7 上配置 udev,以便为 USB 闪存驱动器分配特定的 /dev 名称(即 /dev/backup1、/dev/backup2....)用于特定的闪存驱动器 - 我意识到我无法控制 /dev/sdx 分配,但正在尝试使用 udev 规则设置自动符号链接。

blkid 给我:

/dev/sdi1: LABEL="Samsung USB" UUID="64A5-F009" TYPE="exfat"
/dev/sdj1: LABEL="Samsung USB" UUID="64A5-F009" TYPE="exfat"
/dev/sdk1: LABEL="Samsung USB" UUID="64A5-F009" TYPE="exfat"

我想做类似的事情:在我的规则文件中

KERNEL=="sd*", SUBSYSTEM=="block", PROGRAM=="/lib/udev/scsi_id --whitelisted --replace-whitespace --device=%N", RESULT=="64A5-F009", SYMLINK+="backupkeya%n"

但由于这三个 USB 闪存驱动器具有相同的 uuid - 我希望特定的闪存驱动器链接到特定的虚拟设备名称。因此,如果我插入标有“drive2”的闪存驱动器,它将链接到 /dev/backupkeyb。现在我们有 3 个闪存驱动器 - 但想扩展到大约 8 个。

udevadm 给了我一些独特性......

[root@alpha2 mnt]# udevadm info /dev/sdg | grep "ID_SERIAL_SHORT"
E: ID_SERIAL_SHORT=0305119070014252
[root@alpha2 mnt]# udevadm info /dev/sdi | grep "ID_SERIAL_SHORT"
E: ID_SERIAL_SHORT=0330219070015017
[root@alpha2 mnt]# udevadm info /dev/sdj | grep "ID_SERIAL_SHORT"
E: ID_SERIAL_SHORT=0305119070014208  

我将 udev 规则更改为 (/etc/udev/rules.d/99-symlink.rules)

KERNEL=="sd*", SUBSYSTEM=="block", PROGRAM=="/bin/udevadm info --name=%N", RESULT=="0305119070014208", SYMLINK+="backupkeyc%n"

但是,当我插入序列号为 ...4208 的密钥时,没有创建 /dev/backupkeyc 符号链接。我怀疑这是因为 udevadm 语句的输出与我的 RESULT== 不完全匹配

我创建了一个脚本 /usr/local/udevinfo 并将 PROGRAM=="/usr/local/udevinfo %N" 更改为如下所示,以免使 udev 规则混乱……在我放入闪存驱动器后 - 没有符号链接 - 但更重要的是 /tmp/passeddata 中没有任何内容应该包含设备名称 - 所以看起来 udev 规则从未运行过?

echo "$1" >> /tmp/passeddata
udevadm info --name=$1 | grep "ID_SERIAL_SHORT" | awk -F= '{print $2}'

我遗漏了什么吗?有没有更简单的方法可以完成我想做的事情?

答案1

是的,它并不完全匹配,因为“udevadm info”输出了大量信息 - 而不仅仅是序列号。

但是,你在 udevadm info 中看到的任何内容都是通过设置udev 规则本身(通常通过调用 udev 内置程序)。因此序列号已经可用,无需ENV{ID_SERIAL_SHORT}=="..."调用外部程序。(这就是“E:”前缀实际上所表示的。)

KERNEL=="sd*", SUBSYSTEM=="block", ENV{ID_SERIAL_SHORT}=="0305119070014208", SYMLINK+="backupkeyc"

(事实上​​,‘udevadm info’ 可能不起作用根本在规则处理期间。udev 规则中的一个常见错误是尝试使用本身仅从“规则完成”信号获取信息的工具。)

答案2

我完全同意 @grawity 的回答,不要使用脚本来解决此问题,而是直接使用环境。但对于其他方面:

按照您编写并运行的方式,程序的语法是正确的。也许您的意思是文件中没有创建文件的内容?所以它缺少 shebang 行(如您的代码片段中所示)或执行权限?否则它应该以这种方式工作 - 而且您甚至不需要传递任何参数,因为 udev 所知道的所有信息都可以作为变量在环境中使用。因此脚本可以在通过 udev 规则 PROGRAM 语句调用时访问它们。

但是采用不同的方法应该更加方便和通用:
不要使用设备的序列号,而是为它们分配 UUID 或分区标签(或两者兼而有之,以降低插入具有相同 UUID 或分区标签的其他任何东西的可能性)。因此,只需重新标记分区或重新格式化它们即可设置新的“UUID”。如果您不想重新格式化,也可以在现有分区中修补 UUID 信息(我不知道有哪个工具可以为您执行此操作,但编写自己的工具非常简单)。
这样,您就可以替换目标而无需修改系统。或者例如向池中添加更多棒。
在这种情况下,您甚至可以选择使用一个小的 PROGRAM 脚本,将特定格式的分区标签转换为特定格式的符号链接名称。
另一种(如果可行的话,最符合标准的方法)可能是在设备上使用 GPT,并为您的用例分配一些特定的分区类型和 -UUID 组合 - 可能是附加分区名称。

相关内容