-
1 udev簡介
?
udev 是Linux2.6 內核里的一個功能,它替代了原來的devfs,成為當前Linux 默認的設備管理工具。udev以守護進程的形式運行,通過偵聽內核發出來的uevent 來管理/dev目錄下的設備文件。不像之前的設備管理工具,udev在用戶空間(user space) 運行,而不在內核空間(kernel space) 運行。
?
vue 數據庫,2 udev的優勢
?
2.1 動態管理
當設備添加/ 刪除時,udev的守護進程偵聽來自內核的uevent,以此添加或者刪除/dev下的設備文件,所以udev 只為已經連接的設備產生設備文件,而不會在/dev下產生大量虛無的設備文件。
?
elvui 插件包,2.2 自定義命名規則
?
通過Linux 默認的規則文件,udev在/dev/ 里為所有的設備定義了內核設備名稱,比如/dev/sda、/dev
/hd
a、 /dev/fd等等。由于udev 是在用戶空間(user space) 運行,Linux用戶可以通過自定義的規則文件,靈活地產生標識性強的設備文件名,比如/dev/boot_disk、/dev/root_disk、 /dev/color_printer等等。
?
2.3 設定設備的權限和所有者/ 組
udevadm trigger、
udev可以按一定的條件來設置設備文件的權限和設備文件所有者/ 組。在不同的udev 版本中,實現的方法不同。
?
2.4 下面的流程圖顯示udev 添加/ 刪除設備文件的過程。
?
ps:
vue虛擬列表插件、
1.設備文件:由于本文以較通俗的方式講解udev,所以設備文件是泛指在/dev/下,可被應用程序用來和設備驅動交互的文件。而不會特別地區分設備文件、設備節點或者設備特殊文件。
?
2.sysfs:sysfs是Linux 2.6 內核里的一個虛擬文件系統(/sys)。它把設備和驅動的信息從內核的設備模塊導出到用戶空間(userspace)。從該文件系統中,Linux用戶可以獲取很多設備的屬性。
?
3.devpath:本文的devpath是指一個設備在sysfs文件系統(/sys)下的相對路 徑,該路徑包含了該設備的屬性文件。udev里的多數命令都是針對devpath操作的。例如:sda的devpath是/block/sda,sda2 的devpath是/block/sda/sda2。
vue ui組件庫。?
4.內核設備名稱:設備在sysfs里的名稱,是udev 默認使用的設備文件名。
?
3 配置和使用udev(CentOS6.5)
?
opencv庫?
3.1 檢查udev在CentOS6.5中的版本和運行情況
?
[root@rango~]# rpm -qa | grep -i udev
udev-147-2.51.el6.i686
libudev-147-2.51.el6.i686
vue全局過濾器、
libgudev1-147-2.51.el6.i686
system-config-printer-udev-1.1.16-23.el6.i686
?
[root@rango~]# ps -ef | grep -i udev
root 500 1 0 09:28 ? 00:00:00 /sbin/udevd -d
root 3658 500 0 09:28 ? 00:00:00 /sbin/udevd -d
root 3869 500 0 09:28 ? 00:00:00 /sbin/udevd -d
?
3.2 udev的配置文件
[root@rango~]# cat /etc/udev/udev.conf
#The initial syslog(3) priority: "err", "info","debug" or its
#numerical equivalent. For runtime debugging, the daemons internal
#state can be changed with: "udevadm control--log-priority=<value>".
udev_log="err"
udev_log:syslog記錄日志的級別,默認值是err。如果改為info或者debug的話,會有冗長的udev日志被記錄下來。
實際上在CentOS 里,除了配置文件里列出的參數udev_log外,Linux用戶還可以修改參數udev_root和udev_rules,只不過這2 個參數是不建議修改的,所以沒顯示在udev.conf 里。syslog默認會記錄udev 的日志,Linux用戶只能修改日志的級別(err、info、degub等);設備的權限不能在udev.conf 里設定,而是要在規則文件(*.rules) 里設定。
?
3.3 通過udev設定設備文件的權限
?
在CentOS 6.5 的udev,已經沒有權限文件,所有的權限都是通過規則文件(*.rules)來設置,在下面的規則文件配置過程會介紹到。
?
3.4 udev的規則和規則文件
規則文件是udev里最重要的部分,默認是存放在/etc/udev/rules.d/下。所有的規則文件必須以“.rules”為后綴名。CentOS有默認的規則文件,這些默認規則文件不僅為設備產生內核設備名稱,還會產生標識性強的符號鏈接。例如:
[root@rango~]# ls /dev/disk/by-uuid/
0E29-04AB 624d6d56-8613-4a27-ad6a-50eab26868a9
0F15181B0F15181B 9017-7DE0
1C58125758122FCE f139256a-b396-48e5-ba9c-6c13f4f8923b
281892191891E5DA
但這些鏈接名較長,不易調用,所以通常需要自定義規則文件,以此產生易用且標識性強的設備文件或符號鏈接。
udev按照規則文件名的字母順序來查詢全部規則文件,然后為匹配規則的設備管理其設備文件或文件鏈 接。雖然udev不會因為一個設備匹配了一條規則而停止解析后面的規則文件,但是解析的順序仍然很重要。通常情況下,建議讓自己想要的規則文件最先被解 析。比如,創建一個名為 /etc/udev/rules.d/10-myrule.rules的文件,并把你的規則寫入該文件,這樣udev就會在解析系統默認的規則文件之前解 析到你的文件。
在規則文件里,除了以“#”開頭的行(注釋),所有的非空行都被視為一條規則,但是一條規則不能擴展 到多行。規則都是由多個鍵值對(key-valuepairs)組成,并由逗號隔開,鍵值對可以分為條件匹配鍵值對(以下簡稱“匹配鍵”)和賦值鍵值對 (以下簡稱“賦值鍵”),一條規則可以有多條匹配鍵和多條賦值鍵。匹配鍵是匹配一個設備屬性的所有條件,當一個設備的屬性匹配了該規則里所有的匹配鍵,就 認為這條規則生效,然后按照賦值鍵的內容,執行該規則的賦值。下面是一個簡單的規則:
KERNEL=="sda",NAME="my_root_disk", MODE="0660"
KERNEL是匹配鍵,NAME和MODE是賦值鍵。這條規則的意思是:如果有一個設備的內核設備名稱為sda,則該條件生效,執行后面的賦值:在/dev下產生一個名為my_root_disk的設備文件,并把設備文件的權限設為0660。
僅當操作符是“==”或者“!=”時,其為匹配鍵;若為其他操作符時,都是賦值鍵。
?
udev規則的所有操作符
“==”:比較鍵、值,若等于,則該條件滿足;
“!=”:比較鍵、值,若不等于,則該條件滿足;
“=”:對一個鍵賦值;
“+=”:為一個表示多個條目的鍵賦值。
“:=”:對一個鍵賦值,并拒絕之后所有對該鍵的改動。目的是防止后面的規則文件對該鍵賦值。
?
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 的返回結果。例如:
PROGRAM=="/lib/udev/scsi_id -g -s $devpath", RESULT=="35000c50000a7ef67"
調用外部命令/lib/udev/scsi_id查詢設備的SCSI ID,如果返回結果為35000c50000a7ef67,則該設備匹配該匹配鍵。
?
udev 的重要賦值鍵
NAME:在/dev下產生的設備文件名。只有第一次對某個設備的NAME 的賦值行為生效,之后匹配的規則再對該設備的NAME 賦值行為將被忽略。如果沒有任何規則對設備的NAME 賦值,udev將使用內核設備名稱來產生設備文件。
SYMLINK:為/dev/下的設備文件產生符號鏈接。由于udev 只能為某個設備產生一個設備文件,所以為了不覆蓋系統默認的udev 規則所產生的文件,推薦使用符號鏈接。
OWNER, GROUP, MODE:為設備設定權限。
ENV{key}:導入一個環境變量。
udev 的值和可調用的替換操作符:
在鍵值對中的鍵和操作符都介紹完了,最后是值(value)。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 的內容。其實就是設備的屬性值。例如:$sysfs{size}表示該設備( 磁盤) 的大小。
$env{key}, %E{key}:一個環境變量的值。
$major, %M:設備的major 號。
$minor %m:設備的minor 號。
$result, %c:PROGRAM返回的結果。
$parent, %P:父設備的設備文件名。
$root, %r:udev_root的值,默認是/dev/。
$tempnode, %N:臨時設備名。
%%:符號% 本身。
$$:符號$ 本身。
KERNEL=="sd*", PROGRAM="/lib/udev/scsi_id -g -s %p", \ RESULT=="35000c50000a7ef67", SYMLINK="%k_%c"
該規則的執行:如果有一個內核設備名稱以sd 開頭,且SCSI ID 為35000c50000a7ef67,則為設備文件產生一個符號鏈接“sda_35000c50000a7ef67”.
4 制定udev 規則和查詢設備信息的實例
4.1 查找設備的信息(屬性)來制定udev規則
當我們為指定的設備設定規則時,首先需要知道該設備的屬性,比如設備的序列號、磁盤大小、廠商ID、設備路徑等等。通常我們可以通過以下的方法獲得:
查詢sysfs文件系統:
前面介紹過,sysfs里包含了很多設備和驅動的信息。
例如:設備sda 的SYSFS{size} 可以通過cat/sys/block/sda/size得到;SYSFS{model}信息可以通過cat/sys/block/sda/device/model得到。
udevadm info命令:(Centos5.3為udevinfo命令)
udevadm info 可以查詢udev 數據庫里的設備信息。例如:用udevadm info 查詢設備sda 的model 和size 信息:
[root@rango ~]# udevadm info -a -p /sys/block/sda | egrep"model|size"
ATTR{size}=="976773168"
ATTRS{model}=="ST500DM002-1BD14
?
4.2 udev的簡單規則
產生網卡設備文件的規則
SUBSYSTEM=="net", SYSFS{address}=="AA:BB:CC:DD:EE:FF", NAME="public_NIC"
該規則表示:如果存在設備的子系統為net,并且地址(MAC address) 為“AA:BB:CC:DD:EE:FF”,為該設備產生一個名為public_NIC 的設備文件。
為指定大小的磁盤產生符號鏈接的規則
SUBSYSTEM=="block", SYSFS{size}=="71096640", SYMLINK ="my_disk"
該規則表示:如果存在設備的子系統為block,并且大小為71096640(block),則為該設備的設備文件名產生一個名為my_disk 的符號鏈接。
通過外部命令為指定序列號的磁盤產生設備文件的規則
KERNEL=="sd*[0-9]", PROGRAM=="/lib/udev/scsi_id -g -s %p", \ RESULT=="35000c50000a7ef67", NAME +="root_disk%n"
該規則表示:如果存在設備的內核設備名稱是以 sd 開頭( 磁盤設備),以數字結尾( 磁盤分區),并且通過外部命令查詢該設備的SCSI_ID 號為“35000c50000a7ef67”,則產生一個以root_disk開頭,內核號碼結尾的設備文件,并替換原來的設備文件(如果存在的話)。例 如:產生設備名/dev/root_disk2,替換原來的設備名/dev/sda2。
運用這條規則,可以在/etc/fstab里保持系統分區名稱的一致性,而不會受驅動加載順序或者磁盤標簽被破壞的影響,導致操作系統啟動時找不到系統分區。
?
4.3 其他常用的udev命令
udevadm test(udevadm的子命令):針對一個設備,在不需要uevent 觸發的情況下模擬一次udev的運行,并輸出查詢規則文件的過程、所執行的行為、規則文件的執行結果。
Simulate a udev event run for the given device, and print debugoutput
?
start_udev:start_dev命令重啟udev守護進程,并對所有的設備重新查詢規則目錄下所有的規則文件,然后執行所匹配的規則里的行為。通常使用該命令讓新的規則文件立即生效:
[root@rango ~]# start_udev
Starting udev: [ OK ]
start_udev一般沒有標準輸出,所有的udev 相關信息都按照配置文件(udev.conf)的參數設置,由syslog記錄。
——RangoChen