Shell-Script

查詢父設備時確保子設備上的完整 udev 資訊

  • November 18, 2021

我正在嘗試實現一個自定義函式,該函式在連接 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_TYPEID_FS_LABEL環境變數(仍然)缺失。udevadm settle由於在處理事件時呼叫udev是一個壞主意(也沒有幫助),甚至 0.5 秒的輪詢循環在呼叫之間休眠udevadm info也不起作用(直到資訊最終可用大約需要 1 分鐘),我我在這裡有點不知所措。

不幸的是,重寫udev規則以使其適用於分區而不是驅動器也是不可取的,因為在某些情況下,人們在整個 USB 設備上創建文件系統,而不是創建跨越整個設備的單個分區,然後包含文件系統。

現在的問題是是否

  • 可以延遲udev對給定設備的規則處理,直到該設備的所有設備都已處理完畢,或者
  • 我可以在 shell 腳本中使用一個系統呼叫,它“等待”所有事件(如果有的話!)在繼續查詢udev數據之前完成

我認為現在這是一個相當長的問題。非常感謝所有幫助。

在進行了一些研究後,我發現了blkidin 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:

引用自:https://unix.stackexchange.com/questions/547022