UDEV規則介紹

1 udev簡介

udev 是Linux2.6 內核裏的一個功能,它替代了原來的devfs,成爲當前Linux 默認的設備管理工具。udev以守護進程的形式運行,通過偵聽內核發出來的uevent 來管理/dev目錄下的設備文件。不像之前的設備管理工具,udev在用戶空間(user space) 運行,而不在內核空間(kernel space) 運行。


2 udev的優勢

2.1 動態管理

當設備添加/ 刪除時,udev的守護進程偵聽來自內核的uevent,以此添加或者刪除/dev下的設備文件,所以udev 只爲已經連接的設備產生設備文件,而不會在/dev下產生大量虛無的設備文件。


2.2 自定義命名規則

通過Linux 默認的規則文件,udev在/dev/ 裏爲所有的設備定義了內核設備名稱,比如/dev/sda、/dev/hda、/dev/fd等等。由於udev 是在用戶空間(user space) 運行,Linux用戶可以通過自定義的規則文件,靈活地產生標識性強的設備文件名,比如/dev/boot_disk、/dev/root_disk、/dev/color_printer等等。


2.3 設定設備的權限和所有者/ 組

udev可以按一定的條件來設置設備文件的權限和設備文件所有者/ 組。在不同的udev 版本中,實現的方法不同。


2.4 下面的流程圖顯示udev 添加/ 刪除設備文件的過程。



ps:

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。


4.內核設備名稱:設備在sysfs裏的名稱,是udev 默認使用的設備文件名。


3 配置和使用udev(CentOS6.5)

3.1 檢查udev在CentOS6.5中的版本和運行情況

[root@rango~]# rpm -qa | grep -i udev

udev-147-2.51.el6.i686

libudev-147-2.51.el6.i686

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


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章