linux下udev

若是你使用Linux比較長時間了,那你就知道,在對待設備文件這塊,Linux改變了幾回策略。在Linux早期,設備文件僅僅是是一些帶有適當的屬性集的普通文件,它由mknod命令建立,文件存放在/dev目錄下。後來,採用了devfs,一個基於內核的動態設備文件系統,他首次出如今2.3.46 內核中。Mandrake,Gentoo等Linux分發版本採用了這種方式。devfs建立的設備文件是動態的。可是devfs有一些嚴重的限制,從 2.6.13版本後移走了。目前取代他的即是文本要提到的udev--一個用戶空間程序。

目前不少的Linux分發版本採納了udev的方式,由於它在Linux設備訪問,特別是那些對設備有極端需求的站點(好比須要控制上千個硬盤)和熱插拔設備(好比USB攝像頭和MP3播放器)上解決了幾個問題。下面我咱們來看看如何管理udev設備。

實際上,對於那些爲磁盤,終端設備等準備的標準配置文件而言,你不須要修改什麼。可是,你須要瞭解udev配置來使用新的或者外來設備,若是不修改配置,這些設備可能沒法訪問,或者說Linux可能會採用不恰當的名字,屬組或權限來建立這些設備文件。你可能也想知道如何修改RS-232串口,音頻設備等文件的屬組或者權限。這點在實際的Linux實施中是會遇到的。

爲何使用udev
在此以前的設備文件管理方法(靜態文件和devfs)有幾個缺點:

* 不肯定的設備映射。特別是那些動態設備,好比USB設備,設備文件到實際設備的映射並不可靠和肯定。舉一個例子:若是你有兩個USB打印機。一個可能稱爲 /dev/usb/lp0,另一個即是/dev/usb/lp1。可是到底哪一個是哪一個並不清楚,lp0,lp1和實際的設備沒有一一對應的關係,由於他可能由於發現設備的順序,打印機自己關閉等緣由而致使這種映射並不肯定。理想的方式應該是:兩個打印機應該採用基於他們的序列號或者其餘標識信息的惟一設備文件來映射。可是靜態文件和devfs都沒法作到這點。

*沒有足夠的主/輔設備號。咱們知道,每個設備文件是有兩個8位的數字:一個是主設備號 ,另一個是輔設備號來分配的。這兩個8位的數字加上設備類型(塊設備或者字符設備)來惟一標識一個設備。不幸的是,關聯這些身邊的的數字並不足夠。

*/dev目錄下文件太多。一個系統採用靜態設備文件關聯的方式,那麼這個目錄下的文件必然是足夠多。而同時你又不知道在你的系統上到底有那些設備文件是激活的。

*命名不夠靈活。儘管devfs解決了之前的一些問題,可是它自身又帶來了一些問題。其中一個就是命名不夠靈活;你別想很是簡單的就能修改設備文件的名字。缺省的devfs命令機制自己也很奇怪,他須要修改大量的配置文件和程序。;

*內核內存使用,devfs特有的另一個問題是,做爲內核驅動模塊,devfs須要消耗大量的內存,特別當系統上有大量的設備時(好比上面咱們提到的系統一個上有好幾千磁盤時)

udev的目標是想解決上面提到的這些問題,他通採用用戶空間(user-space)工具來管理/dev/目錄樹,他和文件系統分開。知道如何改變缺省配置能讓你之大如何定製本身的系統,好比建立設備字符鏈接,改變設備文件屬組,權限等。

udev配置文件
主要的udev配置文件是 /etc/udev/udev.conf。這個文件一般很短,他可能只是包含幾行#開頭的註釋,而後有幾行選項:
udev_root="/dev/"

udev_rules="/etc/udev/rules.d/"

