Linux下udev詳細介紹

迷倪小魏發表於2017-07-22

每次在搭建Oracle RAC環境中,遇到問題最多的就是關於ASM磁碟的的問題,通過檢視網上許多搭建RAC的文件,發現Oracle 10g RAC大家普遍的修改/etc/udev/rules.d/60-raw.rules,而一些搭建Oracle11R2的RAC,大家都在配置的是/etc/udev/rules.d/99-oracle-asmdevices.rules這個檔案,面對這樣一種情況,我不是很明白,這兩個檔案到底有什麼區別,這個問題困擾了我很久,直到今天遇到這樣一個問題:使用udev管理asmdisk執行/sbin/scsi_id不顯示UUID。通過查詢相關的資料才算是對這個問題有了更深層次的理解。

   
      Linux平臺通過udev的方式將塊裝置轉換為字元裝置,並固定裝置的許可權和所有者,這種需求只在安裝11gR1之前的RAC資料庫的時候需要這樣做,安裝11gR2RACASM可以直接使用塊裝置。udev除了用於將塊裝置轉換為字元裝置外,還可用於固定裝置檔名稱。


之後,通過實驗來驗證這個結論,詳細的步驟請參考我的另一篇博文:

使用udev管理asmdisk執行/sbin/scsi_id不顯示UUID



目錄


一、udev簡介

二、udev的優勢

2.1 動態管理

2.2 自定義命名規則

2.3 設定裝置的許可權和所有者/

2.4 udev 新增/刪除裝置檔案的過程。

三、配置和使用udevCentOS6.4

3.1 檢查udevCentOS6.5中的版本和執行情況

3.2 udev的配置檔案

3.3 通過udev設定裝置檔案的許可權

3.4 udev的規則和規則檔案

四、制定udev 規則和查詢裝置資訊的例項

4.1 查詢裝置的資訊(屬性)來制定udev規則

4.2 udev的簡單規則

4.3 其他常用的udev命令

一、udev簡介

udev 是Linux2.6 核心裡的一個功能,它替代了原來的devfs,成為當前Linux 預設的裝置管理工具。udev以守護程式的形式執行,通過偵聽核心發出來的uevent 來管理/dev目錄下的裝置檔案。不像之前的裝置管理工具,udev在使用者空間(user space) 執行,而不在核心空間(kernel space) 執行。


二、udev的優勢

2.1 動態管理

當裝置新增/ 刪除時,udev的守護程式偵聽來自核心的uevent,以此新增或者刪除/dev下的裝置檔案,所以udev 只為已經連線的裝置產生裝置檔案,而不會在/dev下產生大量虛無的裝置檔案。

 

2.2 自定義命名規則

通過Linux 預設的規則檔案,udev在/dev/ 裡為所有的裝置定義了核心裝置名稱,比如/dev/sda、/dev/hda、/dev/fd等等。由於udev 是在使用者空間(user space) 執行,Linux使用者可以通過自定義的規則檔案,靈活地產生標識性強的裝置檔名,比如/dev/boot_disk、/dev/root_disk、/dev/color_printer等等。


2.3 設定裝置的許可權和所有者/ 組

udev可以按一定的條件來設定裝置檔案的許可權和裝置檔案所有者/ 組。在不同的udev 版本中,實現的方法不同。


2.4 下面的流程圖顯示udev 新增/刪除裝置檔案的過程。



PS:

1.裝置檔案:由於本文以較通俗的方式講解udev,所以裝置檔案是泛指在/dev/下,可被應用程式用來和裝置驅動互動的檔案。而不會特別地區分裝置檔案、裝置節點或者裝置特殊檔案。


2.sysfssysfs是Linux 2.6 核心裡的一個虛擬檔案系統(/sys)。它把裝置和驅動的資訊從核心的裝置模組匯出到使用者空間(userspace)。從該檔案系統中,Linux使用者可以獲取很多裝置的屬性。


3.devpath本文的devpath是指一個裝置在sysfs檔案系統(/sys)下的相對路徑,該路徑包含了該裝置的屬性檔案。udev裡的多數命令都是針對devpath操作的。例如:sda的devpath是/block/sda,sda2的devpath是/block/sda/sda2。


4.核心裝置名稱:裝置在sysfs裡的名稱,是udev 預設使用的裝置檔名。

三、配置和使用udev(CentOS6.4)

3.1 檢查udev在CentOS6.5中的版本和執行情況

[root@test boot]# rpm -qa | grep -i udev

udev-147-2.46.el6.x86_64

libgudev1-147-2.46.el6.x86_64

python-gudev-147.1-4.el6_0.1.x86_64

libudev-147-2.46.el6.x86_64

system-config-printer-udev-1.1.16-23.el6.x86_64


[root@test boot]# ps -ef | grep -i udev

root     27957     1  0 10:23 ?        00:00:00 /sbin/udevd -d

root     28584 27957  0 10:34 ?        00:00:00 /sbin/udevd -d

root     29017  1955  0 13:28 pts/0    00:00:00 grep -i udev 


3.2 udev的配置檔案

[root@test ~]# cat /etc/udev/udev.conf

# The initial syslog(3) priority: "err", "info", "debug" or its

# numerical equivalent. For runtime debugging, the daemons internal

# state can be changed with: "udevadm control --log-priority=".

udev_log="err"


udev_logsyslog記錄日誌的級別,預設值是err。如果改為info或者debug的話,會有冗長的udev日誌被記錄下來。

實際上在CentOS 裡,除了配置檔案裡列出的引數udev_log外,Linux使用者還可以修改引數udev_root和udev_rules,只不過這2 個引數是不建議修改的,所以沒顯示在udev.conf 裡。syslog預設會記錄udev 的日誌,Linux使用者只能修改日誌的級別(err、info、degub等);裝置的許可權不能在udev.conf 裡設定,而是要在規則檔案(*.rules) 裡設定。


3.3 通過udev設定裝置檔案的許可權

在CentOS 6.4 的udev,已經沒有許可權檔案,所有的許可權都是通過規則檔案(*.rules)來設定,在下面的規則檔案配置過程會介紹到。


3.4 udev的規則和規則檔案

規則檔案是udev裡最重要的部分,預設是存放在/etc/udev/rules.d/下。所有的規則檔案必須以“.rules”為字尾名。CentOS有預設的規則檔案,這些預設規則檔案不僅為裝置產生核心裝置名稱,還會產生標識性強的符號連結。例如:


[root@test ~]# ls /dev/disk/by-uuid/

18f9b7a4-f6a9-4a87-a63b-2660b12c87db  8ac6170e-8e4d-4385-a166-92c2aaeb75ca

5e2405ac-1cb5-4a90-a6c9-67c2c245667b  c42b1176-beaf-4e52-98e3-1b6d386908c0


但這些連結名較長,不易呼叫,所以通常需要自定義規則檔案,以此產生易用且標識性強的裝置檔案或符號連結。

udev按照規則檔名的字母順序來查詢全部規則檔案,然後為匹配規則的裝置管理其裝置檔案或檔案連結。雖然udev不會因為一個裝置匹配了一條規則而停止解析後面的規則檔案,但是解析的順序仍然很重要。通常情況下,建議讓自己想要的規則檔案最先被解析。比如,建立一個名為 /etc/udev/rules.d/10-myrule.rules的檔案,並把你的規則寫入該檔案,這樣udev就會在解析系統預設的規則檔案之前解析到你的檔案。

在規則檔案裡,除了以“#”開頭的行(註釋),所有的非空行都被視為一條規則,但是一條規則不能擴充套件到多行。規則都是由多個鍵值對(key-valuepairs)組成,並由逗號隔開,鍵值對可以分為條件匹配鍵值對(以下簡稱“匹配鍵”)和賦值鍵值對(以下簡稱“賦值鍵”),一條規則可以有多條匹配鍵和多條賦值鍵。匹配鍵是匹配一個裝置屬性的所有條件,當一個裝置的屬性匹配了該規則裡所有的匹配鍵,就認為這條規則生效,然後按照賦值鍵的內容,執行該規則的賦值。下面是一個簡單的規則:

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

