1. 程式人生 > 其它 >【轉】Linux Udev 規則

【轉】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