udev學習筆記匯總


1.什么是udev

udev--就是動態設備管理
  udev 能夠處理設備事件管理設備文件的權限、在/dev目錄中創建額外的符號鏈接重命名網絡接口,等等。 內核通常僅根據設備
被發現的先后順序給設備文件命名,因此很難在設備文件與物理硬件之間建立穩定的對應關系。而根據設備的物理屬性或配置特征創建有
意義的符號鏈接名稱或網絡接口名稱,就可以在物理設備與設備文件名稱之間建立穩定的對應關系。
  udev守護進程(systemd-udevd.service(8) Ubuntu中ps -aux | grep systemd-udevd可以看到)直接從內核接收設備的插入、拔出、改
變狀態等事件,並根據這些事件的各種屬性,到規則庫中進行匹配,以確定觸發事件的設備。被匹配成功的規則有可能提供額外的設備信息,
這些信息可能會被記錄到udev數據庫中,也可能會被用於創建符號鏈接。
  udev處理的所有設備信息都存儲在udev數據庫中,並且會發送給可能的設備事件的訂閱者。可以通過libudev庫訪問udev數據庫以及設
備事件源。

 

2.規則文件

  規則文件分別位於:系統規則目錄(/usr/lib/udev/rules.d)、運行時規則目錄(/run/udev/rules.d)、本機規則目錄(/etc/udev/rules.d)。
所有的規則文件(無論位於哪個目錄中),統一按照文件名的字典順序處理。 對於不同目錄下的同名規則文件,僅以優先級最高的目錄中的那一
個為准。具體說來就是:/etc/的優先級最高、/run/的優先級居中、/usr/lib/的優先級最低。如果系統管理員想要屏蔽 /usr/lib/目錄中的某個
規則文件, 那么最佳做法是在/etc/目錄中創建一個指向/dev/null的同名符號鏈接,即可徹底屏蔽/usr/lib/目錄中的同名文件。注意,規則文
件必須以 .rules 作為后綴名,否則將被忽略
  規則文件中以"#"開頭的行以及空行將被忽略,其他不以"#"開頭的非空行,每行必須至少包含一個"鍵-值"對。"鍵"有兩種類型:匹配賦值
如果某條規則的所有匹配鍵的值都匹配成功,那么就表示此條規則匹配成功,也就是此條規則中的所有賦值鍵都會被賦予指定的值。
一條匹配成功的規則可以:重命名網絡接口、為某個設備文件添加一個軟連接、運行一個指定的程序, 等等。
每條規則都是由一系列逗號分隔的"鍵-值"對組成。 根據操作符的不同,每個鍵都對應着一個唯一的操作。 可用的操作符如下:

"==" (匹配)"等於"
"!=" (匹配)"不等於"
"="  (賦值)為鍵賦予指定的值。 此鍵之前的值(可能是個列表)將被丟棄。
"+=" (賦值)在鍵的現有值列表中增加此處指定的值。
"-=" (賦值)在鍵的現有值列表中刪除此處指定的值。
":=" (賦值)為鍵賦予指定的值,並視為最終值,也就是禁止被繼續修改。

  下面的"鍵"可用於匹配。注意,其中的某些鍵還可以針對父設備進行匹配,而不僅僅是生成設備事件的那個設備自身。 如果在同一條規
則中有多個鍵可以針對父設備進行匹配,那么僅在所有這些鍵都同時成功匹配同一個父設備時,才算匹配成功。 [譯者注]Linux通過sysfs以
樹狀結構展示設備,例如硬盤是SCSI設備的孩子、SCSI設備又是ATA控制器的孩子、 ATA控制器又是PCI總線的孩子。而你經常需要從父設備那
里引用信息, 比如硬盤的序列號就是通過父設備(SCSI設備)展現的。

