利用UDEV機制固定儲存裝置的名稱

2021-06-17 21:27:01 字數 2765 閱讀 1472

什麼是udev

udev為一些實際的裝置提供了乙個動態的裝置目錄,這些目錄裡包含這些實際裝置所對應的檔案。它建立或移除在/dev目錄裡的裝置節點檔案,或者重新命名網路介面。

通常udev執行udevd,如果乙個裝置增加進系統或者從系統中移除,它就會直接從核心中接受到這個udev的事件。

如果udev接受到乙個裝置事件,它就會從它的配置(或是規則)檔案(有三個位置/etc/udev/rules.d、/dev/.udev/rules.d、/lib/udev/rules.d)中去匹配從sysfs中得到的裝置屬性來辨識這個裝置。這些rules配置檔案會去比較所提供的附加(新增加進來的)的裝置的資訊或者指定乙個裝置節點名並操作符號鏈結名來指示udev執行附加的程式來作為裝置事件的處理。

udev的組成

udev由namedev、libsysfs和udev三部分組成。其中,namedev是裝置命名子系統;libsysfs提供訪問sysfs檔案系統,並從中獲取資訊的標準介面;udev提供/dev裝置節點檔案的動態建立和刪除策略。udev程式負責namedev和libsysfs庫互動的任務,當/sbin/hotplug程式被核心呼叫時,udev將執行。

udev有很多以.rules為字尾的規則檔案,以行為單位,除去以「#」開頭的代表注釋的行外,每一行代表乙個規則。每個規則分成乙個或多個匹配和賦值部分。匹配部分用匹配專用的關鍵字來表示,相應的賦值部分用專用的關鍵字來表示。

udev的工作原理

裝置節點的建立,是通過sysfs介面分析dev規則檔案取得裝置節點號。udevd通過netlink socket通訊機制在核心和使用者空間之間傳遞資訊,來得知核心裡模組的變化情況,通過hotplug機制得知裝置的插入移除情況。

核心呼叫kobject_uevent函式傳送netlink message給使用者空間,這部分工作通常無需驅動去自己處理,在統一裝置模型裡面,在子系統這一層面,已將這部分**處理好了,包括在裝置對應的特定的kobject建立和移除的時候都會傳送相應add和remove訊息,當然前提是您在核心中配置了hotplug的支援。

netlink socket作為一種核心和使用者空間的通訊方式,不僅用在hotplug機制中,同樣還應用在其他很多真正和網路相關的核心子系統中。udevd通過標準的socket機制,建立socket連線來獲取核心廣播的uevent事件並解析這些uevent事件。

應用在rhel5,可以使用udevinfo -a -p $(udevinfo -q path -n /dev/sdb)來獲取裝置資訊,在rhel6,使用udevadm info -a -n /dev/sdb來獲取裝置資訊。

針對iscsi裝置,使用udevadm info -a -n /dev/sdb可能獲取不到類似序列號之類的資訊,可以使用udevadm info -q all -n /dev/sdb試試,但是通常我們會這麼去使用,在rhel5, scsi_id -g -s $(udevinfo -q path -n /dev/sdc)獲取資訊,在rhel6,scsi_id --whitelisted --replace-whitespace /dev/sdc獲取資訊,用作書寫udev規則。

下面看看例子:

例一:如我們rhel6系統插入了乙個u盤,自動識別為/dev/sdb,而我們希望將其固定為/dev/myusbdisk。

則我們可以使用udevadm info -a -n /dev/sdb獲取到attrs=="ac681deb"資訊,書寫如下規則即可。

kernel=="sd*", subsystems=="usb",attrs=="ac681deb",name="myusbdisk"

例二:rhel6下,已經掛載乙個iscsi target端匯出的儲存,沒寫udev規則之前,自動識別為sdc,我們想將這個iscsi儲存的節點固定為叫做idisk,如果做了分割槽,則sdc1固定為idisk1。

我們書寫乙個udev規則

kernel=="sd*", subsystem=="block", program="/sbin/scsi_id --whitelisted --replace-whitespace /dev/$name", result=="1iet_00010001",name="idisk%n"

核心檢測資訊是sd*,子系統資訊為塊裝置,執行程式scsi_id --whitelisted --replace-whitespace /dev/$name,結果為1iet_00010001,則重新命名節點為idisk%n,   $name為核心檢測出資訊是sdb則$name=sdb,%n為核心檢測資訊為sdb,則%n為空,檢測資訊為sdb1,則%n為1,這麼寫的作用在於掛載iscsi匯出的乙個lun後,我們對這個lun進行分割槽的情況,如果乙個lun為乙個分割槽,則無需寫上%n。

擴充套件:用如下規則之一也可實現上條規則的效果,只是上條規則在iscsi裝置login時能觸發,如下兩條規則必須由udev觸發,如手動start_udev。所以通常應使用上述規則較好。

kernel=="sd*", subsystem=="block", program="/sbin/udevadm info -q all -n /dev/$name", result=="*beaf11*", name="idisk%n"

kernel=="sd*", subsystem=="block", program="/sbin/udevadm info -q all -p %p", result=="*beaf11*", name="idisk%n"

關於udev的除錯:

udevadm trigger是udev觸發器,執行此指令也是觸發rules規則,執行結果同start_udev。

udevadm test /block/sdc可以看到udev規則執行流程,顯示出來的資訊較多,需要從中提取需要的資訊,達到除錯的目的。

用 UDEV 固定 iSCSI 裝置名稱

size small 用 open iscsi 連上 target 之後,iscsi 裝置的名稱在系統裡總是變來變去,無法固定,這給應用帶來了諸多不便。為了固定系統中 iscsi 裝置的名稱,可以考慮使用linux 2.6 核心引入的 udev 機制。關於 udev 的介紹,網上的資料很多,這裡就不...

udev(四) 裝置的命名問題

二 裝置的命名問題 我們來看下系統對裝置的命名有什麼問題。舉個大家經常遇到的問題來說,例如你有 2個usb行動硬碟,那麼當你插入第 1個usb行動硬碟時,這個行動硬碟就有可能命名了 dev sdb 假設你的 dev sda是系統裡的 sata硬碟 當你再插入第 2個usb行動硬碟時,這個行動硬碟就有...

udev(九) 寫個程式檢測我們的裝置插拔

在這個教程裡我將寫乙個程式,其作用是檢測系統的裝置插拔事件,當有裝置插入 系統時,就可以檢測到這個裝置並把裝置的資訊顯示出來,如果裝置從系統裡移除,也同樣可以檢測出來,並移除裝置。這個 是參考了udev 139的原始碼 的,如果讀者有興趣也可以參考udev的原始碼。其中在udev 139 中有個小小...