KERNEL是匹配鍵,NAME和MODE是賦值鍵。這條規則的意思是:如果有一個裝置的核心裝置名稱為sda,則該條件生效,執行後面的賦值:在/dev下產生一個名為my_root_disk的裝置檔案,並把裝置檔案的許可權設為0660。

僅當操作符是“==”或者“!=”時,其為匹配鍵;若為其他操作符時,都是賦值鍵。


udev規則的所有操作符:

“==”:比較鍵、值,若等於,則該條件滿足;

“!=”:比較鍵、值,若不等於,則該條件滿足;

“=”:對一個鍵賦值;

“+=”:為一個表示多個條目的鍵賦值。

“:=”:對一個鍵賦值,並拒絕之後所有對該鍵的改動。目的是防止後面的規則檔案對該鍵賦值。


udev規則的匹配鍵:

ACTION:事件 (uevent)的行為,例如:add(新增裝置)、remove(刪除裝置)。

KERNEL:核心裝置名稱,例如:sda, cdrom。

DEVPATH:裝置的devpath 路徑。

SUBSYSTEM:裝置的子系統名稱,例如:sda 的子系統為block。

BUS:裝置在 devpath 裡的匯流排名稱,例如:usb。

DRIVER:裝置在 devpath 裡的裝置驅動名稱,例如:ide-cdrom。

ID:裝置在 devpath 裡的識別號。

SYSFS{filename}:裝置的 devpath 路徑下,裝置的屬性檔案“filename”裡的內容。

例如:SYSFS{model}==“ST936701SS”表示:如果裝置的型號為ST936701SS,則該裝置匹配該匹配鍵。

在一條規則中,可以設定最多五條SYSFS 的匹配鍵。

ENV{key}:環境變數。在一條規則中,可以設定最多五條環境變數的匹配鍵。

PROGRAM:呼叫外部命令。

RESULT:外部命令 PROGRAM 的返回結果。例如:

PROGRAM=="/lib/udev/scsi_id -g -s $devpath", RESULT=="35000c50000a7ef67"

呼叫外部命令/lib/udev/scsi_id查詢裝置的SCSI ID,如果返回結果為35000c50000a7ef67,則該裝置匹配該匹配鍵。


udev 的重要賦值鍵:

NAME:在/dev下產生的裝置檔名。只有第一次對某個裝置的NAME 的賦值行為生效,之後匹配的規則再對該裝置的NAME 賦值行為將被忽略。如果沒有任何規則對裝置的NAME 賦值,udev將使用核心裝置名稱來產生裝置檔案。

SYMLINK:為/dev/下的裝置檔案產生符號連結。由於udev 只能為某個裝置產生一個裝置檔案,所以為了不覆蓋系統預設的udev 規則所產生的檔案,推薦使用符號連結。

OWNER, GROUP, MODE:為裝置設定許可權。

ENV{key}:匯入一個環境變數。


udev 的值和可呼叫的替換操作符:

在鍵值對中的鍵和操作符都介紹完了,最後是值(value)。Linux使用者可以隨意地定製udev 規則檔案的值。例如:my_root_disk,my_printer。同時也可以引用下面的替換操作符:

$kernel, %k:裝置的核心裝置名稱,例如:sda、cdrom。

$number, %n:裝置的核心號碼,例如:sda3的核心號碼是3。

$devpath, %p:裝置的devpath路徑。

$id, %b:裝置在devpath裡的ID 號。

$sysfs{file}, %s{file}:裝置的sysfs裡file 的內容。其實就是裝置的屬性值。例如:$sysfs{size}表示該裝置( 磁碟) 的大小。

$env{key}, %E{key}:一個環境變數的值。

