查詢父設備時確保子設備上的完整 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
是分區號)每個已處理的分區。現在的問題
udev
是,雖然這在 shell 腳本的“冷插拔”測試期間有效,但當從規則觸發腳本時它不起作用,因為在處理驅動器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_TYPE
和ID_FS_LABEL
環境變數(仍然)缺失。udevadm settle
由於在處理事件時呼叫udev
是一個壞主意(也沒有幫助),甚至 0.5 秒的輪詢循環在呼叫之間休眠udevadm info
也不起作用(直到資訊最終可用大約需要 1 分鐘),我我在這裡有點不知所措。不幸的是,重寫
udev
規則以使其適用於分區而不是驅動器也是不可取的,因為在某些情況下,人們在整個 USB 設備上創建文件系統,而不是創建跨越整個設備的單個分區,然後包含文件系統。現在的問題是是否
- 可以延遲
udev
對給定設備的規則處理,直到該設備的所有子設備都已處理完畢,或者- 我可以在 shell 腳本中使用一個系統呼叫,它“等待”所有子事件(如果有的話!)在繼續查詢
udev
數據之前完成我認為現在這是一個相當長的問題。非常感謝所有幫助。
在進行了一些研究後,我發現了
blkid
in udev規則的使用(參見例如這篇ArchLinux-Wiki 文章,不幸的是只有德語版本),我發現通過呼叫blkid -o udev -p /dev/sdXn
代替
udeavdm info /dev/sdXn
在
systemd
-triggered 腳本中,甚至可以檢索有關正在處理“添加”規則的 USB 記憶棒的子設備的完整資訊。似乎
-p
這裡的選項是關鍵,因為它切換到實際讀出設備的主動探測模式,而不是依賴記憶體資訊(例如,參見手冊頁或原始碼blkid
)。該
-o udev
選項僅用於以類似於udevadm
呼叫的方式格式化輸出,儘管它不是 100% 的直接替換,因為此處缺少udevadm
輸出的前導標識符標籤(例如E:
、等)。P: