目次
カーネルには、システムの実行中に任意のデバイスを追加したり削除したりする
機能が備わっています。デバイス状態の変化 (デバイスが接続されたり削除されたり)
はユーザ側に通知する必要がありますし、接続されて認識されるとすぐに設定を
行なう必要があります。また、特定のデバイスを利用しているユーザが存在する
場合は、そのデバイスの認識状態についても変化を通知する必要があります。
udev では、 /dev ディレクトリ内に存在するデバイス
ノードファイルとシンボリックリンクについて、動的に管理するために必要な
インフラストラクチャを提供しています。また、 udev のルールはカーネル
デバイスのイベント処理に外部ツールを接続する方法を提供するものです。
たとえばカーネルのデバイス処理の一部として特定のスクリプトを追加で実行
したり、デバイスの処理時に評価を行なう目的で追加データを要求したり
取り込んだりするなど、デバイスの処理方法をカスタマイズすることができます。
/dev ディレクトリ¶
/dev ディレクトリ内にあるデバイスノードは、それぞれ
関連するカーネルデバイスに対して、アクセスを提供するためのものです。
udev を利用することで、 /dev ディレクトリは現在の
カーネル状態を反映するようになります。各カーネルデバイスには 1 つの
デバイスファイルが存在します。あるデバイスがシステムから取り外されると、
デバイスノードが削除されます。
/dev ディレクトリの内容はテンポラリファイルシステム
上に存在していて、全てのファイルはシステム起動時に作成されます。設計上、
このディレクトリ内に手動でファイルを作成しても、システムを再起動すると
ファイルは消えてしまいます。関連するカーネルの状態に関わらず
/dev ディレクトリ内に存在すべき固定のファイルや
ディレクトリについては、 /lib/udev/devices
ディレクトリ内に配置することができます。システム起動時に左記の
ディレクトリ内容は /dev ディレクトリに、
/lib/udev/devices に存在したものと同じ所有権設定と
パーミッションのままコピーされます。
必要なデバイス情報は sysfs ファイルシステムから受け取る仕組みです。 カーネルが検出して初期化した各デバイスに対して、デバイス名の付いた ディレクトリが作成されます。このディレクトリにはデバイス固有の情報を 含む属性ファイルが入っています。
デバイスが追加されたり削除されたりするたびに、カーネルは udev に対して
変更を通知するため uevent を送信します。 udev デーモンは、起動時に
/etc/udev/rules.d/*.rules ファイルから提供される
全てのルールを読み込んで処理し、メモリ内に記憶します。ルールファイルを
変更したり追加または削除したりした場合は、
udevadm control reload_rules コマンドを利用して、
デーモンに対してメモリ内の記憶を読み込み直すように指定することができます。
同じことが /etc/init.d/boot.udev reload コマンドでも
行なうことができます。 udev のルールと書式について、詳しくは
19.6項 「udev ルールによるカーネル側デバイスイベント処理への影響」 をお読みください。
それぞれ受信したイベントは、提供されたルールセットとの適合処理を行ないます。 各ルールは、追加したりイベントの環境キーを変更したりすることができるほか、 作成するデバイスノードに対して特定の名前を要求したり、ノードを示す シンボリックリンクを追加したり、デバイスノード作成後に実行すべきプログラム を追加したりすることができます。ドライバ中枢部分の uevent は、カーネルの netlink ソケットから受信します。
カーネルのバスドライバは、デバイスに対する探査を行ないます。カーネルはデバイスを
検出すると、それぞれに対して内部用のデバイス構造を作成し、ドライバの中枢部から
uevent の形で udev デーモンに送信します。バスデバイスは特別に作成した ID の
形で、自分自身がどんな種類のデバイスであるのかを識別します。通常、これらの ID は
製造元 ID と製品 ID 、およびサブシステム固有の値から構成されています。各バスは
それらの ID について独自の方針を持っていて、それらは MODALIAS
と呼ばれます。まとめると、カーネルはデバイス情報を取得してそれらの情報から
MODALIAS ID 文字列を生成し、イベントとともにその値を
送信します。 USB マウスの場合、たとえば下記のようになります:
MODALIAS=usb:v046DpC03Ed2000dc00dsc00dp00ic03isc01ip02
各デバイスドライバには、処理可能なそれぞれのデバイスに対して、既知の別名を
保持しています。その一覧はカーネルモジュールファイル自身に含まれる形に
なっています。 depmod プログラムは利用可能な全てのモジュールに対して
ID の一覧を読み込み、カーネルの /lib/modules
ディレクトリ以下の modules.alias ファイルを作成します。
このような構造から、モジュールの読み込みは、 MODALIAS
を含んだ各イベントに対して modprobe を呼び出すだけの
簡易な処理で実現できるようになっています。
modprobe $MODALIAS が呼び出されると、モジュールが提供する
別名情報の一覧内を検索し、適合する項目があればそのモジュールを読み込むように
なっています。これらの処理は全て udev から実行されます。
udev が起動する前の起動処理時に発生した全てのデバイスイベントは、読み込む
ことができません。これはこれらのイベントを処理するための仕組みがルートファイル
システム内に存在していて、その時点ではそれらを利用できないためです。
このような損失をカバーするため、カーネルは sysfs ファイルシステム内の各
デバイスディレクトリ内に uevent というファイルを
提供しています。これらのファイルに add と書き込むことで、
起動時に送信され失われてしまったものと同じイベントを再送することができます。
/sys 内にある全ての uevent
ファイルに対して単純に繰り返して処理するだけで、デバイスノードを作成して
デバイスの設定を実施するために必要な、全てのイベントを再送することができます。
たとえば、その時点ではドライバを用意することができない理由から、初期の起動処理で USB マウスの準備は行なわれません。そのためデバイス検出のイベントは失われ、 それらのデバイスに対するカーネルモジュールの発見もできなくなってしまいます。 接続されている可能性のあるデバイスを手動で検索する代わりに、 udev はルート ファイルシステムの準備が完了すると、カーネルが検出した全てのデバイスに対して イベントを要求し、 USB マウスに対するイベントが再度送信されるようにしています。 マウント済みのルートファイルシステム内にカーネルモジュールが見つかると、 USB マウスが利用できるようになります。
ユーザ側からは、デバイスのコールドプラグ (システム起動時から接続すること) と 稼働時のデバイス検出には確認できる違いはありません。両方のケースとも同じ ルールが適用され、同じ設定済みプログラムが実行されます。
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 がそのイベントの処理を行なうために費やした時間か、もしくは
関連していたり既に実行中だったりするイベントと同期を待ちあわせるため、実行を遅らせた
時間を表わします。たとえばハードディスクのパーティションに対するイベントは、
常にディスクそのもののイベントが完了するまで待機します。これは、ディスク全体の
イベントが問い合わせるハードウエア情報に依存して動作するためです。
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 の既定 priority は、 udev の設定ファイル
/etc/udev/udev.conf で指定することができます。
既に起動中のデーモンに対して priority を変更するように指定したい場合は、
udevadm control log_priority=レベル/番号
のように実行します。
udev のルールは、カーネルがイベント自身に追加したプロパティ情報や、カーネルが
sysfs 経由でエクスポートした情報であれば、どんなものに
でも適合させることができます。また、ルールでは外部のプログラムから得られる
追加情報を要求することもできます。また、それぞれのイベントは提供された全ての
ルールに対して適合性を確認します。全てのルールは
/etc/udev/rules.d ディレクトリ内に配置します。
ルールファイル内のそれぞれの行には、少なくとも 1 対のキーと値が書かれています。
キーには 2 種類のものがあります。それは適合キーと代入キーです。全ての適合キー
がその値と適合するとそのルールが適用され、代入キーで指定された値が代入されます。
適合ルールにはデバイスノードの名前のほか、ノードを指し示すシンボリックリンクや
イベント処理の一部として指定したプログラムを指定することもできます。適合する
ルールが見つからない場合は、デバイスノードの作成には既定のデバイスノード名が
使用されます。ルールの文法と提供されている適合キーまたは取り込みデータについては、
それぞれ udev のマニュアルページで説明しています。下記の例では、 udev のルール
文法に関する基本的な内容を説明しています。下記の例は
/etc/udev/rules.d/50-udev-default.rules ファイル内に
存在するルールからの抜粋です。
例19.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 つは代入キー
(MODE, OPTIONS) になっています。
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 のキーで使用されていて、内部のデバイス名に
置き換えるような作りになっています。たとえば 1 台目の lp
USB プリンタであれば、 /dev/usblp0 のようになります。
さらに kernel firmware loader のルールでは、
その実行時に udev に対して外部のヘルパースクリプトを起動して、追加のファーム
ウエアを読み込むように指定しています。また、 SUBSYSTEM の
適合キーでは firmware サブシステムを対象としています。
ACTION キーは、デバイスが firmware
サブシステムに属しているかどうかを追加で判断するように指定しています。
最後の RUN+= キーでは、読み込むべきファームウエアの場所を
判断するため、 firmware.sh スクリプトを実行するように
指定しています。
いくつかの汎用ルールを下記に示します:
各ルールには 1 つ以上のキーと値の組み合わせが書かれていて、それらはカンマで区切ります。
キーの操作は演算子で決定します。 udev ルールは複数の演算子に対応しています。
実値として与える値は、引用符で括らなければなりません。
ルールのファイル内の各行は 1 つのルールを表わすものです。 1 行よりも
長いルールを記述する場合は、シェルで利用するのと同じ \
記号を行末に書き込んで連続していることを宣言してください。
udev のルールでは、シェル形式のパターンマッチを利用することができます。
それぞれ *, ?, []
を利用することができます。
udev のルールは置換文字列に対応しています。
キーを作成するにあたっては、いくつかの演算子の中から演算子を指定することに なります。これは作成したいキーの種類に依存します。適合キーの場合は検索値に 該当するかどうかの条件を指定します。適合キーには下記の演算子を利用します:
==
等しいかどうかを検証します。キーに検索パターンが含まれている場合、 そのパターンに該当するもの全てを有効と見なします。
!=
等しくないかどうかを検証します。キーに検索パターンが含まれている場合、 そのパターンに該当するもの全てを有効と見なします。
代入キーの場合は、下記の演算子を利用します:
=
キーに値を代入します。以前のルール処理で、そのキーに値の一覧が代入されていた 場合は、キーはリセットされて単一の値が代入されます。
+=
項目の一覧を保持しているキーに対して、値を追加します。
:=
最終値を代入します。後のルールでの変更を許可しないようになります。
udev のルールでは、プレースホルダや置換文字列を使用することができます。これらは 他のスクリプトで行なうのと似たような仕組みになっています。下記に udev で使用できる 置換文字列の一覧を示します:
%r, $root
デバイスディレクトリを表わします。既定では /dev です。
%p, $devpath
DEVPATH の値を表わします。
%k, $kernel
KERNEL の値か、もしくは内部デバイス名の値を表わします。
%n, $number
デバイス番号を表わします。
%N, $tempnode
デバイスファイルの一時名を表わします。
%M, $major
デバイスのメジャー番号を表わします。
%m, $minor
デバイスのマイナー番号を表わします。
%s{attribute},
$attr{attribute}
variable で指定した
sysfs 属性の値を表わします。
%E{variable},
$attr{variable}
variable で指定した
環境変数の値を表わします。
%c, $result
PROGRAM の出力を表わします。
%%
% 文字そのものを表わします。
$$
$ 文字そのものを表わします。
適合キーは、 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{ファイル名}
udev に対して、該当する sysfs 属性値を検索するため上位のデバイスパスを 検索するように指定します。
ENV{key}
環境変数の値を表わします。たとえば ENV{ID_BUS}="ieee1394
のように指定すると、 FireWire のバス ID に関連する全てのイベントに
適合するようになります。
PROGRAM
udev に対して外部プログラムを実行するように指定します。適合と判断させる
には、プログラムは 0 を返さなければなりません。プログラムが標準出力
(stdout) に出力した内容は、 RESULT キーから利用する
ことができます。
RESULT
最後の PROGRAM 呼び出しに対して、出力文字列の適合
処理を行ないます。このキーは PROGRAM キーを指定した
のと同じルール内で行なうか、もしくはそれ以降のルールで行なうことが
できます。
上述の適合キーとは異なり、代入キーは適合すべき条件を表わすことはありません。 代入キーは値や名前を代入したり、 udev で管理されるデバイスノードに対する 動作を指定したりします。
NAME
作成すべきデバイスノード名を表わします。あるルールでいったんノード名が
設定されると、それ以降の全てのルールで NAME キー
への代入が無視されるようになります。
SYMLINK
作成すべきノードに関連づけるシンボリックリンク名を表わします。 1 つのデバイスノードに対して複数の適合ルールから、作成すべき複数のシンボリック リンクを追加することかできます。 1 つのノードに対して 1 つのルールで 複数のシンボリックリンクを指定することもできます。この場合は、複数の シンボリックリンク名の間をスペースで区切ってください。
OWNER, GROUP, MODE
新しく作成するデバイスノードに対して設定する、パーミッションを指定します。 設定した値は任意のルールで上書きすることができます。
ATTR{key}
イベントの発生したデバイスに対して書き込むべき、 sysfs 属性の値を
指定します。 == 演算子を使用すると、このキーは
sysfs 属性に対する適合キーとして解釈されます。
ENV{key}
udev に対して環境変数に値を設定するように指定します。
== 演算子を使用すると、このキーは環境変数に
対する適合キーとして解釈されます。
RUN
udev に対して、このデバイスに対して実行するプログラムの一覧に プログラムを追加するよう指定します。なお、このデバイスに対する 後続のイベント処理を止めないようにする目的で、実行するプログラムは 非常に短い時間で完了するタスクにしてください。
LABEL
GOTO からジャンプすることのできるラベル和
指定します。
GOTO
udev に対して、複数のルールを飛ばしてラベルの位置まで移動するよう 指定します。
IMPORT{種類}
値を外部プログラムの出力などのイベント環境に読み込みます。 udev は複数の種類の値を取り込むことができます。種類を指定しない場合は、 udev はファイルパーミッションの実行許可ビットをベースにして、 種類を自分自身で判別しようとします。
program を指定すると、 udev は外部プログラムを
実行して、その出力を取り込みます。
file を指定すると、テキストファイルを取り込みます。
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 はブロックデバイス
上の全ての利用可能なパーティションについて、デバイスノードを作成するように
なります。
動的なデバイスディレクトリと 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/sys/*
Linux カーネルから提供されている仮想ファイルシステムで、既知の全ての
デバイスについて情報を公開しています。この情報は、デバイスノードを
/dev 以下に作成する際に udev が使用します。
/dev/*
動的に作成されたデバイスノードと、 /lib/udev/devices/*
からコピーされた静的コンテンツの両方が含まれます。
下記のファイルやディレクトリは、 udev を構成するために欠くことのできないものです:
/etc/udev/udev.conf
メインの udev 設定ファイルです。
/etc/udev/rules.d/*
udev イベント適合ルールです。
/lib/udev/devices/*
/dev に配置される静的なデバイスノードなどを
表わすディレクトリです。
/lib/udev/*
udev ルールから呼び出されるヘルパープログラムです。
udev の仕組みについてさらなる情報を得るには、下記のマニュアルページを お読みください:
udev やキー、ルール、その他重要な設定周りの問題について、 一般情報を提供しています。
udevadm は udev の実行制御を行なうために使用し、カーネルイベントの 要求やイベントキューの管理、およびシンプルなデバッグ機構を提供して います。
udev イベント管理デーモンに関する情報が書かれています。