如果你使用Linux比較長時間了,那你就知道,在對待設備文件這塊,Linux改變了幾次策略。在Linux早期,設備文件僅僅是是一些帶有適當?shù)膶傩约钠胀ㄎ募蒻knod命令創(chuàng)建,文件存放在/dev目錄下。后來,采用了devfs,一個基于內(nèi)核的動態(tài)設備文件系統(tǒng),他首次出現(xiàn)在2.3.46 內(nèi)核中。Mandrake,Gentoo等Linux分發(fā)版本采用了這種方式。devfs創(chuàng)建的設備文件是動態(tài)的。但是devfs有一些嚴重的限制,從 2.6.13版本后移走了。目前取代他的便是文本要提到的udev--一個用戶空間程序。
目前很多的Linux分發(fā)版本采納了udev的方式,因為它在Linux設備訪問,特別是那些對設備有極端需求的站點(比如需要控制上千個硬盤)和熱插拔設備(比如USB攝像頭和MP3播放器)上解決了幾個問題。下面我我們來看看如何管理udev設備。
實際上,對于那些為磁盤,終端設備等準備的標準配置文件而言,你不需要修改什么。但是,你需要了解udev配置來使用新的或者外來設備,如果不修改配置,這些設備可能無法訪問,或者說Linux可能會采用不恰當?shù)拿郑瑢俳M或權限來創(chuàng)建這些設備文件。你可能也想知道如何修改RS-232串口,音頻設備等文件的屬組或者權限。這點在實際的Linux實施中是會遇到的。
為什么使用udev
在此之前的設備文件管理方法(靜態(tài)文件和devfs)有幾個缺點:
* 不確定的設備映射。特別是那些動態(tài)設備,比如USB設備,設備文件到實際設備的映射并不可靠和確定。舉一個例子:如果你有兩個USB打印機。一個可能稱為 /dev/usb/lp0,另外一個便是/dev/usb/lp1。但是到底哪個是哪個并不清楚,lp0,lp1和實際的設備沒有一一對應的關系,因為他可能因為發(fā)現(xiàn)設備的順序,打印機本身關閉等原因而導致這種映射并不確定。理想的方式應該是:兩個打印機應該采用基于他們的序列號或者其他標識信息的唯一設備文件來映射。但是靜態(tài)文件和devfs都無法做到這點。
*沒有足夠的主/輔設備號。我們知道,每一個設備文件是有兩個8位的數(shù)字:一個是主設備號 ,另外一個是輔設備號來分配的。這兩個8位的數(shù)字加上設備類型(塊設備或者字符設備)來唯一標識一個設備。不幸的是,關聯(lián)這些身邊的的數(shù)字并不足夠。
*/dev目錄下文件太多。一個系統(tǒng)采用靜態(tài)設備文件關聯(lián)的方式,那么這個目錄下的文件必然是足夠多。而同時你又不知道在你的系統(tǒng)上到底有那些設備文件是激活的。
*命名不夠靈活。盡管devfs解決了以前的一些問題,但是它自身又帶來了一些問題。其中一個就是命名不夠靈活;你別想非常簡單的就能修改設備文件的名字。缺省的devfs命令機制本身也很奇怪,他需要修改大量的配置文件和程序。;
*內(nèi)核內(nèi)存使用,devfs特有的另外一個問題是,作為內(nèi)核驅動模塊,devfs需要消耗大量的內(nèi)存,特別當系統(tǒng)上有大量的設備時(比如上面我們提到的系統(tǒng)一個上有好幾千磁盤時)
udev的目標是想解決上面提到的這些問題,他通采用用戶空間(user-space)工具來管理/dev/目錄樹,他和文件系統(tǒng)分開。知道如何改變?nèi)笔∨渲媚茏屇阒笕绾味ㄖ谱约旱南到y(tǒng),比如創(chuàng)建設備字符連接,改變設備文件屬組,權限等。
udev配置文件
主要的udev配置文件是/etc/udev/udev.conf。這個文件通常很短,他可能只是包含幾行#開頭的注釋,然后有幾行選項:
udev_root="/dev/"udev_rules="/etc/udev/rules.d/"udev_log="err"
上面的第二行非常重要,因為他表示udev規(guī)則存儲的目錄,這個目錄存儲的是以.rules結束的文件。每一個文件處理一系列規(guī)則來幫助udev分配名字給設備文件以保證能被內(nèi)核識別。
你的/etc/udev/rules.d下面可能有好幾個udev規(guī)則文件,這些文件一部分是udev包安裝的,另外一部分則是可能是別的硬件或者軟件包生成的。比如在Fedora Core 5系統(tǒng)上,sane-backends包就會安裝60-libsane.rules文件,另外initscripts包會安裝60-net.rules文件。這些規(guī)則文件的文件名通常是兩個數(shù)字開頭,它表示系統(tǒng)應用該規(guī)則的順序。
規(guī)則文件里的規(guī)則有一系列的鍵/值對組成,鍵/值對之間用逗號(,)分割。每一個鍵或者是用戶匹配鍵,或者是一個賦值鍵。匹配鍵確定規(guī)則是否被應用,而賦值鍵表示分配某值給該鍵。這些值將影響udev創(chuàng)建的設備文件。賦值鍵可以處理一個多值列表。
規(guī)則說明
1、udev 規(guī)則的所有操作符
“==”:比較鍵、值,若等于,則該條件滿足;
“!=”:? 比較鍵、值,若不等于,則該條件滿足;
“=”:? 對一個鍵賦值;
“+=”:為一個表示多個條目的鍵賦值。
“:=”:對一個鍵賦值,并拒絕之后所有對該鍵的改動。目的是防止后面的規(guī)則文件對該鍵賦值。
2、udev 規(guī)則的匹配鍵
ACTION:? ? 事件 (uevent) 的行為,例如:add( 添加設備 )、remove( 刪除設備 )。
KERNEL:? 內(nèi)核設備名稱,例如:sda, cdrom。
DEVPATH:??設備的 devpath 路徑。
SUBSYSTEM:? ?設備的子系統(tǒng)名稱,例如:sda 的子系統(tǒng)為 block。
BUS:? ?設備在 devpath 里的總線名稱,例如:usb。
DRIVER:? ? ?設備在 devpath 里的設備驅動名稱,例如:ide-cdrom。
ID: ?設備在 devpath 里的識別號。
SYSFS{filename}:? 設備的 devpath 路徑下,設備的屬性文件“filename”里的內(nèi)容。
例如:SYSFS{model}==“ST936701SS”表示:如果設備的型號為 ST936701SS,則該設備匹配該 匹配鍵。
在一條規(guī)則中,可以設定最多五條 SYSFS 的 匹配鍵。
ENV{key}:? ? ?環(huán)境變量。在一條規(guī)則中,可以設定最多五條環(huán)境變量的 匹配鍵。
PROGRAM:調(diào)用外部命令。
RESULT:? ?外部命令 PROGRAM 的返回結果。
3、udev 的重要賦值鍵
NAME:在 /dev下產(chǎn)生的設備文件名。只有第一次對某個設備的 NAME 的賦值行為生效,之后匹配的規(guī)則再對該設備的 NAME 賦值行為將被忽略。如果沒有任何規(guī)則對設備的 NAME 賦值,udev 將使用內(nèi)核設備名稱來產(chǎn)生設備文件。
SYMLINK:?為 /dev/下的設備文件產(chǎn)生符號鏈接。由于 udev 只能為某個設備產(chǎn)生一個設備文件,所以為了不覆蓋系統(tǒng)默認的 udev 規(guī)則所產(chǎn)生的文件,推薦使用符號鏈接。
OWNER, GROUP, MODE:為設備設定權限。
ENV{key}:導入一個環(huán)境變量。
4、udev 的值和可調(diào)用的替換操作符
Linux 用戶可以隨意地定制 udev 規(guī)則文件的值。例如:my_root_disk, my_printer。同時也可以引用下面的替換操作符:
$kernel, %k:設備的內(nèi)核設備名稱,例如:sda、cdrom。
$number, %n:?設備的內(nèi)核號碼,例如:sda3 的內(nèi)核號碼是 3。
$devpath, %p:設備的 devpath路徑。
$id, %b:設備在 devpath里的 ID 號。
$sysfs{file}, %s{file}:??設備的 sysfs里 file 的內(nèi)容。其實就是設備的屬性值。
$env{key}, %E{key}:一個環(huán)境變量的值。
$major, %M:設備的 major 號。
$minor %m:設備的 minor 號。
$result, %c:PROGRAM 返回的結果。
$parent, %P:? ?父設備的設備文件名。
$root, %r:?udev_root的值,默認是 /dev/。
$tempnode, %N:臨時設備名。
%%:符號 % 本身。
$$:符號 $ 本身。
給出一個列子來解釋如何使用這些鍵,下面的例子來自Fedora Core 5系統(tǒng)的標準配置文件:
KERNEL=="*", OWNER="root" GROUP="root", MODE="0600"KERNEL=="tty", NAME="%k", GROUP="tty", MODE="0666", OPTIONS="last_rule"KERNEL=="scd[0-9]*", SYMLINK+="cdrom cdrom-%k"KERNEL=="hd[a-z]", BUS=="ide", SYSFS{removable}=="1", SYSFS{device/media}=="cdrom", SYMLINK+="cdrom cdrom-%k"ACTION=="add", SUBSYSTEM=="scsi_device", RUN+="/sbin/modprobe sg"
上面的例子給出了5個規(guī)則,每一個都是KERNEL或者ACTION鍵開頭:
*第一個規(guī)則是缺省的,他匹配任意被內(nèi)核識別到的設備,然后設定這些設備的屬組是root,組是root,訪問權限模式是0600(-rw-------)。這也是一個安全的缺省設置保證所有的設備在默認情況下只有root可以讀寫。
*第二個規(guī)則也是比較典型的規(guī)則了。它匹配終端設備(tty),然后設置新的權限為0600,所在的組是tty。它也設置了一個特別的設備文件名:%K。在這里例子里,%k代表設備的內(nèi)核名字。那也就意味著內(nèi)核識別出這些設備是什么名字,就創(chuàng)建什么樣的設備文件名。
*第三行開始的KERNEL=="scd[0-9]*",表示 SCSI CD-ROM 驅動. 它創(chuàng)建一對設備符號連接:cdrom和cdrom-%k。
*第四行,開始的 KERNEL=="hd[a-z]", 表示ATA CDROM驅動器。這個規(guī)則創(chuàng)建和上面的規(guī)則相同的符號連接。ATA CDROM驅動器需要sysfs值以來區(qū)別別的ATA設備,因為SCSI CDROM可以被內(nèi)核唯一識別。.
*第五行以 ACTION=="add"開始,它告訴udev增加 /sbin/modprobe sg 到命令列表,當任意SCSI設備增加到系統(tǒng)后,這些命令將執(zhí)行。其效果就是計算機應該會增加sg內(nèi)核模塊來偵測新的SCSI設備。
當然,上面僅僅是一小部分例子,如果你的系統(tǒng)采用了udev方式,那你應該可以看到更多的規(guī)則。如果你想修改設備的權限或者創(chuàng)建信的符號連接,那么你需要熟讀這些規(guī)則,特別是要仔細注意你修改的那些與之相關的設備。
修改你的udev配置
在修改udev配置之前,我們一定要仔細,通常的考慮是:你最好不要修改系統(tǒng)預置的那些規(guī)則,特別不要指定影響非常廣泛的配置,比如上面例子中的第一行。不正確的配置可能會導致嚴重的系統(tǒng)問題或者系統(tǒng)根本就無法這個正確的訪問設備。
而我們正確的做法應該是在/etc/udev/rules.d/下創(chuàng)建一個信的規(guī)則文件。確定你給出的文件的后綴是rules文件名給出的數(shù)字序列應該比標準配置文件高。比如,你可以創(chuàng)建一個名為99-my-udev.rules的規(guī)則文件。在你的規(guī)則文件中,你可以指定任何你想修改的配置,比如,假設你修改修改floppy設備的所在組,還準備創(chuàng)建一個信的符號連接/dev/floppy,那你可以這么寫:
KERNEL=="fd[0-9]*", GROUP="users", SYMLINK+="floppy"
有些發(fā)行版本,比如Fedora,采用了外部腳本來修改某些特定設備的屬組,組關系和權限。因此上面的改動可能并不見得生效。如果你遇到了這個問題,你就需要跟蹤和修改這個腳本來達到你的目的。或者你可以修改PROGRAM或RUN鍵的值來做到這點。
某些規(guī)則的修改可能需要更深的挖掘。比如,你可能想在一個設備上使用sysfs信息來唯一標識一個設備。這些信息最好通過udevinfo命令來獲取。
$?udevinfo –a –p $(udevinfo –q path –n /dev/hda)
上面的命令兩次使用udevinfo:一次是返回sysfs設備路徑(他通常和我們看到的Linux設備文件名所在路徑--/dev/hda--不同);第二次才是查詢這個設備路徑,結果將是非常常的syfs信息匯總。你可以找到最夠的信息來唯一標志你的設備,你可以采用適當?shù)奶鎿Qudev配置文件中的 SYSFS選項。下面的結果就是上面的命令輸出
[root@localhost rules.d]#?udevinfo -a -p $(udevinfo -q path -n /dev/hda1)
Udevinfo starts with the device specified by the devpath and thenwalks up the chain of parent devices. It prints for every devicefound, all possible attributes in the udev rules key format.A rule to match, can be composed by the attributes of the deviceand the attributes from one single parent device.looking at device '/block/hda/hda1':KERNEL=="hda1"SUBSYSTEM=="block"DRIVER==""ATTR{stat}==" 1133 2268 2 4"ATTR{size}=="208782"ATTR{start}=="63"ATTR{dev}=="3:1"looking at parent device '/block/hda':KERNELS=="hda"SUBSYSTEMS=="block"DRIVERS==""ATTRS{stat}==" 28905 18814 1234781 302540 34087 133247 849708 981336 0 218340 1283968"ATTRS{size}=="117210240"ATTRS{removable}=="0"ATTRS{range}=="64"ATTRS{dev}=="3:0"looking at parent device '/devices/pci0000:00/0000:00:1f.1/ide0/0.0':KERNELS=="0.0"SUBSYSTEMS=="ide"DRIVERS=="ide-disk"ATTRS{modalias}=="ide:m-disk"ATTRS{drivename}=="hda"ATTRS{media}=="disk"looking at parent device '/devices/pci0000:00/0000:00:1f.1/ide0':KERNELS=="ide0"SUBSYSTEMS==""DRIVERS==""looking at parent device '/devices/pci0000:00/0000:00:1f.1':KERNELS=="0000:00:1f.1"SUBSYSTEMS=="pci"DRIVERS=="PIIX_IDE"ATTRS{broken_parity_status}=="0"ATTRS{enable}=="1"ATTRS{modalias}=="pci:v00008086d000024CAsv0000144Dsd0000C009bc01sc01i8a"ATTRS{local_cpus}=="1"ATTRS{irq}=="11"ATTRS{class}=="0x01018a"ATTRS{subsystem_device}=="0xc009"ATTRS{subsystem_vendor}=="0x144d"ATTRS{device}=="0x24ca"ATTRS{vendor}=="0x8086"looking at parent device '/devices/pci0000:00':KERNELS=="pci0000:00"SUBSYSTEMS==""DRIVERS==""
例子一:修改USB掃描儀的配置。
通過一系列的嘗試,你已經(jīng)為這個掃描儀標識了Linux設備文件(每次打開掃描儀時,名字都會變)。
你可以使用上面的命令替換這個正確的Linux設備文件名,然后定位輸出的采用SYSFS{idVendor}行和SYSFS{idProduct}行。
最后你可以使用這些信息來為這個掃描儀創(chuàng)建新的選項。
SYSFS{idVendor}=="0686", SYSFS{idProduct}=="400e", SYMLINK+="scanner", MODE="0664", group="scanner"
上面的例子表示將掃描儀的組設置為scanner,訪問權限設置為0664,同時創(chuàng)建一個/dev/scanner的符號連接。
例子二:使用udev修改u盤設備文件名 ?
編寫我們的/etc/udev/rules.d/10-local.rules文件
sudo vim /etc/udev/rules.d/10-local.rules
在里面加入這幾個變量信息,如下:
KERNEL=="sdc4",SUBSYSTEMS=="block", NAME+="kinstonusb",SYMLINK+="kinstonusb_link"
上面的KERNEL=="sdc4",SUBSYSTEMS=="block"我們可以根據(jù)上面的輸出直接拷貝過去的。我們保存這個文件。
一般我們要使這個規(guī)則文件生效,要熱插拔我們的設備以產(chǎn)生一個事件或在設備中的event文件中增加信息以達到發(fā)送事件的目的來更新我們的udev規(guī)則,但這里有個更加方便的方法,我們可以運行下面這個命令。
sudo ?udevadm test /sys/class/block/sdc4
這樣我們就更新了我們的規(guī)則。
看下/dev里的情況,如下圖:
看下sdc,如下圖:
sdc4不見了,即是我們命名我們的sdc4為kinstonusb了,而且還有個kinstonusb_link鏈接到它,以后我們就可用/dev/kinstonusb或/dev/kinstonusb_link來操作我們的優(yōu)盤而不是/dev/sdc4了。
---------------------------------------------------------------------------------
理解和認識udev
因為本身從事存儲行業(yè),在工作中多次碰到用戶有這樣的要求:我的linux系統(tǒng)中原來有一塊SCSI硬盤,系統(tǒng)分配的設備文件是/dev/sda。現(xiàn)在新增加了一個外置的磁盤陣列,通過SCSI卡連接。但接上這個磁盤陣列后,/dev/sda變成了磁盤陣列的硬盤了,原來內(nèi)置的SCSI硬盤變成了 /dev/sdb,我希望將設備文件固定下來。
過去,我總是對用戶說,這個比較麻煩,因為/dev/sda等文件都是linux內(nèi)核自動分配的。很難固定下來,除非你更改加載SCSI卡驅動程序的順序,讓內(nèi)置硬盤連接的SCSI卡比外接磁盤陣列連接的SCSI卡的驅動模塊先加載到內(nèi)核,這樣就能保證/dev/sda總是指向內(nèi)置的硬盤。但這種解決方法畢竟不太完美,而且對于其他的即插即用設備,如USB設備等都不適用。
近來,通過安裝和升級linux-2.6內(nèi)核,發(fā)現(xiàn)這個問題已經(jīng)可以通過2.6內(nèi)核新的sysfs文件系統(tǒng)和udev程序得到解決。下面就是我在學習了udev配置后的一點心得。我喜歡用FAQ的形式來說明。
問:什么是udev?
答:udev是一種工具,它能夠根據(jù)系統(tǒng)中的硬件設備的狀態(tài)動態(tài)更新設備文件,包括設備文件的創(chuàng)建,刪除等。設備文件通常放在/dev目錄下。使用udev后,在/dev目錄下就只包含系統(tǒng)中真正存在的設備。
問:udev支持什么內(nèi)核?
答:udev只支持linux-2.6內(nèi)核,因為udev嚴重依賴于sysfs文件系統(tǒng)提供的信息,而sysfs文件系統(tǒng)只在linux-2.6內(nèi)核中才有。
問:udev是一個內(nèi)核程序還是用戶程序?
答:udev是一個用戶程序(user-mode daemon)。
問:udev和devfs有什么差別?
答:udev能夠實現(xiàn)所有devfs實現(xiàn)的功能。但udev運行在用戶模式中,而devfs運行在內(nèi)核中。據(jù)稱:devfs具有一些不太容易解決的先天缺陷。
問:udev的配置文件放在哪里?
答:udev是一個用戶模式程序。它的配置文件是/etc/udev/udev.conf。這個文件一般缺省有這樣幾項:
udev_root="/dev" ; udev產(chǎn)生的設備文件的根目錄是/dev
udev_db="/dev/.udevdb" ; 通過udev產(chǎn)生的設備文件形成的數(shù)據(jù)庫
udev_rules="/etc/udev/rules.d" ;用于指導udev工作的規(guī)則所在目錄。
udev_log="err" ;當出現(xiàn)錯誤時,用syslog記錄錯誤信息。
問:udev的工作過程是怎樣的?
答:由于沒有研究過udev的源程序,不敢貿(mào)然就說udev的工作過程。我只是通過一些網(wǎng)上的資料和udev的說明文檔,大致猜測它的工作過程可能是這樣的。
1. 當內(nèi)核檢測到在系統(tǒng)中出現(xiàn)了新設備后,內(nèi)核會在sysfs文件系統(tǒng)中為該新設備生成一項新的記錄,一般sysfs文件系統(tǒng)會被 mount到 /sys目錄中。新記錄是以一個或多個文件或目錄的方式來表示。每個文件都包含有特定的信息。(信息是如何表述的,還要另外研究?)
2. udev在系統(tǒng)中是以守護進程的方式udevd在運行,它通過某種途徑(到底什么途徑,目前還沒搞懂。)檢測到新設備的出現(xiàn),通過查找設備對應的sysfs中的記錄得到設備的一些信息。
3. udev 會根據(jù)/etc/udev/udev.conf文件中的udev_rules指定的目錄,逐個檢查該目錄下的文件,這個目錄下的文件都是針對某類或某個設備應該施行什么措施的規(guī)則文件。udev讀取文件是按照文件名的ASCII字母順序來讀取的,如果udev一旦找到了與新加入的設備匹配的規(guī)則,udev 就會根據(jù)規(guī)則定義的措施對新設備進行配置。同時不再讀后續(xù)的規(guī)則文件。
問:udev的規(guī)則文件的語法是怎樣的?
答:udev的規(guī)則文件以行為單位,以"#"開頭的行代表注釋行。其余的每一行代表一個規(guī)則。每個規(guī)則分成一個或多個“匹配”和“賦值”部分。“匹配”部分用“匹配“專用的關鍵字來表示,相應的“賦值”部分用“賦值”專用的關鍵字來表示。“匹配”關鍵字包括:ACTION,KERNEL,BUS, SYSFS等等,“賦值”關鍵字包括:NAME,SYMLINK,OWNER等等。具體詳細的描述可以閱讀udev的man文檔。
下面舉個例子來說明一下,有這樣一條規(guī)則:
SUBSYSTEM=="net", ACTION=="add", SYSFS{address}=="00:0d:87:f6:59:f3", IMPORT="/sbin/rename_netiface %k eth0"
這個規(guī)則中的“匹配”部分有三項,分別是SUBSYSTEM,ACTION和SYSFS。而"賦值"部分有一項,是IMPORT。這個規(guī)則就是說,當系統(tǒng)中出現(xiàn)的新硬件屬于net子系統(tǒng)范疇,系統(tǒng)對該硬件采取的動作是加入這個硬件,且這個硬件在SYSFS文件系統(tǒng)中的“address”信息等于“00: 0d..."時,對這個硬件在udev層次施行的動作是調(diào)用外部程序/sbin/rename_netiface,傳遞的參數(shù)有兩個,一個是“%k”,代表內(nèi)核對該新設備定義的名稱。另一個是”eth0“。
從上面這個例子中可以看出,udev的規(guī)則的寫法比較靈活的,尤其在“匹配”部分中,可以通過諸如”*“, ”?“,[a-c],[1-9]等shell通配符來靈活匹配多個匹配項。具體的語法可以參考udev的man文檔。
問:udev怎樣做到不管設備連接的順序而維持一個統(tǒng)一的設備名?
答:實際上,udev是通過對內(nèi)核產(chǎn)生的設備名增加別名的方式來達到上述目的的。前面說過,udev是用戶模式程序,不會更改內(nèi)核的行為。因此,內(nèi)核依然會我行我素地產(chǎn)生設備名如sda,sdb等。但是,udev可以根據(jù)設備的其他信息如總線(bus),生產(chǎn)商(vendor)等不同來區(qū)分不同的設備,并產(chǎn)生設備文件。udev只要為這個設備文件取一個固定的文件名就可以解決這個問題。在后續(xù)對設備的操作中,只要引用新的設備名就可以了。但為了保證最大限度的兼容,一般來說,新設備名總是作為一個對內(nèi)核自動產(chǎn)生的設備名的符號鏈接(link)來使用的。
例如:內(nèi)核產(chǎn)生了sda設備名,而根據(jù)信息,這個設備對應于是我的內(nèi)置硬盤,那我就可以制定udev規(guī)則,讓udev除了產(chǎn)生/dev/sda設備文件外,另外創(chuàng)建一個符號鏈接叫/dev/internalHD。這樣,我在fstab文件中,就可以用/dev/internalHD來代替原來的 /dev/sda了。下次,由于某些原因,這個硬盤在內(nèi)核中變成了sdb設備名了,那也不用著急,udev還會自動產(chǎn)生/dev/internalHD這個鏈接,并指向正確的/dev/sdb設備。所有其他的文件像fstab等都不用修改。
問:怎樣才能找到這些設備信息,并把他們放到udev的規(guī)則文件中來匹配呢?
答:這個問題比較難,網(wǎng)上資料不多,我只找到一篇文章來介紹如何寫udev的規(guī)則。他的基本方法是通過udevinfo這個實用程序來找到那些可以作為規(guī)則文件里的匹配項的項目。有這樣兩種情況可以使用這個工具:
第一種情況是,當你把設備插入系統(tǒng)后,系統(tǒng)為設備產(chǎn)生了設備名(如/dev/sda)。那樣的話,你先用udevinfo -q path -n /dev/sda,命令會產(chǎn)生一個該設備名對應的在sysfs下的路徑,如/block/sda。然后,你再用udevinfo -a -p /sys/block/sda,這個命令會顯示一堆信息,信息分成很多塊。這些信息實際來自于操作系統(tǒng)維護的sysfs鏈表,不同的塊對應不同的路徑。你就可以用這些信息來作為udev規(guī)則文件中的匹配項。但需要注意的是,同一個規(guī)則只能使用同一塊中顯示的信息,不能跨塊書寫規(guī)則。
第二種情況是,不知道系統(tǒng)產(chǎn)生的設備名,那就只有到/sys目錄下去逐個目錄查找了,反復用udevinfo -a -p /sys/path...這個命令看信息,如果對應的信息是這個設備的,那就恭喜你。否則就再換個目錄。當然,在這種情況下,成功的可能性比較小。
----------------------------------------------------------------------------------
Udev (簡體中文)
注意: 如果您是從DevFS升級到Udev, 請查看 DevFS to Udev.
這篇文檔將介紹udev的一些新的變化。從084版開始,udev能夠代替hotplug和coldplug的所有功能。正因為這樣,hotplug包已經(jīng)從Arch倉庫中去掉了。
* 1 重要提示
* 2 基本需求
* 3 最近更新
* 4 模塊禁用列表
* 5 load_modules: 有用的啟動參數(shù)
* 6 已知的硬件問題
* 7 自動加載帶來的一些問題
o 7.1 CPUFreq模塊
o 7.2 聲音問題和一些不能自動加載的模塊
o 7.3 多個同類型設備(網(wǎng)卡,聲卡)每次啟動的都不同
* 8 自己編譯內(nèi)核造成的一些已知問題
o 8.1 Udev無法啟動
o 8.2 CD/DVD符號和權限錯誤
* 9 Udev小竅門
o 9.1 自動加載usb設備
重要提示
...切記,在使用udev加載任何modules(內(nèi)核模塊)之前(無論是否是啟動時自動加載),您必須在/etc/rc.conf將MOD_AUTOLOAD選項設置為yes ,否則您必須手動加載這些modules。您可以修改rc.conf中的MODULES或者使用modprobe命令來手動加載您所需要的modules。另一種方法是用hwdetect --modules生成系統(tǒng)硬件的modules列表,然后將這個列表添加到rc.conf中讓系統(tǒng)啟動時自動加載這些modules。
基本需求
* 內(nèi)核: 2.6.15或更高版本。
* 您將無法在fstab和bootloader設置中再使用DevFS格式的設備名稱! 更多相關內(nèi)容請查看DevFS to Udev。
最近更新
* startudev程序被取出。如果需要重新加載udev規(guī)則請使用 /etc/start_udev。
* Udev代替了hotplug和hwdetect的功能。同時我們保存了hwdetect,并且只在 mkinitrd程序生成initrd的時候用到。
* Udev可以同時加載多個模塊,這樣可以加快啟動速度,然而,這樣做的結果是她不能保證每次加載的順序,所以當你使用多聲卡或網(wǎng)卡的時候就會出現(xiàn)問題,這個問題下面將會再討論。
模塊禁用列表
udev也會犯錯或加載錯誤的模塊。為了防止錯誤的發(fā)生,你可以使用模塊禁用列表 。一旦加入該列表的模塊,無論是啟動時,或者時運行時(如usb硬盤等)udev都不會加載這些模塊。
只需在您在 rc.conf的MODULES中對應模塊前加上感嘆號(!)就可禁用該模塊。
例如,
MODULES=(!moduleA !moduleB)
load_modules: 有用的啟動參數(shù)
如果您在內(nèi)核啟動參數(shù)中加入load_modules=off,那么udev會停止任何自動加載工作. 如果系統(tǒng)出現(xiàn)問題時,這個功能會十分有用。如果udev加載了有問題的模塊導致系統(tǒng)掛起或者其它嚴重的問題時,你可以使用這個參數(shù)來禁用自動加載,以此來防止加載有問題的模塊。
已知的硬件問題
- BusLogic設備被損壞而且導致啟動時死機。
這是一個內(nèi)核的Bug目前還沒有修正。
- PCMCIA讀卡器被認為是可移除設備.
把它們加入到/etc/pmount.allow中,使用hal的pmount來讀取
自動加載帶來的一些問題
CPUFreq模塊
我門還沒有找到一個很好的方法加載不同的CPUFreq控制器,所以我們把從自動加載進程里把它去掉了。如果您需要測量CPU頻率,你必須在rc.conf的MODULES隊列中顯式的加入合適的模塊。
聲音問題和一些不能自動加載的模塊
一些用戶跟蹤發(fā)現(xiàn)問題出在/etc/modprobe.conf中一些舊的部分,試著去掉這些舊的部分再試試看。
多個同類型設備(網(wǎng)卡,聲卡)每次啟動的都不同
因為udev同時加載所有模塊,所以一些設備可能初始化順序不同。例如同時有兩個網(wǎng)卡時,它們總是在eth0和eth1之間變來變?nèi)ァ?br />
常用的解決辦法是在您的rc.conf文件中通過修改MODULES隊列來指明順序。這個隊列里的模塊將在udev自動加載之前由系統(tǒng)加載,因此您可以控制模塊在啟動時加載順序。
# 在e100之前加載8139too
MODULES=(8139too e100)
另一個解決網(wǎng)卡的方法是使用udev-sanctified方法為每個網(wǎng)卡靜態(tài)命名。創(chuàng)建文件/etc/udev/rules.d/10-network.rules然后將不同的網(wǎng)卡通過MAC地址綁定到不同的名字上:
SUBSYSTEM=="net", SYSFS{address}=="aa:bb:cc:dd:ee:ff", NAME="lan0"SUBSYSTEM=="net", SYSFS{address}=="ff:ee:dd:cc:bb:aa", NAME="wlan0"
同時,您需要注意以下內(nèi)容:
* 您可以通過下面的命令獲得網(wǎng)卡的MAC地址:: udevinfo -a -p /sys/class/net/<你的網(wǎng)卡>
* 注意在udev規(guī)則文件中使用小寫的16進制MAC地址,因為udev無法識別大寫的MAC地址。
* 一些用戶在使用舊的命名方式時出現(xiàn)問題,例如: eth0, eth1, 等等. 如果出現(xiàn)這個問題,試試使用 "lan"或者"wlan"之類的名字.
注意不要忘記修改您的/dec/rc.conf和其它使用ethX命名的配置文件。
自己編譯內(nèi)核造成的一些已知問題
Udev無法啟動
請確定您的內(nèi)核版本大于或等于2.6.15。較早的內(nèi)核沒有udev自動裝載所需要的uevent功能。
CD/DVD符號和權限錯誤
如果您使用2.6.15的內(nèi)核的話,您需要安裝ABS的uevent補丁(它從2.6.16內(nèi)核中抽取了一些uevent功能)。您可以使用abs命令來同步ABS樹,然后您就可以在/var/abs/kernels/kernel26/下找到abs補丁。
Udev小竅門
自動加載usb設備
KERNEL=="sd[a-z]", NAME="%k", SYMLINK+="usb%m", GROUP="users", OPTIONS="last_rule"ACTION=="add", KERNEL=="sd[a-z][0-9]", SYMLINK+="usb%n", GROUP="users", NAME="%k"ACTION=="add", KERNEL=="sd[a-z][0-9]", RUN+="/bin/mkdir -p /mnt/usb%n"ACTION=="add", KERNEL=="sd[a-z][0-9]", PROGRAM=="/lib/udev/vol_id -t %N", RESULT=="vfat", RUN+="/bin/mount -t vfat -o rw,noauto,sync,dirsync,noexec,nodev,noatime,dmask=000,fmask=111 /dev/%k /mnt/usb%n", OPTIONS="last_rule"ACTION=="add", KERNEL=="sd[a-z][0-9]", RUN+="/bin/mount -t auto -o rw,noauto,sync,dirsync,noexec,nodev,noatime /dev/%k /mnt/usb%n", OPTIONS="last_rule"ACTION=="remove", KERNEL=="sd[a-z][0-9]", RUN+="/bin/umount -l /mnt/usb%n"ACTION=="remove", KERNEL=="sd[a-z][0-9]", RUN+="/bin/rmdir /mnt/usb%n", OPTIONS="last_rule"
把這些udev規(guī)則放到/etc/udev/rules.d/下任何一個文件名以.rules結尾的文件中,例如/etc/udev/rules.d/sda.rules。
如果想同時建立/media到/mnt符號連接,可以使用下面的版本:
KERNEL=="sd[a-z]", NAME="%k", SYMLINK+="usbhd-%k", GROUP="users", OPTIONS="last_rule"ACTION=="add", KERNEL=="sd[a-z][0-9]", SYMLINK+="usbhd-%k", GROUP="users", NAME="%k"ACTION=="add", KERNEL=="sd[a-z][0-9]", RUN+="/bin/mkdir -p /media/usbhd-%k"ACTION=="add", KERNEL=="sd[a-z][0-9]", RUN+="/bin/ln -s /media/usbhd-%k /mnt/usbhd-%k"ACTION=="add", KERNEL=="sd[a-z][0-9]", PROGRAM=="/lib/udev/vol_id -t %N", RESULT=="vfat", RUN+="/bin/mount -t vfat -o rw,noauto,sync,dirsync,noexec,nodev,noatime,dmask=000,fmask=111 /dev/%k /media/usbhd-%k", OPTIONS="last_rule"ACTION=="add", KERNEL=="sd[a-z][0-9]", RUN+="/bin/mount -t auto -o rw,noauto,sync,dirsync,noexec,nodev,noatime /dev/%k /media/usbhd-%k", OPTIONS="last_rule"ACTION=="remove", KERNEL=="sd[a-z][0-9]", RUN+="/bin/rm -f /mnt/usbhd-%k"ACTION=="remove", KERNEL=="sd[a-z][0-9]", RUN+="/bin/umount -l /media/usbhd-%k"ACTION=="remove", KERNEL=="sd[a-z][0-9]", RUN+="/bin/rmdir /media/usbhd-%k", OPTIONS="last_rule"
注意!如果你是用的其它的固定設備(例如SATA的硬盤,您可以從/etc/fstab中查看)被識別為/dev/sdX,您必須從sd[a-z] 中去掉你的那個sdX。例如,如果您的SATA硬盤被是識別為/dev/sda,您就需要把所有的“sd[a-z]”替換成“sd[b-z]”。在規(guī)則文件的文件名前加上數(shù)字(如:010.udev.rules)是個很好的主意,這樣udev在讀取標準規(guī)則前,將會讀取這個規(guī)則文件。這些規(guī)則設置后不需要修改/etc/fstab文件。請查看mount命令的參數(shù)來修改權限等特性(您可以從論壇搜索查看mount命令的參數(shù),然后根據(jù)您的需要修改它們)。
?
評論
查看更多