第33章 udevをもつ動的デバイスノード

目次

33.1. ルールの作成
33.2. プレースホルダの置き換え
33.3. キーのパターンマッチング
33.4. キーの選択
33.5. 大容量ストレージデバイスの持続的な名前

概要

Linuxカーネル2.6は、動的デバイスのディレクトリ/devに対して、新しいユーザ空間ソリューションを導入し、持続的なデバイス指定を実現しました。udevがこれに該当します。これは、実際に存在するデバイスにのみファイルを提供します。通常、/devディレクトリに存在するデバイスノードファイルを作成または削除し、ネットワークインタフェースの名前を変更することができます。devfsによる動的な/devの以前の実装は機能しなくなり、udevへ置き換えられました。

従来は、デバイスノードはLinuxシステム上の/devディレクトリ内に格納されていました。システム内に実際に存在しているかどうかにかかわりなく、使用可能なすべてのデバイスタイプに対して1つのノードが存在していました。その結果、このディレクトリには何千もの使用されていないファイルが含まれていました。新しく追加したサブシステムやカーネルデバイスを利用する前に、対応するノードを、特別なアプリケーションで作成する必要がありました。devfsファイルは大きな改善をもたらしました。実際に存在するものとしてカーネルに通知されたでばいすだけが、/dev内のデバイスノードを与えられたからです。

udevは、デバイスノードを作成する新しい方法を採用しました。カーネルはその内部状態をsysfsにエクスポートし、デバイスがカーネルによって認識されるたびに、sysfs内の情報を更新して、ユーザスペースにイベントを送信します。情報がsysfsによって利用可能になると、udevは簡単なルール構文と、適用されたデバイス属性とのマッチングを行い、対応するデバイスノードの作成または削除を行います。

ユーザは、新しいデバイスのためのudevルールを作成する必要はありません。あるデバイスが接続された場合、適切なデバイスノードが自動的に作成されます。しかし、ルールは、ノードの名前を定義するためのポリシーを導入します。これは、あいまいなデバイス名を覚えやすい名前へ置き換える規則を提供し、また、同じタイプのデバイスが同時に2台接続された状況で、持続するデバイス名を実現します。

仮に、高画質なカラーレーザプリンタと、白黒のインクジェットプリンタの2台のプリンタを持っていて、どちらもUSBに接続されているとしましょう。これらは/dev/usb/lpXのようになります。ここでXは、接続の順序に応じた番号です。udevを使い、カスタムのudevルールを作成すれば、一方のプリンタに/dev/colorlaserという名前を付け、もう一方に/dev/inkprinterという名前を付けることができます。これらのデバイスノードは、デバイスの特性に基づいてudevにより作成されたものなので、接続の順序やステータスにはかかわりなく、常に正しいデバイスを指します。

33.1. ルールの作成

udevは、/devの下にデバイスノードを作成する前に、/etc/udev/rules.d内で拡張子.rulesをもつすべてのファイルをアルファベット順に読み取ります。デバイスに当てはまる最初のルールが使用されます。たとえ、他のルールも当てはまる場合であってもです。コメントを記述するには、行頭にシャープ記号(#)を入力します。ルールは、次の形式を使用します。

key, [key,...]NAME [, SYMLINK]

少なくとも1つのキーを指定する必要があります。これらのキーに基づいて、ルールがデバイスに対して割り当てられるからです。また、名前を指定することも重要です。この名前は、/dev内で作成されるデバイスノードに使用されます。オプションのsymlinkパラメータを使用すると、他の場所にノードを作成できます。プリンタに関するルールは、次の形式を使用します。

BUS=="usb", SYSFS{serial}=="12345", NAME="lp_hp", SYMLINK+="printers/hp"

この例では、BUSSYSFS{serial}という2つのキーがあります。udevは、シリアル番号をUSBバスに接続されたデバイスのシリアル番号と比較します。名前lp_hp/devディレクトリ内のデバイスに割り当てるには、すべてのキーが同じである必要があります。さらに、このデバイスノードを参照する、シンボリックリンク/dev/printers/hpも作成されます。この操作を実行している間に、printersディレクトリが自動的に作成されます。その後、印刷ジョブは/dev/printers/hpまたは/dev/lp_hpへ送信できます。