跳至內容跳至頁面導覽:上一頁 [access key p]/下一頁 [access key n]
documentation.suse.com / SUSE Linux Enterprise Server 文件 / 管理指南 / 系統 / 使用 udev 進行動態核心裝置管理
適用範圍 SUSE Linux Enterprise Server 12 SP5

21 使用 udev 進行動態核心裝置管理

核心可以新增或移除執行中系統內幾乎所有的裝置。裝置狀態的變更 (無論裝置插入或移除) 必須傳播至使用者空間。插入及識別裝置後需要對其進行設定。如果辨識到的裝置狀態發生任何變更,必須通知該裝置的使用者。udev 會提供所需的基礎結構,以便動態維護 /dev 目錄中的裝置節點檔案和符號連結。udev 規則能將外部工具插入核心裝置事件處理。因而,您可以透過新增在核心裝置處理過程中執行的特定程序檔,來自訂 udev 裝置處理方式,或者可以在裝置處理期間要求並輸入其他資料進行評估。

21.1 /dev 目錄

/dev 中的裝置節點可用來存取對應的核心裝置。透過 udev/dev 目錄會反映核心的目前狀態。每個核心裝置都有一個對應的裝置檔案。如果裝置與系統的連接中斷,該裝置節點就會遭到移除。

/dev 目錄的內容保存在暫存檔案系統中,而且所有檔案都會在每次系統開機時顯示。根據系統設計,手動建立或修改的檔案在重新開機後都將遺失。無論可使用 systemd-tmpfiles 建立的對應核心裝置狀態為何,靜態檔案和目錄都必須在 /dev 目錄中。組態檔案可在 /usr/lib/tmpfiles.d//etc/tmpfiles.d/ 中找到;如需詳細資訊,請參閱 systemd-tmpfiles(8) 線上文件。

21.2 核心 ueventudev

sysfs 檔案系統會輸出必要的裝置資訊。每個核心已偵測和啟始化的裝置,都會建立包含其裝置名稱的目錄。其中會包含裝置特定的屬性內容。

