ソースコード・リテラシーのススメ

第15回 udevを読む

この記事を読むのに必要な時間:およそ 6.5 分

udevdとsysfs

udevd がカーネルの内部情報を監視すると言いましたが,UNIX/Linuxの設計ではカーネルとカーネル以外のアプリケーションは隔離されており,カーネル内部のデータをアプリケーションが直接参照することはできません。そのために用意されているのが sys fs(sys ファイルシステム)という仕組みです。

sys fsは/sysにマウントされた仮想的なファイルシステムで,動作中のカーネルの内部構造がファイルシステムの構造に投影されて表示され,ユーザ領域のアプリケーションから参照したり変更したりできるようになっています。

かつては/procにマウントされた仮想ファイルシステムであるproc fs(procファイルシステム)を用いてカーネルの内部情報を利用していましたが,proc fsはもともとプロセス情報を管理するためのファイルシステムでカーネルの内部情報用のファイルシステムではないこと,また必要に応じて追加してきたad hocな拡張が積み重なって見通しが悪くなったため,最近のカーネルでは内部情報はsys fsを利用して公開するように変更されました。

sys fsは現在も開発が進行中の機能のためドキュメントも少なく,仕様などもカーネルのバージョンによっていろいろと変更されていて,筆者自身も手探り状態なため詳細な解説をすることはできませんが,たとえば/sys/blockの下にはカーネルが認識しているブロックデバイスの一覧の情報が表示されています。

# ls  /sys/block
hda/  hdc/  ram0/  ram10/  ram12/  ram14/  ram2/  ram4/  ram6/  ram8/  sda/
hdb/  hdd/  ram1/  ram11/  ram13/  ram15/  ram3/  ram5/  ram7/  ram9/  sdb/

/sys/block/hdaディレクトリには,1台目のATA(IDE)HDDに関する情報が収められています。

# ls  /sys/block/hda
capability  device@  hda2/  hda4/     queue/  removable  slaves/  subsystem@
dev         hda1/    hda3/  holders/  range   size       stat     uevent

# ls /sys/block/hda/device
block:hda@  bus@  drivename  driver@  firmware  media  modalias  model  power/  serial  subsystem@  uevent

# cat /sys/block/hda/device/model
WDC WD800BB-22HEA1

# cat /sys/block/hda/device/serial
WD-WMAJ51314493

このように,/sys/block/hda以下にはハードディスクのサイズやパーティションの切り方といった情報だけではなく,モデル番号やシリアルナンバーといった情報も登録されています。

一方udevは,システム起動の初期にデーモン(udevd)として起動され,カーネルから新しい周辺機器が接続された旨の通知を受けとると,このsysfsの情報を元に,その機器に適したデバイスファイルを作成します。その際に利用されるのが udev.rules と呼ばれる設定ファイル(ルールファイル)です。

かつてudevと同等の機能を提供するdevfsと呼ばれる仕組みが開発されたことがありました。udevがユーザ領域で動くのに対して,devfsはカーネル内部で動くように設計されていました。

この設計の結果,devfsはカーネル自身の情報を効率よく利用できるというメリットはあったものの,カーネルに組み込まれてしまうために設定ルールの柔軟性に欠け,開発のテンポもカーネルの他の部分の開発速度に追従できなかったため,公式リリースに至ることなく開発は中止され,必要な機能はudevとして新しく開発されることになったそうです。

udev.rulesを読む

udevのルールファイルは/etc/udev/rules.dディレクトリにまとめられています。今回もfedora core 9の例を用いてみます。

# ls /etc/udev/rules.d/
05-udev-early.rules        60-persistent-storage-tape.rules   80-drivers.rules
10-console.rules           60-persistent-storage.rules        85-pcscd_ccid.rules
40-alsa.rules              60-wacom.rules                     85-pcscd_egate.rules
40-multipath.rules         61-persistent-storage-edd.rules    88-clock.rules
40-redhat.rules            64-device-mapper.rules             90-alsa.rules
50-udev-default.rules      64-md-raid.rules                   90-hal.rules
60-cdrom_id.rules          70-mdadm.rules                     91-drm-modeset.rules
60-libmtp.rules            70-persistent-cd.rules             95-pam-console.rules
60-net.rules               70-persistent-net.rules            95-udev-late.rules
60-pcmcia.rules            75-cd-aliases-generator.rules      97-bluetooth.rules
60-persistent-input.rules  75-persistent-net-generator.rules

udevのルールファイルはこのように先頭に2ケタの数字を付けたファイル名になっており,番号の小さいファイルのルールから順に適用されるようになっています。 udevのルールは後述する"last_rule" オプションなどを指定しない限りすべてのルールが適用されるようになっており,1つの周辺機器に対して異なるルールファイルがそれぞれ別のデバイスファイルを作成することもあります。

それでは実際のファイルを眺めてみましょう。

# cat -n /etc/udev/rules.d/05-udev-early.rules

1  # do not edit this file, it will be overwritten on update
2
3  # sysfs is populated after the event is sent
4  ACTION=="add", KERNEL=="[0-9]*:[0-9]*", SUBSYSTEM=="scsi", WAIT_FOR_SYSFS="ioerr_cnt"
5

udevのルールファイルも他の多くの設定ファイル同様,#から行末まではコメントと見なされるので,05-udev-early.rulesの実際のルールは最後の1行だけです。

udevのルールファイルは⁠==⁠で条件を記述し,⁠=⁠で条件に記述した際の動作を記述するようになっています。複数の条件を並べるとそれらが順に適用され,より細かい条件に絞り込むことも可能です。

ACTION, KERNEL, SUBSYSTEMというのはカーネルから通知される情報に対する条件で,ACTION が周辺機器の着脱について,KERNEL がカーネルが認識している周辺機器の名前について,SUBSYSTEM がカーネル内部のサブシステムの部位について,それぞれ一致するかどうかをチェックします。

上記の例では「周辺機器が新しく接続(カーネルに認識)された際(ACTION=="add")⁠⁠その機器の名前をカーネルが0から9までの数字とコロン(:)のみで認識し(KERNEL=="[0-9]*:[0-9]*")⁠⁠その機器を扱うのがSCSIサブシステムならば(SUBSYSTEM=="scsi")⁠⁠その機器用に定義されているioerr_cntのタイミング分,SYSFS の動作待ちをする(WAIT_FOR_SYSFS="ioerr_cnt")⁠という意味になります。このルールはカーネルに認識されたSCSIデバイスが反応を返すようになるまでの時間待ち用です。

著者プロフィール

こじまみつひろ

Plamo Linuxとりまとめ役。もともとは人類学的にハッカー文化を研究しようとしていたのが,いつの間にかミイラ取りがミイラになってOSSを仕事にするようになってしまいました。最近はスペシャリスト養成を目的とした専門職大学院で教壇に立ったりもしています。

URLhttp://www.linet.gr.jp/~kojima/Plamo/index.html