【轉】Linux Udev 規則
轉載自:https://blog.csdn.net/xiaoliu5396/article/details/46531893
看完本章,朋友們可以進行隨心所欲的運用udev,編寫udev規則,更好的管理Linux裝置。例如,把硬碟sda根據盤的SN碼生成一個軟連線,使得SN碼當做sda一樣使用。
udev
udev 是 Linux2.6 核心裡的一個功能,它替代了原來的 devfs,成為當前 Linux 預設的裝置管理工具。udev 以守護程序的形式執行,通過偵聽核心發出來的 uevent 來管理 /dev目錄下的裝置檔案。不像之前的裝置管理工具,udev 在使用者空間 (user space) 執行,而不在核心空間 (kernel space) 執行。
devfs
linux下有專門的檔案系統用來對裝置進行管理,devfs和sysfs就是其中兩種。在2.6核心以前一直使用的是devfs,devfs掛載於/dev目錄下,提供了一種類似於檔案的方法來管理位於/dev目錄下的所有裝置,我們知道/dev目錄下的每一個檔案都對應的是一個裝置,至於當前該裝置存在與否先且不論,而且這些特殊檔案是位於根檔案系統上的,在製作檔案系統的時候我們就已經建立了這些裝置檔案,因此通過操作這些特殊檔案,可以實現與核心進行互動。但是devfs檔案系統有一些缺點,例如:不確定的裝置對映,有時一個裝置對映的裝置檔案可能不同,例如我的U盤可能對應sda有可能對應sdb;沒有足夠的主/輔裝置號,當裝置過多的時候,顯然這會成為一個問題;/dev目錄下檔案太多而且不能表示當前系統上的實際裝置;命名不夠靈活,不能任意指定等等
sysfs
正因為上述這些問題的存在,在linux2.6核心以後,引入了一個新的檔案系統sysfs,它掛載於/sys目錄下,跟devfs一樣它也是一個虛擬檔案系統,也是用來對系統的裝置進行管理的,它把實際連線到系統上的裝置和匯流排組織成一個分級的檔案,使用者空間的程式同樣可以利用這些資訊以實現和核心的互動,該檔案系統是當前系統上實際裝置樹的一個直觀反應,它是通過kobject子系統來建立這個資訊的,當一個kobject被建立的時候,對應的檔案和目錄也就被建立了,位於/sys下的相關目錄下,既然每個裝置在sysfs中都有唯一對應的目錄,那麼也就可以被使用者空間讀寫了。使用者空間的工具udev就是利用了sysfs提供的資訊來實現所有devfs的功能的,但不同的是udev執行在使用者空間中,而devfs卻執行在核心空間,而且udev不存在devfs那些先天的缺陷。很顯然,sysfs將是未來發展的方向。
udev工作流程圖:
udev規則檔案:
規則檔案,在udev中至關重要,這些規則檔案,預設是放在/etc/udev/rules.d/下,都是以 *.rules命名格式,例如10-dm.rules,60-persistent-storage.rules,執行規則檔案,是根據開頭的數字大小,同數字,根據字母順序執行,且後面的規則檔案會覆蓋前面的規則;('NAME'動作除外,因為'NAME'只能操作一次,後續NAME操作無用,後面會描述。) 先舉一個例子:
ACTION=="add", SUBSYSTEM=="net", DRIVERS=="?*", ATTR{type}=="1", PROGRAM="/lib/udev/rename_device", RESULT=="?*", NAME="$result"
該條例子,就是重新命名網絡卡,在centos 7中,添加了這條網絡卡重新命名的規則,把eth0,這種網絡卡名,通過程式rename_device進行修改名稱,返回結果作為新名稱。
編寫udev規則檔案:
匹配鍵和賦值鍵操作符解釋:
- == 匹配 相等比較
- != 匹配 不等比較
- = 賦值 分配一個特定的值給該鍵,他可以覆蓋之前的賦值.
- += 賦值 追加特定的值給已經存在的鍵
- := 賦值 分配一個特定的值給該鍵,後面的規則不可能覆蓋它.
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 | 等待一個特定的裝置檔案的建立.主要是用作時序和依賴問題. |
OPTIONS | last_rule 對這類裝置終端規則執行; ignore_device 忽略當前規則; ignore_remove 忽略接下來的並移走請求. all_partitions 為所有的磁碟分割槽建立裝置檔案. |
udev一些特殊的值和替換值:
獲取KERNEL等一些基本資訊:
[root/]#udevadm info -a -p /sys/block/sdb
獲取USB資訊:
lsusb sudo apt install hwinfo hwinfo --usb
注意事項:
1、規則檔案的結尾,要有回車符,不然會報錯(檢視是否有回車符,cat -A xxx 或者 od -cb xxx)
2、啟動順序
在zfs匯入池中,一直髮現,匯入硬碟失敗(而建raid的盤是用的syslink生成的SN碼的盤);檢視問題發現:
新增的規則檔案,並沒有放在最小核心裡進行生成,導致了匯入的時候,最小核心裡沒有規則檔案,並沒有生成連線,當然失敗。
檢視檔案:
lsinitrd -f usr/lib/udev/rules.d/60-persistent-storage.rules
果然裡面並沒有新增的規則檔案!
修改方法:
dracut --fstab