ACTION    
匹配事件的動作。例如"add"表示插入一個設備,“remove”移除一個設備。 DEVPATH
匹配設備的路徑(也就是該設備在sysfs文件系統下的相對路徑)。[舉例]
/dev/sda1對應的devpath是/block/sda/sda1(一般對應着/sys/block/sda/sda1目錄)。 KERNEL
匹配設備的內核名稱。
"內核名稱"是指設備在sysfs里的名稱,也就是默認的設備文件名稱,例如"sda"NAME
匹配網絡接口的名稱。僅在先前的規則中已將NAME鍵賦值的前提下,才可將此鍵用於匹配。 SYMLINK
匹配指向此設備節點的軟連接的名稱。僅在先前的規則中已將SYMLINK鍵賦值的前提下,才可將此鍵用於匹配。可能有多個軟連接指向同一個設備節點,但只需其中的一
個匹配成功即可。 SUBSYSTEM
匹配設備所屬的子系統。例如
"sound""net" DRIVER
匹配設備的驅動程序名稱。僅在設備事件發生時,此設備確實正好綁定着一個驅動程序情況下,此鍵才會被設置。 ATTR{文件}
匹配設備在sysfs中的屬性值。屬性值中的尾部空白會被忽略,除非指定的值自身就包含尾部空白。[譯者注]大括號中的
"文件" 是指設備路徑(devpath)下的文件。
例如,對於
/dev/sda1來說,ATTR{size}的含義其實是指/sys/block/sda/sda1/size文件的內容。 ATTRS{文件}
匹配設備及其所有父設備在sysfs中的屬性值。如果指定了多個ATTRS匹配,那么必須在同一個設備上全部匹配成功,才算最終匹配成功。 屬性值中的尾部空白會被忽
略,除非指定的值自身就包含尾部空白。 SYSCTL{內核參數} 
匹配
"內核參數"的值。[譯者注]所謂"內核參數"其實是指/proc/sys/中的"內核參數"。例如,可以用SYSCTL{kernel/hostname}
匹配
/proc/sys/kernel/hostname的值。 KERNELS
匹配設備及其所有父設備的內核名稱 SUBSYSTEMS
匹配設備及其所有父設備所屬的子系統 DRIVERS
匹配設備及其所有父設備的驅動程序名稱 TAG
匹配設備的標簽。 TAGS
匹配設備及其所有父設備的標簽。 ENV{設備屬性}
匹配設備的屬性。例如
"DEVTYPE", "ID_PATH", "SYSTEMD_WANTS" 等等。[提示]可以通過udevadm info --query=property /dev/sda 命令查看/dev/sda的所有屬性。add_uevent_var(env, "SUBSYSTEM=%s", subsystem); ==> ENV{SUBSYSTEM} TEST{八進制模式掩碼}
檢測指定的文件是否存在。 如果有必要,還可以額外指定一個八進制的訪問模式掩碼。 PROGRAM
執行指定的程序並檢查返回值,如果返回值為零,則匹配成功,否則匹配失敗。設備的屬性會轉化為該程序的環境變量供其使用。 同時該程序的標准輸出會被自動保存在RESULT 鍵中。注意,僅可用於執行時間很短的前台程序。 參見 RUN RESULT
匹配最近一次PROGRAM程序的輸出字符串, 必須位於PROGRAM之后(但可出現在同一條規則中)。可以在用於匹配的
""中使用shell風格的通配符, 具體說來就是: "*" 匹配任意數量的字符(包括零個) "?" 匹配單獨一個字符 "[]" 匹配中括號內的任意一個字符。 例如 "tty[SR]" 可以匹配 "ttyS""ttyR" 。 還可以使用 "-" 符號表示一個區間。 例如 "[0-9]" 可以匹配任意數字。 如果在左括號 "[" 后緊接着一個 "!" 則表示匹配非括號內的字符。 "|" 用於分隔兩個可相互替代的匹配模式(也就是""的意思)。 例如 "abc|x*" 的意思是匹配 "abc""x*"

下面的鍵可用於賦值:

