使用udev高效、動態的管理Linux裝置檔案

gegeman發表於2020-10-29

導讀:

在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

 

 

相關文章