udev_log="err"
上面的第二行很是重要,由於他表示udev規則存儲的目錄,這個目錄存儲的是以.rules結束的文件。每個文件處理一系列規則來幫助udev分配名字給設備文件以保證能被內核識別。
你的 /etc/udev/rules.d下面可能有好幾個udev規則文件,這些文件一部分是udev包安裝的,另一部分則是多是別的硬件或者軟件包生成的。好比在Fedora Core 5系統上,sane-backends包就會安裝60-libsane.rules文件,另外initscripts包會安裝60-net.rules文件。這些規則文件的文件名一般是兩個數字開頭,它表示系統應用該規則的順序。

規則文件裏的規則有一系列的鍵/值對組成,鍵/值對之間用逗號(,)分割。每個鍵或者是用戶匹配鍵,或者是一個賦值鍵。匹配鍵肯定規則是否被應用,而賦值鍵表示分配某值給該鍵。這些值將影響udev建立的設備文件。賦值鍵能夠處理一個多值列表。

規則說明
一、udev 規則的全部操做符
「==」:  比較鍵、值,若等於,則該條件知足;
「!=」:   比較鍵、值,若不等於,則該條件知足;
「=」:    對一個鍵賦值;
「+=」:  爲一個表示多個條目的鍵賦值。
「:=」:  對一個鍵賦值,並拒絕以後全部對該鍵的改動。目的是防止後面的規則文件對該鍵賦值。

二、udev 規則的匹配鍵
ACTION:          事件 (uevent) 的行爲,例如:add( 添加設備 )、remove( 刪除設備 )。
KERNEL:          內核設備名稱,例如:sda, cdrom。
DEVPATH:          設備的 devpath 路徑。
SUBSYSTEM:        設備的子系統名稱,例如:sda 的子系統爲 block。
BUS:            設備在 devpath 裏的總線名稱,例如:usb。
DRIVER:           設備在 devpath 裏的設備驅動名稱,例如:ide-cdrom。
ID:             設備在 devpath 裏的識別號。
SYSFS{filename}:     設備的 devpath 路徑下,設備的屬性文件「filename」裏的內容。
               例如:SYSFS{model}==「ST936701SS」表示:若是設備的型號爲 ST936701SS,則該設備匹配該 匹配鍵。
               在一條規則中,能夠設定最多五條 SYSFS 的 匹配鍵。
ENV{key}:          環境變量。在一條規則中,能夠設定最多五條環境變量的 匹配鍵。
PROGRAM:        調用外部命令。
RESULT:           外部命令 PROGRAM 的返回結果。

三、udev 的重要賦值鍵 
NAME:           在 /dev下產生的設備文件名。只有第一次對某個設備的 NAME 的賦值行爲生效,以後匹配的規則再對該設備的 NAME 賦值行爲將被忽略。若是沒有任何規則對設備的 NAME 賦值,udev 將使用內核設備名稱來產生設備文件。
SYMLINK:          爲 /dev/下的設備文件產生符號連接。因爲 udev 只能爲某個設備產生一個設備文件,因此爲了避免覆蓋系統默認的 udev 規則所產生的文件,推薦使用符號連接。
OWNER, GROUP, MODE:  爲設備設定權限。
ENV{key}:         導入一個環境變量。

四、udev 的值和可調用的替換操做符 
Linux 用戶能夠隨意地定製 udev 規則文件的值。例如:my_root_disk, my_printer。同時也能夠引用下面的替換操做符:
$kernel, %k:        設備的內核設備名稱,例如:sda、cdrom。
$number, %n:        設備的內核號碼,例如:sda3 的內核號碼是 3。
$devpath, %p:       設備的 devpath路徑。
$id, %b:          設備在 devpath裏的 ID 號。
$sysfs{file}, %s{file}:     設備的 sysfs裏 file 的內容。其實就是設備的屬性值。
$env{key}, %E{key}:   一個環境變量的值。
$major, %M:        設備的 major 號。
$minor %m:        設備的 minor 號。
$result, %c:        PROGRAM 返回的結果。
$parent, %P:          父設備的設備文件名。
$root, %r:          udev_root的值,默認是 /dev/。
$tempnode, %N:      臨時設備名。
%%:            符號 % 自己。
$$:             符號 $ 自己。