$major, %M:裝置的major 號。

$minor %m:裝置的minor 號。

$result, %c:PROGRAM返回的結果。

$parent, %P:父裝置的裝置檔名。

$root, %r:udev_root的值,預設是/dev/。

$tempnode, %N:臨時裝置名。

%%:符號% 本身。

$$:符號$ 本身。

KERNEL=="sd*", PROGRAM="/lib/udev/scsi_id -g -s %p", \ RESULT=="35000c50000a7ef67", SYMLINK="%k_%c"

該規則的執行:如果有一個核心裝置名稱以sd 開頭,且SCSI ID 為35000c50000a7ef67,則為裝置檔案產生一個符號連結“sda_35000c50000a7ef67”.


四、制定udev 規則和查詢裝置資訊的例項

4.1 查詢裝置的資訊(屬性)來制定udev規則

當我們為指定的裝置設定規則時,首先需要知道該裝置的屬性,比如裝置的序列號、磁碟大小、廠商ID、裝置路徑等等。通常我們可以通過以下的方法獲得:

查詢sysfs檔案系統:

前面介紹過,sysfs裡包含了很多裝置和驅動的資訊。

例如:裝置sda 的SYSFS{size} 可以通過cat/sys/block/sda/size得到;SYSFS{model}資訊可以通過cat/sys/block/sda/device/model得到。

udevadm info命令:(Centos5.3為udevinfo命令)

udevadm info 可以查詢udev 資料庫裡的裝置資訊。例如:用udevadm info 查詢裝置sda 的model 和size 資訊:


[root@test ~]# udevadm info -a -p /sys/block/sda | egrep "model|size"

    ATTR{size}=="62914560"

    ATTRS{model}=="VBOX HARDDISK   "


[root@test ~]# udevadm info -a -p /sys/block/sda

Udevadm info starts with the device specified by the devpath and then

walks up the chain of parent devices. It prints for every device

found, all possible attributes in the udev rules key format.

A rule to match, can be composed by the attributes of the device

and the attributes from one single parent device.


  looking at device '/devices/pci0000:00/0000:00:0d.0/host2/target2:0:0/2:0:0:0/block/sda':

    KERNEL=="sda"

    SUBSYSTEM=="block"

    DRIVER==""

    ATTR{range}=="16"

    ATTR{ext_range}=="256"

    ATTR{removable}=="0"

    ATTR{ro}=="0"

    ATTR{size}=="62914560"

    ATTR{alignment_offset}=="0"

    ATTR{discard_alignment}=="0"

    ATTR{capability}=="52"

    ATTR{stat}=="   30322     6547  1191594   333118     7382    94590   811468   137604        0   154932   470661"

    ATTR{inflight}=="       0        0"


  looking at parent device '/devices/pci0000:00/0000:00:0d.0/host2/target2:0:0/2:0:0:0':

    KERNELS=="2:0:0:0"

    SUBSYSTEMS=="scsi"

    DRIVERS=="sd"

    ATTRS{device_blocked}=="0"

    ATTRS{type}=="0"

    ATTRS{scsi_level}=="6"

    ATTRS{vendor}=="ATA     "

    ATTRS{model}=="VBOX HARDDISK   "

    ATTRS{rev}=="1.0 "

    ATTRS{state}=="running"

    ATTRS{timeout}=="30"

    ATTRS{iocounterbits}=="32"

    ATTRS{iorequest_cnt}=="0x95a8"

    ATTRS{iodone_cnt}=="0x957d"

    ATTRS{ioerr_cnt}=="0x5"

    ATTRS{modalias}=="scsi:t-0x00"

    ATTRS{evt_media_change}=="0"

    ATTRS{dh_state}=="detached"

    ATTRS{queue_depth}=="31"

    ATTRS{queue_ramp_up_period}=="120000"

    ATTRS{queue_type}=="simple"


  looking at parent device '/devices/pci0000:00/0000:00:0d.0/host2/target2:0:0':

    KERNELS=="target2:0:0"

    SUBSYSTEMS=="scsi"

    DRIVERS==""


  looking at parent device '/devices/pci0000:00/0000:00:0d.0/host2':

    KERNELS=="host2"

    SUBSYSTEMS=="scsi"

    DRIVERS==""


  looking at parent device '/devices/pci0000:00/0000:00:0d.0':

    KERNELS=="0000:00:0d.0"

    SUBSYSTEMS=="pci"

    DRIVERS=="ahci"

    ATTRS{vendor}=="0x8086"

    ATTRS{device}=="0x2829"

    ATTRS{subsystem_vendor}=="0x0000"

    ATTRS{subsystem_device}=="0x0000"

    ATTRS{class}=="0x010601"

    ATTRS{irq}=="21"

    ATTRS{local_cpus}=="1"

    ATTRS{local_cpulist}=="0"

    ATTRS{modalias}=="pci:v00008086d00002829sv00000000sd00000000bc01sc06i01"

    ATTRS{numa_node}=="-1"

    ATTRS{enable}=="1"

    ATTRS{broken_parity_status}=="0"

    ATTRS{msi_bus}==""


  looking at parent device '/devices/pci0000:00':

    KERNELS=="pci0000:00"

    SUBSYSTEMS==""

