29 udevによる動的カーネルデバイス管理 #
カーネルは、実行中のシステムのほぼすべてのデバイスを追加または削除できます。デバイス状態の変更(デバイスが接続されているか、または取り外されたか)をユーザスペースに反映させる必要があります。デバイスは、接続後、検出されたら、設定しなければなりません。特定のデバイスのユーザは、このデバイスの認識された状態が変更された場合は通知される必要があります。udevは、/devディレクトリのデバイスノードファイルおよびシンボリックリンクを動的に維持するために必要なインフラストラクチャを提供します。udev規則は、外部ツールをカーネルデバイスイベント処理に接続する方法を提供します。これにより、カーネルデバイス処理の一部として実行する特定のスクリプトを追加して、udevデバイス処理をカスタマイズしたり、デバイス処理中に評価する追加データを要求およびインポートしたりできます。
29.1 /devディレクトリ #
/devディレクトリ内のデバイスノードを使用して、対応するカーネルデバイスにアクセスできます。udevにより、/devディレクトリにカーネルの現在の状態が反映されます。カーネルデバイスは、それぞれ1つの対応するデバイスファイルを持ちます。デバイスがシステムから取り外されると、そのデバイスノードは削除されます。
/devディレクトリのコンテンツは一時的なファイルシステム内で管理され、すべてのファイルはシステムの起動時にレンダリングされます。意図的に、手動で作成または変更されたファイルはリブート時に復元されません。対応するカーネルデバイスの状態にかかわらず、/devディレクトリ内に存在する静的ファイルおよびディレクトリは、systemd-tmpfilesで作成できます。設定ファイルは、/usr/lib/tmpfiles.d/および/etc/tmpfiles.d/にあります。詳細については、systemd-tmpfiles(8)のマニュアルページを参照してください。
29.2 カーネルueventsとudev #
必要なデバイス情報は、sysfsファイルシステムによってエクスポートされます。カーネルが検出および初期化するすべてのデバイスについて、そのデバイス名を含んだディレクトリが作成されます。このディレクトリには、デバイス固有のプロパティのある属性ファイルが含まれます。
デバイスが追加または削除されるたびに、カーネルはueventを送信して、udevに変更を通知します。udevデーモンは、起動時に/usr/lib/udev/rules.d/*.rulesおよび/etc/udev/rules.d/*.rulesファイルからのすべてのルールを読み込み、解析し、メモリに保持します。規則ファイルが変更、追加、または削除されると、このデーモンは、udevadm control --reloadコマンドで、メモリに再ロードできます。udevのルールとそれらの構文の詳細については、29.6項 「udevルールによるカーネルデバイスイベント処理への影響」を参照してください。
受信したすべてイベントは、提供されている一連のルールに照らして照合されます。ルールによって、イベント環境キーを追加または変更したり、作成するデバイスノードに特定の名前を要求したり、ノードを指すシンボリックリンクを追加したり、またはデバイスノードの作成後に実行するプログラムを追加したりできます。ドライバのコアueventsは、カーネルのネットリンクソケットから受信されます。
29.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によって自動的にトリガされます。
29.4 ブートおよび初期デバイスセットアップ #
udevデーモンが実行される前のブートプロセスで発生するすべてのデバイスイベントは失われます。これは、これらのイベントを処理するインフラストラクチャがルートファイルシステムに常駐し、その時点で使用できないからです。その消失の埋め合せに、カーネルは、sysfsファイルシステム内の各デバイスのデバイスディレクトリにueventファイルを生成します。そのファイルにaddと書き込むことにより、カーネルは、ブート時に消失したものと同じイベントを再送します。/sys内のすべてのueventファイルを含む単純なループにより、すべてのイベントが再びデバイスノードを作成し、デバイスセットアップを実行します。
たとえば、ブート時に存在するUSBマウスは、ドライバがその時点で使用できないため、初期のブートロジックでは初期化されない場合があります。デバイス検出イベントは、消失し、そのデバイスのカーネルモジュールは検出されません。接続されているデバイスを手動で検索する代わりに、ルートファイルシステムが使用可能になった後で、udevがカーネルにすべてのデバイスイベントを要求します。これにより、USBマウスデバイスのイベントが再び実行されます。これで、マウントされたrootファイルシステム上のカーネルモジュールが検出され、USBマウスを初期化できます。
ユーザスペースでは、実行時のデバイスのcoldplugシーケンスとデバイス検出との間に明らかな違いはありません。どちらの場合も、同じルールを使用して一致検出が行われ、設定された同じプログラムが実行されます。
29.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で変更できます。
29.6 udevルールによるカーネルデバイスイベント処理への影響 #
udevルールは、カーネルがイベント自体に追加する任意のプロパティや、カーネルがsysfsにエクスポートする任意の情報と一致することができます。また、この規則で、外部プログラムからの追加情報を要求することもできます。イベントは、ディレクトリ/usr/lib/udev/rules.d/ (デフォルトルール用)および/etc/udev/rules.d (システム固有の設定用)で提供されるすべてのルールと照合されます。
規則ファイル内の各行には、少なくとも1つのキー値ペアが含まれています。これらは、一致と割り当てキーという2種類のキーです。すべての一致キーが各値と一致する場合、その規則が適用され、割り当てキーに指定された値が割り当てられます。一致するルールがある場合、デバイスノードの名前を指定、ノードを指すシンボリックリンクを追加、またはイベント処理の一部として指定されたプログラムを実行できます。一致するルールがない場合、デフォルトのデバイスノード名を使用して、デバイスノードが作成されます。ルールの構文とデータの一致またはインポート用に提供されているキーの詳細については、udevのマニュアルページで説明されています。以下に示すルール例では、udevルール構文の基本を紹介します。これらのルール例は、すべてudevデフォルトルールセット/usr/lib/udev/rules.d/50-udev-default.rulesに含まれています。
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ルールは、1つの一致キー(KERNEL)と、2つの割り当てキー(MODE、OPTIONS)の3つのキーで構成されます。KERNEL一致ルールはconsoleタイプのアイテムをデバイスリストから検索します。正確な一致だけが有効であり、このルールの実行をトリガします。MODEキーは、特別パーミッションをデバイスノードに割り当てます。この例では、読み取り/書き込みパーミッションをこのデバイスの所有者にのみ割り当てます。OPTIONSキーは、この規則をこのタイプのデバイスに適用される最後の規則にします。以降の規則は、この特定デバイスタイプとマッチしても、どのような結果も生じません。
serial devicesルールは、50-udev-default.rulesには存在しなくなりましたが、依然その知識は重要です。この規則は、2つの一致キー(KERNELとATTRS)および1つの割り当てキー(SYMLINK)で構成されます。KERNELキーは、ttyUSBタイプのすべてのデバイスを検索します。このキーで*ワイルドカードを使用すると、これらのデバイスのいくつかとマッチします。2つ目の一致キーATTRSは、ttyUSBデバイスのsysfsにあるproduct属性ファイルに一定の文字列が含まれているかどうかをチェックします。割り当てキー(SYMLINK)は、/dev/pilotの下に、このデバイスへのシンボリックリンクを追加します。このキーで演算子(+=)を使用すると、前/後の規則が他のシンボリックリンクを追加した場合でも、udevはこの操作を追加実行します。この規則は、2つの一致キーを含むので、両方の条件が満たされる場合のみ適用されます。
printerルールは、USBプリンタを対象とし、2つの一致キー(SUBSYSTEMとKERNEL)を含みます。規則全体を適用するには、これらのキーを両方とも適用する必要があります。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ルールは、置換をサポートします。
29.6.1 udevルールでの演算子の使用 #
キーを作成する場合は、作成するキーのタイプによって、いくつかの演算子から選択できます。一致キーは、通常、検索値に一致するか、明示的に一致しない値を見つけるために使用されます。一致キーは、次の演算子のいずれかを含みます。
==等価の比較。キーに検索パターンが含まれている場合は、そのパターンと一致するすべての結果が有効です。
!=非等価の比較。キーに検索パターンが含まれている場合は、そのパターンと一致するすべての結果が有効です。
割り当てキーでは、次のどの演算子でも使用できます。
=値をキーに割り当てます。すでに値のリストで構成されているキーはリセットされ、指定した1つの値だけが割り当てられます。
+=エントリのリストを含むキーに値を追加します。
:=最終値を割り当てます。以降の規則による変更は許可されません。
29.6.2 udevルールでの置換の使用 #
udevルールは、プレースホルダと置換の使用をサポートします。それらは、他のスクリプトでの使用と同様な方法で使用します。udevルールでは、次の置換を使用できます。
%r、$rootデフォルトのデバイスディレクトリ
/dev。%p、$devpath値
DEVPATH。%k、$kernelKERNELの値または内部デバイス名。%n、$numberデバイス番号。
%N、$tempnodeデバイスファイルの一時名。
%M、$majorデバイスのメジャー番号。
%m、$minorデバイスのマイナー番号。
%s{ATTRIBUTE}、$attr{ATTRIBUTE}sysfs属性の値(ATTRIBUTEで指定)。%E{VARIABLE}、$env{VARIABLE}環境変数の値(VARIABLEで指定)。
%c、$resultPROGRAMの出力。%%%文字。$$$文字。
29.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"を使用できます。KERNELSudevにデバイスパスを上方に検索させ、一致するデバイス名を見つけます。SUBSYSTEMSudevにデバイスパスを上方に検索させ、一致するデバイスサブシステム名を見つけます。DRIVERSudevにデバイスパスを上方に検索させ、一致するデバイスドライバ名を見つけます。ATTRS{FILENAME}udevにデバイスパスを上方に検索させ、一致するsysfs属性値を持つデバイスを見つけます。ENV{KEY}環境変数の値。たとえば、
ENV{ID_BUS}="ieee1394でFireWire bus IDに関連するすべてのイベントを検索します。PROGRAMudevに外部プログラムを実行させます。成功の場合は、プログラムが終了コードとしてゼロを返します。プログラムの出力はSTDOUTに送られ、RESULTキーで使用できます。RESULT最後の
PROGRAM呼び出しの出力文字列とマッチします。このキーは、PROGRAMキーと同じ規則に含めるか、それ以降のキーに含めてください。
29.6.4 udev割り当てキーの使用 #
上記で説明した一致キーに対し、割り当てキーでは満たすべき条件を記述しません。値、名前、アクションをudevが保守するデバイスノードに割り当てます。
NAME作成するデバイスノードの名前。いったんルールでノード名が設定されると、このノードの
NAMEキーを持つ他のルールはすべて無視されます。SYMLINK作成するノードに関連するシンボリックリンクの名前。複数の一致ルールで、デバイスノードとともに作成するシンボリックリンクを追加できます。1つのルール内で、スペース文字でシンボリックリンク名を区切ることで、1つのノードに複数のシンボリックリンクを指定することもできます。
OWNER, GROUP, MODE新しいデバイスノードのパーミッションここで指定する値は、すでにコンパイルされている値を上書きします。
ATTR{KEY}イベントデバイスの
sysfs属性に書き込む値を指定します。==演算子を使用すると、このキーは、sysfs属性の値とのマッチングにも使用されます。ENV{KEY}環境への変数のエクスポートを
udevに指示します。==演算子を指定すると、このキーは、環境変数とのマッチングにも使用されます。RUNこのデバイスに対して実行されるプログラムのリストにプログラムを追加するように、
udevに指示します。このデバイスのイベントをブロックしないようにするため、これは短いタスクに限定してください。LABELGOTOのジャンプ先にするラベルを追加します。GOTOいくつかのルールをスキップし、
GOTOキーで参照されるラベルを含むルールから続行するように、udevに指示します。IMPORT{TYPE}変数をイベント環境(外部プログラムの出力など)にロードします。
udevは、いくつかのタイプの変数をインポートします。タイプが指定されていない場合、udevは、ファイルパーミッションの実行可能ビットに基づいてタイプを決定しようとします。program- 外部プログラムを実行し、その出力をインポートするように、udevに指示します。file- テキストファイルをインポートするように、udevに指示します。parent- 親デバイスから保存されたキーをインポートするように、udevに指示します。
WAIT_FOR_SYSFSudevに、指定されたsysfsファイルが特定のデバイス用に作成されるのを待機するように指示します。たとえば、WAIT_FOR_SYSFS="ioerr_cnt"は、udevに、ioerr_cntファイルが作成されるまで待機するように通知します。OPTIONSOPTIONキーには、いくつかの値を指定できます。last_rule- 以降のすべての規則を無視するように、udevに指示します。ignore_deviceは、このイベントを無視するようにudevに指示します。ignore_remove- このデバイスの以降のすべての削除イベントを無視するように、udevに指示します。all_partitions- ブロックデバイス上のすべての使用可能なパーティションにデバイスノードを作成するように、udevに指示します。
29.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 -> ../../sdd129.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コンテンツを管理します。
29.9 詳細情報 #
udevインフラストラクチャの詳細については、以下のマニュアルページを参照してください。
udevudev、キー、ルールなどの重要な設定課題に関する一般情報udevadmudevadmは、udevのランタイム動作を制御し、カーネルイベントを要求し、イベントキューを管理し、簡単なデバッグメカニズムを提供します。udevdudevイベント管理デーモンに関する情報