給出一個列子來解釋如何使用這些鍵,下面的例子來自Fedora Core 5系統的標準配置文件:
複製代碼
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個規則,每個都是KERNEL或者ACTION鍵開頭:

*第一個規則是缺省的,他匹配任意被內核識別到的設備,而後設定這些設備的屬組是root,組是root,訪問權限模式是0600(-rw-------)。這也是一個安全的缺省設置保證全部的設備在默認狀況下只有root能夠讀寫。
 
*第二個規則也是比較典型的規則了。它匹配終端設備(tty),而後設置新的權限爲0600,所在的組是tty。它也設置了一個特別的設備文件名:%K。在這裏例子裏,%k表明設備的內核名字。那也就意味着內核識別出這些設備是什麼名字,就建立什麼樣的設備文件名。
 
*第三行開始的KERNEL=="scd[0-9]*",表示 SCSI CD-ROM 驅動. 它建立一對設備符號鏈接:cdrom和cdrom-%k。
 
*第四行,開始的 KERNEL=="hd[a-z]", 表示ATA CDROM驅動器。這個規則建立和上面的規則相同的符號鏈接。ATA CDROM驅動器須要sysfs值以來區別別的ATA設備,由於SCSI CDROM能夠被內核惟一識別。.
 
*第五行以 ACTION=="add"開始,它告訴udev增長 /sbin/modprobe sg 到命令列表,當任意SCSI設備增長到系統後,這些命令將執行。其效果就是計算機應該會增長sg內核模塊來偵測新的SCSI設備。

固然,上面僅僅是一小部分例子,若是你的系統採用了udev方式,那你應該能夠看到更多的規則。若是你想修改設備的權限或者建立信的符號鏈接,那麼你須要熟讀這些規則,特別是要仔細注意你修改的那些與之相關的設備。

修改你的udev配置
在修改udev配置以前,咱們必定要仔細,一般的考慮是:你最好不要修改系統預置的那些規則,特別不要指定影響很是普遍的配置,好比上面例子中的第一行。不正確的配置可能會致使嚴重的系統問題或者系統根本就沒法這個正確的訪問設備。

而咱們正確的作法應該是在/etc/udev/rules.d/下建立一個信的規則文件。肯定你給出的文件的後綴是rules文件名給出的數字序列應該比標準配置文件高。好比,你能夠建立一個名爲99-my-udev.rules的規則文件。在你的規則文件中,你能夠指定任何你想修改的配置,好比,假設你修改修改floppy設備的所在組,還準備建立一個信的符號鏈接/dev/floppy,那你能夠這麼寫:
KERNEL=="fd[0-9]*", GROUP="users", SYMLINK+="floppy"

有些發行版本,好比Fedora,採用了外部腳原本修改某些特定設備的屬組,組關係和權限。所以上面的改動可能並不見得生效。若是你遇到了這個問題,你就須要跟蹤和修改這個腳原本達到你的目的。或者你能夠修改PROGRAM或RUN鍵的值來作到這點。

某些規則的修改可能須要更深的挖掘。好比,你可能想在一個設備上使用sysfs信息來惟一標識一個設備。這些信息最好經過udevinfo命令來獲取。
$  udevinfo –a –p $(udevinfo –q path –n /dev/hda)

上面的命令兩次使用udevinfo:一次是返回sysfs設備路徑(他一般和咱們看到的Linux設備文件名所在路徑--/dev/hda--不一樣);第二次纔是查詢這個設備路徑,結果將是很是常的syfs信息彙總。你能夠找到最夠的信息來惟一標誌你的設備,你能夠採用適當的替換udev配置文件中的 SYSFS選項。下面的結果就是上面的命令輸出

[root@localhost rules.d]#  udevinfo -a -p $(udevinfo -q path -n /dev/hda1)
複製代碼
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/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掃描儀的配置。
 
經過一系列的嘗試,你已經爲這個掃描儀標識了Linux設備文件(每次打開掃描儀時,名字都會變)。
 