NAME 
設置網絡接口的名稱。參見systemd.link(5)以了解設置網絡接口名稱的高級機制。實際上,udev並不能直接修改網絡接口的設 備節點名稱,只是額外創建了一個符號鏈接而已。 SYMLINK 
設置指向此設備節點的軟連接名稱。軟連接的名字中僅允許使用下列字符:
"0-9A-Za-z#+-.:=@_/" 、有效的UTF-8字符、"\x00" 風格的十六進制編碼(實際的文件名並不轉碼)。其他字符將被替換為"_"字符。只需在多個名稱之間使用空格分隔,即可一次指定 多個軟連接名稱。如果為多個不同的設備指定了相同的軟連接,那么實際的軟連接將指向link_priority值最高的設備。 如果link_priority值最高的設備被移除,那么該軟連接將重新指向下一個 link_priority值最高的設備,以此類推。 對於未指定 link_priority值或者link_priority值相等的設備,它們之間的順序是不確定的。符號連接的名稱必須不能與內核的默認名稱相同, 否則會得到無法預知的結果。 OWNER, GROUP, MODE
設置設備節點的屬主、屬組、權限。 會覆蓋內置的默認值。 SECLABEL{模塊}
設置設備節點的Linux安全模塊標簽。 ATTR{文件}
設置在sysfs中的設備屬性。[譯者注]大括號中的
"文件"是指設備路徑(devpath)下的文件。例如,對於/dev/sda1來說, ATTR{size}  
的含義其實是指
/sys/block/sda/sda1/size文件的內容。 SYSCTL{內核參數}
設置
"內核參數"的值。[譯者注]所謂"內核參數"其實是指/proc/sys/中的"內核參數"。 例如,可以用SYSCTL{kernel/hostname} 設置/proc/sys/kernel/hostname的值。SYSCTL{/proc/sys/kernel/printk}設置打印等級 ENV{屬性}
設置設備的屬性。例如
"DEVTYPE","ID_PATH","SYSTEMD_WANTS"等等。[提示]可以通過udevadm info --query=property /dev/sda 命令查看/dev/sda的所有屬性。如果屬性名以"."開頭,那么此屬性將不會被記錄到udev數據庫中,也不會被導出為環境變量(例如PROGRAM)。 TAG
設置設備的標簽。用於為libudev監視(monitor)功能的用戶過濾事件或者枚舉已標記的設備。標簽僅在與特殊的設備過濾器一起使用時 才有意義,千萬不要用於常規目的。濫用標簽將會導致設備事件處理效率顯著下降,所以應該盡量避免為設備設置標簽。 RUN{類型}
對於每一個設備事件來說,在處理完所有udev規則之后,都可以再接着執行一個由此鍵設置的程序列表(默認為空)。 不同的
"類型"含義如下:   "program" 一個外部程序,如果是相對路徑,那么視為相對於/usr/lib/udev目錄。否則必須使用絕對路徑。如果未明確指定"類型",那么這是默認值。   "builtin" 與program類似,但是僅用於表示內置的程序。程序名與其參數之間用空格分隔。 如果參數中含有空格,那么必須使用單引號(')界定。僅可
       使用運行時間非常短的前台程序, 切勿設置任何后台守護進程或者長時間運行的程序。設備事件處理完成之后,
所有派生的進程(無論是否已經
       分離),都將會被無條件的殺死。 LABEL
設置一個可用作GOTO跳轉目標的標簽。 GOTO
跳轉到下一個匹配的LABEL標簽所在的規則。 IMPORT{類型}
將一組變量導入為設備的屬性。不同的
"類型"含義如下:     "program" 執行一個外部程序,並且當其返回值為零時導入其輸出內容。注意,輸出內容的每一行都必須符合"key=value"格式。關於程序 路徑、命令與參數分隔符、
            引號的使用規則、程序執行時間,等等,都與RUN相同。     
"builtin""program"類似,但是僅用於執行內置的程序。     "file" 導入一個文本文件的內容。該文本文件的每一行都必須符合"key=value"格式。以"#"開頭的行將被視為注釋而忽略。     "db" 從當前已有的udev數據庫中導入一個單獨的屬性。僅可用於udev數據庫確實已經被早先的設備事件所填充的情形。     "cmdline" 從內核引導選項導入一個單獨的屬性。對於那些僅有單獨的標記而沒有值的屬性, 其值將被指定為 "1" 。     "parent" 從父設備導入已有的屬性(包括對應的值)。可以將IMPORT{parent}賦值為shell風格的匹配模式,以導入多個屬性名稱與匹配模            式相符的屬性。僅可使用運行時間非常短的前台程序,切勿設置任何后台守護進程或者長時間運行的程序。 參見 RUN

規則與設備的選項:

link_priority=value
指定創建符號鏈接時的優先級。 數值越大優先級越高。默認值是"0"string_escape=none|replace
在對設備進行命名時,如何處理設備名字中的非常規字符(比如控制字符與不安全的字符)。 none 表示不做處理,保持原樣; replace 表示將這些非常規字符替換為"_"(下划線)。
static_node=
將本條規則設定的權限應用到此選項指定的靜態設備節點上。 同時,如果在本規則中指定了標簽(tag), 那么還會在 /run/udev/static_node-tags/tag 目錄中創建一個指向
該靜態設備節點的軟連接。 注意,在 systemd-udevd 啟動之前, 靜態設備節點就已經由 systemd-tmpfiles 創建完成了。 創建靜態設備節點時,並不要求存在對應的內核設
備, 因為當這些設備節點被訪問時,會觸發內核模塊的自動加載功能。 watch 使用文件系統的 inotify 功能監視設備節點。 當節點被打開並寫入之后又被關閉, 將會觸發一個
"設備狀態已變化"的事件。 nowatch 禁用針對設備節點的 inotify 監視功能。 NAME, SYMLINK, PROGRAM, OWNER, GROUP, MODE, SECLABEL, RUN 都支持簡單的字符串替換。 RUN 的替換發生在 所有規則全部處理完成之后、程序將要執行之前, 因此
可以使用由匹配成功的規則所設置的設備屬性。 而其他鍵的替換發生在該鍵所在規則被處理完成的當時。 可用的替換標記如下: $kernel,
%k 設備的內核名稱 $number, %n 設備在內核中的序號。例如,對於 "sda3" 來說,此值為 "3" $devpath, %p 設備路徑(devpath)。也就是該設備在sysfs文件系統下的相對路徑。例如,/dev/sda1 對應的設備路徑是 /block/sda/sda1 (一般對應着 /sys/block/sda/sda1 目錄)。 $id, %b 被SUBSYSTEMS, KERNELS, DRIVERS, ATTRS 成功匹配到的設備的設備名稱 $driver 被 SUBSYSTEMS, KERNELS, DRIVERS, ATTRS 成功匹配到的設備的驅動名稱 $attr{文件}, %s{文件} 在規則匹配成功時, 設備路徑(devpath)下"文件"的內容(用於表示設備的屬性)。 如果該設備路徑下沒有此文件, 則從先前 KERNELS, SUBSYSTEMS, DRIVERS, ATTRS 匹配的父設備中提取。 如果"文件"是一個軟連接, 則一直追蹤軟連接到最終的實際文件。 $env{屬性}, %E{屬性} 設備的屬性值。例如 "DEVTYPE", "ID_PATH", "SYSTEMD_WANTS" 等等。[提示]可以通過 udevadm info --query=property /dev/sda 命令查看 /dev/sda 的所有屬性。 $major, %M 設備的主設備號 $minor, %m 設備的次設備號 $result, %c PROGRAM 程序的輸出字符串。 可以使用 "%c{N}" 提取第N個子字符串(以空格為分隔符,從"1"開始計數)。 也可以通過 "%c{N+}"(也就是在數字后附加一個 "+")提取從第N個子字符串開始一直到結尾的部分。 $parent, %P 父設備的節點名稱 $name 設備的當前名稱。如果沒有被任何udev規則修改, 那么等於該設備的內核名稱。 $links 一個空格分隔的軟鏈接名稱列表,這些軟鏈接都指向該設備的節點。 該值僅在兩種情況下存在:(1)發生"remove"事件;(2)先前的規則已對 SYMLINK 賦值。 $root, %r udev_root 的值 $sys, %S sysfs 文件系統的掛載點 $devnode, %N 設備節點的名稱(也就是設備文件的名稱) %% 百分號 "%" 自身 $$ 美元符號 "$" 自身

 

例子:匹配上后執行腳本usb-if.sh,它后面的是它的參數

root@hw:/etc/udev/rules.d# cat usb-if.rules 
ACTION=="change", SUBSYSTEM=="usb", ENV{DEVPATH}=="/[1-4]-1", RUN+="/bin/sh /etc/udev/usb-if.sh no_response"
ACTION=="change", SUBSYSTEM=="usb", ENV{DEVPATH}=="/devices/platform/soc/*/usb[1-4]/[1-4]-1", RUN+="/bin/sh /etc/udev/usb-if.sh unknown"
ACTION=="remove", SUBSYSTEM=="usb", ENV{DEVPATH}=="/devices/platform/soc/*/usb[1-4]/[1-4]-1", RUN+="/bin/sh /etc/udev/usb-if.sh remove"
#KERNEL=="4-1:1.0", SUBSYSTEM=="usb", ATTR{bInterfaceClass}=="09", RUN+="/bin/sh /etc/udev/usb-if.sh usbhub"
#KERNEL=="4-1:1.0", SUBSYSTEM=="usb", ATTR{bInterfaceClass}=="ff", RUN+="/bin/sh /etc/udev/usb-if.sh unsupport"
#KERNEL=="4-1", SUBSYSTEM=="usb", ATTRS{bDeviceClass}=="ff", RUN+="/bin/sh /etc/udev/usb-if.sh unsupport"
ACTION=="change", SUBSYSTEM=="block", KERNEL=="sd[a-z]", RUN+="/bin/sh /etc/udev/usb-if.sh bad_udisk" 
ACTION=="add", SUBSYSTEM=="usb", ENV{DEVPATH}=="/devices/platform/soc/*/usb[1-4]/[1-4]-1/[1-4]-1:1.0", RUN+="/bin/sh /etc/udev/usb-if.sh"
#block sysfs info is ready
ACTION=="add", SUBSYSTEM=="block", KERNEL=="sd[a-z]", RUN+="/bin/sh /etc/udev/usb-if.sh udisk"
 
        

 

 

 

 

參考:http://www.jinbuguo.com/systemd/udev.html 

 

https://blog.csdn.net/nhczp/article/details/4099647

https://www.cnblogs.com/cslunatic/p/3171837.html

https://blog.csdn.net/ericzhong83/article/details/4739987

http://www.cnblogs.com/sopost/archive/2013/01/09/2853200.html

https://blog.csdn.net/xiaoliu5396/article/details/46531893

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM