udevの概要

Linuxカーネル・メーリングリスト(LKML)に流れている、次期カーネルの開発用バージョンであるカーネル2.5に関するトピックスの中から、新しいドライバ・モデルに関する話題を取り上げて紹介している。今回は前回に続いて、カーネル2.5/2.6で導入されるsysfsアーキテクチャに基づき、ユーザ空間においてデバイス・ノードの動的な管理を新しく実現する、udevの内部構造と実際の動作について紹介する。

LKML

Linuxカーネル・メーリングリスト(LKML)で流れる膨大なメールにおいて、新しいドライバ・モデルや、アーキテクチャに関するメールの量は、多く無い。Kernel Trafficを見ればわかるように現在は、LKMLでのカーネル2.5に関する議論では、個別の機能に関してや、個別のデバイスやマシン・アーキテクチャに関する内容がほとんどを占めている。

次期安定板カーネルのリリースを控えながら、今後新しく導入されるバスやデバイスの種類は多くなる一方で、既存のデバイスドライバに関しては、新しいドライバ・モデルへの対応だけでなく、パワーマネジメントやhotplug対応等、残作業も多いのが現実である。今回は、ユーザ空間においてデバイス・ノードの動的な管理を新しく実現する、udevのアーキテクチャを構成するとされるudevとそれを含む3つのサブシステムの役割と、実際の動作を解説する。

udev

udevは、デバイスに関するイベント発生によって/sbin/hotplugから呼び出される、単純なアプリケーション・コマンドとして現在はデザインされている。次にudevの動作とサブシステムとの関連を示す。

  • udevの動作時にはまず、ユーザ空間から参照できるsysfsディレクトリを経由して、対象デバイスのクラス情報を受け取る。
  • 次にudevは、その情報をもつデバイス・ネーミング・サブシステムから「名前付け機能」を呼び出し、リターン値としてユニークなデバイス名を入手する。
  • udevはlibsysfsを介して、メジャー番号、マイナ番号のような/devノードの作成に必要な特別な情報をsysfsから入手する。
  • 必要な情報が入手できれば、udevは従来通りのmknodを使用してデバイスの/devノード・エントリを作成し、デバイスを現在のメモリ・テーブルに追加して、D-BUSメッセージ(*注1)を介して成功のイベントを通知する。
  • 削除時の呼び出しでは、udevはまずデバイスの/devノード・エントリを削除し、デバイスを現在のメモリ・テーブルから削除してから通知を行う。
*注1:D-BUSは、アプリケーション間のメッセージ通信用の論理的なバスで、概念的にはCorbaとRaw Socketの間に位置付けられて、QtやGlib等からも利用できる。

udev自体はアプリケーション・コマンドとして構成されるが、現在の接続デバイスを追跡するために、メモリ中の動的なデータベースかテーブルと、それにアクセスするためのライブラリのルーチンが必要となる。udev自体はデバイスの名前付けには関与せず、その機能をデバイス・ネーミング・サブシステムとして分割されるようにデザインされ、それは名前付けに使用する共通なデバイス・ネーミングAPIを提供する。

namedev

開発者たちの議論によって、udev内のデバイス・ネーミング機構は、サブシステムとして押しやられた。その理由は、なるべくフレキシブルに、また交換可能とさせる事である。デバイス・ネーミング・サブシステムであるnamedevは、udevからの呼び出しに対して、特定のデバイスの名前付けに関する標準的なインタフェイスを提供する。システム管理者は、このインタフェイスのもとで、自由なデバイスの名前付け方法を導入する事が可能になる。

greg KHらの開発者は、標準ネーミング規約をも用意する事になっている。udevの最初のプロトタイプ実装では、デバイス・ネーミング機構は、単に、sysfsディレクトリからの転送となっていて、メジャー番号とマイナ番号をsysfsに問い合わせ、固定的なデバイス・ネーミング・ファイルから該当のデバイス名を探し出す。このファイルはちょうど、カーネルのDocumentディレクトリにあるdevice.txtのような感じになる。これは明らかに、動的なメジャー番号、マイナ番号を付けるためには、いい実装とは言えない。

標準ネーミング規約は将来、数々のデバイス名決定のため、一貫したポリシーを持つ事になる。namedevは、目的のデバイス名割付けのために、sysfsディレクトリ内の以下の情報を使用するようになる。

  1. SCSIのUUID(Universal Unique Identifier *注2)のようなラベル情報
  2. バス・デバイス番号
  3. バスのトポロジ
  4. カーネルの名前(標準項目)
