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

第15回 udevを読む

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

次に 50-udev-default.rules を見てみましょう。50-udev-default.rules はその名の通りudevのデフォルトルールで,多くの周辺機器がこのルールによってデバイスファイルと結び付けられています。このファイルは長いので一部だけを摘み読みします。

# cat -n /etc/udev/rules.d/50-udev-default-rules

1  # do not edit this file, it will be overwritten on update
2  
3  KERNEL=="pty[pqrstuvwxyzabcdef][0123456789abcdef]", GROUP="tty", MODE="0660", OPTIONS="last_rule"
4  KERNEL=="tty[pqrstuvwxyzabcdef][0123456789abcdef]", GROUP="tty", MODE="0660", OPTIONS="last_rule"
5  KERNEL=="ptmx",                 GROUP="tty", MODE="0666", OPTIONS="last_rule"

このルールでは,最初にptyやttyといった端末入力用デバイスに関するルールが並んでいます。3行目から5行目のルールでは,カーネルからptyやttyといった名称の情報が届いた場合,グループをttyGROUP="tty")⁠パーミッションを0660MODE="0660"にした同名のデバイスファイルを/dev 以下に作成します。OPTIONS="last_rule" はこのルールが最終的なルールであって,以後の設定で同じ条件が適合した場合でもそのルールは適用されないことを指示します。

26  # input
27  KERNEL=="mouse*|mice|event*",   NAME="input/%k", MODE="0640"
28  KERNEL=="ts[0-9]*|uinput",      NAME="input/%k", MODE="0600"
29  KERNEL=="js[0-9]*",             NAME="input/%k", MODE="0644", SYMLINK+="%k"

これらのルールはマウスやジョイスティックに関するもので,27行目ではカーネルからmouseやmice, eventという情報が来れば/dev/input以下にその名称でデバイスファイルを0640のパーミッションで作成することを指示します。%k はカーネルから届いた名称に置換され,mouse0ならば/dev/input/mouse0というデバイスファイルが作成されることになります。

29行目のSYMLINKはデバイスファイルと共にシンボリックリンクを作成する指示で,カーネルからjs0といった情報が届けば,/dev/input/js0を作ると共に,/dev/js0へシンボリックリンクを作成します。

61  # block, tapes, block-releated
62  SUBSYSTEM=="block", GROUP="disk", MODE="0640"
63  SUBSYSTEM=="block", KERNEL=="sr[0-9]*", SYMLINK+="scd%n"
64  SUBSYSTEM=="scsi", KERNEL=="[0-9]*:[0-9]*", ACTION=="add", ATTR{type}=="0|7|14", ATTR{timeout}="60"
65  SUBSYSTEM=="scsi", KERNEL=="[0-9]*:[0-9]*", ACTION=="add", ATTR{type}=="1", ATTR{timeout}="900"

これらはブロックデバイスに関するルールで,62行目では「カーネルのブロックサブシステムが操作する機器の場合(SUBSYSTEM=="block")⁠デバイスファイルの所属グループを「diskグループ(GROUP="disk")⁠パーミッションを「0640(MODE="0640")⁠にして,デバイスファイルを作成することを指示してます。このルールはブロックサブシステムに該当する機器全般に適用されるルールで,HDDやCD-ROMに関する個別のルールは別途定義されています。

63行目はSCSI CD-ROMに関するルールで,カーネルからsr0といった情報が届けば/dev/sr0を作ると共に/dev/scd0 にリンクを張り,/dev/scd0 という名前でも使えるようにしています。%n はカーネルが認識している機器番号(sr0ならば0, sr1ならば1,等)に置換されます。

64行目ではSCSIサブシステム(SUBSYSTEM=="scsi")が扱う機器で,カーネルが数字とコロンのみの名称で認識 ⁠KERNEL=="[0-9]*:[0-9]*")した機器が接続され(ACTION=="add")⁠その種類が0か7か14の場合ATTR{type}=="0|7|14")⁠タイムアウトまでの時間を60秒に設定しますATTR{timeout}="60")⁠65行目では同様に種類が1の場合,タイムアウトの時間を長く取っています。