你可使用上面的命令替換這個正確的Linux設備文件名,而後定位輸出的採用SYSFS{idVendor}行和SYSFS{idProduct}行。
 
最後你可使用這些信息來爲這個掃描儀建立新的選項。
複製代碼
SYSFS{idVendor}=="0686", \

SYSFS{idProduct}=="400e", \

SYMLINK+="scanner", MODE="0664", \

group="scanner"
複製代碼
上面的例子表示將掃描儀的組設置爲scanner,訪問權限設置爲0664,同時建立一個/dev/scanner的符號鏈接。
 
例子二:使用udev修改u盤設備文件名  
 

編寫咱們的/etc/udev/rules.d/10-local.rules文件node

 sudo vim /etc/udev/rules.d/10-local.ruleslinux

在裏面加入這幾個變量信息,以下:shell

KERNEL=="sdc4",SUBSYSTEMS=="block", NAME+="kinstonusb",SYMLINK+="kinstonusb_link"

上面的KERNEL=="sdc4",SUBSYSTEMS=="block"咱們能夠根據上面的輸出直接拷貝過去的。咱們保存這個文件。數據庫

通常咱們要使這個規則文件生效,要熱插拔咱們的設備以產生一個事件或在設備中的event文件中增長信息以達到發送事件的目的來更新咱們的udev規則,但這裏有個更加方便的方法,咱們能夠運行下面這個命令。vim

sudo  udevadm test /sys/class/block/sdc4安全

這樣咱們就更新了咱們的規則。ide

看下/dev裏的狀況,以下圖:工具

看下sdc,以下圖:學習

sdc4不見了,便是咱們命名咱們的sdc4爲kinstonusb了,並且還有個kinstonusb_link連接到它,之後咱們就可用/dev/kinstonusb或/dev/kinstonusb_link來操做咱們的優盤而不是/dev/sdc4了。spa

---------------------------------------------------------------------------------
理解和認識udev

由於自己從事存儲行業,在工做中屢次碰到用戶有這樣的要求:個人linux系統中原來有一塊SCSI硬盤,系統分配的設備文件是/dev/sda。如今新增長了一個外置的磁盤陣列,經過SCSI卡鏈接。但接上這個磁盤陣列後,/dev/sda變成了磁盤陣列的硬盤了,原來內置的SCSI硬盤變成了 /dev/sdb,我但願將設備文件固定下來。
過去,我老是對用戶說,這個比較麻煩,由於/dev/sda等文件都是linux內核自動分配的。很難固定下來,除非你更改加載SCSI卡驅動程序的順序,讓內置硬盤鏈接的SCSI卡比外接磁盤陣列鏈接的SCSI卡的驅動模塊先加載到內核,這樣就能保證/dev/sda老是指向內置的硬盤。但這種解決方法畢竟不太完美,並且對於其餘的即插即用設備,如USB設備等都不適用。
近來,經過安裝和升級linux-2.6內核,發現這個問題已經能夠經過2.6內核新的sysfs文件系統和udev程序獲得解決。下面就是我在學習了udev配置後的一點心得。我喜歡用FAQ的形式來講明。

問:什麼是udev?
答:udev是一種工具,它可以根據系統中的硬件設備的狀態動態更新設備文件,包括設備文件的建立,刪除等。設備文件一般放在/dev目錄下。使用udev後,在/dev目錄下就只包含系統中真正存在的設備。

問:udev支持什麼內核?
答:udev只支持linux-2.6內核,由於udev嚴重依賴於sysfs文件系統提供的信息,而sysfs文件系統只在linux-2.6內核中才有。

問:udev是一個內核程序仍是用戶程序?
答:udev是一個用戶程序(user-mode daemon)。

問:udev和devfs有什麼差異?
答:udev可以實現全部devfs實現的功能。但udev運行在用戶模式中,而devfs運行在內核中。據稱:devfs具備一些不太容易解決的先天缺陷。