每次新增或移除裝置時,核心都會傳送 uevent 來通知 udev 此變更。udev 精靈會在啟動時從 /usr/lib/udev/rules.d/*.rules/etc/udev/rules.d/*.rules 檔案中讀取並剖析所有規則,然後將剖析結果保留在記憶體中。如果變更、新增或移除了規則檔案,精靈可以使用 udevadm control --reload 指令重新載入這些規則在記憶體中的表示。如需有關 udev 規則及其語法的詳細資訊,請參閱第 21.6 節 「透過 udev 規則影響核心裝置事件的處理」

每個收到的事件都將與提供的規則集合進行比對。這些規則可新增或變更事件環境識別碼、要求要建立之裝置節點的特定名稱、新增指向該節點的符號連結,或是新增要在裝置節點建立後執行的程式。驅動程式核心 uevent 是從核心網路連結插槽接收。

21.3 驅動程式、核心模組和裝置

核心匯流排驅動程式會查探裝置。核心 (kernel) 會為每個偵測到的裝置建立一個內部裝置結構,而驅動程式核心 (core) 會向 udev 精靈傳送一個 uevent。匯流排裝置會以特殊格式的 ID 識別本身,表明其為何種裝置。通常這些 ID 會包含廠商和產品 ID,以及其他子系統特定值。每個匯流排都會指定自己的 ID 配置,即所謂的 MODALIAS。核心會接收這些裝置資訊,並根據這些資訊設定 MODALIAS ID 字串,然後隨事件一起傳送該字串。例如,USB 滑鼠的 ID 字串將如下所示︰

MODALIAS=usb:v046DpC03Ed2000dc00dsc00dp00ic03isc01ip02

每個裝置驅動程式都包含有裝置可處理的已知別名清單。清單會包含在核心模組檔案本身。depmod 程式會讀取 ID 清單,並且為目前所有可用模組在核心的 /lib/modules 目錄中建立 modules.alias 檔案。透過此基礎結構,模組載入方式就會像在每次出現帶有 MODALIAS 識別碼的事件時呼叫 modprobe 一樣容易。如果是呼叫 modprobe $MODALIAS,此次呼叫就會比對裝置的已組織裝置別名和模組指定別名。如果有找到符合項目,該模組就可載入。以上這一切都是由 udev 自動觸發。

21.4 開機和初始裝置設定

udev 精靈執行之前,於開機過程中發生的所有裝置事件都會遺失,這是因為處理這些事件的基礎結構位於根檔案系統中,在該階段無法使用。為彌補這一損失,核心在 sysfs 檔案系統中之每部裝置的裝置目錄中都提供了一份 uevent 檔案。使用 add 寫入該檔案,核心便可重新傳送與開機期間所遺失的相同事件。負責 /sys 中所有 uevent 檔案的簡易迴圈,可以再次觸發所有事件,建立裝置節點並執行裝置設定。

例如,開機期間出現的 USB 滑鼠可能無法由早期的開機邏輯啟始化,這是因為當時尚無法使用驅動程式。裝置探查事件遺失,而且無法找到裝置的核心模組。您無需手動搜尋連接的裝置,udev 會在根檔案系統可用後向核心要求所有裝置事件,這樣 USB 滑鼠裝置的事件就會再次執行。現在,它會在已掛接根目錄檔案系統中找到核心模組,並讓 USB 滑鼠完成啟始化。

從使用者空間的角度,執行期間的裝置冷插拔 (ColdPlud) 順序和裝置探查並沒有明顯的不同。這兩種情況都會使用相同規則來進行比對,而且會執行相同的設定程式。

21.5 監控執行中的 udev 精靈

udevadm monitor 程式可用來視覺化驅動程式核心事件以及 udev 事件程序的時間。

UEVENT[1185238505.276660] add   /devices/pci0000:00/0000:00:1d.2/usb3/3-1 (usb)
UDEV  [1185238505.279198] add   /devices/pci0000:00/0000:00:1d.2/usb3/3-1 (usb)
UEVENT[1185238505.279527] add   /devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0 (usb)
UDEV  [1185238505.285573] add   /devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0 (usb)
UEVENT[1185238505.298878] add   /devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/input/input10 (input)
UDEV  [1185238505.305026] add   /devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/input/input10 (input)
UEVENT[1185238505.305442] add   /devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/input/input10/mouse2 (input)
UEVENT[1185238505.306440] add   /devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/input/input10/event4 (input)
UDEV  [1185238505.325384] add   /devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/input/input10/event4 (input)
UDEV  [1185238505.342257] add   /devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/input/input10/mouse2 (input)

UEVENT 行會顯示核心已透過網路連結傳送的事件。UDEV 行會顯示已完成的 udev 事件處理常式。列印時間是百萬分之一秒。介於 UEVENTUDEV 之間的時間是指 udev 處理此事件所耗費的時間,或者是 udev 精靈延遲執行以便此事件能與執行中相關事件同步的時間。例如,硬碟分割區的事件始終會等待主要磁碟裝置事件完成,因為分割區事件可能與主要磁碟事件向硬體查詢的資料有關。

udevadm monitor --env 會顯示完整的事件環境︰

ACTION=add
DEVPATH=/devices/pci0000:00/0000:00:1d.2/usb3/3-1/3-1:1.0/input/input10
SUBSYSTEM=input
SEQNUM=1181
NAME="Logitech USB-PS/2 Optical Mouse"
PHYS="usb-0000:00:1d.2-1/input0"
UNIQ=""
EV=7
KEY=70000 0 0 0 0
REL=103
MODALIAS=input:b0003v046DpC03Ee0110-e0,1,2,k110,111,112,r0,1,8,amlsfw

udev 也會將訊息傳送到 syslog。控制哪些訊息要傳送到 syslog 的預設 syslog 優先程度是在 udev 的組態檔 /etc/udev/udev.conf 中指定。可以使用 udevadm control --log_priority=LEVEL/NUMBER 變更執行中精靈的記錄優先程度。

21.6 透過 udev 規則影響核心裝置事件的處理

udev 規則可以比對核心新增至事件本身的任何內容,或者核心輸出到 sysfs 的任何資訊。規則也可向外部程式要求其他資訊。系統會將事件與目錄 /usr/lib/udev/rules.d/ (適用於預設規則) 和 /etc/udev/rules.d (系統專屬的組態) 中提供的所有規則進行比對。

規則檔案中的每一行都包含至少一個鍵值組合。鍵類型共有兩種,包括比對和指定鍵。當所有比對鍵都與指定值相符時就會套用規則,而該指定值就會指定給指定鍵。相符規則可以指定裝置節點的名稱、新增指向該節點的符號連結,或是在事件處理過程中執行指定的程式。如果找不到任何符合規則,就會使用預設的裝置節點名稱來建立裝置節點。如需有關規則語法和系統提供之用於比對或輸入資料的鍵的詳細資訊,請參閱 udev man 頁面。以下範例規則提供了對 udev 規則語法的基本介紹。這些範例規則全部摘自 udev 預設規則集 /usr/lib/udev/rules.d/50-udev-default.rules

範例 21.1︰ 範例 udev 規則
# console
KERNEL=="console", MODE="0600", OPTIONS="last_rule"

# serial devices
KERNEL=="ttyUSB*", ATTRS{product}=="[Pp]alm*Handheld*", SYMLINK+="pilot"

# printer
SUBSYSTEM=="usb", KERNEL=="lp*", NAME="usb/%k", SYMLINK+="usb%k", GROUP="lp"

# kernel firmware loader
SUBSYSTEM=="firmware", ACTION=="add", RUN+="firmware.sh"

主控台規則包含三個鍵︰一個比對鍵 (KERNEL) 以及兩個指定鍵 (MODEOPTIONS)。KERNEL 比對規則用於搜尋類型為主控台的所有項目的裝置清單。只有完全符合的項目才有效,才會觸發此規則讓其執行。MODE 鍵用於將特殊權限指派給裝置節點,在此案例中,僅此裝置的擁有者才會被指派讀取與寫入權限。OPTIONS 鍵用於將此規則做為要套用至所有此類型裝置的最後一條規則。符合此特殊裝置類型的任何後續規則都不會生效。

序列裝置規則在 50-udev-default.rules 中雖已不再可用,但仍值得瞭解一下。它包含兩個比對鍵 (KERNELATTRS) 與一個指派鍵 (SYMLINK)。KERNEL 鍵用於搜尋類型為 ttyUSB 的所有裝置。使用 * 萬用字元時,此鍵可比對多部此類裝置。第二個比對鍵 ATTRS 用於檢查 sysfs 中針對 ttyUSB 裝置的 product 屬性檔案是否包含特定字串。指派鍵 (SYMLINK) 用於觸發將符號連結新增至 /dev/pilot 下的此裝置。此鍵中使用的運算子 (+=) 將告知 udev 額外執行此動作,即使先前或之後的規則會新增其他符號連結也是如此。由於此規則包含兩個比對鍵,因此僅當兩個條件均滿足時才適用。

印表機規則可處理 USB 印表機,它包含兩個比對鍵,必須同時套用這兩個鍵才能套用整個規則 (SUBSYSTEMKERNEL)。三個指定鍵用於命名此裝置類型 (NAME)、建立符號裝置連結 (SYMLINK) 以及對此裝置類型的成員進行分組 (GROUP)。在 KERNEL 鍵中使用 * 萬用字元可使其符合多部 lp 印表機裝置。可以在 NAMESYMLINK 鍵中使用替代項,透過內部裝置名稱延伸這些字串。例如,第一部 lp USB 印表機的符號連結會讀取 /dev/usblp0

核心韌體載入程式規則可讓 udev 在執行時期透過外部輔助程式程序檔載入其他韌體。SUBSYSTEM 比對鍵可搜尋韌體子系統。ACTION 鍵可檢查是否已新增任何屬於韌體子系統的裝置。RUN+= 鍵可觸發執行 firmware.sh 程序檔以查找要載入的韌體。

某些一般特性適用於所有規則︰

  • 每條規則都包含一個或多個以逗號分隔的鍵值對。

  • 鍵的操作由運算子決定。udev 規則支援多個運算子。

  • 每個指定值必須括在引號中。

  • 規則檔案中的每一行都表示一條規則。如果某規則的長度超出一行,請使用 \ 連接不同的行,就如同在外圍程序語法中一樣。

  • udev 規則支援符合 *?[] 模式的外圍程序式模式。

  • udev 規則支援替代項。

21.6.1 udev 規則中使用運算子

建立金鑰時,您可以根據要建立的金鑰類型從多個運算子中進行選擇。比對鍵通常用於尋找符合或明顯不符合搜尋值的值。比對鍵可包含以下運算子︰

==

比較是否相等。如果鍵包含搜尋模式,則所有符合此模式的結果均有效。

!=

比較是否不相等。如果鍵包含搜尋模式,則所有符合此模式的結果均有效。

指派鍵可使用以下運算子︰

=

將某個值指派給鍵。如果鍵先前包含值清單,則此鍵將重設並僅指派單一值。

+=

將某個值新增至包含項目清單的鍵。

:=

指派最終值。不允許後續規則再做任何變更。

21.6.2 udev 規則中使用替代項

udev 規則支援使用佔位符與替代項。使用方式與任何其他程序檔中的方式類似。在 udev 規則中可以使用以下替代項︰

%r, $root

依預設為裝置目錄 /dev

%p, $devpath

DEVPATH 的值。

%k, $kernel

KERNEL 的值或內部裝置名稱。

%n, $number

裝置編號。

%N, $tempnode

裝置檔案的暫存名稱。

%M, $major

裝置的主要編號。

%m, $minor

裝置的次要編號。

%s{ATTRIBUTE}, $attr{ATTRIBUTE}

sysfs 屬性的值 (透過 ATTRIBUTE 指定)。

%E{VARIABLE}, $env{VARIABLE}

環境變數的值 (透過 VARIABLE 指定)。

%c, $result

PROGRAM 的輸出。

%%

% 字元。

$$

$ 字元。

21.6.3 使用 udev 比對鍵

比對鍵定義要套用 udev 規則所必須滿足的條件。以下為可用的比對鍵︰

ACTION

事件動作的名稱,例如新增或移除裝置時的 addremove

DEVPATH

事件裝置的裝置路徑,例如 DEVPATH=/bus/pci/drivers/ipw3945,用於搜尋與 ipw3945 驅動程式相關的所有事件。

KERNEL

事件裝置的內部 (核心) 名稱。

SUBSYSTEM

事件裝置的子系統,例如 SUBSYSTEM=usb,適用於與 USB 裝置相關的所有事件。

ATTR{FILENAME}

事件裝置的 sysfs 屬性。例如,若要比對 vendor 屬性檔案名稱中包含的字串,可以使用 ATTR{vendor}=="On[sS]tream"

KERNELS

udev 向上搜尋符合裝置名稱的裝置路徑。

SUBSYSTEMS

udev 向上搜尋相符裝置子系統名稱的裝置路徑。

DRIVERS

udev 向上搜尋相符裝置驅動程式名稱的裝置路徑。

ATTRS{FILENAME}

udev 向上搜尋與 sysfs 屬性值相符之裝置的裝置路徑。

ENV{KEY}

環境變數的值,例如 ENV{ID_BUS}="ieee1394,用於搜尋與 FireWire 匯流排 ID 相關的所有事件。

PROGRAM

udev 執行外部程式。若要成功執行,程式必須以離開碼零返回。RESULT 鍵可使用程式的輸出 (列印至 STDOUT)。

RESULT

比對上次 PROGRAM 呼叫的輸出字串。即可將此鍵包含於相同規則中 (如 PROGRAM 鍵),也可含於後續規則中。

21.6.4 使用 udev 指定鍵

與上述比對鍵不同,指定鍵不會說明必須滿足的條件,而是將值、名稱和動作指定給 udev 維護的裝置節點。

NAME

要建立之裝置節點的名稱。如果規則已設定了節點名稱,則將忽略適用於此節點的所有其他含 NAME 鍵的規則。

SYMLINK

與要建立的節點相關聯之符號連結的名稱。可以為多項比對規則新增符號連結以便使用裝置節點進行建立。您還可以使用空格字元分隔符號連結名稱,從而為一項規則中的一個節點指定多個符號連結。

OWNER、GROUP、MODE

新裝置節點的權限。在此處指定的值將覆寫已編譯的任何項目。

ATTR{KEY}

指定要寫入事件裝置之 sysfs 屬性的值。如果使用運算子 ==,也會使用此鍵來比對 sysfs 屬性的值。

ENV{KEY}

告知 udev 將某變數輸出到環境中。如果使用運算子 ==,也會使用此鍵來比對環境變數。

RUN

告知 udev 將某程式新增至要為此裝置執行的程式清單。對極短任務套用此項時要格外小心,以免封鎖此裝置的其他事件。

LABEL

GOTO 可以跳轉之處新增一個標籤。

GOTO

告知 udev 跳過數個規則,繼續執行 GOTO 鍵所參考標籤對應的規則。

IMPORT{TYPE}

將變數載入事件環境,如外部程式的輸出。udev 可輸入多種類型的變數。如果未指定任何類型,udev 會根據檔案權限的可執行位元嘗試自行決定類型。

  • program 可告知 udev 執行外部程式並輸入其輸出。

  • file 可告知 udev 輸入文字檔。

  • parent 可告知 udev 輸入父代裝置中儲存的鍵。

WAIT_FOR_SYSFS

告知 udev 等待系統為特定裝置建立指定的 sysfs 檔案。例如,WAIT_FOR_SYSFS="ioerr_cnt" 通知 udev 等待,直到 ioerr_cnt 檔案建立。

OPTIONS

OPTION 鍵可以使用多個值︰

  • last_rule 告知 udev 忽略所有後續規則。

  • ignore_device 告知 udev 完全忽略此事件。

  • ignore_remove 告知 udev 忽略針對該裝置的所有後續移除事件。

  • all_partitions 告知 udev 為區塊裝置上的所有可用分割區建立裝置節點。

21.7 永久裝置命名

動態裝置目錄和 udev 規則基礎架構讓系統可以為所有磁碟裝置提供固定名稱,無論裝置的辨識順序或所使用的連接為何。核心所建立的每個相應區塊裝置,都會採用針對特定匯流排、磁碟類型或檔案系統所設計的工具進行檢查。udev 會根據核心動態提供的裝置節點名稱,維護指向裝置的永久符號連結類別︰

/dev/disk
|-- by-id
|   |-- scsi-SATA_HTS726060M9AT00_MRH453M4HWHG7B -> ../../sda
|   |-- scsi-SATA_HTS726060M9AT00_MRH453M4HWHG7B-part1 -> ../../sda1
|   |-- scsi-SATA_HTS726060M9AT00_MRH453M4HWHG7B-part6 -> ../../sda6
|   |-- scsi-SATA_HTS726060M9AT00_MRH453M4HWHG7B-part7 -> ../../sda7
|   |-- usb-Generic_STORAGE_DEVICE_02773 -> ../../sdd
|   `-- usb-Generic_STORAGE_DEVICE_02773-part1 -> ../../sdd1
|-- by-label
|   |-- Photos -> ../../sdd1
|   |-- SUSE10 -> ../../sda7
|   `-- devel -> ../../sda6
|-- by-path
|   |-- pci-0000:00:1f.2-scsi-0:0:0:0 -> ../../sda
|   |-- pci-0000:00:1f.2-scsi-0:0:0:0-part1 -> ../../sda1
|   |-- pci-0000:00:1f.2-scsi-0:0:0:0-part6 -> ../../sda6
|   |-- pci-0000:00:1f.2-scsi-0:0:0:0-part7 -> ../../sda7
|   |-- pci-0000:00:1f.2-scsi-1:0:0:0 -> ../../sr0
|   |-- usb-02773:0:0:2 -> ../../sdd
|   |-- usb-02773:0:0:2-part1 -> ../../sdd1
`-- by-uuid
    |-- 159a47a4-e6e6-40be-a757-a629991479ae -> ../../sda7
    |-- 3e999973-00c9-4917-9442-b7633bd95b9e -> ../../sda6
    `-- 4210-8F8C -> ../../sdd1

21.8 udev 使用的檔案

/sys/*

由 Linux 核心提供的虛擬檔案系統,可輸出所有目前已知裝置。udev 用此資訊在 /dev 中建立裝置節點。

/dev/*

動態建立的裝置節點和使用 systemd-tmpfiles 建立的靜態內容;如需詳細資訊,請參閱 systemd-tmpfiles(8) 線上文件。

下列檔案和目錄包含了 udev 基礎結構的重要元件︰

/etc/udev/udev.conf

udev 主組態檔。

/etc/udev/rules.d/*

系統專屬的 udev 事件比對規則。可在這裡新增自訂規則,以修改或覆寫 /usr/lib/udev/rules.d/* 中的預設規則。

系統依英數字元順序剖析檔案。檔案中優先程度較高的規則會修改或覆寫優先程度較低的規則。數值越小,優先程度越高。

/usr/lib/udev/rules.d/*

預設的 udev 事件比對規則。此目錄中的檔案由套件擁有,將在更新時覆寫。請勿在這裡新增、移除或編輯檔案,應該使用 /etc/udev/rules.d

/usr/lib/udev/*

udev 規則中呼叫的協助程式。

/usr/lib/tmpfiles.d//etc/tmpfiles.d/

針對靜態 /dev 內容。

21.9 更多資訊

如需關於 udev 基礎結構的詳細資訊,請參閱下列 man 頁面︰

udev

關於 udev、鍵、規則和其他重要組態問題的一般資訊。

udevadm

udevadm 可用於控制 udev 的執行時期行為、要求核心事件、管理事件佇列以及提供簡單的除錯機制。

udevd

關於 udev 事件管理精靈的資訊。