ATTR{type}で示される機器の種類は,SCSIドライバあたりで定義されているのだと思いますが,どのような分類になっているかの具体的記述は見つけられませんでした。手元の環境で調べた限りではSCSI(SATA)HDDが0, CD/DVDライタが5でした。

106  # do not delete static device nodes
107  ACTION=="remove", NAME=="?*", TEST=="/lib/udev/devices/$name", OPTIONS+="ignore_remove"

50-udev-default.ruleの最終行である107行目は接続されていた機器が取り外された際(ACTION=="remove")の指定です。通常,機器が取り外されるとそのデバイスファイルも削除されるのですが,この行では/lib/udev/device/を調べて,そこに名前が登録されているデバイスについては"ignore_remove"オプションを指定してデバイスファイルを削除しないようにしています。

今回はudevルールのごく一部しか紹介できませんでしたが,udevにはこれら以外にもさまざまな機能が用意され,デバイスファイルの動的な作成だけではなく,活線挿抜時のさまざまな動作が指定できるようになっており,最近のLinuxでは,これらの機能を使ってUSBやフラッシュメモリの活線挿抜に対応しています。

正確に言うと,udevが扱うのは活線挿抜時のデバイスファイルの作成やデバイスの自動マウントといったシステムの裏方的な作業で,接続したUSBメモリのアイコンがデスクトップ上に自動表示される,といったユーザ向けの作業は,カーネルからのイベント通知を受けたhalがdbus経由でアナウンスし,それを受け取ったデスクトップ環境のVFSレイヤーが適切なアイコンを表示する,という流れになっています。

udev情報の調べ方

sys fsにどのような情報が登録されているかを知るには,上述のように/sysディレクトリ以下を直接調べることもできますが,udevに付属のudevinfoというコマンドで調べることもできます。udevinfo に -a オプションを付けると,指定したデバイスだけでなく,そのデバイスが接続されている上位デバイスについても表示されます。また-pオプションはsys fs上の調べたいデバイス名です。以下の例は,USB接続のメディアプレイヤーについて調べています。

# udevinfo -a -p  /sys/bus/usb/devices/1-2

 looking at device '/devices/pci0000:00/0000:00:10.4/usb1/1-2':
   KERNEL=="1-2"
   SUBSYSTEM=="usb"
   DRIVER=="usb"
   ATTR{configuration}=="Media"
   ATTR{bNumInterfaces}==" 1"
   ATTR{bConfigurationValue}=="1"
   ATTR{bmAttributes}=="80"
   ATTR{bMaxPower}=="500mA"
   ATTR{urbnum}=="68227"
   ATTR{idVendor}=="041e"
   ATTR{idProduct}=="4154"
   ATTR{bcdDevice}=="1061"
   ATTR{bDeviceClass}=="00"
   ATTR{bDeviceSubClass}=="00"
   ATTR{bDeviceProtocol}=="00"
   ATTR{bNumConfigurations}=="1"
   ATTR{bMaxPacketSize0}=="64"
   ATTR{speed}=="480"
   ATTR{busnum}=="1"
   ATTR{devnum}=="4"
   ATTR{version}==" 2.00"
   ATTR{maxchild}=="0"
   ATTR{quirks}=="0x0"
   ATTR{authorized}=="1"
   ATTR{manufacturer}=="CREATIVE"
   ATTR{product}=="ZEN Stone"
   ATTR{serial}=="40030033C9630A97"

 looking at parent device '/devices/pci0000:00/0000:00:10.4/usb1':
   KERNELS=="usb1"
   SUBSYSTEMS=="usb"
   DRIVERS=="usb"
   ATTRS{configuration}==""
   ATTRS{bNumInterfaces}==" 1"
   ATTRS{bConfigurationValue}=="1"
   ....

この例からもわかるように,sys fsには周辺機器の種類によってさまざまに異なる情報が登録されます。どのような情報が登録されるかはデバイスドライバごとに決まっており,USBデバイスならば上記の例のように製品名やシリアル番号まで知ることができます。この製品名やシリアル番号をudevのルールファイルに指定して,自分の使っているメディアプレイヤは常に特定のマウントポイントにマウントする,といった指定も可能です。

著者プロフィール

こじまみつひろ

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

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