Linux┊详解udev
是一小部分例子,如果你的系統(tǒng)采用了udev方式,那你應(yīng)該可以看到更多的規(guī)則。如果你想修改設(shè)備的權(quán)限或者創(chuàng)建信的符號(hào)連接,那么你需要熟讀這些規(guī)則,特別是要仔細(xì)注意你修改的那些與之相關(guān)的設(shè)備。
修改你的udev配置
在修改udev配置之前,我們一定要仔細(xì),通常的考慮是:你最好不要修改系統(tǒng)預(yù)置的那些規(guī)則,特別不要指定影響非常廣泛的配置,比如上面例子中的第一行。不正確的配置可能會(huì)導(dǎo)致嚴(yán)重的系統(tǒng)問題或者系統(tǒng)根本就無法這個(gè)正確的訪問設(shè)備。
而我們正確的做法應(yīng)該是在/etc/udev/rules.d/下創(chuàng)建一個(gè)信的規(guī)則文件。確定你給出的文件的后綴是rules文件名給出的數(shù)字序列應(yīng)該比 標(biāo)準(zhǔn)配置文件高。比如,你可以創(chuàng)建一個(gè)名為99-my-udev.rules的規(guī)則文件。在你的規(guī)則文件中,你可以指定任何你想修改的配置,比如,假設(shè)你 修改修改floppy設(shè)備的所在組,還準(zhǔn)備創(chuàng)建一個(gè)信的符號(hào)連接/dev/floppy,那你可以這么寫:
KERNEL==”fd[0-9]*“, GROUP=“users“,?? SYMLINK+=“floppy“
有些發(fā)行版本,比如Fedora,采用了外部腳本來修改某些特定設(shè)備的屬組,組關(guān)系和權(quán)限。因此上面的改動(dòng)可能并不見得生效。如果你遇到了這個(gè)問題,你就需要跟蹤和修改這個(gè)腳本來達(dá)到你的目的。或者你可以修改PROGRAM或RUN鍵的值來做到這點(diǎn)。
某些規(guī)則的修改可能需要更深的挖掘。比如,你可能想在一個(gè)設(shè)備上使用sysfs信息來唯一標(biāo)識(shí)一個(gè)設(shè)備。這些信息最好通過udevinfo命令來獲取。
$ udevinfo –a –p $(udevinfo –q path????? –n /dev/hda)上面的命令兩次使用udevinfo:一次是返回sysfs設(shè)備路徑(他通常和我們看到的Linux設(shè)備文件名所在路徑--/dev/hda--不同);第 二次才是查詢這個(gè)設(shè)備路徑,結(jié)果將是非常常的syfs信息匯總。你可以找到最夠的信息來唯一標(biāo)志你的設(shè)備,你可以采用適當(dāng)?shù)奶鎿Qudev配置文件中的 SYSFS選項(xiàng)。下面的結(jié)果就是上面的命令輸出
?
[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==""???
舉一個(gè)例子:假設(shè)你想修改USB掃描儀的配置。通過一系列的嘗試,你已經(jīng)為這個(gè)掃描儀標(biāo)識(shí)了Linux設(shè)備文件(每次打開掃描儀時(shí),名字都會(huì)變)。你可以使 用上面的命令替換這個(gè)正確的Linux設(shè)備文件名,然后定位輸出的采用SYSFS{idVendor}行和SYSFS{idProduct}行。最后你可 以使用這些信息來為這個(gè)掃描儀創(chuàng)建新的選項(xiàng)。
SYSFS{idVendor}=="0686",?? SYSFS{idProduct}=="400e",??
SYMLINK+="scanner", MODE="0664",?? group="scanner"上面的例子表示將掃描儀的組設(shè)置為scanner,訪問權(quán)限設(shè)置為0664,同時(shí)創(chuàng)建一個(gè)/dev/scanner的符號(hào)連接。
udev-FAQ
問:udev是什么? 它的目的何在?
答:udev是一種工具,它能夠根據(jù)系統(tǒng)中的硬件設(shè)備的狀態(tài)動(dòng)態(tài)更新設(shè)備文件,包括設(shè)備文件的創(chuàng)建,刪除等。設(shè)備文件通常放在/dev目錄下。使用udev后,在/dev目錄下就只包含系統(tǒng)中真正存在的設(shè)備。
問:udev支持什么內(nèi)核?
答:udev只支持linux-2.6內(nèi)核,因?yàn)閡dev嚴(yán)重依賴于sysfs文件系統(tǒng)提供的信息,而sysfs文件系統(tǒng)只在linux-2.6內(nèi)核中才有。
問:udev是一個(gè)內(nèi)核程序還是用戶程序?
答:udev是一個(gè)用戶程序(user-mode daemon)。
問:udev和devfs有什么差別?
答:udev能夠?qū)崿F(xiàn)所有devfs實(shí)現(xiàn)的功能。但udev運(yùn)行在用戶模式中,而devfs運(yùn)行在內(nèi)核模式中。據(jù)稱:devfs具有一些不太容易解決的先天缺陷。
問:udev的配置文件放在哪里?
答:udev是一個(gè)用戶模式程序。它的配置文件是/etc/udev/udev.conf。這個(gè)文件一般缺省有這樣幾項(xiàng):
udev_root=”/dev” ; udev產(chǎn)生的設(shè)備文件的根目錄是/dev
udev_db=”/dev/.udevdb” ; 通過udev產(chǎn)生的設(shè)備文件形成的數(shù)據(jù)庫
udev_rules=”/etc/udev/rules.d” ;用于指導(dǎo)udev工作的規(guī)則所在目錄。
udev_log=”err” ;當(dāng)出現(xiàn)錯(cuò)誤時(shí),用syslog記錄錯(cuò)誤信息。
問:udev的工作過程是怎樣的?
答:由于沒有研究過udev的源程序,不敢貿(mào)然就說udev的工作過程。我只是通過一些網(wǎng)上的資料和udev的說明文檔,大致猜測(cè)它的工作過程可能是這樣的。
當(dāng)內(nèi)核檢測(cè)到在系統(tǒng)中出現(xiàn)了新設(shè)備后,內(nèi)核會(huì)在sysfs文件系統(tǒng)中為該新設(shè)備生成一項(xiàng)新的記錄,一般sysfs文件系統(tǒng)會(huì)被mount到/sys目錄中。新記錄是以一個(gè)或多個(gè)文件或目錄的方式來表示。每個(gè)文件都包含有特定的信息。(信息是如何表述的,還要另外研究?)
udev在系統(tǒng)中是以守護(hù)進(jìn)程的方式udevd在運(yùn)行,它通過某種途徑(到底什么途徑,目前還沒搞懂。)檢測(cè)到新設(shè)備的出現(xiàn),通過查找設(shè)備對(duì)應(yīng)的sysfs中的記錄得到設(shè)備的一些信息。
udev會(huì)根據(jù)/etc/udev/udev.conf文件中的udev_rules指定的目錄,逐個(gè)檢查該目錄下的文件,這個(gè)目錄下的文件都是針對(duì)某類或某個(gè)設(shè)備應(yīng)該施行什么措施的規(guī)則文件。udev讀取文件是按照文件名的ASCII字母順序來讀取的,如果udev一旦找到了與新加入的設(shè)備匹配的規(guī)則,udev就會(huì)根據(jù)規(guī)則定義的措施對(duì)新設(shè)備進(jìn)行配置。同時(shí)不再讀后續(xù)的規(guī)則文件。
問:udev的規(guī)則文件的語法是怎樣的?
答:udev的規(guī)則文件以行為單位,以”#”開頭的行代表注釋行。其余的每一行代表一個(gè)規(guī)則。每個(gè)規(guī)則分成一個(gè)或多個(gè)“匹配”和“賦值”部分。“匹配”部分用“匹配“專用的關(guān)鍵字來表示,相應(yīng)的“賦值”部分用“賦值”專用的關(guān)鍵字來表示。“匹配”關(guān)鍵字包括:ACTION,KERNEL,BUS,SYSFS等等,“賦值”關(guān)鍵字包括:NAME,SYMLINK,OWNER等等。具體詳細(xì)的描述可以閱讀udev的man文檔。
下面舉個(gè)例子來說明一下,有這樣一條規(guī)則:SUBSYSTEM==”net”, ACTION==”add”, SYSFS{address}==”00:0d:87:f6:59:f3″, IMPORT=”/sbin/rename_netiface %k eth0″
這個(gè)規(guī)則中的“匹配”部分有三項(xiàng),分別是SUBSYSTEM,ACTION和SYSFS。而”賦值”部分有一項(xiàng),是IMPORT。這個(gè)規(guī)則就是說,當(dāng)系統(tǒng)中出現(xiàn)的新硬件屬于net子系統(tǒng)范疇,系統(tǒng)對(duì)該硬件采取的動(dòng)作是加入這個(gè)硬件,且這個(gè)硬件在SYSFS文件系統(tǒng)中的“address”信息等于“00:0d…”時(shí),對(duì)這個(gè)硬件在udev層次施行的動(dòng)作是調(diào)用外部程序/sbin/rename_netiface,傳遞的參數(shù)有兩個(gè),一個(gè)是“%k”,代表內(nèi)核對(duì)該新設(shè)備定義的名稱。另一個(gè)是”eth0“。??? 從上面這個(gè)例子中可以看出,udev的規(guī)則的寫法比較靈活的,尤其在“匹配”部分中,可以通過諸如”*“, ”?“,[a-c],[1-9]等shell通配符來靈活匹配多個(gè)匹配項(xiàng)。具體的語法可以參考udev的man文檔。
問:udev怎樣做到不管設(shè)備連接的順序而維持一個(gè)統(tǒng)一的設(shè)備名?
答:實(shí)際上,udev是通過對(duì)內(nèi)核產(chǎn)生的設(shè)備名增加別名的方式來達(dá)到上述目的的。前面說過,udev是用戶模式程序,不會(huì)更改內(nèi)核的行為。因此,內(nèi)核依然會(huì)我行我素地產(chǎn)生設(shè)備名如sda,sdb等。但是,udev可以根據(jù)設(shè)備的其他信息如總線(bus),生產(chǎn)商(vendor)等不同來區(qū)分不同的設(shè)備,并產(chǎn)生設(shè)備文件。udev只要為這個(gè)設(shè)備文件取一個(gè)固定的文件名就可以解決這個(gè)問題。在后續(xù)對(duì)設(shè)備的操作中,只要引用新的設(shè)備名就可以了。但為了保證最大限度的兼容,一般來說,新設(shè)備名總是作為一個(gè)對(duì)內(nèi)核自動(dòng)產(chǎn)生的設(shè)備名的符號(hào)鏈接(link)來使用的。
例如:內(nèi)核產(chǎn)生了sda設(shè)備名,而根據(jù)信息,這個(gè)設(shè)備對(duì)應(yīng)于是我的內(nèi)置硬盤,那我就可以制定udev規(guī)則,讓udev除了產(chǎn)生/dev/sda設(shè)備文件外,另外創(chuàng)建一個(gè)符號(hào)鏈接叫/dev/internalHD。這樣,我在fstab文件中,就可以用/dev/internalHD來代替原來的/dev/sda了。下次,由于某些原因,這個(gè)硬盤在內(nèi)核中變成了sdb設(shè)備名了,那也不用著急,udev還會(huì)自動(dòng)產(chǎn)生/dev/internalHD這個(gè)鏈接,并指向正確的/dev/sdb設(shè)備。所有其他的文件像fstab等都不用修改。
問:怎樣才能找到這些設(shè)備信息,并把他們放到udev的規(guī)則文件中來匹配呢?
答:這個(gè)問題比較難,網(wǎng)上資料不多,我只找到一篇文章來介紹如何寫udev的規(guī)則。他的基本方法是通過udevinfo這個(gè)實(shí)用程序來找到那些可以作為規(guī)則文件里的匹配項(xiàng)的項(xiàng)目。有這樣兩種情況可以使用這個(gè)工具:
第一種情況是,當(dāng)你把設(shè)備插入系統(tǒng)后,系統(tǒng)為設(shè)備產(chǎn)生了設(shè)備名(如/dev/sda)。那樣的
話,你先用udevinfo -q path -n/dev/sda,命令會(huì)產(chǎn)生一個(gè)該設(shè)備名對(duì)應(yīng)的在sysfs下的路徑,如/block/sda。然后,你再用udevinfo -a -p/sys/block/sda,這個(gè)命令會(huì)顯示一堆信息,信息分成很多塊。這些信息實(shí)際來自于操作系統(tǒng)維護(hù)的sysfs鏈表,不同的塊對(duì)應(yīng)不同的路徑。你就可以用這些信息來作為udev規(guī)則文件中的匹配項(xiàng)。但需要注意的是,同一個(gè)規(guī)則只能使用同一塊中顯示的信息,不能跨塊書寫規(guī)則。
第二種情況是,不知道系統(tǒng)產(chǎn)生的設(shè)備名,那就只有到/sys目錄下去逐個(gè)目錄查找了,反復(fù)用udevinfo -a -p/sys/path…這個(gè)命令看信息,如果對(duì)應(yīng)的信息是這個(gè)設(shè)備的,那就恭喜你。否則就再換個(gè)目錄。當(dāng)然,在這種情況下,成功的可能性比較小。
問: udev和devfs是什么關(guān)系
答: udev完全在用戶態(tài)(userspace)工作,利用設(shè)備加入或移除時(shí)內(nèi)核所發(fā)送的hotplug事件(event)來工作。關(guān)于設(shè)備的詳細(xì)信息是由內(nèi)核輸出(export)到位于/sys的sysfs文件系統(tǒng)的。所有的設(shè)備命名策略、權(quán)限控制和事件處理都是在用戶態(tài)下完成的。與此相反,devfs是作為內(nèi)核的一部分工作的。
問: 如果udev不能完成所有devfs的工作的話,為什么把devfs標(biāo)記為OBSOLETE/removed?
答: 引用 Al Viro (Linux VFS 內(nèi)核維護(hù)者):
-devfs所做的工作被確信可以在用戶態(tài)來完成。
-devfs被加入內(nèi)核之時(shí),大家寄望它的質(zhì)量可以迎頭趕上。
-devfs被發(fā)現(xiàn)了一些可修復(fù)和無法修復(fù)的 bug。
-對(duì)于可修復(fù)的 bug,幾個(gè)月前就已經(jīng)被修復(fù)了,其維護(hù)者認(rèn)為一切良好。
-對(duì)于后者,同樣是相當(dāng)常一段時(shí)間以來沒有改觀了。
-devfs的維護(hù)者和作者對(duì)它感到失望并且已經(jīng)停止了對(duì)代碼的維護(hù)工作。
問: 但是當(dāng)一個(gè)并不存在的/dev節(jié)點(diǎn)被打開的時(shí)候,udev并不能如devfs一樣自動(dòng)加載驅(qū)動(dòng)程序。
答: 的確如此,但Linux的設(shè)計(jì)是在設(shè)備被發(fā)現(xiàn)的時(shí)候加載模塊,而不是當(dāng)它被訪問的時(shí)候。
問: 不過等等,我確實(shí)希望 udev 可以在不存在的節(jié)點(diǎn)被打開的時(shí)候自動(dòng)加載驅(qū)動(dòng)。這是我使用devfs的唯一原因了。給udev 增加這個(gè)功能吧。
答: 不,udev 是用來管理/dev 的,不是用來加載內(nèi)核驅(qū)動(dòng)的。
問: 嗨,求你們了。這不難做到的。
答: 這么個(gè)功能對(duì)于一個(gè)配置正確的計(jì)算機(jī)是多余的。系統(tǒng)中所有的設(shè)備都應(yīng)該產(chǎn)生hotplug 事件、加載恰當(dāng)?shù)尿?qū)動(dòng),而 udev 將會(huì)注意到這點(diǎn)并且為它創(chuàng)建對(duì)應(yīng)的設(shè)備節(jié)點(diǎn)。如果你不想讓所有的設(shè)備驅(qū)動(dòng)停留在內(nèi)存之中,應(yīng)該使用其它東西來管理你的模塊(如腳本, modules.conf, 等等) 這不是udev 的工作。
問: 但是我真的喜歡那個(gè)功能,還是加上吧
答: devfs用的方法導(dǎo)致了大量無用的modprobe嘗試,以此程序探測(cè)設(shè)備是否存在。每個(gè)試探性探測(cè)都新建一個(gè)運(yùn)行 modprobe 的進(jìn)程,而幾乎所有這些都是無用的。
問: 我喜歡devfs的設(shè)備文件命名方式,udev 可以這樣命名么?
答: 可以,udev 可以使用 /dev 的命名策略來創(chuàng)建節(jié)點(diǎn)。通過一個(gè)配置文件,可以把內(nèi)核缺省的名字映射到 devfs 的名字。可以看看udev 中帶的 udev.rules.devfs 文件。注意: devfs 的命名方式是不被建議并且不被官方支持的,因?yàn)樗玫暮?jiǎn)單枚舉設(shè)備的方式在設(shè)備可能被隨時(shí)加入或刪除的情況下確實(shí)是一個(gè)比較笨的方法。這些編號(hào)代給你的將只有麻煩,而并不能用來確定設(shè)備。看看那個(gè)永久性磁盤 (persistentdisk) 的規(guī)則就知道如何在用戶態(tài)下正確的做這件事,而不是傻傻地列出設(shè)備。
問: udev 可以為哪些設(shè)備創(chuàng)建節(jié)點(diǎn)?
答: 所有在 sysfs 中顯示的設(shè)備都可以由 udev 來創(chuàng)建節(jié)點(diǎn)。如果內(nèi)核中增加了其它設(shè)備的支持,udev 也就自動(dòng)地可以為它們工作了。現(xiàn)在所有的塊設(shè)備都在被支持之列,大部分的主字符設(shè)備也是被支持的。內(nèi)核開發(fā)者們正致力于讓所有的字符設(shè)備都被支持。可以到linux-kernel郵件列表上尋找補(bǔ)丁或是查看補(bǔ)丁的狀態(tài)。
問: udev 是否會(huì)去掉匿名設(shè)備數(shù)量的限制?
答: udev 完全工作于用戶態(tài)。如果內(nèi)核支持了更多的匿名設(shè)備,udev就會(huì)支持。
問: udev 是否會(huì)支持符號(hào)鏈接?
答: udev 現(xiàn)在就支持符號(hào)鏈接,每個(gè)設(shè)備節(jié)點(diǎn)擁有多個(gè)符號(hào)鏈接也是被支持的。
問: udev如何處理/dev文件系統(tǒng)?
答: 建議使用一個(gè)每次啟動(dòng)系統(tǒng)的時(shí)候重新創(chuàng)建的 tmpfs 作為 /dev 的文件系統(tǒng)。不過實(shí)際上udev并不關(guān)心那種文件系統(tǒng)在被使用。
問: 在 init 運(yùn)行之前,udev 如何處理設(shè)備?
答: udev 可以被放入 initramfs 之中,并在每個(gè)設(shè)備被發(fā)現(xiàn)的時(shí)候運(yùn)行。也可以讓udev 工作在一個(gè)真的根分區(qū)被加載之后根據(jù) /sys 的內(nèi)容創(chuàng)建的初始/dev目錄之中。
問: 我是否可以利用 udev 在一個(gè) USB 設(shè)備被加載的時(shí)候自動(dòng)加載上這個(gè)設(shè)備?
答: 技術(shù)上講是可以的,但是 udev 不是用于這個(gè)工作的。所有的主流發(fā)布版 (distro)都包含了 HAL (http://freedesktop.org/wiki/Software_2fhal) 用于這個(gè)工作,它也是專門用于監(jiān)視設(shè)備變更的,并且集成進(jìn)入了桌面軟件。
換個(gè)角度說,這可以簡(jiǎn)單的通過 fstab 來實(shí)現(xiàn):/dev/disk/by-label/PENDRIVE /media/PENDRIVE vfat user,noauto 0 0
這樣,用戶可以用如下命令來訪問設(shè)備:
$mount /media/PENDRIVE
同樣不需要管理員權(quán)限,但卻擁有了設(shè)備的全部訪問權(quán)限。使用永久性磁盤鏈接(label, uuid) 將可以指定同一設(shè)備,無論其實(shí)際上的內(nèi)核名字是什么。
問: 有什么我需要注意的安全問題么?
答: 當(dāng)使用動(dòng)態(tài)設(shè)備編號(hào)的時(shí)候,一個(gè)給定的主/從設(shè)備號(hào)可能在不同時(shí)間對(duì)應(yīng)不同的設(shè)備,如果一個(gè)用戶擁有對(duì)這個(gè)節(jié)點(diǎn)的訪問權(quán)限,并且可以創(chuàng)建一個(gè)到這個(gè)節(jié)點(diǎn)的硬鏈接,他就可以如此得到一個(gè)這個(gè)設(shè)備節(jié)點(diǎn)的拷貝。當(dāng)設(shè)備被移除之后,udev 刪除了設(shè)備節(jié)點(diǎn),但硬鏈接依然存在。如果這個(gè)設(shè)備節(jié)點(diǎn)之后被重新使用不同的訪問權(quán)限被創(chuàng)建的時(shí)候,其硬鏈接仍然可以使用先前的訪問權(quán)限來訪問。(同樣的問題也存在在使用 PAM 改變?cè)L問權(quán)限的 login 上。)
簡(jiǎn)單的解決方案就是通過把 /dev 放在 tmpfs 這樣的單獨(dú)的文件系統(tǒng)之上來防止建立硬鏈接。
轉(zhuǎn)載于:https://www.cnblogs.com/lvdongjie/p/7053716.html
總結(jié)
以上是生活随笔為你收集整理的Linux┊详解udev的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 计算机浮点数运算误差与解决误差的算法
- 下一篇: java RSA加密解密实现(含分段加密