第12章 udevによる動的カーネルデバイス管理

目次

12.1. /devディレクトリ
12.2. カーネルのueventudev
12.3. ドライバ、カーネルモジュールおよびデバイス
12.4. ブートおよび初期デバイスセットアップ
12.5. 実行中のudevデーモンの監視
12.6. udevルールによるカーネルデバイスイベン処理への影響
12.7. 永続的なデバイス名の使用
12.8. udevで使用するファイル
12.9. 詳細情報

実行中のシステムで、カーネルは、ほとんどどのデバイスでも追加または削除できます。デバイス状態の変更(デバイスが接続されているか、または取り外されたか)をユーザスペースに反映させる必要があります。デバイスは、接続後、検出されるとすぐに設定されなければなりません。特定のデバイスのユーザは、このデバイスの認識された状態が変更された場合は通知される必要があります。udevは、/devディレクトリのデバイスノートファイルおよびシンボリックリンクを動的に維持するために必要なインフラストラクチャを提供します。udev規則は、外部ツールをカーネルデバイスイベント処理に接続する方法を提供します。これにより、カーネルデバイス処理の一部として実行する特定のスクリプトを追加するなど、udevデバイス処理をカスタマイズしたり、デバイス処理中に評価する追加データを要求およびインポートしたりできます。

12.1. /devディレクトリ

/devディレクトリ内のデバイスノードを使用して、対応するカーネルデバイスにアクセスできます。udevにより、 /dev ディレクトリにカーネルの現在の状態が反映されます。カーネルデバイスは、それぞれ1つの対応するデバイスファイルを持ちます。デバイスがシステムから取り外されると、そのデバイスノードは削除されます。

/devディレクトリのコンテンツは一時的なファイルシステム内で管理され、すべてのファイルはシステムの起動時にレンダリングされます。意図的に、手動で作成または変更されたファイルはリブート時に復元されません。対応するカーネルデバイスの状態にかかわらず、/devディレクトリ内に常駐する静的ファイルおよびディレクトリは、/lib/udev/devicesディレクトリ内に保管できます。システムの起動時、そのディレクトリのコンテンツは、/lib/udev/devices内のファイルと同じ所有者およびパーミッションの/devディレクトリ内にコピーされます。

12.2. カーネルのueventudev

必要なデバイス情報は、sysfsファイルシステムによってエクスポートされます。カーネルが検出および初期化するすべてのデバイスについて、そのデバイス名を含んだディレクトリが作成されます。このディレクトリには、デバイス固有のプロパティのある属性ファイルが含まれます。

デバイスが追加または削除されるたびに、カーネルはueventを送信して、udevに変更を通知します。udevデーモンは、起動時に1回、 /etc/udev/rules.d/*.rules ファイルから提示されたすべてのルールを読み込んで解析し、メモリ内に保存します。規則ファイルが変更、追加、または削除されると、このデーモンは、udevadm control reload_rulesコマンドで、すべての規則をメモリに再ロードできます。これは、/etc/init.d/boot.udev reloadの実行時にも行われます。udevのルールとそれらの構文の詳細については、12.6項 「udevルールによるカーネルデバイスイベン処理への影響」を参照してください。

着信したイベントは、すべて一連のプロバイダルールと一致します。規則によって、イベント環境キーを追加または変更したり、作成するデバイスノードに特定の名前を要求したり、ノードを指すシンボリックリンクを追加したり、またはデバイスノードの作成後に実行するプログラムを追加したりできます。ドライバのコアueventは、カーネルのネットリンクソケットから受信されます。

12.3. ドライバ、カーネルモジュールおよびデバイス

カーネルバスドライバは、デバイスを検出します。検出されたデバイスごとに、カーネルは内部デバイス構造を作成し、ドライバコアは、ueventをudevデーモンに送信します。バスデバイスは、デバイスの種類を示す特別な形式のIDを識別します。通常、これらのIDは、ベンダー、製品IDおよびサブシステム固有の値で構成されています。各バスには、これらのIDに対してMODALIASという独自のスキームを持ちます。カーネルは、デバイス情報を読み取り、この情報からMODALIAS ID文字列を作成し、イベントとともに文字列を送信します。USBマウスの場合、次のようになります。

MODALIAS=usb:v046DpC03Ed2000dc00dsc00dp00ic03isc01ip02

各デバイスドライバは、既知の処理可能デバイスのエイリアスのリストを持ちます。このリストは、カーネルモジュールファイル自体にも含まれています。depmodプログラムは、IDリストを読み取り、現在使用可能なすべてのモジュールについて、カーネルの/lib/modulesディレクトリ内にmodules.aliasを作成します。このインフラストラクチャにより、MODALIASキーを持つイベントごとにmodprobeを呼び出すだけで簡単にモジュールをロードできます。modprobe $MODALIASが呼び出されると、そのデバイスに付けられたデバイスエイリアスとモジュールによって提示されるエイリアスとが一致します。一致したエントリが見つかると、そのモジュールがロードされます。これはすべてudevによって自動的にトリガされます。

12.4. ブートおよび初期デバイスセットアップ

udevデーモンが実行される前のブートプロセスで発生するすべてのデバイスイベントは失われます。これは、これらのイベントを処理するインフラストラクチャがルートファイルシステムに常駐し、その時点で使用できないからです。その消失の埋め合せに、カーネルは、sysfsファイルシステム内の各デバイスのデバイスディレクトリにueventファイルを生成します。そのファイルにaddと書き込むことにより、カーネルは、ブート時に消失したものと同じイベントを再送します。/sys内のすべてのueventファイルを含む単純なループにより、すべてのイベントが再びデバイスノードを作成し、デバイスセットアップを実行します。

たとえば、ブート時に存在するUSBマウスは、ドライバがその時点で使用できないため、初期のブートロジックでは初期化されない場合があります。デバイス検出イベントは、消失し、そのデバイスのカーネルモジュールは検出されません。接続されている可能性のあるデバイスを手動で検索する代わりに、ルートファイルシステムが使用可能になった後で、udevがカーネルからすべてのデバイスイベントを要求します。これにより、USBマウスデバイスのイベントが再び実行されます。これで、マウントされたrootファイルシステム上のカーネルモジュールが検出され、USBマウスが初期化されます。

ユーザスペースでは、実行時のデバイスのcoldplugシーケンスとデバイス検出との間に明らかな違いはありません。両方の場合も、同じ規則を使用して一致検出が行われ、同じ設定されたプログラムが実行されます。

12.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行は、カーネルがnetlinkで送信したイベントを示します。UDEV行は、完了したudevイベントハンドラを示します。タイミングは、マイクロ秒で出力されます。UEVENTおよびUDEV間の時間は、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で変更できます。

12.6. udevルールによるカーネルデバイスイベン処理への影響

udevルールは、カーネルがイベント自体に追加する任意のプロパティや、カーネルがsysfsにエクスポートする任意の情報と一致することができます。また、この規則で、外部プログラムからの追加情報を要求することもできます。各イベントは、指定されたすべての規則と一致します。すべての規則は、/etc/udev/rules.dディレクトリにあります。

規則ファイル内の各行には、少なくとも1つのキー値ペアが含まれています。これらは、一致と割り当てキーという2種類のキーです。すべての一致キーが各値と一致する場合、その規則が適用され、割り当てキーに指定された値が割り当てられます。一致する規則がある場合、デバイスノードの名前を指定、ノードを指すシンボリックリンクを追加、またはイベント処理の一部として指定されたプログラムを実行できます。一致する規則がない場合、デフォルトのデバイスノード名を使用して、デバイスノードが作成されます。ルールの構文とデータの一致またはインポート用に提供されているキーの詳細については、udevのマニュアルページで説明されています。以下に示すルール例では、udevルール構文の基本を紹介します。これらのルール例は、すべて、/etc/udev/rules.d/50-udev-default.rulesの下にあるudevデフォルトルールセットに含まれています。

例12.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"

consoleルールは、3つのキーで構成されています。その内訳は、一致キーが1つ(KERNEL)、割り当てキーが2つ(MODEOPTIONS)です。KERNEL一致ルールはconsoleタイプのアイテムをデバイスリストから検索します。正確な一致だけが有効であり、このルールの実行をトリガします。MODEキーは、特別パーミッションをデバイスノードに割り当てます。この例では、読み取り/書き込みパーミッションをこのデバイスの所有者にのみ割り当てます。OPTIONSキーは、この規則をこのタイプのデバイスに適用される最後の規則にします。以降の規則は、この特定デバイスタイプとマッチしても、どのような結果も生じません。

serial devicesルールは、50-udev-default.rulesには存在しなくなりましたが、依然その知識は重要です。この規則は、2つの一致キー(KERNELATTRS)および1つの割り当てキー(SYMLINK)で構成されます。KERNELキーは、ttyUSBタイプのすべてのデバイスを検索します。このキーで*ワイルドカードを使用すると、これらのデバイスのいくつかとマッチします。2つ目の一致キーATTRSは、ttyUSBデバイスのsysfsにあるproduct属性ファイルに一定の文字列が含まれているかどうかをチェックします。割り当てキー(SYMLINK)は、/dev/pilotの下に、このデバイスへのシンボリックリンクを追加します。このキーで演算子(+=)を使用すると、前/後の規則が他のシンボリックリンクを追加した場合でも、udevはこの操作を追加実行します。この規則は、2つの一致キーを含むので、両方の条件が満たされる場合のみ適用されます。

printerルールは、USBプリンタを対象とし、2つの一致キー(SUBSYSTEMKERNEL)を含みます。規則全体を適用するには、これらのキーを両方とも適用する必要があります。3つの割り当てキーは、このデバイスタイプの名前付け(NAME)、シンボリックデバイスリンクの作成、(SYMLINK)、およびこのデバイスタイプのグループメンバーシップ(GROUP)を処理します。KERNELキーで*ワイルドカードを使用すると、いくつかのlpプリンタデバイスとマッチします。NAMEおよびSYMLINKの両キーで置き換えを使用すると、これらの文字列を内部デバイス名で拡張できます。たとえば、最初のlp USBプリンタへのシンボリックリンクは/dev/usblp0となります。

kernel firmware loaderルールでは、ランタイム時の外部ヘルパースクリプトで、udevが追加ファームウェアをロードします。SUBSYSTEM一致キーは、firmwareサブシステムを検索します。ACTIONキーは、firmwareサブシステムに属するデバイスが追加されているかどうかをチェックします。RUN+=キーは、firmware.shスクリプトの実行をトリガして、ファームウェアを見つけます。

すべての規則に共通する一般的特性は次のとおりです。

  • 各規則は、カンマで区切られた1つ以上のキー値ペアで構成されます。

  • キーの動作は、演算子で決定されます。udevルールは、いくつかの異なる演算子をサポートします。

  • 指定する各値は、引用符で囲む必要があります。

  • 規則ファイルの各行が1つの規則に相当します。規則が1行を超える場合は、shell構文のように、\を使用して異なる行を結合してください。

  • udevルールは、shell型のパターンをサポートします。このパターンは、*?、および[]の各パターンとマッチします。

  • udevルールは、置換をサポートします。

12.6.1. udevルールでの演算子の使用

キーを作成する場合は、作成するキーのタイプによって、いくつかの異なる演算子から選択できます。一致キーは、通常、検索値とマッチするか、明示的にミスマッチする値を見つけるためにだけ使用されます。一致キーは、次の演算子のいずれかを含みます。

==

等価の比較。キーに検索パターンが含まれている場合は、そのパターンと一致するすべての結果が有効です。

!=

非等価の比較。キーに検索パターンが含まれている場合は、そのパターンと一致するすべての結果が有効です。

割り当てキーでは、次のどの演算子でも使用できます。

=

値をキーに割り当てます。すでに値のリストで構成されているキーはリセットされ、指定した1つの値だけが割り当てられます。

+=

エントリのリストを含むキーに値を追加します。

:=

最終値を割り当てます。以降の規則による変更は許可されません。

12.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}$attr{variable}

環境変数の値(variableで指定)。

%c$result

PROGRAMの出力。

%%

%文字。

$$

$文字。

12.6.3. udev一致キーの使用

一致キーは、udevルールの適用前に満たす必要のある条件を記述します。次の一致キーが使用可能です。

ACTION

イベント動作の名前。たとえば、addまたはremove(デバイスの追加または削除の場合)。

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 bus IDに関連するすべてのイベントを検索します。

PROGRAM

udevに外部プログラムを実行させます。成功の場合は、プログラムが終了コードとしてゼロを返します。stdoutに印刷されるプログラムの出力は、RESULTキーで使用できます。

RESULT

最後のPROGRAM呼び出しの出力文字列とマッチします。このキーは、PROGRAMキーと同じ規則に含めるか、それ以降のキーに含めてください。

12.6.4. udev割り当てキーの使用

上記で説明した一致キーに対し、割り当てキーでは満たすべき条件を記述しません。値、名前、アクションをudevが保守するデバイスノードに割り当てます。

NAME

作成するデバイスノードの名前。いったん規則でノード名が設定されると、このノードのNAMEキーを持つ他の規則はすべて無視されます。

SYMLINK

作成するノードに関連するシンボリックリンクの名前。複数の一致ルールで、デバイスノードとともに作成するシンボリックリンクを追加できます。1つのルール内で、スペース文字でシンボリックリンク名を区切ることで、1つのノードに複数のシンボリックリンクを指定することもできます。

OWNER、GROUP、MODE

新しいデバイスノードのパーミッションここで指定する値は、すでにコンパイルされている値を上書きします。

ATTR{key}

イベントデバイスのsysfs属性に書き込む値を指定します。==演算子を使用すると、このキーは、sysfs属性の値とのマッチングにも使用されます。

ENV{key}

環境への変数のエクスポートをudevに指示します。==演算子を指定すると、このキーは、環境変数とのマッチングにも使用されます。

RUN

このデバイスに対して実行されるプログラムのリストにプログラムを追加するように、udevに指示します。このデバイスのイベントをブロックしないようにするため、これは非常に短いタスクに限定してください。

LABEL

GOTOのジャンプ先にするラベルを追加します。

GOTO

いくつかのルールをスキップし、GOTOキーで参照されるラベルを含むルールから続行するように、udevに指示します。

IMPORT{type}

変数をイベント環境(外部プログラムの出力など)にロードします。udevは、いくつかの異なるタイプの変数をインポートします。タイプが指定されていない場合、udevは、ファイルパーミションの実行可能ビットに基づいてタイプを決定しようとします。

  • program - 外部プログラムを実行し、その出力をインポートします。

  • file - テキストファイルをインポートします。

  • parent - 親デバイスから保存されたキーをインポートします。

WAIT_FOR_SYSFS

一定のデバイスに指定されたsysfsファイルが作成されるまで、udevを待機させます。たとえば、WAIT_FOR_SYSFS="ioerr_cnt"では、ioerr_cntファイルが作成されるまで、udevを待機させます。

オプション

OPTIONキーには、次の可能な値があります。

  • last_rule - 以降のすべての規則を無視します。

  • ignore_device - このイベントを完全に無視します。

  • ignore_remove - このデバイスの以降のすべての削除イベントを無視します。

  • all_partitions - ブロックデバイス上のすべての使用可能なパーティションにデバイスノードを作成します。

12.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

12.8. udevで使用するファイル

/sys/*

Linuxカーネルによって提供される仮想ファイルシステム。現在知られているデバイスをすべてエクスポートします。この情報は、udevが使用して/dev内にデバイスノードを作成します。

/dev/*

動的に作成されるデバイスノードと静的コンテンツ。ブート時に/lib/udev/devices/*からコピーされます。

以下のファイルおよびディレクトリには、udevインフラストラクチャの重要な要素が含まれています。

/etc/udev/udev.conf

メインudev設定ファイル

/etc/udev/rules.d/*

規則と一致するudevイベント.

/lib/udev/devices/*

静的/devコンテンツ

/lib/udev/*

udevルールから呼び出されるヘルパープログラム

12.9. 詳細情報

udevインフラストラクチャの詳細については、以下のマニュアルページを参照してください。

udev

udev、キー、ルールなどの重要な設定課題に関する一般情報

udevadm

udevadmは、udevのランタイム動作を制御し、カーネルイベントを要求し、イベントキューを管理し、簡単なデバッグメカニズムを提供します。

udevd

udevイベント管理デーモンに関する情報