使用udev高效、動態的管理Linux設備文件

導讀:

在Linux環境中,所有的設備都以文件的形式存在,在早期的Linux版本中,/dev目錄包含了了所有可能出現的設備文件,很難想象Linux用戶如何從大量的設備文件中找到想要的設備文件。舉個例子,服務器上有sda、sdb、sdc、sdd四塊磁盤,這些名字都是操作系統識別到磁盤後自動生成的,通過名字,我們並不知道每一塊盤是做什麼的,要是能夠實現自定義命名,那就再好不過了,udev(動態設備管理)正是一款能夠實現自定義命名的軟件。

 


(一)udev介紹
udev是Linux2.6內核的一個功能,它替換原來的devfs,成爲當前Linux默認的設備管理工具。udev以守護進程的形式運行,通過偵聽內核發出來的uevent來管理/dev目錄下的設備文件。udev的功能可以概括爲:

  • 動態管理:當設備插入、拔出、改變狀態時,udev的守護進程偵聽來自內核的uevent,以此添加或刪除/dev下的設備文件,所以udev只爲已經連接的設備產生設備文件,而不會在/dev下產生大量虛無的設備文件;
  • 自定義命名規則:內核通常僅根據設備被發現的先後順序給設備文件命名,因此很難在設備文件與物理硬件之間建立穩定的對應關係,而udev根據設備的物理屬性或配置特性創建有意義的符號鏈接名稱,就可以在物理設備和設備文件名之間建立穩定且有意義的對應關係。舉個例子,同一塊物理磁盤,第一次啓動時磁盤名稱爲sdc,下一次啓動後就變爲了sdd,這是完全有可能的,因爲磁盤命名完全取決於設備被發現的先後順序,如果我們通過udev根據磁盤scsi id號,將磁盤重新命名爲datadisk,則不論你如何重啓,datadisk都與物理磁盤是對應的。
  • 設定設備的權限和所有組

 

                        圖. udev工作流程圖

 NOTE:udev守護進程

[root@testserver sdb]# ps -ef|grep udev
root 554 1 0 09:15 ? 00:00:01 /usr/lib/systemd/systemd-udevd

 

(二)udev規則文件
本章節適用環境:centos7,redhat7,其它版本的Linux可能會存在一些差異
udev規則文件分別位於系統規則目錄(/usr/lib/udev/rules.d)、運行時規則目錄(/run/udev/rules.d)、本機規則目錄(/etc/udev/rules.d)。所有規則文件(無論位於哪個目錄中),同一按照文件名的字典順序處理。對於不同目錄下的同名文件,僅以優先級最高的哪一個爲準,具體來說就是:/etc的優先級最高,/run的優先級居中,/usr的優先級最低。規則文件以.rules作爲後綴名,否則將被忽略。
在規則文件裏,除了以“#開頭的行(註釋),所有的非空行都被視爲一條規則,規則都是由多個鍵值對組成,並由逗號分隔開,鍵值對可以分爲條件匹配鍵值對(匹配鍵)和賦值鍵值對(賦值鍵),一條規則可以有多條匹配鍵和多條賦值鍵。如果某條規則的所有匹配鍵的值都匹配成功,那麼就表示此條規則匹配成功,帶來的結果就是所有賦值鍵都會被賦予指定的值。

例子1:一個簡單的udev規則

KERNEL=="sda", NAME="my_root_disk", MODE="0660"

這條規則的意思是:如果存在一個名爲sda的設備,則將其命名爲my_root_disk,並把文件的權限設置爲0660。

 

(2.1)規則操作符
每條規則都是由一系列逗號分隔的“鍵-值”對組成,“鍵-值”之間由操作符連接,根據操作的不同,可用的操作符如下:

 "==" :(匹配)等於
 "!=" :(匹配)不等於
 "= :(賦值)爲鍵賦予指定的值。此鍵之前的值將被丟棄
 "+=" :(賦值)在現有值列表中追加此處指定的值,追加
 "-=" :(賦值)在現有值列表中刪除此處指定的值
 ":=" :(賦值)爲鍵賦予指定的值,並視爲最終值,禁止被繼續修改


(2.2)條件匹配鍵值對(常用)
 ACTION     :匹配事件的動作。例如“add”表示插入一個設備
 KERNEL     :匹配設備的內核名稱。即設備的默認文件名,例如"sda"
 ATTR{file} :匹配設備在sysfs中的屬性值。例如對於/dev/sdb來說,ATTR{size}的含義就是/sys/block/sdb/size的值。
 PROGRAM    :執行外部命令
 RESULT     :匹配最近一次PROGRAM程序輸出的字符串,必須位於PROGRAM之後。例如:PROGRAM=="/lib/udev/scsi_id -g -s $devpath", RESULT=="35000c50000a7ef67",代表調用命令"/lib/udev/scsi_id -g -s $devpath"查詢設備的scsi id,如果爲35000c50000a7ef67,則該設備匹配該匹配鍵。

