udev
udev stands for “userspace implementation of devfs”,也就是說 udev 是在 userspace 下的 device file system 的實作。(從 Linux 2.6 kernel 開始實作)
udev 可以利用裝置的屬性,例如: vender ID, device ID,來動態識別裝置,並為裝置建立一個具有一致性且專屬的名稱。
udev 允許以定義 rules 的方式,來對同一個裝置設定同一個名稱,不管這個裝置是否有連接在 port 上。
Overview
udev 包含一部分的 kernel services 及 udevd daemon。
當特定的 events 發生時,kernel 會通知 udevd daemon,而 udevd daemon 則被設定為會對這些特定的 events 作出適當的回應。
這些特定的 events 從 kernel 發出來,適當的回應發生在 userspace,而對這些特定 events 的回應方式,則是以設定 "rules" 的方式來實作。
udev 在 userspace 的功能實作在 systemd-udevd.service,它的 config file 位於 /etc/udev/udev.conf。
"rules" 的檔案則是位於 /etc/udev/rules.d/, /run/udev/rules.d/ 及 /usr/lib/udev/rules.d/ 資料夾下。
安裝 packages 時,packages 的 rule 會安裝在 /usr/lib/udev/rules.d/。
如果有相同檔名的 "rules" 存在於上述的資料夾中,則後者的檔案會被忽略,只要檔案是以 ".rules" 為結尾,就會被以字母為順序來解析。
當 config file 或 rules 有變動時,需要利用 udevadm 程式來要告知 systemd-udevd 更新 rules。
udev 主要的功能是用來回應熱插拔類型的 events,很多文件中提到 udev 是用來對這些新出現的裝置產生 device file,但 udev 其實更為通用,針對新出現的裝置或其它任何 event,udev 可以執行任何在 userspace 的指令。
udevd 的執行時機:
1、剛開機完成時,udevd 會先解析所有的 config 及 rules 檔案,接著在記憶體中產生一個 rules 資料庫。
2、當有 event 發生時,udev 會比對 rules 資料庫,如果符合 rule 指令的條件,就執行 rule 指定的動作。
Rules
rule 的規則:
1、rule 的內容限定在同一行,除非以 \ 作切割。
2、rule 包含 "matches" 及 "actions"。
3、"matches" 及 "actions" 的型式都是 "key" "operator" "value"。
4、"matches" 的 operator 有 "==" 及 "!="。
5、"actions" 的 operator 為 "="、 "+="、"-="、":="。
6、"matches" 用來辨別 event 的一個或一個以上的屬性是否符合。
7、"actions" 指定如果 "matches" 完全符合的話,要執行的動作。
8、"matches" 的範例: BUS=="usb"
9、"actions" 的範例: NAME="mydev"
10、 rule 的範例 1: (如果該 Device Node 的 KERNEL 值符合 "sd*[0-9]|dasd*[0-9]",且 ENV{ID_SERIAL} 有值,則增加 symbolic link。)
KERNEL=="sd*[0-9]|dasd*[0-9]", ENV{ID_SERIAL}=="?*", \
SYMLINK+="disk/by-id/$env{ID_BUS}-$env{ID_SERIAL}-part%n"
11、rule 的範例 2: (如果該 Device Node 的 device path 中,有任一 KERNELS 的值符合,則對該 Device Node 增加 symbolic link。)
KERNELS=="1-1:1.0", SYMLINK+="usb_dev1"
KERNELS=="2-1:1.0", SYMLINK+="usb_dev2"
KERNELS=="5-1:1.0", SYMLINK+="usb_dev3"
12、所有的 "matches" 都要符合,"actions" 才會執行。
13、愈早解析到的 rule ,其優先權愈高,所以客製化的 rule 擺得愈前面愈好。
14、key="value" 的 action,會重新設定 key 值。
15、key+="value" 的 action,會增加要執行的動作, 也就是說: SYMLINK+="foo" 指的是 "除了要對這個 event 所執行的所有動作之外,額外增加一個名稱為 foo 的 symbolic link"。
Rules 群
1、就算 rules 分別定義在不同的檔案中,但是所有的 rules 最終都會統一放在一起。
2、在這些放在一起的 rules 中,有一個組織結構上的設定,稱為 "label",用來和 GOTO 動作一起使用。
3、舉例來說,label 可以設定為: LABEL="persistent_storage_end",則 rule 的執行會從以下的 rule 跳到此 rule:
ACTION!="add", GOTO="persistent_storage_end"
4、GOTO 的使用通常會限定在同一個檔案,如果跨檔案的話,則需要把檔案排序納入考量。
5、使用 GOTO 指令,不要跳到之前的 label,否則可能有造成無窮迴圈的風險。
6、可以利用初期會執行的 rules 在 ENV 空間建立變數,之後執行的 rules,就可以使用這些變數。
7、如果要動態建立 rules,也是可以做到的。
8、如果 kernel event 有比對到符合的 rule 條件,在執行完相對的回應後,仍然會繼續比對剩餘的 rules,不會停止。
建立 rules 以對同一個 device 產生一致的 device name
舉例來說,如果要對一張 3G 網卡設定一致的 device name,而不管它是在何時接在哪個接口的話,可以利用比對它的 attributes,建立 symbolic link 來達到。
第一步,先插上 3G 網卡。
第二步,在3G 網卡的裝置上執行以下指令,這個指令會顯示該裝置的 attributes:
$ udevadm info --name=/dev/ttyS1 --attribute-walk
looking at parent device '/devices/pci0000:00/0000:00:1e.0/0000:15:00.0/0.0':
KERNELS=="0.0"
SUBSYSTEMS=="pcmcia"
DRIVERS=="serial_cs"
ATTRS{modalias}=="pcmcia:m00A4c1AAFf02fn00pfn00pa32607776pbD9E73B13pcAF9C4D7Fpd00000000"
ATTRS{prod_id3}=="NRM6831"
ATTRS{prod_id2}=="Merlin UMTS Modem"
ATTRS{prod_id1}=="Novatel Wireless"
ATTRS{card_id}=="0x1aaf"
ATTRS{manf_id}=="0x00a4"
ATTRS{func_id}=="0x02"
ATTRS{pm_state}=="on"
ATTRS{function}=="0x00"
在 rule 用來比對的條件,就可以從這些 attributes 中尋找。
第三步,在 /etc/udev/rules.d 下,建立 rule 檔案,名稱為: z21_persistent-local.rules。
ATTRS{prod_id2}=="Merlin UMTS Modem", ATTRS{prod_id1}=="Novatel Wireless", SYMLINK+="MerlinUMTS"
## Alternatively we could use :
# ATTRS{card_id}=="0x1aaf", ATTRS{manf_id}=="0x00a4", SYMLINK+="MerlinUMTS"
第四步,強制使此 rule 生效:(或重開機)
$ udevadm control --reload-rules
$ udevadm test -a -p $(udevadm info -q path -n /dev/ttyS1)
udevadm 是 udev 管理工具 (management tool),詳細的使用方式及意義可以利用:
$ man udevadm
來作進一步的瞭解。
補充
列出目前所有 storage 的 Device Node:
$ ls -l /sys/class/block/sd*
lrwxrwxrwx 1 root root 0 11月 21 05:12 /sys/class/block/sda -> ../../devices/platform/fc800000.usb/usb1/1-1/1-1:1.0/host1/target1:0:0/1:0:0:0/block/sda
lrwxrwxrwx 1 root root 0 11月 21 05:12 /sys/class/block/sda1 -> ../../devices/platform/fc800000.usb/usb1/1-1/1-1:1.0/host1/target1:0:0/1:0:0:0/block/sda/sda1
查詢 Device Node 的 sys 路徑:
$ udevadm info -q path -n /dev/sda1
/devices/platform/fc800000.usb/usb1/1-1/1-1:1.0/host1/target1:0:0/1:0:0:0/block/sda
在 udevadm 的 manual 有對 NAME 作說明如下:
udev supplies the system software with device events, manages permissions of device nodes and may create additional symlinks in the /dev directory, or renames network interfaces.
意思是如果 Device Node 是 Network Interface 的話,則可以修改名稱,否則,無法修改名稱,只能在 /dev/ 下,增加 symbolic link。
Reference
udev - Linux dynamic device management
文字內容 或 影像內容 部份參考、引用自網路,如有侵權,請告知。
留言列表