天天看點

Udev 的使用

我常常見到的一個問題,不知大家有沒有常常發現這種問題,就是 Linux 系統中原來有一個 SCSI 的硬碟,系統配置設定是 /dev/sda ,後來維護又加了一個新的硬碟,接上後,新的硬碟變成了 /dev/sda ,原來的老的硬碟變成了 /dev/sdb 。是否有法子固定下來啦?

這個問題在過去一直無解,直到 udev 出來,這個能完美的解決這個問題。

Linux 裡都是以裝置檔案的形式存在。在早期的 Linux 版本中,/dev目錄包含了所有可能出現的裝置的裝置檔案。但因為這樣 Linux 使用者很難在這些大量的裝置檔案中找到比對條件的裝置檔案。現在 udev 隻為那些連接配接到 Linux 作業系統的裝置産生裝置檔案。并且 udev 能通過定義一個 udev 規則 (rule) 來産生比對裝置屬性的裝置檔案,這些裝置屬性可以是核心裝置名稱、總線路徑、廠商名稱、型号、序列号或者磁盤大小等等。

動态自動管理裝置資訊:當有裝置添加 / 删除時,udev 的守護程序偵聽到來自核心的 uevent 的事件,用來添加或者删除 /dev下的裝置檔案,是以 udev 可以隻為已經連接配接的裝置産生裝置檔案,而不會象 2.4 核心一樣在 /dev下産生大量裝置檔案。另外可以使用這個功能 ,當有裝置加入時運作外部的程式,比如滑鼠加入時自動禁用觸摸闆之類

使用自定義命名和管理裝置:使用 Udev 規則檔案,udev 在 /dev/ 裡為所有的裝置定義了核心裝置名稱,比如 /dev /sda、/dev/hda、/dev/fd等等。由于 udev 是在使用者空間 (user space) 運作,Linux 使用者可以接下來對這些資訊進行操作,比如可以通過自定義的規則檔案,生成人性的裝置辨別,比如 /dev/my_disk、/dev/nameusb 等,還能對設定進行參數成員使用者組權限之類的修改。

開始之類需要了解

• sysfs:sysfs是 Linux 2.6 核心裡的一個虛拟檔案系統 (/sys)。它把裝置和驅動的資訊從核心的裝置子產品導出到使用者空間 (userspace)。從該檔案系統中,Linux 使用者可以擷取很多裝置的屬性。

• devpath:本文的 devpath是指一個裝置在 sysfs檔案系統 (/sys)下的相對路徑,該路徑包含了該裝置的屬性檔案。udev 裡的多數指令都是針對 devpath操作的。例如:sda的 devpath是 /block/sda,sda2 的 devpath是 /block/sda/sda2。

• 核心裝置名稱:裝置在 sysfs裡的名稱,是 udev 預設使用的裝置檔案名。

udev 主配置檔案

主要的udev 主配置檔案是 /etc/udev/udev.conf。這個檔案通常很短,他可能隻是包含幾行#開頭的注釋,然後有幾行選項:

udev_root="/dev/"  # 設定的絕對路徑,相當于建立 chroot 的根。
udev_rules="/etc/udev/rules.d/"    #規則的存放位址
udev_log="err"      # 日志的輸入級别      

udev 的規則配置檔案執行個體

預設的規則配置檔案存放在 /etc/udev/rules.d/ 中,我們進入這個可以看到 RedHat 預設對裝置建好的一些規則和一些硬體公司寫好的規則。

進入目錄,可以見到以二位數字開頭的字首的配置檔案,可以使用 vi 進入配置檔案中檢視,一行是一條規則,預設是從小數字到大數字,這些表示生效的順序。

我們在使用 udev 寫規則前,先來看一個例子

KERNEL=="sd*", PROGRAM="/lib/udev/scsi_id -g -s %p", RESULT=="123456", SYMLINK="%k_%c"      

該規則的執行:如果有一個核心裝置名稱以 sd 開頭,且 SCSI ID 為 123456,則為裝置檔案産生一個符号連結“sda_123456”. %p %k %c 請看後面的“udev 的值和可調用的替換操作符 ”

udev 的規則配置檔案

