udevとdevfs

sysfs/kobjectが提供する新しいドライバ・モデルにおいて、カーネル内のhotplugサポート機構に基づく動的なデバイス・ノードの管理をユーザモードで実現するudevは、カーネル2.4で導入されたdevfsを置き換え、付加機能を提供するものである。今回はこのudevを取り上げて従来のdevfsと比較しながら、新しいドライバ・モデルにおけるhotplugの取り扱いと、アーキテクチャの目指す方向を紹介する。

udevの導入

前回紹介したgreg KHのkobject / hotplugに関するカーネル・パッチは、次のバージョンである2.5.68で早速取り入れられた。そのため、udev機構を実現するアプリケーションは、2.5.68以降ではパッチ無しに動作する事ができる。新しいドライバ・モデルのhotplugサポートにおいて、udevを始めとする一連の作業が目指すゴールと対応状況は、以下のようになっている。greg KHが公開したudevプログラムは、各アクション項目に対応する3つのサブシステムのうちで、最初のものとなる。

  1. /dev以下のデバイス・ノードの動的な置き換え → udevにおいて提供(今回バージョン0.1が公開された)
  2. 各deviceに対するネームサービス → namedevにおいて提供(未提供)
  3. 現在のシステム・デバイスにアクセスするためのAPI → 標準ライブラリとしてlibsysfsを提供する事によって実現(未提供)

udevは、単純なユーザモード・アプリケーションであるが、カーネル2.5の新しいドライバ・モデルが提供する以下の2つの機能を使用して、動的な/dev以下のデバイス・ノードの名前付けルールに関する、フレキシブルで優れた実装を行っている。

  • システムのすべての物理的な、または仮想デバイスは、ユーザ空間からsysfsを通して参照する事ができる。
  • デバイスがシステムに追加されるか、または削除されるときに、カーネル内のhotplug機構は、/proc/sys/kernel/hotplugを介して、ユーザ空間に通知する。

またudevでは、以前のdevfsが単独では実現できなかった以下の機能を補うとともに、devfsを置き換える事が可能である。

  • デバイス・ツリーの中をデバイスが動くときのデバイスに対する継続的な名前付け
  • 外部システムのデバイス交換時の通知
  • 自由な名前付けのサポート

devfs

Unix系オペレーティング・システムでは長い間、主に歴史的慣例と互換性を理由に/dev以下にデバイス・ノードファイルという特別なファイル群をあらかじめ設けておいて、それがほとんど唯一のユーザ空間のアプリケーションとカーネルやデバイスドライバとの接続点であった。しかしこの構造は単純で扱いやすい反面、次のような問題点を持っている。

  • デバイスが接続されている時にそのデバイス用のノードファイルが必ずあるかどうかわからない。
  • システムの動作中にデバイスを接続、取り外しする使い方(hotplug)に対応していない。
  • デバイス・ノード機構の実体がメジャー番号、マイナ番号とファイル名の関連付けであるため、ファイル名と各番号の取り扱いによる制限と衝突が発生する可能性がある。

このような問題点に関しては、他のUnix系OSでは独自な対応策が取られているが、Linuxにおいてこれに対処したのが、devfs (Device Filesystem)である。devfsは、他のいくつかの新しいファイルシステムと同様に、仮想的なファイルシステムとして実装されている。すなわちブート時に一旦/devをdevfsでマウントした後では、従来のハードディスク上の/dev以下のノードファイルは参照されずに、全てのデバイス・ノードはカーネル内のリソースによって管理されるようになる。

devfsはRichard Goochらの努力によってカーネル2.2の頃からパッチで提供されてきて、2.3.46以降はカーネルに導入された。現在の最新カーネルでも利用できるが、カーネル・オプションではいまだに「EXPERIMENTAL」扱いとされている。また、多くのディストリビューションではこの機能はオフにされているが、devfsに依存したシステムやデバイスドライバもいくつかあり、カーネル関連のメーリングリストでは現在でもdevfsに関する、改善策やバグFIXが議論され、修正パッチも投稿されているので、udevの登場によりdevfsが無くなるわけでは無い。ただしdevfsの導入には、現在でもブート時等の互換性の問題と、設定ファイル、devfsdデーモンの起動といったコストがかかる作業があるため、(現在はまだ利用できる状況にない)udevがまともに動作するようになれば、devfsからudevへの乗り換えは発生すると思われる。

udevの登場により、アプリケーションからあるデバイスにアクセスするための手段が、従来からの/dev以下のデバイス・ノードファイルと、devfs、udevの3種類となるが、これらは今後当分の間、共存していく事になる。

udevの実際

udevの動作には特別なカーネル・オプションを必要としない。また、標準Linuxの/dev以下ですでに使用されている名前とメジャー番号、マイナ番号と、既存の物理的なファイル型のデバイス・ノードファイルをそのままサポートする。このしくみでは、カーネルのhotplug機構を利用して、デバイスがsysfsに現れるときにだけ、呼び出されたアプリケーションがmknodによってデバイス・ノードファイルを作成する。これにはカーネルのsysfs/kobjectによって正しいメジャー番号、マイナ番号やノードファイル名が供給される必要があるため、現在はまだ、ブロック型デバイスとUSBシリアル・デバイスにしか対応していない。それだけでなく、udevが解決しなければならない問題はとても多い。これらの問題点とudevの内部構造、実際の動作、今後の課題に関しては、次回以降で取り上げる。

/sbin/hotplugの変更

2003年5月1日に、greg KHによって新しいhotplugプログラムがアナウンスされた。今までは、/proc/sys/kernel/hotplug に一つだけhotplug対応のアプリケーション(helperプログラム)のパスを記述する事になっていて、その標準プログラムが「Linux Hotplugging」プロジェクトで開発されている、/sbin/hotplugであった。しかし今後/sbin/hotplugは、/etc/hotplug.d以下のディレクトリに配置されるプログラムを順に呼び出す小さな「マルチプレクサ」シェル・スクリプトとなった。これによって一般的な方法で、カーネルからのhotplugイベントを複数のアプリケーションが受け取る事ができるようになる。そして、従来の/sbin/hotplug(「Linux Hotplugging」プロジェクトの成果)は、このスクリプトから最後に呼び出される/etc/hotplug.d/default/default.hotplugとして配置される事になった。

udevプログラムが動作するためには、/proc/sys/kernel/hotplug にudevアプリケーションのパスを記述するか、/sbin/hotplugからの呼び出しが必要だとされていたが、今後はおそらく/etc/hotplug.d以下のエントリに配置する事によって制御される事になると推測される。