第二章:Udev硬件設備管理機制數據庫
·理解Linux中的Udev是如何管理硬件設備;服務器
·學習如何爲自定義設備名編寫udev規則;架構
在Linux系統中,內核的主要功能能夠分爲5大部分:文件系統、內存調度、進程調度、協議管理、硬件管理。其中的硬件管理就是由Udev提供的。app
系統中的/dev目錄是一個包含了大量設備條目的目錄,經過Udev來對設備進行管理,給設備提供對應的名稱空間,爲設備命名,應用程序能夠查詢設備是否存在以及設備的名稱等。它同時也是用來接替devfs及hotplug的功能,這意味着它要在添加/刪除硬件時處理/dev目錄以及全部用戶空間的行爲。Udev聽從LSB(Linux Standard Based)的標準,但也支持用戶自定義的規則。很重要的一點,Udev是一個極其小而精的程序,因此嵌入式設備上經常使用它。socket
HAL(Hardware Abstraction Layer)硬件抽象層是一個爲設備服務的程序,應用程序須要瞭解任何硬件設備信息或底層架構,只須要跟HAL索取相應的設備信息便可,簡單點說,硬件抽象層就是介於硬件層和應用層之間一個起着橋樑做用的邏輯層服務。ide
HAL爲每個物理上接入到計算機的設備加入到一個實時數據庫中,爲每一個設備對象提供了一個API去使用D-bus(system message bus)系統總線,應用程序可使用API在設備上進行發現、監控、調用等操做。系統中會有一個hald的服務,他即是HAL的服務,但內核發現新設備時,hald將通告應用程序進行識別。可使用hal-device-manager來查看存儲在HAL中的設備信息,在view菜單下,選擇Device Properties能夠查看該設備的詳細信息。工具
HAL管理的設備信息是以文件的形式存在,其配置文件存放在/usr/share/hal/fdi/下,用戶管理配置文件存放在/etc/hal/fdi/下,且數據文件都是以.fdi爲後綴的。在設備信息文件裏面有3個部分:Information、Policy、Preprobe。分別包含了設備信息、策略和設備配置信息。學習
能夠經過查看/usr/share/doc/hal-version/spec文檔來了解HAL更多的信息。spa
1.當一個設備插入到計算機,系統內核檢測到插入的設備,並將設備的信息寫入到/sys中。Sysfs是一個內核級別的保持追蹤全部設備的設備虛擬文件系統,在系統中掛載爲/sys。debug
2.經過netlink socket(一個在內核和用戶空間之間傳送信息的方便的無鏈接的Socket),系統內核通知udev該事件。
3.此時,udev將讀取在/etc/udev/rule.d/中的一系列udev規則文件,在通知HAL以前,爲設備建立設備文件或運行一段程序。在90-hal.rules規則中的RUN+=」socket:/org/freedesktop/hal/udev_event」便是執行socket通知HAL該設備事件。Udev的事件可使用udevmonitor –eny來進行監控。
4.當HAL接到該設備事件的通知,HAL便開始經過多個渠道獲取設備相關信息,如內核、配置文件、硬件信息數據庫等。
5.hald服務以後再D-BUS上廣播該設備事件,讓用戶空間的程序接收調用。
以上即是設備插入到系統中,整個系統的硬件管理機制的工做流程,熟悉了硬件管理規則,有利於之後在項目中解決各種奇怪的突發問題,也有利於之後的學習。
當一個設備從系統中添加/刪除時,系統內核會發送一個信息到udevd且會將信息展現在/sys中。Udev以後會在/sys中查詢設備信息,根據udev的相關定義規則來決定建立設備節點或建立symlink連接。
Sysfs是udev用來在系統中查詢全部設備相關屬性的,如location、name、serial number、major/minor number、vendor/product IDs等等。
經過udev規則能夠對各種設備進行自定義的設置,能夠自定義設備名,能夠爲某設備建立symlink,能夠爲某設備設置某屬性等等。可使用udevmonitor工具來進行監控udev的事件,–env參數能夠顯示詳細信息。
全部的udev配置文件存放在/etc/udev目錄下,配置文件是由一行行的配置信息組成的,#號表示註銷該行配置。
/etc/udev/udev.conf是udev的全局配置文件,其中有幾個重要參數項,udev_root表示建立的設備文件存放在哪裏,默認是/dev;udev_rules表示udev規則存放在哪裏,默認是/etc/udev/rules.d/;udev_log設置udev的日誌級別,默認級別是err,在運行udev進行debug時,可使用命令臨時改變日誌級別「udevcontrol log_priority=debug」,日誌級別分爲err,info,debug三類。
Udev的規則文件默認是存放在/etc/udev/rules.d/目錄下,文件以數字序號開頭,以.rules爲後綴,例如75-custom.rules。序號不能大於100,自定義的規則最好設置序號爲99,由於序號越大則規則的優先權越高,這樣最能保證你的自定義策略會被udev執行。
Udev規則的語法至關簡單,舉個例子:
BUS==」usb」, SYSFS{serial}==」123123″, SYMLINK+=」xxx%n」
其中,「==」表示若是等於,「+=」表示添加一個,以上規則的意思是,若是該設備的總線是usb,若是設備的序列號是123123,則建立一個設備鏈接爲xxx,%n表示設備的序號。
用戶能夠根據本身的需求對某設備的特徵信息進行匹配綁定,能夠匹配多個特徵值,最後一項爲對該設備的操做。寫入規則後,可使用「udevcontrol reload_rules」命令從新加載udev規則,也能夠touch更新規則文件的時間戳,一般狀況下系統講自動讀取到新的規則文件。
「==」表示若是等於某鍵值時;「!=」表示若是不等於某鍵值時;如下爲一些匹配鍵值實例:
ACTION==」add」
KERNEL==」sd[a-z]1″
BUS==」scsi」
DEVICE!=」ide-cdrom」
PROGRAM==」custom_app.pl」 RESULT==」some return strings」此實例較爲難理解,表示當執行custom_app.pl程序時,若是返回的值是「some return strings」,則如何如何。
Udev規則支持使用通配符,「*」能夠通配一個或多個字符;「?」能夠通配一個字符;「[a-z]」通配a-z任一字母;「[!a]」能夠通配除a外任一字母。
以前一直都沒有介紹udev的做用,能夠不少新人並不大瞭解,到了這裏就來介紹一下。
如今的IT架構都是將運算和存儲分離的,即計算交給服務器,而存儲則交給存儲,例如一個雙機的HA集羣,兩臺服務器連的是同一套存儲,存儲連到服務器上被識別成一個硬件設備,就像插了一塊磁盤那樣。因爲這樣的屬於外圍設備接入,因此設備名經常會飄,特別是多個數據存儲接入到同一臺服務器時,這樣給HA帶來很大的麻煩。而udev就能夠根據各塊盤的特有的特徵值進行綁定,設置易於管理的自定義的設備名,方便了HA的使用。
那麼,要怎樣才能查到這些設備的特徵值呢?
一般地,咱們可使用udevinfo來收集設備信息。
# udevinfo -a -p $(udevinfo -q path -n /dev/<device>) 其中裏面的udevinfo命令是查詢該設備在/sys中對應的文件,外面的命令則是將設備存放在/sys中的信息讀取出來,其中-a表示顯示全部屬性,-p表示指定路徑。
對於SCSI設備可使用:
# scsi_id -g -x -s /block/sdX
對於sata設備:
# /lib/udev/ata_id /dev/hdX
對於usb設備:
# /lib/udev/usb_id /block/sdX
「=」表示分配一個值;「+=」表示新增一個連接;「:=」表示分配一個值,且任何最新的規則都不能改變;
分配鍵值實例:
NAME=」usb_crypto」 分配名稱鍵值;
SYMLINK+=」data1″ 新增連接;
OWNER=」student」 設置設備文件全部者;
MODE=」0600″ 設置設備文件的權限;
LABEL=」test_rule_end」 設置設備文件的標籤;
GOTO=」test_rule_end」 轉向命令;
RUN=」app.sh」 執行某程序;
更多的鍵值能夠查看udev的幫助文檔進行設置。
當udev規則生效的時候,規則中相應的替換變量便開始生效,經過這些替換變量,能夠簡化和縮寫規則,便於讀和寫。如下各項支持使用替換變量:NAME,SYMLINK,PROGRAM,OWNER,GROUP,RUN等。
如此實例:
KERNEL==」sda*」, SYMLINK+=」iscsi%n」
其中,%n就是$number的縮寫替換,用於表示設備數量。如下即是經常使用的替換變量:
$kernel = %k 表示設備名;
$devpath = %p 表示設備devpath(例如是/block/sda/…下的,而不是/sys/block/sda/…下的設備文件);
$id = %b 表示設備名和devpath的匹配;
$sysfs{file} = %s{file} 當前設備的SYSFS屬性值;
$env{key} = %E{key} 表示環境變量的值;
$major = %M 表示設備的主設備號;
$minor = %m 表示設備的次設備號;
$result = %c 表示使用GROGRAM執行返回的結果串;
$root = %r 表示udev_root的值;
$parent = %P 表示父設備的設備名;
$$ 表示「$」字符;
%% 表示「%」字符;
BUS==」scsi」, SYSFS{serial}==」123123″, NAME=」/dev/sda…」
此規則表示當設備總線爲scsi時,且設備序列號爲123123時,將設備文件放置帶/dev/sda…
KERNEL==」sd*」, BUS==」scsi」, PROGRAM==」xx.sh」, RESULT==」123123″, NAME=」xxx%n」
此規則表示當設備內核設備名爲sd*,其中*爲通配符,總線爲scsi時,執行程序xx.sh,若得出的結果爲123123時,則將設備命名爲xxx,其中%n則表示設備數量號。
ACTION==」add」,KERNEL==」PPP0″,RUN+=」wall PPP Success!」
此規則表示當設備動做爲添加時,當設備名爲PPP0時,運行命令廣播撥號接口添加成功。
可使用udevmonitor工具對系統內核和udev規則事件進行持續性地監控。
# udevmonitor –env查看完整的udev事件日誌;