在定制項目中,對外設的熱插拔的管理基本都在udev/systemd-udev來管理。這裏沒有對基本的udev使用/rules書寫進行介紹。
1. udev的rules可能的位置
/lib/udev/rules.d -- udev默認/預置的rules
/etc/udev/rules.d/ -- 定制的rules, 優先級高於/lib/udev/rules.d,官方建議客戶寫的rules都放這裏
至於放在哪個位置,自己決定就好,既然妳在修改系統就應該知道妳在做什麽
2. 定制自己的rules
定制熱插拔的事件,具體到rules就是:
? 1)過濾到正確的udev事件。
? 2)指定執行的動作,rules裏的“RUN”,通常是腳本(畢竟要完成壹個功能,絕大多數場景都不是壹個命令能搞定的)
3.到這裏就要設計到rules的調試了
? 1)如何知道要過濾的是條件?
? 2)如何將必要的參數傳遞給RUN執行的腳本?
方法1:
udevadm monitor -p
-- 監測所以的kernel/udevd的熱插拔事件, -p選項很有必要,打印出本次熱插拔事件的壹些屬性
這裏就是比較設備插入和拔出時的事件屬性的不同,可作為過濾的條件
比如:
rules文件對於規則:
到這裏很多時候就能滿足要求了,如果還有解決不裏的場景,就要進壹步修改過濾條件。
man udev裏會有絕大部分的關鍵字的信息(想全部的就只能去擼源碼)。
方法2:
通過在RUN指定的腳本裏傳遞參數,來找到設備存在和不存在的屬性差異。
比如:
參考信息:
a)、udev 規則的匹配鍵
ACTION: 事件 (uevent) 的行為,例如:add( 添加設備 )、remove( 刪除設備 )。
KERNEL: 內核設備名稱,例如:sda, cdrom。
DEVPATH: ? 設備的 devpath 路徑。
SUBSYSTEM: 設備的子系統名稱,例如:sda 的子系統為 block。
BUS: 設備在 devpath 裏的總線名稱,例如:usb。
DRIVER: 設備在 devpath 裏的設備驅動名稱,例如:ide-cdrom。
ID: 設備在 devpath 裏的識別號。
SYSFS{filename}: 設備的 devpath 路徑下,設備的屬性文件“filename”裏的內容。
例如:SYSFS{model}==“ST936701SS”表示:如果設備的型號為 ST936701SS,則該設備匹配該 匹配鍵。
在壹條規則中,可以設定最多五條 SYSFS 的 匹配鍵。
ENV{key}: 環境變量。在壹條規則中,可以設定最多五條環境變量的 匹配鍵。
PROGRAM: 調用外部命令。
RESULT: ? 外部命令 PROGRAM 的返回結果。
b)、udev 的重要賦值鍵
NAME: 在 /dev下產生的設備文件名。只有第壹次對某個設備的 NAME 的賦值行為生效,之後匹配的規則再對該設備的 NAME 賦值行為將被忽略。如果沒有任何規則對設備的 NAME 賦值,udev 將使用內核設備名稱來產生設備文件。
SYMLINK: 為 /dev/下的設備文件產生符號鏈接。由於 udev 只能為某個設備產生壹個設備文件,所以為了不覆蓋系統默認的 udev 規則所產生的文件,推薦使用符號鏈接。
OWNER, GROUP, MODE: 為設備設定權限。
ENV{key}: 導入壹個環境變量。
c)、udev 的值和可調用的替換操作符
Linux 用戶可以隨意地定制 udev 規則文件的值。例如:my_root_disk, my_printer。同時也可以引用下面的替換操作符:
$kernel, %k: 設備的內核設備名稱,例如:sda、cdrom。
$number, %n: 設備的內核號碼,例如:sda3 的內核號碼是 3。
$devpath, %p: 設備的 devpath路徑。
$id, %b: 設備在 devpath裏的 ID 號。
$sysfs{file}, %s{file}: ? 設備的 sysfs裏 file 的內容。其實就是設備的屬性值。
$env{key}, %E{key}: 壹個環境變量的值。
$major, %M: 設備的 major 號。
$minor %m: 設備的 minor 號。
$result, %c: PROGRAM 返回的結果。
$parent, %P: 父設備的設備文件名。
$root, %r: ? udev_root的值,默認是 /dev/。
$tempnode, %N: 臨時設備名。
%%: 符號 % 本身。
$$: 符號 $ 本身。
對比壹下和man裏的差別,$sysfs{file},這個在實際解決問題的時候是很有用的。
這種方法適合調試系統啟動的時候對rules的調試,這個過程中是沒得udevadmin monitor使用的。(當然,可以嘗試自己寫壹個systemd啟動服務,這就涉及到啟動的時機、關聯、影響,實際操作會比預想的復雜)
這裏提兩個點:
1. env - 可以是udev事件裏的屬性(-p打印的)
2. $sysfs{file}, 這裏的file就是在系統/sys目錄下對應的節點下的文件,有些情況下只能在sysfs的file的內存才能準確區分事件。