問:udev的配置文件放在哪裏?
答:udev是一個用戶模式程序。它的配置文件是/etc/udev/udev.conf。這個文件通常缺省有這樣幾項:
udev_root="/dev" ; udev產生的設備文件的根目錄是/dev
udev_db="/dev/.udevdb" ; 經過udev產生的設備文件造成的數據庫
udev_rules="/etc/udev/rules.d" ;用於指導udev工做的規則所在目錄。
udev_log="err" ;當出現錯誤時,用syslog記錄錯誤信息。

問:udev的工做過程是怎樣的?
答:因爲沒有研究過udev的源程序,不敢貿然就說udev的工做過程。我只是經過一些網上的資料和udev的說明文檔,大體猜想它的工做過程多是這樣的。

1. 當內核檢測到在系統中出現了新設備後,內核會在sysfs文件系統中爲該新設備生成一項新的記錄,通常sysfs文件系統會被 mount到 /sys目錄中。新記錄是以一個或多個文件或目錄的方式來表示。每一個文件都包含有特定的信息。(信息是如何表述的,還要另外研究?)
2. udev在系統中是以守護進程的方式udevd在運行,它經過某種途徑(到底什麼途徑,目前還沒搞懂。)檢測到新設備的出現,經過查找設備對應的sysfs中的記錄獲得設備的一些信息。
3. udev 會根據/etc/udev/udev.conf文件中的udev_rules指定的目錄,逐個檢查該目錄下的文件,這個目錄下的文件都是針對某類或某個設備應該施行什麼措施的規則文件。udev讀取文件是按照文件名的ASCII字母順序來讀取的,若是udev一旦找到了與新加入的設備匹配的規則,udev 就會根據規則定義的措施對新設備進行配置。同時再也不讀後續的規則文件。

問:udev的規則文件的語法是怎樣的?
答:udev的規則文件以行爲單位,以"#"開頭的行表明註釋行。其他的每一行表明一個規則。每一個規則分紅一個或多個「匹配」和「賦值」部分。「匹配」部分用「匹配「專用的關鍵字來表示,相應的「賦值」部分用「賦值」專用的關鍵字來表示。「匹配」關鍵字包括:ACTION,KERNEL,BUS, SYSFS等等,「賦值」關鍵字包括:NAME,SYMLINK,OWNER等等。具體詳細的描述能夠閱讀udev的man文檔。

下面舉個例子來講明一下,有這樣一條規則:
SUBSYSTEM=="net", ACTION=="add", SYSFS{address}=="00:0d:87:f6:59:f3", IMPORT="/sbin/rename_netiface %k eth0"
這個規則中的「匹配」部分有三項,分別是SUBSYSTEM,ACTION和SYSFS。而"賦值"部分有一項,是IMPORT。這個規則就是說,當系統中出現的新硬件屬於net子系統範疇,系統對該硬件採起的動做是加入這個硬件,且這個硬件在SYSFS文件系統中的「address」信息等於「00: 0d..."時,對這個硬件在udev層次施行的動做是調用外部程序/sbin/rename_netiface,傳遞的參數有兩個,一個是「%k」,表明內核對該新設備定義的名稱。另外一個是」eth0「。
從上面這個例子中能夠看出,udev的規則的寫法比較靈活的,尤爲在「匹配」部分中,能夠經過諸如」*「, 」?「,[a-c],[1-9]等shell通配符來靈活匹配多個匹配項。具體的語法能夠參考udev的man文檔。

問:udev怎樣作到無論設備鏈接的順序而維持一個統一的設備名?
答:實際上,udev是經過對內核產生的設備名增長別名的方式來達到上述目的的。前面說過,udev是用戶模式程序,不會更改內核的行爲。所以,內核依然會我行我素地產生設備名如sda,sdb等。可是,udev能夠根據設備的其餘信息如總線(bus),生產商(vendor)等不一樣來區分不一樣的設備,併產生設備文件。udev只要爲這個設備文件取一個固定的文件名就能夠解決這個問題。在後續對設備的操做中,只要引用新的設備名就能夠了。但爲了保證最大限度的兼容,通常來講,新設備名老是做爲一個對內核自動產生的設備名的符號連接(link)來使用的。