在規則檔案裡,除了以“#”開頭的行(注釋),所有的非空行都被視為一條規則,但是一條規則不能擴充到多行。規則都是由多個 鍵值對(key-value pairs)組成,并由逗号隔開,鍵值對可以分為 條件比對鍵值對( 以下簡稱“比對鍵 ”) 和 指派鍵值對( 以下簡稱“指派鍵 ”),一條規則可以有多條比對鍵和多條指派鍵。比對鍵是比對一個裝置屬性的所有條件,當一個裝置的屬性比對了該規則裡所有的比對鍵,就認為這條規則生效,然後按照指派鍵的内容,執行該規則的指派。

規則檔案裡的規則有一系列的鍵/值對組成,鍵/值對之間用逗号(,)分割。

通過上面例子中也能看出,這些配置,但我想大家可能會産生疑惑,為什麼 KERNEL 是比對鍵,而 NAME 和 MODE 是指派鍵呢?這由中間的操作符 (operator) 決定。

僅當操作符是“==”或者“!=”時,其為比對鍵;若為其他操作符時,都是指派鍵。

比對鍵和指派鍵操作符解釋見下表:

操作符     比對或指派t                         解釋
----------------------------------------
==            比對              相等比較
!=            比對             不等比較
=            指派              配置設定一個特定的值給該鍵,他可以覆寫之前的指派。
+=          指派              追加特定的值給已經存在的鍵
:=            指派                  配置設定一個特定的值給該鍵,後面的規則不可能覆寫它。      

udev 規則的比對鍵 :

鍵        含義
----------------------------------------
ACTION         事件 (uevent) 的行為,例如:add( 添加裝置 )、remove( 删除裝置 )。
KERNEL         在核心裡看到的裝置名字,比如sd*表示任意SCSI磁盤裝置
DEVPATH       核心裝置錄進,比如/devices/*
SUBSYSTEM       子系統名字,例如:sda 的子系統為 block。
BUS         總線的名字,比如IDE,USB
DRIVER         裝置驅動的名字,比如ide-cdrom
ID           獨立于核心名字的裝置名字
SYSFS{ value}       sysfs屬性值,他可以表示任意
ENV{ key}       環境變量,可以表示任意
PROGRAM       可執行的外部程式,如果程式傳回0值,該鍵則認為為真(true)
RESULT         上一個PROGRAM調用傳回的标準輸出。
NAME         根據這個規則建立的裝置檔案的檔案名。
注意:僅僅第一行的NAME描述是有效的,後面的均忽略。   
    如果你想使用使用兩個以上的名字來通路一個裝置的話,可以考慮SYMLINK鍵。
SYMLINK       為 /dev/下的裝置檔案産生符号連結。由于 udev 隻能為某個裝置産生一個裝置檔案,
    是以為了不覆寫系統預設的 udev 規則所産生的檔案,推薦使用符号連結。
OWNER         裝置檔案的屬組
GROUP         裝置檔案所在的組。
MODE         裝置檔案的權限,采用8進制
RUN         為裝置而執行的程式清單
LABEL         在配置檔案裡為内部控制而采用的名字标簽(下下面的GOTO服務)
GOTO         跳到比對的規則(通過LABEL來辨別),有點類似程式語言中的GOTO
IMPORT{ type}     導入一個檔案或者一個程式執行後而生成的規則集到目前檔案
WAIT_FOR_SYSFS   等待一個特定的裝置檔案的建立。主要是用作時序和依賴問題。
PTIONS         特定的選項: 
last_rule 對這類裝置終端規則執行;
ignore_device 忽略目前規則;
ignore_remove 忽略接下來的并移走請求。
all_partitions 為所有的磁盤分區建立裝置檔案。      

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:臨時裝置名。
%%:符号 % 本身。
$$:符号 $ 本身。      

udev 規則所需要資訊的查詢

常用的查上面比對鍵資訊的指令

udevinfo -a -p $(udevinfo  -q path -n /dev/sda1 )
上面的指令兩次使用udevinfo:
  第一次是傳回sysfs裝置路徑(他通常和我們看到的Linux裝置檔案名所在路徑--/dev/hda--不同);
  第二次才是查詢這個裝置路徑,結果将是非常常的syfs資訊彙總
udevinfo -a -p /sys/class/net/eth0
scsi_id -g -s /block/sda
scsi_id -g -x -s /block/sda/sda3
ata_id /dev/hda      

udev 資訊的測試和生效

查出來後,根據上面檔案中的内容寫規則後,怎麼測試

udevtest /block/sda
start_dev #指令重新開機 udev守護程序
本操作會對所有的裝置重新查詢規則目錄下所有的規則檔案,然後執行所比對的規則裡的行為。
通常使用該指令讓新的規則檔案立即生效。      

繼續閱讀