|
|
|
|
|
Linux - udev
-
什麼是 udev?
- /dev/fb: frame buffer
- /dev/fd: floppy disks
- /dev/hd: hda 就是 IDE 的硬碟
- /dev/lp: printers (compare lp)
- /dev/par: parallel ports
- /dev/pt: pseudo-terminals (virtual terminals)
- /dev/sd: sda 就是 SCSI 的硬碟. (but also SATA and USB disks)
- scd: SCSI audio-oriented optical disc drives
- sd: SCSI hard disks (also SATA or USB disks)
- sg: SCSI generic devices
- sr: SCSI data-oriented optical disc drives
- st: SCSI magnetic tapes
- /dev/tty: (physical) terminals
- ttyS: ttyS0 就是serial port.
- /dev/null: Accepts and discards all input; produces no output.
- /dev/full: Always full device.
- /dev/loop: loop device
- /dev/zero: Produces a continuous stream of NUL (zero value) characters.
- /dev/random: Produces a variable-length stream of pseudo-random (random in Linux) characters. (Blocking)
- /dev/urandom: Produces a variable-length stream of pseudo-random characters. (Non-Blocking)
-
舊時代的 Linux 2.4 – 2.6.18 採用 /dev/ (devfs) + hotplug
-
從核心 Linux 2.6.15 版後,Linux 全面採用 sysfs 取代過去的 devfs
-
為什麼採用 udev(sysfs)?
- 從前的裝置名稱是固定的 sda 代表第一個 SCSI 的硬碟,但是 udev 可以依據需求將 sda 任意改成你想要的名稱 如:my_first_scsi_disk
- 採用連結(symbolic link)的方式儲存裝置的別名.
- 在 /sys 可以看到依據 id / label / path / uuid 所對應出來的名稱.
- 裝置(device node)的permissions and ownership 也都可以修改.
- 當裝置在連接或移除時,可以執行相對應的程式(script).
- network 裝置可以依需求修改成想要命名的方式.
-
預設命名規則
-
裝置命名方式!!
-
Rule 語法(syntax)
-
基本 Rules
-
比對(Matching) sysfs 屬性(attributes)
-
階層式的裝置名稱
在 /sys 裝置目錄下面裝置是以樹狀結構建立存放的.而且同一個裝置會依據屬性分別屬於不同裝置的子結點,比如一顆硬碟 sda 會分別屬於 /block/ 的子結點和 /devices/pci-bus/ 的子結點.
[root@benjr ~]# udevinfo -ap /sys/block/sda/
Udevinfo starts with the device specified by the devpath and then
walks up the chain of parent devices. It prints for every device
found, all possible attributes in the udev rules key format.
A rule to match, can be composed by the attributes of the device
and the attributes from one single parent device.
looking at device '/block/sda':
KERNEL=="sda"
SUBSYSTEM=="block"
SYSFS{stat}==" 66506 30435 1907086 288822 205862 430773 5092764 11282351 0 1204560 11571133"
SYSFS{size}=="286748000"
SYSFS{removable}=="0"
SYSFS{range}=="16"
SYSFS{dev}=="8:0"
looking at parent device '/devices/pci0000:00/0000:00:1c.2/0000:0c:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0':
ID=="0:0:0:0"
BUS=="scsi"
DRIVER=="sd"
SYSFS{dh_state}=="detached"
SYSFS{ioerr_cnt}=="0x0"
SYSFS{iodone_cnt}=="0x42ea2"
SYSFS{iorequest_cnt}=="0x42ea2"
SYSFS{iocounterbits}=="32"
SYSFS{timeout}=="60"
SYSFS{state}=="running"
SYSFS{rev}=="SB04"
SYSFS{model}=="MBB2147RC "
SYSFS{vendor}=="IBM-ESXS"
SYSFS{scsi_level}=="6"
SYSFS{type}=="0"
SYSFS{queue_type}=="simple"
SYSFS{queue_depth}=="64"
SYSFS{device_blocked}=="0"
looking at parent device '/devices/pci0000:00/0000:00:1c.2/0000:0c:00.0/host0/port-0:0/end_device-0:0/target0:0:0':
ID=="target0:0:0"
BUS==""
DRIVER==""
looking at parent device '/devices/pci0000:00/0000:00:1c.2/0000:0c:00.0/host0/port-0:0/end_device-0:0':
ID=="end_device-0:0"
BUS==""
DRIVER==""
looking at parent device '/devices/pci0000:00/0000:00:1c.2/0000:0c:00.0/host0/port-0:0':
ID=="port-0:0"
BUS==""
DRIVER==""
looking at parent device '/devices/pci0000:00/0000:00:1c.2/0000:0c:00.0/host0':
ID=="host0"
BUS==""
DRIVER==""
looking at parent device '/devices/pci0000:00/0000:00:1c.2/0000:0c:00.0':
ID=="0000:0c:00.0"
BUS=="pci"
DRIVER=="mptsas"
SYSFS{broken_parity_status}=="0"
SYSFS{enable}=="1"
SYSFS{modalias}=="pci:v00001000d00000056sv00001014sd00000306bc01sc00i00"
SYSFS{local_cpus}=="00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000"
SYSFS{irq}=="169"
SYSFS{class}=="0x010000"
SYSFS{subsystem_device}=="0x0306"
SYSFS{subsystem_vendor}=="0x1014"
SYSFS{device}=="0x0056"
SYSFS{vendor}=="0x1000"
looking at parent device '/devices/pci0000:00/0000:00:1c.2':
ID=="0000:00:1c.2"
BUS=="pci"
DRIVER=="pcieport-driver"
SYSFS{broken_parity_status}=="0"
SYSFS{enable}=="1"
SYSFS{modalias}=="pci:v00008086d00002940sv00000000sd00000000bc06sc04i00"
SYSFS{local_cpus}=="00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000"
SYSFS{irq}=="217"
SYSFS{class}=="0x060400"
SYSFS{subsystem_device}=="0x0000"
SYSFS{subsystem_vendor}=="0x0000"
SYSFS{device}=="0x2940"
SYSFS{vendor}=="0x8086"
looking at parent device '/devices/pci0000:00':
ID=="pci0000:00"
BUS==""
DRIVER=="";這些資料對於要寫 rules 是很有用的.你可以依據不同的屬性加以區別出不同的裝置並為各裝置命名!!
-
裝置名稱參數
在設定 rules 如果不同裝置都符合時,那裝置名稱要如何命名呢!!udev 提供幾個參數來使用讓裝置名稱可以依據不同的狀況有多個裝置的產生.最常使用的是 %k 和 %n.
%k 代表是用 kernel 名稱來命名裝置.
比如 /etc/udev/rules.d/50-udev.rules 對光碟裝置的定義.
KERNEL=="hd[a-z]", BUS=="ide", SYSFS{removable}=="1", SYSFS{device/media}=="cdrom", SYMLINK+="cdrom cdrom-%k"
cdrom-%k 如果 kernel 的裝置名稱為 hdc ,udev 名稱就會被命名為 /dev/cdrom-hdc%n 代表是用 number 來命名裝置.
比如 /etc/udev/rules.d/50-udev.rules 對光碟裝置的定義.
KERNEL=="sr[0-9]*", BUS=="scsi", NAME+="scd%n"
NAME+="scd%n" %n 就會依據當時實際的裝置順序來指定.第一個符合的裝置就會是 /dev/scd0 ..參數很有很多請自行參考 udev 的 man page.其中 % 和 $ 都被當作特殊字元所以要真的使用這兩個字元時,用 %% 和 $$ 來取代.
-
Shell 符號比對
-
實例:
有時要設定網卡 IP 時常常會搞不清楚哪個是哪張卡.下面可以看的出來嗎??是我就不行了.