*注2:UUIDは、それが世界中でユニークであるように配慮された識別子。近年のOSやバス・アーキテクチャにおいて、オブジェクトを識別するために使用されている。一般的には、16バイト(128ビット)の時間やMacアドレス、乱数を組み合わせて自動生成されたデータが使用される。

システム管理者はLinux標準のデバイス・ネーミング機構を利用する事が可能であるし、エンタープライズ環境においては、UUIDに基づいた名前付けを導入する事も可能となる。このアイデアはデバイスの名前に関して、可能な限り柔軟でかつ交換可能な対応を作り出すはずである。デバイス・ネーミング・サブシステムであるnamedevはまだ実装されていないが、動作と構成は次のようになるはずである。

  • namedevは、デバイス情報取得のために、sysfsへのアクセスを要求する。
  • namedevはudevからの呼び出しにより、目的のデバイスのsysfsディレクトリを入手して、名前を決定付けるのに必要な追加情報をそこから引き出す。
  • namedevサブシステムには、udevでの使用に対する標準的な名前付けのAPIを含む。
  • 標準ネーミング規約は、それを提供する機能(ルーチン)と(/etcか/varに置かれる事になる)固定的なファイルを含んで提供される。

libsysfs

sysfsのデバイス情報にアクセスするために、一般的なAPIが必要になる事が判明している。デバイス・ネーミング・サブシステムとudevサブシステムは、sysyfsのディレクトリ・パスを入手して、デバイス情報を取得する必要があるからである。

例えばディレクトリ操作のため、readdir等からのコードを各プログラマがコピーして使う代わりに、このsysfsを扱うロジックをライブラリとして切り出す事である。このライブラリ化作業は、APIの標準化によってsysfsのアーキテクチャをより洗練させる事にも役立つ。また、sysfsからのコールバックは、各デバイスに渡って共通ではないので、このライブラリ化作業は、デバイス情報取得のための共通で標準的なAPIを提供する事にもなるのだが、libsysfsはまだ作成されていない。

実際の動作

udev0.1のtarballに含まれているREADMEには、udev.hに記述してあるsysfsのルート、udevのルート、メジャー番号、マイナ番号を含むsysfsのファイル名「dev」、mknodのパスを設定後に、makeするように記述してある。makeの環境によって実際は、Makefileの修正が必要なようである。動作テストの手順は次のようになる。

  • sysfsをマウントする。
  • /proc/sys/kernel/hotplugが、udevコマンドのパスを指すように設定する。
  • sysfsにデバイス情報を作成するデバイス(現在対応しているのは、ブロック型デバイスか、USBシリアル・デバイスに)をプラグインするか、scsi_debug moduleをロードする。
  • デバイスの抜き差し、またはロード・アンロードに伴って、udevのルート以下にデバイス・ノード・ファイルが現われ、消えるはずである。

実際にカーネル2.5.69環境でテストしてみると、scsi_debug moduleやUSBシリアル・デバイスではうまく動作しないが、sd_mod(SCSIディスク)のロード、アンロード(insmod / rmmod)によって、コンパイル時に指定したudevのルート・ディレクトリ以下に、ノード・ファイル「sda」が出現、消滅する事を確認した。いくつかの他のデバイスではうまく行かないために、udevのソースを参照して調べた結果、ほとんどがsysfsの該当デバイスのエントリの下にメジャー番号・マイナ番号を記述した「dev」ファイルが作成されない様子である。

TODO

tarballには、次のような内容のTODOファイルが入っている。

  • 現在のudevでは、ノードの作成にmknod(1)コマンドをfork()して使用しているが、mknod(2)のシステムコールに置き換える事。(これはLKMLでの指摘に対しても、gregKHは単なる手抜きであると釈明している)
  • より小さいバイナリ・イメージにさせるために、ビルド時にklibcを追加するか、またはそれに代わる別の簡単な方法を導入する事。
  • 本来あるべきデザインであると言われるようにして、プログラムを動作させなくてはならない。 即ち現在1個のアプリケーションで提供されているものを、3つのサブシステムとして提供する事。
  • 新しいノードを作成するか削除する時に、D-BUSのコールにフックを加える事
  • そのほかにもまだまだ沢山の事がある...

このように、まだまだ利用に耐える状況ではないudevであるが、新しいドライバ・モデルの導入に伴って対応作業が現在進められている。udev / namedev / libsysfsに関しては、もっとまともに動作するようになってから、再び取り上げたい。