查询父设备时确保子设备上的完整 udev 信息

查询父设备时确保子设备上的完整 udev 信息

我正在尝试实现一个自定义功能,在连接 USB 驱动器时扫描它包含的所有文件系统,然后根据检测到的文件系统类型执行操作。我按照“推荐”的方式编写了一条udev规则,为设备节点触发实例化的systemd“oneshot”服务,该服务反过来执行“完成所有魔法(TM)”的 shell 脚本(出于平台独立性的原因,编译的此处不考虑该程序的选项)。

ACTION=="add", SUBSYSTEMS=="usb", SUBSYSTEM=="block", ENV{DEVTYPE}=="disk", RUN{program}="/bin/systemctl start usb-drive-manager@$devnode.service"

[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=/usr/local/bin/usb_drive_manager.sh attach %I
ExecStop=/usr/local/bin/usb_drive_manager.sh detach %I

在 shell 脚本中,我ls /sys/.../sdX/sdX*在驱动器的设备路径上执行操作来定位任何分区,然后通过调用查询这些分区上的信息

udevadm info /dev/sdXn

(其中n是分区号)每个已处理的分区。

问题现在,虽然这在 shell 脚本的“冷插拔”测试期间有效,但在从规则触发脚本时却不起作用,udev因为当时的udev事件驾驶被处理后,有关的信息分区驱动器上的信息尚未被内核收集,即调用udevadm info仅返回基本信息:

P: /devices/.../block/sdb/sdb1
N: sdb1
E: DEVNAME=/dev/sdb1
E: DEVPATH=/devices/.../block/sdb/sdb1
E: DEVTYPE=partition
E: MAJOR=8
E: MINOR=17
E: SUBSYSTEM=block

并且所有相关信息,特别是ID_FS_TYPEID_FS_LABEL环境变量(仍然)丢失。由于udevadm settle在处理udev事件时调用是一个坏主意(也没有帮助),甚至 0.5 秒的轮询循环在调用之间休眠也不起作用udevadm info(大约需要 1 分钟直到信息最终可用),我我在这里有点不知所措。

不幸的是,重写udev规则以使其适用于分区代替驱动器这也是不可取的,因为在某些情况下,人们在整个 USB 设备上创建文件系统,而不是创建跨整个设备的单个分区,然后包含该文件系统。

问题现在是否

  • 可以延迟udev给定设备的规则处理,直到所有孩子们该设备的部分已被处理,或者
  • 我可以在 shell 脚本中使用一个系统调用来“等待”所有孩子在继续查询udev数据之前要完成的事件(如果有!)

我认为这是一个相当长的问题;非常感谢所有帮助。

答案1

blkid经过更多研究后,我发现了in的使用乌德夫规则(见例如ArchLinux-Wiki 文章,不幸的是只有德语),我发现通过打电话

blkid -o udev -p /dev/sdXn

代替

udeavdm info /dev/sdXn

systemd-triggered 脚本内,甚至可以检索有关正在处理“添加”规则的 USB 记忆棒子设备的完整信息。

看起来-p这里的选项是关键,因为它切换到主动探测模式,在该模式下设备实际上被读出,而不是依赖于缓存的信息(例如手册页或者源代码blkid)。

-o udev选项只是以类似于调用的方式格式化输出udevadm,尽管它不是 100% 的直接替换,因为这里缺少udevadm输出的前导标识符标签(例如E:、等)。P:

相关内容