在匹配的"值"中可以使用shell風格的匹配符:
 "* :匹配任意數量的字符(包括0個)
 "? :匹配1個字符
 "[]" :匹配括號內的任意一個字符,例如sd[bc],可以匹配sdb或者sdc;也可以使用"-"代表一個區間,例如sda[1-4]可以sda1、sda2、sda3、sda4。左括號後跟着一個"!"代表匹配非括號內的字符
 "| :用於分隔2個可以互相替代的匹配模式。例如"a|b"匹配a或者b


(2.3)賦值鍵值對(常用)
 NAME      :設置網絡接口的名稱,實際上udev並不能直接修改設備的名稱,他只能爲設備節點創建額外的符號鏈接(相當於別名)
 SYMLINK   :設置指向此設備節點的軟鏈接名稱
 OWNER,GROUP,MODE :設置設備節點的屬主、屬組、權限,會覆蓋內置的默認值。
 RUN{type} :對於每個設備事件來說,在處理完所有udev規則之後,都可以接着執行一個由此鍵設置的程序列表。

NAME,SYMLINK,PROGRAM,WONER,GROUP,MODE,RUN都接收簡單的字符串替換。可替換的標記如下(常用):
 $kernel,%k  : 設備的內核名稱
 $number,%n  : 設備在內核中的序號,例如,對於"sda3"來說,此值爲3
 $devnode,%N  : 設備節點的名稱


(三)udev在centos6/7下的配置
udev在redhat6/centos6和在redhat7/centos7下面的配置是不同的,這裏對6和7分別進行配置。
(3.1)查看硬盤的scsi id

### redhat6/centos6
[root@source-node ~]# /sbin/scsi_id -g -u -d /dev/sdb
36000c298a7f98907e1172b026e94a044
# 或者是
[root@source-node ~]# scsi_id --whitelisted --replace-whitespace --device=/dev/sdb
36000c298a7f98907e1172b026e94a044


### redhat7/centos7
[root@server1 ~]# /usr/lib/udev/scsi_id -g -u -d /dev/sdb
36000c29a40098c25f2972c185641cb7a

 NOTE:VMware下scsi_id獲取不到設備的wwid的解決辦法:http://blog.sina.com.cn/s/blog_a3adb3220102xkq1.html

 

(3.2)使scsi設備可信

相關介紹:https://docs.oracle.com/en/database/oracle/oracle-database/12.2/ladbi/configuring-device-persistence-manually-for-oracle-asm.html#GUID-70D50812-CCB2-41E4-AA3B-4689E1DA934E

### 6和7操作相同
[root@server1 ~]# vim /etc/scsi_id.config
options=-g

 

(3.3)配置udev的rules文件
編輯文件 /etc/udev/rules.d/99-oracle-asmdevices.rules 。特別有意思的是:6和7中,磁盤命名方式不一樣,centos6中是使用NAME進行重命名,centos7中是使用SYMLINK創建鏈接。

### redhat6/centos6
KERNEL=="sd*", BUS=="scsi", PROGRAM=="/sbin/scsi_id --whitelisted --replace-whitespace --device=/dev/$name", RESULT=="36000c298a7f98907e1172b026e94a044", NAME="asm-diskb", OWNER="grid", GROUP="asmadmin", MODE="0660"

### redhat7/centos7
KERNEL=="sd*1", SUBSYSTEM=="block", PROGRAM=="/usr/lib/udev/scsi_id -g -u -d /dev/$parent", RESULT=="36000c29a40098c25f2972c185641cb7a", SYMLINK+="asm-ocrdisk1", OWNER="grid", GROUP="asmadmin", MODE="0660"

 

(3.4)重啓動udev

### redhat6/centos6
[root@source-node ~]# start_udev
Starting udev: [ OK ]

### redhat7/centos7
# 首先進行測試
[root@server1 ~] /sbin/partprobe /dev/sdb1
[root@server1 ~] /sbin/udevadm test /block/sdb/sdb1
# 接着綁定命令
[root@server1 ~] /sbin/udevadm control --reload-rules
[root@server1 ~] /sbin/udevadm trigger

 

(3.5)查看udev設備是否生效

### redhat6/centos6
[root@source-node ~]# ll /dev/asm-diskb 
brw-rw----. 1 grid asmadmin 8, 16 Oct 29 20:02 /dev/asm-diskb

### redhat7/centos7
# 特別注意,新創建的設備文件名權限是root:root,但是真正的磁盤文件權限已經改變了
[root@mysqlserver dev]# ll
/dev/asm-ocrdisk1 lrwxrwxrwx. 1 root root 4 Oct 29 20:40 /dev/asm-ocrdisk1 -> sdb1 [root@mysqlserver dev]# ll /dev/sdb* brw-rw----. 1 grid asmadmin 8, 16 Oct 29 20:40 /dev/sdb brw-rw----. 1 grid asmadmin 8, 17 Oct 29 20:40 /dev/sdb1

 

 

參考
1.https://www.ibm.com/developerworks/cn/linux/l-cn-udev/index.html?ca=drs-cn-0304
2.http://www.jinbuguo.com/systemd/udev.html
3.https://mirrors.edge.kernel.org/pub/linux/utils/kernel/hotplug/udev/udev.html

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章