例如:內核產生了sda設備名,而根據信息,這個設備對應因而個人內置硬盤,那我就能夠制定udev規則,讓udev除了產生/dev/sda設備文件外,另外建立一個符號連接叫/dev/internalHD。這樣,我在fstab文件中,就能夠用/dev/internalHD來代替原來的 /dev/sda了。下次,因爲某些緣由,這個硬盤在內核中變成了sdb設備名了,那也不用着急,udev還會自動產生/dev/internalHD這個連接,並指向正確的/dev/sdb設備。全部其餘的文件像fstab等都不用修改。

問:怎樣才能找到這些設備信息,並把他們放到udev的規則文件中來匹配呢?
答:這個問題比較難,網上資料很少,我只找到一篇文章來介紹如何寫udev的規則。他的基本方法是經過udevinfo這個實用程序來找到那些能夠做爲規則文件裏的匹配項的項目。有這樣兩種狀況可使用這個工具:
第一種狀況是,當你把設備插入系統後,系統爲設備產生了設備名(如/dev/sda)。那樣的話,你先用udevinfo -q path -n /dev/sda,命令會產生一個該設備名對應的在sysfs下的路徑,如/block/sda。而後,你再用udevinfo -a -p /sys/block/sda,這個命令會顯示一堆信息,信息分紅不少塊。這些信息實際來自於操做系統維護的sysfs鏈表,不一樣的塊對應不一樣的路徑。你就能夠用這些信息來做爲udev規則文件中的匹配項。但須要注意的是,同一個規則只能使用同一塊中顯示的信息,不能跨塊書寫規則。
第二種狀況是,不知道系統產生的設備名,那就只有到/sys目錄下去逐個目錄查找了,反覆用udevinfo -a -p /sys/path...這個命令看信息,若是對應的信息是這個設備的,那就恭喜你。不然就再換個目錄。固然,在這種狀況下,成功的可能性比較小。

----------------------------------------------------------------------------------
Udev (簡體中文)

注意: 若是您是從DevFS升級到Udev, 請查看 DevFS to Udev.

這篇文檔將介紹udev的一些新的變化。從084版開始,udev可以代替hotplug和coldplug的全部功能。正由於這樣,hotplug包已經從Arch倉庫中去掉了。

* 1 重要提示
* 2 基本需求
* 3 最近更新
* 4 模塊禁用列表
* 5 load_modules: 有用的啓動參數
* 6 已知的硬件問題
* 7 自動加載帶來的一些問題
  o 7.1 CPUFreq模塊
  o 7.2 聲音問題和一些不能自動加載的模塊
  o 7.3 多個同類型設備(網卡,聲卡)每次啓動的都不一樣
* 8 本身編譯內核形成的一些已知問題
  o 8.1 Udev沒法啓動
  o 8.2 CD/DVD符號和權限錯誤
* 9 Udev小竅門
  o 9.1 自動加載usb設備

重要提示
...切記,在使用udev加載任何modules(內核模塊)以前(不管是不是啓動時自動加載),您必須在/etc/rc.conf將MOD_AUTOLOAD選項設置爲yes ,不然您必須手動加載這些modules。您能夠修改rc.conf中的MODULES或者使用modprobe命令來手動加載您所須要的modules。另外一種方法是用hwdetect --modules生成系統硬件的modules列表,而後將這個列表添加到rc.conf中讓系統啓動時自動加載這些modules。

基本需求
* 內核: 2.6.15或更高版本。
* 您將沒法在fstab和bootloader設置中再使用DevFS格式的設備名稱! 更多相關內容請查看DevFS to Udev。