DRIVERS=="" 


4.2 udev的簡單規則

產生網路卡裝置檔案的規則:

SUBSYSTEM=="net", SYSFS{address}=="AA:BB:CC:DD:EE:FF", NAME="public_NIC"

該規則表示:如果存在裝置的子系統為net,並且地址(MAC address) 為“AA:BB:CC:DD:EE:FF”,為該裝置產生一個名為public_NIC 的裝置檔案。

為指定大小的磁碟產生符號連結的規則


SUBSYSTEM=="block", SYSFS{size}=="71096640", SYMLINK ="my_disk"

該規則表示:如果存在裝置的子系統為block,並且大小為71096640(block),則為該裝置的裝置檔名產生一個名為my_disk 的符號連結。

通過外部命令為指定序列號的磁碟產生裝置檔案的規則


KERNEL=="sd*[0-9]", PROGRAM=="/lib/udev/scsi_id -g -s %p", \ RESULT=="35000c50000a7ef67", NAME +="root_disk%n"

該規則表示:如果存在裝置的核心裝置名稱是以 sd 開頭( 磁碟裝置),以數字結尾( 磁碟分割槽),並且通過外部命令查詢該裝置的SCSI_ID 號為“35000c50000a7ef67”,則產生一個以root_disk開頭,核心號碼結尾的裝置檔案,並替換原來的裝置檔案(如果存在的話)。例如:產生裝置名/dev/root_disk2,替換原來的裝置名/dev/sda2。

運用這條規則,可以在/etc/fstab裡保持系統分割槽名稱的一致性,而不會受驅動載入順序或者磁碟標籤被破壞的影響,導致作業系統啟動時找不到系統分割槽。


4.3 其他常用的udev命令

udevadm test(udevadm的子命令):針對一個裝置,在不需要uevent 觸發的情況下模擬一次udev的執行,並輸出查詢規則檔案的過程、所執行的行為、規則檔案的執行結果。

Simulate a udev event run for the given device, and print debugoutput


start_udev:start_dev命令重啟udev守護程式,並對所有的裝置重新查詢規則目錄下所有的規則檔案,然後執行所匹配的規則裡的行為。通常使用該命令讓新的規則檔案立即生效:

[root@test ~]# start_udev

Starting udev: [ OK ]


start_udev一般沒有標準輸出,所有的udev相關資訊都按照配置檔案(udev.conf)的引數設定,由syslog記錄。

作者:SEian.G(苦練七十二變,笑對八十一難)

ITPUBhttp://blog.itpub.net/31015730/

51CTOhttp://seiang.blog.51cto.com/



來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31015730/viewspace-2142429/,如需轉載,請註明出處,否則將追究法律責任。

相關文章