再加上之前遇到一個問題就是網絡介面卡的順序,不知道系統是怎麼偵測的,常常在開關機後順序大亂,寫信詢問 RedHat 他們建議我們可以使用 udev.來為每個裝置個別命名.其實概念很簡單先找出目前的網路卡順序.
[root@benjr ~]# cat /etc/moprobe.conf
alias eth0 tg3
alias eth1 e1000e
alias eth2 e1000e目前我的網卡分別是 Broadcom - eth0 , Intel - eth1/eth2 3(eth0/eth1/eth2)個埠.接下來看一下 eth0 在 udev 儲存了哪些資訊.可以使用指令 "udevinfo" 查看.
[root@benjr ~]# udevinfo -ap /sys/class/net/eth0 Udevinfo starts with the device specified by the devpath and then
walks up the chain of parent devices. It prints for every device
found, all possible attributes in the udev rules key format.
A rule to match, can be composed by the attributes of the device
and the attributes from one single parent device.looking at device '/class/net/eth0':
KERNEL=="eth0"
SUBSYSTEM=="net"
SYSFS{weight}=="64"
SYSFS{tx_queue_len}=="1000"
SYSFS{flags}=="0x1003"
SYSFS{mtu}=="1500"
SYSFS{operstate}=="up"
SYSFS{dormant}=="0"
SYSFS{carrier}=="1"
SYSFS{broadcast}=="ff:ff:ff:ff:ff:ff"
SYSFS{address}=="00:1a:64:22:04:83"
SYSFS{link_mode}=="0"
SYSFS{type}=="1"
SYSFS{features}=="0x1101a9"
SYSFS{ifindex}=="4"
SYSFS{iflink}=="4"
SYSFS{addr_len}=="6"looking at parent device '/devices/pci0000:00/0000:00:1c.1/0000:03:00.0':
SYSFS{broken_parity_status}=="0"
ID=="0000:03:00.0"
BUS=="pci"
DRIVER=="tg3"
SYSFS{enable}=="1"
SYSFS{modalias}=="pci:v000014E4d0000165Asv00001014sd00000378bc02sc00i00"
SYSFS{local_cpus}=="00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000"
SYSFS{irq}=="58"
SYSFS{class}=="0x020000"
SYSFS{subsystem_device}=="0x0378"
SYSFS{subsystem_vendor}=="0x1014"
SYSFS{device}=="0x165a"
SYSFS{vendor}=="0x14e4"looking at parent device '/devices/pci0000:00/0000:00:1c.1':
ID=="0000:00:1c.1"
BUS=="pci"
DRIVER=="pcieport-driver"
SYSFS{broken_parity_status}=="0"
SYSFS{enable}=="1"
SYSFS{modalias}=="pci:v00008086d0000294Asv00000000sd00000000bc06sc04i00"
SYSFS{local_cpus}=="00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000"
SYSFS{irq}=="209"
SYSFS{class}=="0x060400"
SYSFS{subsystem_device}=="0x0000"
SYSFS{subsystem_vendor}=="0x0000"
SYSFS{device}=="0x294a"
SYSFS{vendor}=="0x8086"looking at parent device '/devices/pci0000:00':
ID=="pci0000:00"
BUS==""
DRIVER==""udev 可以依據裝置特性來個別命名,也就是說剛剛的 eth0 MAC 為 "00:1a:64:22:04:83" 我們就可以依據這個裝置所提供的資訊來個別命名我們網路卡.udev 的設定檔存放在 /etc/udev/rules.d/ 系統已經有一個是專門為網路卡預設的檔案 "60-net.rules"
[root@benjr ~]# cd /etc/udev/rules.d/
60-net.rules 式系統預設的 rule
[root@benjr rules.d]# ll
total 248
-rw-r--r-- 1 root root 515 Sep 12 17:34 05-udev-early.rules
-rw-r--r-- 1 root root 920 Dec 11 06:03 40-multipath.rules
-rw-r--r-- 1 root root 15647 Sep 12 17:34 50-udev.rules
-rw-r--r-- 1 root root 163 Dec 4 05:32 51-dlm.rules
-rw-r--r-- 1 root root 471 Sep 12 17:34 51-hotplug.rules
-rw-r--r-- 1 root root 58016 Oct 13 2006 60-libsane.rules
-rw-r--r-- 1 root root 143 Nov 13 23:48 60-net.rules
-rw-r--r-- 1 root root 1088 Jul 18 2006 60-pcmcia.rules
-rw-r--r-- 1 root root 452 Nov 26 07:15 60-raw.rules
-rw-r--r-- 1 root root 8209 Sep 22 22:39 60-wacom.rules
-rw-r--r-- 1 root root 129 Sep 10 00:11 61-uinput-stddev.rules
-rw-r--r-- 1 root root 214 Sep 10 00:11 61-uinput-wacom.rules
-rw-r--r-- 1 root root 1823 Sep 19 06:20 85-pcscd_ccid.rules
-rw-r--r-- 1 root root 114 Aug 29 2008 90-alsa.rules
-rw-r--r-- 1 root root 61 Sep 12 17:34 90-dm.rules
-rw-r--r-- 1 root root 82 Oct 10 21:20 90-hal.rules
-rw-r--r-- 1 root root 331 Oct 15 00:08 90-ib.rules
-rw-r--r-- 1 root root 107 Sep 12 17:34 95-pam-console.rules
-rw-r--r-- 1 root root 292 Dec 10 03:27 98-kexec.rules
-rw-r--r-- 1 root root 2319 Jul 9 2008 bluetooth.rules
-rw-r--r-- 1 root root 590 Dec 19 02:16 xen-backend.rules
好的我們現在就依 "udevinfo" 所提供的資訊進行裝置名稱改變,我會依據系統的 driver 和 PCI Bus 順序來為我的網卡命名.還記得 eth0 的資訊嗎?
ID=="0000:03:00.0"
DRIVER=="tg3"
其他 eth1 /eth2 都是使用同樣的方法 "udevinfo" 查出 ID 和 Driver[root@benjr rules.d]# vi 60-net.rules
ACTION=="add", SUBSYSTEM=="net", IMPORT{program}="/lib/udev/rename_device"
SUBSYSTEM=="net", RUN+="/etc/sysconfig/network-scripts/net.hotplug"
DRIVER=="tg3", ID=="0000:03:00.0", NAME="BCM1"
DRIVER=="e1000e", ID=="0000:09:00.0", NAME="INTEL0"
DRIVER=="e1000e", ID=="0000:09:00.1", NAME="INTEL1"重新將模組移除和載入.
[root@benjr rules.d]# rmmod tg3
[root@benjr rules.d]# rmmod e1000e
[root@benjr rules.d]# modprobe tg3
[root@benjr rules.d]# modprobe e1000e
[root@benjr rules.d]# ifconfig -a|grep -i HWaddr
BCM1 Link encap:Ethernet HWaddr 00:1A:64:22:04:83
INTEL0 Link encap:Ethernet HWaddr 00:15:17:78:5D:D6
INTEL1 Link encap:Ethernet HWaddr 00:15:17:78:5D:D7
virbr0 Link encap:Ethernet HWaddr 00:00:00:00:00:00你會發現名稱都依據你的需求改變了. 當然方式是千千萬萬種你也可以依據 MAC Address 的方式作依據.
#KERNEL=="eth*", SYSFS{address}=="00:1a:64:22:04:83", NAME="BCM1"
不過工作還沒完成在 /etc/sysconfig/network-scripts/ 目錄下還是有之前儲存下來的裝置名稱,可以用手動方式移除修改或是用 #system-config-network 來修改!!
如果使用 RHEL 時遇到相關問題可以在 http://kbase.redhat.com/faq/en 先做搜尋.
老實說是最近遇到一個問題 "網絡介面卡的順序與名稱" 才開始接觸 udev 這個東西的,雖然他在 kernel 2.6.15 就開始使用了.目前我的 RHEL5 已經用到 kernel 2.6.18,先來看一下 devfs(dev) 和 sysfs(udev) 的不同.
有上過 Linux 課的,還記得老師的第一句話就是 Linux 下所有的東西都是以檔案的模式存在,這也包括了硬體裝置.
所以在最早的 Linux 裝置通通存放在 /dev/ 目錄下,名稱的命名很簡單.
其他的虛擬裝置 (Pseudo-devices)
使用者如果要對硬體進行存取,很簡單的只要針對 /dev/ 檔案作存取即可.但是缺點就是系統一開始就必須先將所以的裝置先預備好.假如你的系統明明只有一顆硬碟 sda 但是 /dev/ 目錄下可早就已經預備好了 sdb , sdc .... 不同的硬碟裝置在做準備.所以 /dev/ 會相當龐大,都是因為儲存了一些不是真實存在的裝置.
在核心 Linux 2.4–2.6.18 ,devfs(device file system) 這樣的模式就是將所有的裝置沒有規則可循的直接存放在 /dev/ 目錄下面加上動態可以偵測 USB 裝置的 hotplug.devfs 所有的裝置都必須在關機狀態才能才能插上裝置,但是因為USB 裝置的產生.Linux 使用一種 hotplug 來動態增減裝置,但是實際上 /dev/ 目錄還是一開始就必須有相對應的裝置才可以.
/dev/ 的文件都是以靜態的方式存在,如果系統的裝置不夠用時還需要自行增加(#mknod).加上所有的 device 都有它的 [MAJOR MINOR] number 至於 number 要怎麼看請自行參考裝置的參數表 /usr/src/linux-kernel-version/Documentation/devices.txt 使用上不是很方便,所以在 2.6.15 kernel 就採用了 udev 的方式.
裝置還是存放在 /dev/ 目錄下但是多了一個 /sys/ 的目錄存放動態設備節點 udev (sysfs)
優點是 /dev/ 不再需要預先產生很多不必要的裝置.有需要時系統在自行產生.udev則提供了,並以規則式的方式來存放.
參考文件:
http://reactivated.net/writing_udev_rules.html
因為 udev(sysfs) 採用比較彈性而且較有效的方式管理 /dev/ 裝置,所以 Linux 在 2.6.15 kernel 之後採用了 udev(sysfs) .原因很多大可以瓜括下面幾個:
系統已經有一套規則命名所有的裝置,而且很好懂.基本上我們除非有特別需求其實是不用再去修改規則.比如在 /dev/disk 就代表所有的硬碟裝置,依 id / label / path / uuid 規則的擺放.
| [root@benjr ~]# ll -lR /dev/disk/ /dev/disk/: total 0 drwxr-xr-x 2 root root 100 Mar 13 03:43 by-id drwxr-xr-x 2 root root 60 Mar 13 03:43 by-label drwxr-xr-x 2 root root 120 Mar 13 03:43 by-path drwxr-xr-x 2 root root 60 Mar 13 03:43 by-uuid /dev/disk/by-id: /dev/disk/by-label: /dev/disk/by-path: /dev/disk/by-uuid: |
你可以看到光是一個硬碟就又這麼完整的方式來呈現,其中大部分都是連結(symbolic link)的方式儲存裝置的別名並對應到真實的裝置名稱.
如: boot -> ../../sda1 就很清楚知道 boot 這個 partition 是在 sda1 上面.
前面有提到裝置名稱可以依據需要自行命名,加上系統有一套預設的命名規則.而這些規則都是存放在目錄 /etc/udev/rules.d 下.所有的檔名都必須以 .rules 為結尾!!
先來看看預設的 udev rules 檔案在 /etc/udev/rules.d/50-udev.rules不過不建議將你新的 rules 直接寫在這一個檔案,你可以自行產生新的 rules 檔.
還有一點前面的 50-udev.rules "50"(16 位元的數字) 數字是有其用意的,系統會依據數字的大小依序執行,所以你要新增的 rule 已經登錄在 50-udev.rules 時
你要產生的 rules 數是就要比 50-udev.rules 要小比如 /etc/udev/rules.d/10-local.rules.
在撰寫 rule 時需一段完成,不可使用分段撰寫,可以使用 "#" 來當注釋.
我們來看一下 /etc/udev/rules.d/50-udev.rules 對 cdrom / dvdrom 光碟裝置的定義
| [root@benjr ~]# cat /etc/udev/rules.d/50-udev.rules # old compat symlinks with enumeration KERNEL=="sr[0-9]*", SYMLINK+="cdrom cdrom-%k" KERNEL=="scd[0-9]*", SYMLINK+="cdrom cdrom-%k" KERNEL=="pcd[0-9]*", SYMLINK+="cdrom cdrom-%k" KERNEL=="hd[a-z]", BUS=="ide", SYSFS{removable}=="1", SYSFS{device/media}=="cdrom", SYMLINK+="cdrom cdrom-%k" KERNEL=="hd[a-z]", BUS=="ide", SYSFS{removable}=="1", PROGRAM=="check-cdrom.sh %k DVD", SYMLINK+="dvd dvd-%k" KERNEL=="hd[a-z]", BUS=="ide", SYSFS{removable}=="1", PROGRAM=="check-cdrom.sh %k CD-R", SYMLINK+="cdwriter cdwriter-%k cdrw cdrw-%k" KERNEL=="hd[a-z]", BUS=="ide", SYSFS{removable}=="1", PROGRAM="check-cdrom.sh %k DVD-R", SYMLINK+="dvdwriter dvdwriter-%k dvdrw dvdrw-%k" |
可以看到光是 cdrom / dvdrom 光碟裝置或是其他相關的裝置都被命名成不同的裝置名稱.
目前我系統上有兩個光碟裝置(),光是符合上面的 rules 所產生的裝置就會這麼多了!!不過他們最終的連結還是會連結到 cdrom / dvdrom 真實的裝置.
| [root@benjr mnt]# ll /dev/cd* lrwxrwxrwx 1 root root 4 Mar 20 05:46 /dev/cdrom -> scd0 lrwxrwxrwx 1 root root 3 Mar 17 01:23 /dev/cdrom-hdc -> hdc lrwxrwxrwx 1 root root 4 Mar 20 05:46 /dev/cdrom-sr0 -> scd0 lrwxrwxrwx 1 root root 4 Mar 20 05:46 /dev/cdrw -> scd0 lrwxrwxrwx 1 root root 4 Mar 20 05:46 /dev/cdrw-sr0 -> scd0 lrwxrwxrwx 1 root root 4 Mar 20 05:46 /dev/cdwriter -> scd0 lrwxrwxrwx 1 root root 4 Mar 20 05:46 /dev/cdwriter-sr0 -> scd0 |
所以不管你為這裝置設了多少 rules (可以在同一個檔案或是不同的檔案)來定義 cdrom /dvdrom 系統都會加以產生.
剛剛我們看到 rules 的撰寫但是其中寫了很多的規則,系統是依據什麼做比對呢!!現在我們直接用 udev 提供的程式 udevinfo 來看 /sys/block/hdc 的光碟裝置(這是我實體的光碟裝置位置,可能會跟你的不盡相同).
| [root@benjr ~]# udevinfo -ap /sys/block/hdc Udevinfo starts with the device specified by the devpath and then walks up the chain of parent devices. It prints for every device found, all possible attributes in the udev rules key format. A rule to match, can be composed by the attributes of the device and the attributes from one single parent device. looking at device '/block/hdc': looking at parent device '/devices/ide1/1.0': looking at parent device '/devices/ide1': |
筆對一下 /etc/udev/rules.d/50-udev.rules 哪一些是符合上面條件的
KERNEL=="hd[a-z]", BUS=="ide", SYSFS{removable}=="1", SYSFS{device/media}=="cdrom", SYMLINK+="cdrom cdrom-%k"
KERNEL=="hd[a-z]", BUS=="ide", SYSFS{removable}=="1", PROGRAM=="check-cdrom.sh %k DVD", SYMLINK+="dvd dvd-%k"
KERNEL=="hd[a-z]", BUS=="ide", SYSFS{removable}=="1", PROGRAM=="check-cdrom.sh %k CD-R", SYMLINK+="cdwriter cdwriter-%k cdrw cdrw-%k"
KERNEL=="hd[a-z]", BUS=="ide", SYSFS{removable}=="1", PROGRAM="check-cdrom.sh %k DVD-R", SYMLINK+="dvdwriter dvdwriter-%k dvdrw dvdrw-%k"
目前只有第一個符合,因為其他的會去執行程式 check-cdrom.sh 檢查是否符合條件.
check-cdrom.sh 會去檢查檔案 /proc/sys/dev/cdrom/info ,有興趣的可以看這個 bash file(/lib/udev/check-cdrom.sh)
他既不是 DVD / Cd-R / DVD-R 等裝置.
| [root@benjr mnt]# cat /proc/sys/dev/cdrom/info CD-ROM information, Id: cdrom.c 3.20 2003/12/17 drive name: hdc |
所以系統只會幫我們產生 /dev/cdrom 和 /dev/cdrom-hdc
| [root@benjr ~]# ll /dev/cdrom* lrwxrwxrwx 1 root root 3 Mar 22 03:17 /dev/cdrom -> hdc lrwxrwxrwx 1 root root 3 Mar 22 03:17 /dev/cdrom-hdc -> hdc |
前面使用過 udevinfo 看裝置的訊息時裡面最常被拿來配對(match)的 udev 的基本 Rules 有下面幾種.
* KERNEL - kernel 對於裝置會有一個預設名稱如第一顆 IDE 硬碟名稱就是 hda,第一個乙太網路就是 eth0 .
* SUBSYSTEM - 通常會指出這是什麼裝置硬碟就是 block,乙太網路就是 net.
* DRIVER - driver 當然就是這個裝置是靠哪一個 driver(module) 在運作的.
udev 要在命名裝置時有兩種方式 NAME 和 SYMLINK.
* NAME - 會產生唯一裝置名稱出來.
* SYMLINK - 是一個連結到真實裝置的 symbolic links.
雖然 udev 會產生很多符合 rules 的裝置名稱出來但裡面只有一個是真的裝置(使用 NAME)其他的都是連結(symbolic link),而且 SYMLINK 沒有個數的限制.常見的基本 rules 範例如下:
KERNEL=="hdb", NAME="my_spare_disk"
系統會找到符合 KERNEL 為 hdb 裝置,並產生這個裝置為 /dev/my_spare_disk.之後你就可以使用 /dev/my_spare_disk 取代原本的 /dev/hdb.
KERNEL=="hdb", DRIVER=="ide-disk", SYMLINK+="sparedisk"
系統會找到符合KERNEL 為 hdb 裝置而且 driver(module) 是 ide-disk 的.當沒有指定 NAME 時系統會自動產生一個預設的裝置還會多出一個指定連結 /dev/sparedisk 出來.
KERNEL=="hdc", SYMLINK+="cdrom cdrom0"
當然 SYMLINK 可以同時指定多個名稱出來,SYMLINK+="cdrom cdrom0" 就會產生連結到 /dev/hdc(系統預設的) 的 /dev/cdrom 和 /dev/cdrom0.
使用 udevinfo 看得到的最多的資訊就是 SYSFS{key}.
| [root@benjr ~]# udevinfo -ap /sys/block/hdc Udevinfo starts with the device specified by the devpath and then walks up the chain of parent devices. It prints for every device found, all possible attributes in the udev rules key format. A rule to match, can be composed by the attributes of the device and the attributes from one single parent device. looking at device '/block/hdc': looking at parent device '/devices/ide1/1.0': looking at parent device '/devices/ide1': |
SYSFS 是存在 /sys 的一個檔案值,如 SYSFS{dev} 就是儲存在 /sys/block/hdc/dev .這個值也是可以拿來比對(matching)的條件,不過在使用上和一般 Rules 一樣. 比如 /etc/udev/rules.d/50-udev.rules 就使用了 SYSFS{removable}=="1", SYSFS{device/media}=="cdrom" 當做比對條件.
KERNEL=="hd[a-z]", BUS=="ide", SYSFS{removable}=="1", SYSFS{device/media}=="cdrom", SYMLINK+="cdrom cdrom-%k"
為了讓比對能夠精簡你可以用下面 3 個符號來指定.這3個就是一般我們使用 Linux Shell 常見的符號
* - 符合所以的字元可以是 0 個也可以是多個.
如 : KERNEL=="ttyUSB*" 就代表只要是 ttyUSB 開頭的都可以
? - 符合這一個字元的
如 : KERNEL=="ttyUSB?" 就代表只要是 ttyUSB 開頭然後多一個字元的皆可
[] - 符合[]內指定的任何一個字元.
如 : KERNEL=="hd[a-z]" 就代表 hda,hdb...一直到 hdz
-
- sunchiahome's blog
- 增加新的回應
- 瀏覽次數 4953