最近更新
* startudev程序被取出。若是須要從新加載udev規則請使用 /etc/start_udev。
* Udev代替了hotplug和hwdetect的功能。同時咱們保存了hwdetect,而且只在 mkinitrd程序生成initrd的時候用到。
* Udev能夠同時加載多個模塊,這樣能夠加快啓動速度,然而,這樣作的結果是她不能保證每次加載的順序,因此當你使用多聲卡或網卡的時候就會出現問題,這個問題下面將會再討論。

模塊禁用列表
udev也會犯錯或加載錯誤的模塊。爲了防止錯誤的發生,你可使用模塊禁用列表 。一旦加入該列表的模塊,不管是啓動時,或者時運行時(如usb硬盤等)udev都不會加載這些模塊。

只需在您在 rc.conf的MODULES中對應模塊前加上感嘆號(!)就可禁用該模塊。

例如,
MODULES=(!moduleA !moduleB)
 
load_modules: 有用的啓動參數
若是您在內核啓動參數中加入load_modules=off,那麼udev會中止任何自動加載工做. 若是系統出現問題時,這個功能會十分有用。若是udev加載了有問題的模塊致使系統掛起或者其它嚴重的問題時,你可使用這個參數來禁用自動加載,以此來防止加載有問題的模塊。

已知的硬件問題
- BusLogic設備被損壞並且致使啓動時死機。

這是一個內核的Bug目前尚未修正。

- PCMCIA讀卡器被認爲是可移除設備.

把它們加入到/etc/pmount.allow中,使用hal的pmount來讀取

自動加載帶來的一些問題
CPUFreq模塊

我門尚未找到一個很好的方法加載不一樣的CPUFreq控制器,因此咱們把從自動加載進程裏把它去掉了。若是您須要測量CPU頻率,你必須在rc.conf的MODULES隊列中顯式的加入合適的模塊。

聲音問題和一些不能自動加載的模塊
一些用戶跟蹤發現問題出在/etc/modprobe.conf中一些舊的部分,試着去掉這些舊的部分再試試看。
多個同類型設備(網卡,聲卡)每次啓動的都不一樣

由於udev同時加載全部模塊,因此一些設備可能初始化順序不一樣。例如同時有兩個網卡時,它們老是在eth0和eth1之間變來變去。

經常使用的解決辦法是在您的rc.conf文件中經過修改MODULES隊列來指明順序。這個隊列裏的模塊將在udev自動加載以前由系統加載,所以您能夠控制模塊在啓動時加載順序。

# 在e100以前加載8139too
MODULES=(8139too e100)

另外一個解決網卡的方法是使用udev-sanctified方法爲每一個網卡靜態命名。建立文件/etc/udev/rules.d/10-network.rules而後將不一樣的網卡經過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"

同時,您須要注意如下內容:

* 您能夠經過下面的命令得到網卡的MAC地址:: udevinfo -a -p /sys/class/net/<你的網卡>
* 注意在udev規則文件中使用小寫的16進制MAC地址,由於udev沒法識別大寫的MAC地址。
* 一些用戶在使用舊的命名方式時出現問題,例如: eth0, eth1, 等等. 若是出現這個問題,試試使用 "lan"或者"wlan"之類的名字.

注意不要忘記修改您的/dec/rc.conf和其它使用ethX命名的配置文件。

本身編譯內核形成的一些已知問題
Udev沒法啓動

請肯定您的內核版本大於或等於2.6.15。較早的內核沒有udev自動裝載所須要的uevent功能。

CD/DVD符號和權限錯誤

若是您使用2.6.15的內核的話,您須要安裝ABS的uevent補丁(它從2.6.16內核中抽取了一些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規則放到/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]」。在規則文件的文件名前加上數字(如:010.udev.rules)是個很好的主意,這樣udev在讀取標準規則前,將會讀取這個規則文件。這些規則設置後不須要修改/etc/fstab文件。請查看mount命令的參數來修改權限等特性(您能夠從論壇搜索查看mount命令的參數,而後根據您的須要修改它們)。
相關文章
相關標籤/搜索