歡迎您光臨本站 註冊首頁

介紹現代Linux系統的設備管理

←手機掃碼閱讀     火星人 @ 2014-03-09 , reply:0

  現代Linux發行版可以在已經運行的系統裡面識別一個新加入的硬體.有許多用戶友好的發行版,比如Ubuntu,可以在像iPod這樣的移動設備插入系統時自動運行指定的應用程序,比如Rhythmbox.

  Linux發行版裡面的熱插拔(這個詞用於描述將設備插入已經運行的系統的過程)功能是三個組件的融合:Udev, HAL, and Dbus.

  Udev為已經連接在系統上面的設備節點提供一個動態設備目錄.當設備插入或移出系統的時候,Udev就在 /dev目錄下面創建或者刪除設備節點文件.Dbus類似於系統匯流排,主要用於進程間通信.HAL從Udev的服務中獲取信息,當一個設備連接到系統時它 就創建關於這個設備的XML描述.然後它會通過Dbus通知相應的桌面應用程序,比如說Nautilus,Nautius則會打開這個新掛載設備上面的文 件.

  本文只關注Udev, 是它完成了基本的設備識別.

  什麼是Udev?

  Udev是Linux 2.6內核的設備管理器,它在/dev目錄下動態地創建/移除設備節點.它是devfs和hotplug的繼承者,運行在用戶空間,並且用戶可以用Udev規則來改變設備的命名.

  Udev依賴2.5內核引入的sysfs文件系統.sysfs是的設備在用戶空間可見.每當一個設備被加入或移除,就會產生內核事件通知用戶空間的Udev.

  在早期的發行中常使用一個外部二進位文件/sbin/hotplug來將設備狀態的改變通知Udev.現在這個工具已經被替換掉,Udev可以通過Netlink直接監聽這些事件了.

  為什麼我們需要它 ?

  在早期的內核中/dev目錄包括一些靜態的設備文件.而使用動態設備創建后,只有那些真正存在於系統中的設備節點才會被創建.讓我們來看看靜態/dev目錄的缺點,正是這些缺點導致了Udev的開發.

  在/dev的設備節點中精確辨別一個硬體設備的問題

  在系統啟動過程中,內核會為一個識別到的硬體設備分配一個主/次設備號對.讓我們考慮兩個硬碟,連接/校準的的方式是一個連接到主介面,另一個連接 到從介面.Linux系統會稱它們為/dev/hda和/dev/hdb.現在,如果我們交換兩個磁碟,那麼它們的設備名也會改變.這是的將一個可用的動 態設備節點定位到正確的設備發生困難.當有一堆的硬碟連接在系統時,情況會變得更加糟糕.

  Udev通過/dev目錄提供了一個永久性設備命名系統,是的定位設備變得容易.

  下面是一個例子,顯示了Udev為接入系統的硬碟創建的永久性符號鏈接.

  $ ls -lR /dev/disk//dev/disk/by-id:lrwxrwxrwx 1 root root 9 Jul 4 06:48 scsi-SATA_WDC_WD800JD-75M_WD-WMAM9UT48593 -> ../../sda lrwxrwxrwx 1 root root 10 Jul 4 06:48 scsi-SATA_WDC_WD800JD-75M_WD-WMAM9UT48593-part1 -> ../../sda1lrwxrwxrwx 1 root root 10 Jul 4 06:48 scsi-SATA_WDC_WD800JD-75M_WD-WMAM9UT48593-part2 -> ../../sda2lrwxrwxrwx 1 root root 10 Jul 4 06:48 scsi-SATA_WDC_WD800JD-75M_WD-WMAM9UT48593-part3 -> ../../sda3lrwxrwxrwx 1 root root 10 Jul 4 06:48 scsi-SATA_WDC_WD800JD-75M_WD-WMAM9UT48593-part4 -> ../../sda4lrwxrwxrwx 1 root root 10 Jul 4 06:48 scsi-SATA_WDC_WD800JD-75M_WD-WMAM9UT48593-part5 -> ../../sda5lrwxrwxrwx 1 root root 10 Jul 4 06:48 scsi-SATA_WDC_WD800JD-75M_WD-WMAM9UT48593-part6 -> ../../sda6lrwxrwxrwx 1 root root 10 Jul 4 06:48 scsi-SATA_WDC_WD800JD-75M_WD-WMAM9UT48593-part7 -> ../../sda7/dev/disk/by-label:lrwxrwxrwx 1 root root 10 Jul 4 06:48 1 -> ../../sda6lrwxrwxrwx 1 root root 10 Jul 4 06:48 boot1 -> ../../sda2lrwxrwxrwx 1 root root 10 Jul 4 06:48 project -> ../../sda3lrwxrwxrwx 1 root root 10 Jul 4 06:48 SWAP-sda7 -> ../../sda7/dev/disk/by-path:lrwxrwxrwx 1 root root 9 Jul 4 06:48 pci-0000:00:1f.2-scsi-0:0:0:0 -> ../../sdalrwxrwxrwx 1 root root 10 Jul 4 06:48 pci-0000:00:1f.2-scsi-0:0:0:0-part1 -> ../../sda1lrwxrwxrwx 1 root root 10 Jul 4 06:48 pci-0000:00:1f.2-scsi-0:0:0:0-part2 -> ../../sda2lrwxrwxrwx 1 root root 10 Jul 4 06:48 pci-0000:00:1f.2-scsi-0:0:0:0-part3 -> ../../sda3lrwxrwxrwx 1 root root 10 Jul 4 06:48 pci-0000:00:1f.2-scsi-0:0:0:0-part4 -> ../../sda4lrwxrwxrwx 1 root root 10 Jul 4 06:48 pci-0000:00:1f.2-scsi-0:0:0:0-part5 -> ../../sda5lrwxrwxrwx 1 root root 10 Jul 4 06:48 pci-0000:00:1f.2-scsi-0:0:0:0-part6 -> ../../sda6lrwxrwxrwx 1 root root 10 Jul 4 06:48 pci-0000:00:1f.2-scsi-0:0:0:0-part7 -> ../../sda7/dev/disk/by-uuid:lrwxrwxrwx 1 root root 10 Jul 4 06:48 18283DC6283DA422 -> ../../sda1lrwxrwxrwx 1 root root 10 Jul 4 06:48 25a4068c-e84a-44ac-85e6-461b064d08cd -> ../../sda6lrwxrwxrwx 1 root root 10 Jul 4 06:48 3ea7cf15-511b-407a-a56b-c6bfa046fd9f -> ../../sda5lrwxrwxrwx 1 root root 10 Jul 4 06:48 8878a0a4-604e-4ddf-b62c-637c4fa84d3f -> ../../sda2lrwxrwxrwx 1 root root 10 Jul 4 06:48 e50bcd6d-61ea-4b05-81a8-3cbe17ad6674 -> ../../sda3永久性設備命名為識別硬體設備省去了很多麻煩.

  /dev中的巨多設備節點

  在設備節點的靜態創建模型中,沒有辦法可以分辨出硬體設備是否真的存在於系統之中.因此,所有這會兒被Linux認識的設備都會創建好設備節點./dev中巨大數目的設備節點是的鑒別一個系統中存在的設備變得困難.

  主/次設備號對不夠了

  近年來需要包含的靜態設備節點的數目增加得太多,以至於以前所使用的8位模式用來處理所有的設備變得不夠用了.因此主/次設備號對開始用光了.

  字元設備和塊設備擁有固定分配的主/次設備號對.分配主/次設備號對的官方機構是Linux Assigned Name and Number Authority.但是,一台機器不會使用所有可能的設備,因此一個系統中肯定有未使用的主/次設備號.在這種情況下,那台機器的內核就可以借用那些未使用設備的主/次設備號,給其他一些需要的設備.

  有時候這樣會產生問題.用戶空間操作設備的應用程序未必會感知設備號的變化.對於用戶空間的程序,LANANA分配的設備號非常重要.因此,主/次設備號的改變必須通知這些應用程序.這被稱為主/次設備號的動態分配,Udev完成了這項任務.

  Udev的目標

  運行在用戶空間.

  創建永久性設備名, 將設備命名蔥內核空間剝離,並且基於設備命名實現一些規則.

  在/dev中為存在於系統的設備動態創建設備節點,並且為之動態分配主/次設備號.

  提供用戶空間的API,用於訪問系統中的設備信息.

  安裝Udev

  Udev是2.6內核中的預設設備管理器.幾乎所有的現代Linux發行版都會將Udev作為默認安裝的一部分.你也可以從linux/utils/kernel/hotplug/">http://www.kernel.org/pub/linux/utils/kernel/hotplug/這裡獲取Udev.最新版本的Udev需要2.6.25的內核,並且開啟了sysfs, procfs, signalfd, inotify, Unix domain sockets, networking和 hotplug的支持.

  CONFIG_HOTPLUG=yCONFIG_UEVENT_HELPER_PATH=」"CONFIG_NET=yCONFIG_UNIX=yCONFIG_SYSFS=yCONFIG_SYSFS_DEPRECATED*=nCONFIG_PROC_FS=yCONFIG_TMPFS=yCONFIG_TMPFS_POSIX_ACL=y CONFIG_INOTIFY=yCONFIG_SIGNALFD=y作為一個更加可靠的操作,內核必須不使用CONFIG_SYSFS_DEPRECATED*選項.

  Udev依賴於proc和sys文件系統,並且它們必須掛載在/proc和/sys.

  Udev的工作

  Udev守護進程監聽一個netlink套接字,這個套接字是內核用來與用戶空間的應用程序進行通信的.當一個設備被加入或移出系統時,內核可能會 通過這個netlink套接字發送一大堆的數據.Udev守護進程截取所有這些數據並完成剩下的工作,也就是創建設備節點,載入模塊,等等.

  內核設備事件管理

  啟動初始化時, /dev目錄使用tmpfs掛載.

  然後, Udev拷貝/lib/udev/devices 的靜態設備節點到 /dev 目錄.

  Udev守護進程開始運行,為所有連接到系統的設備收集來自內核的uevents.

  Udev守護進程解析uevent數據,並且對/etc/udev/rules.d中指定的規則進行匹配.

  根據指定的規則為設備創建設備節點和符號鏈接.

  Udev守護進程讀取/etc/udev/rules.d/*.rules 中的規則並且保存到內存裡面.

  Udev接收接收inotify事件,如果某個規則發生了改變,讀取這些改變並更新內存副本.

  設備驅動程序載入

  Udev使用modalias方法來載入設備驅動程序. 位於/lib/modules/`uname -r`/modules.alias 的modalias文件用於協助Udev載入設備驅動. modalias文件由depmod命令創建,包括了設備驅動的別名.

  讓我們檢查一個Linux設備驅動載入的例子:

  我使用一個C程序來從netlink套接字收集數據,並且使用它們來創建設備節點以及載入模塊.

  [root@arch ~]# ./a.outadd@/devices/pci0000:00/0000:00:02.1/usb1/1-4ACTION=addDEVPATH=/devices/pci0000:00/0000:00:02.1/usb1/1-4SUBSYSTEM=usbMAJOR=189MINOR=1DEVTYPE=usb_deviceDEVICE=/proc/bus/usb/001/002PRODUCT=1058/1010/105TYPE=0/0/0BUSNUM=001DEVNUM=002SEQNUM=1163add@/devices/pci0000:00/0000:00:02.1/usb1/1-4/1-4:1.0ACTION=addDEVPATH=/devices/pci0000:00/0000:00:02.1/usb1/1-4/1-4:1.0SUBSYSTEM=usbDEVTYPE=usb_interfaceDEVICE=/proc/bus/usb/001/002PRODUCT=1058/1010/105 …………………………………………你可以看到它提供了很多關於這個設備的信息.這其中包括了用來告訴Udev載入某個特定模塊的modalias變數.

  modalias數據看起來像這樣:

  MODALIAS=pci:v000010ECd00008169sv00001385sd0000311Abc02sc00i00The modalias data contains all the information required to find the corresponding device driver :

  pci :- 這是一個PCI設備 v :- 設備的廠商ID. 在這裡就是 000010EC ( 即 10EC )d :- 設備的設備ID. 在這裡就是 00008169 ( 即 8169 )sv 和 sd 是廠商和設備的子系統版本號. 依據ID查找一個PCI設備的廠商/產品的最好地方是 http://www.pcidatabase.com.

  Udev使用modalias數據來從/lib/modules/`uname -r`/modules.alias 查找正確的設備驅動.

  $ grep -i 10EC /lib/modules/`uname -r`/modules.alias | grep -i 8169alias pci:v000010ECd00008129sv*sd*bc*sc*i* r8169alias pci:v000010ECd00008169sv*sd*bc*sc*i* r8169你可以看到適合這個設備的模塊是r8169. 讓我們獲取關於這個驅動程序的更多的信息.

  $ /sbin/modinfo r8169filename: /lib/modules/2.6.18-53.el5/kernel/drivers/net/r8169.koversion: 2.2LK-NAPIlicense: GPLdescription: RealTek RTL-8169 Gigabit Ethernet driverauthor: Realtek and the Linux r8169 crew srcversion: D5EDA4980B92CA2CF677B62alias: pci:v00001737d00001032sv*sd00000024bc*sc*i*alias: pci:v000016ECd00000116sv*sd*bc*sc*i*alias: pci:v00001186d00004300sv*sd*bc*sc*i*alias: pci:v000010ECd00008129sv*sd*bc*sc*i*alias: pci:v000010ECd00008169sv*sd*bc*sc*i*depends:vermagic: 2.6.18-53.el5 SMP mod_unload 686 REGPARM 4KSTACKS gcc-4.1parm: media:force phy operation. Deprecated by ethtool (8). (array of int)parm: rx_copybreak:Copy breakpoint for copy-only-tiny-frames (int)parm: use_dac:Enable PCI DAC. Unsafe on 32 bit PCI slot. (int)parm: debug:Debug verbosity level (0=none, …, 16=all) (int)注意查看從"depends」開始的那些行. 它描述了r8169這個模塊所依賴的其他一些模塊.因此Udev也會載入這些模塊.

  規則處理和設備節點創建

  如前所述,Udev會為內核中每個設備狀態的改變解析/etc/udev/rules.d/ 中的規則.Udev規則可以用於在用戶空間操作設備節點的名字/許可權/符號鏈接.

  讓我們看一些示例規則,有利於幫助你更好地理解Udev規則.

  內核通過netlink提供的數據可以被Udev用來創建設備節點.這些數據包括主/次設備號對和另外一些設備相關的數據,比如設備/廠商id,設備序列號等.Udev規則可以匹配所有的這些數據,並且用來改變設備節點的名字,創建符號鏈接,或者註冊網路連接.

  下面這個例子展示了怎樣書寫Udev規則來重命名系統中的一個網路設備.

  我們需要得到一些用於創建規則的設備信息.

  # udevadm info -a -p /sys/class/net/eth0/llooking at device '/devices/pci0000:00/0000:00:04.0/0000:01:06.0/net/eth0':KERNEL==」eth0″SUBSYSTEM==」net」DRIVER==」"ATTR{addr_len}==」6″ATTR{dev_id}==」0×0″ATTR{ifalias}==」"ATTR{iflink}==」3″ATTR{ifindex}==」3″ATTR{features}==」0×829″ATTR{type}==」1″ATTR{link_mode}==」0″ATTR{address}==」00:80:48:62:2a:33″ATTR{broadcast}==」ff:ff:ff:ff:ff:ff」ATTR{carrier}==」1″ATTR{dormant}==」0″ATTR{operstate}==」unknown」ATTR{mtu}==」1500″ATTR{flags}==」0×1003″ATTR{tx_queue_len}==」1000″looking at parent device 『/devices/pci0000:00/0000:00:04.0/0000:01:06.0′:KERNELS==」0000:01:06.0″SUBSYSTEMS==」pci」DRIVERS==」8139too」ATTRS{vendor}==」0×10ec」ATTRS{device}==」0×8139″ATTRS{subsystem_vendor}==」0×10ec」ATTRS{subsystem_device}==」0×8139″ATTRS{class}==」0×020000″ATTRS{irq}==」19″ATTRS{local_cpus}==」ff」ATTRS{local_cpulist}==」0-7″ATTRS{modalias}==」pci:v000010ECd00008139sv000010ECsd00008139bc02sc00i00″ATTRS{enable}==」1″ATTRS{broken_parity_status}==」0″ATTRS{msi_bus}==」"looking at parent device 『/devices/pci0000:00/0000:00:04.0′:KERNELS==」0000:00:04.0″SUBSYSTEMS==」pci」DRIVERS==」"ATTRS{vendor}==」0×10de」ATTRS{device}==」0×03f3″ATTRS{subsystem_vendor}==」0×0000″ATTRS{subsystem_device}==」0×0000″ATTRS{class}==」0×060401″ATTRS{irq}==」0″ATTRS{local_cpus}==」ff」ATTRS{local_cpulist}==」0-7″ATTRS{modalias}==」pci:v000010DEd000003F3sv00000000sd00000000bc06sc04i01″ATTRS{enable}==」1″ATTRS{broken_parity_status}==」0″ATTRS{msi_bus}==」1″looking at parent device 『/devices/pci0000:00′:KERNELS==」pci0000:00″SUBSYSTEMS==」"DRIVERS==」"你可以發現Udev擁有大量關於這個網路設備的信息.讓我們深入檢查一下:

  KERNEL=="eth0" :- 該設備的內核名字是eth0DRIVERS==」8139too」 :- 載入的驅動程序是8139tooATTR{address}==」00:80:48:62:2a:33″ :- 該設備的硬體地址ATTRS{vendor}==」0×10ec」 :- 廠商 idATTRS{device}==」0×8139″ :- 設備 id讓我們創建一個規則來將這個網路設備重命名為eth1 (這個名字將是永久性的並且重啟系統以後也不會復原).

  >[root@arch ~]# cat /etc/udev/rules.d/70-persistent-net.rulesSUBSYSTEM==」net」, ACTION==」add」, DRIVERS==」?*」, ATTR{address}==」00:80:48:62:2a:33″, ATTR{type}==」1″, KERNEL==」eth*」, NAME=」eth1″這個規則就將這個設備重命名成了eth1. 用這種方式我們可以很容易地管理系統中的網路設備或者其他設備節點.

  Udev 實用工具

  Udev提供了一些用戶空間的實用程序,用於管理系統中的設備和設備節點.在所有最近的Linux發行版中都可以找到的這樣的一個命令就是'udevadm',udevadm這個命令在功能上可以實現上面提到的各個命令完成的所有任務.

  這個工具可以用來在正在運行的系統裡面重新生成設備節點,如下所示:

  [root@arch ~]# ls -l /dev/ | wc -l150[root@arch ~]# rm -rf /dev/*rm: cannot remove `/dev/pts/0′: Operation not permittedrm: cannot remove directory `/dev/shm』: Device or resource busy[root@arch ~]# ls -l /dev/ | wc -l4[root@arch ~]# udevadm trigger[root@arch ~]# ls -l /dev/ | wc -l150有更多的其他有用的操作都可以通過udevadm命令完成.你可以通過udevadm的man手冊頁來獲取更多的信息.

  Udev的未來會怎樣 ?

  預測Linux子系統的將來是不可能的.Linux正在快速開發的過程當中,因此預測Linux的內核的未來是不明智的.DEVfs曾經被當作靜態設備節點的一個解決方案被引入,但是在經歷一小段時間之後就消失了.而Udev則被證明是現代Linux內核中一個成功的設備管理器,並且有希望在未來的 發布中成為一個更加穩定,多功能的設備管理系統.


[火星人 ] 介紹現代Linux系統的設備管理已經有458次圍觀

http://coctec.com/docs/linux/show-post-52243.html