Ubuntu Weekly Recipe

第555回 いま,あらためてudev

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

ACTIONとGOTO変数

ACTION!="add", GOTO="drivers_end"

上記は「ACTIONがaddでなければ,GOTOで指定されたdrivers_endラベルにジャンプする」です。前者がマッチングに使われ,後者に値を代入しています。

「ACTION」は代表的なマッチング変数の一つです。この変数はカーネル内部で次のいずれかがセットされます。

  • add:デバイスの追加
  • remove:デバイスの除去
  • change:デバイスの状態変更
  • move:デバイスの親子関係や名前の変更
  • online:デバイスがオンラインになった
  • offline:デバイスがオフラインになった
  • bind:ドライバーとデバイスが紐付けられた
  • unbind:ドライバーとデバイスの関連付けを切断

大抵のルールはaddとremoveのみを考慮しています。それ以外については必要になったときに調べると良いでしょう。

「GOTO」は制御構造を作るときに使われます。特定の条件のとき(今回はデバイスが追加されたとき)のみルールを適用したい場合に,条件にマッチしなければGOTOでスキップするのに用います。また,1行のうちカンマで区切られたマッチング変数は「AND」で連結されます。もし「OR」のような制御をしたい場合は,GOTOが必要になります。

ENVとRUN変数

前項のACTIONとGOTOのおかげで,これ以降はデバイスが追加されたときのみ反映されるルールとなります。最初は,モジュールのロードを行う部分です。

ENV{MODALIAS}=="?*", RUN{builtin}+="kmod load $env{MODALIAS}"

ENVはカーネルドライバーの中や他のルールで設定されるデバイスプロパティです。連想配列的にアクセス可能なので,上記の前半は「ENVのMODALIASに何か値が設定されていたとき」となります。このように右辺のダブルクオートの中はシェルグロブのような簡易的なパターンを記述可能です。

RUNは追加したコマンドを実行する変数です。⁠kmod load $env{MODALIAS}」が実行されるということですね。⁠+=」とすることでこれまで他のルールが追加した値に追記することになります。ちなみにRUNが評価される(内部のコマンドが実行される)のは,すべてのルールが評価されたあとです。

「builtin」はudevコマンド内部のビルドインコマンドを実行することを意味します。実はシステムには/bin/kmodが存在しますが,この/bin/kmodにはloadサブコマンドが存在しません。udevのビルトインコマンドであるkmodにのみloadオプションが存在するのです。

変数の値の中で他の変数を参照できます。上記の例だと「$env{MODALIAS}」の部分ですね。他にもいくつかの参照変数が存在しますので,詳しいことはudevのmanページを参照してください。

MODALIASには「acpi:(PNP ID⁠⁠」や「i2c:foo⁠⁠,⁠usb:v(ベンダーID)p(プロダクトID)...」といった文字列が渡されます。これらの文字列と「/lib/modules/(カーネルバージョン)/modules.alias」の内容から,適切なモジュールがロードされるというわけです。

SUBSYSTEMとKERNEL,LABEL変数

ここまでの基本をおさえておくと,あとは直感的に読めるようになります。

SUBSYSTEM=="tifm", ENV{TIFM_CARD_TYPE}=="SD", RUN{builtin}+="kmod load tifm_sd"
SUBSYSTEM=="tifm", ENV{TIFM_CARD_TYPE}=="MS", RUN{builtin}+="kmod load tifm_ms"
SUBSYSTEM=="memstick", RUN{builtin}+="kmod load ms_block mspro_block"
SUBSYSTEM=="i2o", RUN{builtin}+="kmod load i2o_block"
SUBSYSTEM=="module", KERNEL=="parport_pc", RUN{builtin}+="kmod load ppdev"
KERNEL=="mtd*ro", ENV{MTD_FTL}=="smartmedia", RUN{builtin}+="kmod load sm_ftl"

SUBSYSTEMはそのデバイスが所属しているサブシステムです。⁠tifm」はTexas InstrumentsのFlash Mediaコントローラー向けのサブシステムで,接続されたメディアの種別によってロードするモジュールを変えているようです。⁠memstick」はソニーのメモリースティックですね。

「i2o」Intelligent Input/Output (I2O)なるデバイス向けのようですが,Linux Kernel 4.2あたりでで削除されたので今となってはもう意味はありません。

「module」はカーネルモジュール全般の操作のためのサブシステムです。その先のKERNEL変数は,そのデバイスのカーネル上の名前(⁠⁠sda1」とか「eth0」とか)を表します。おそらく読者の大抵のPCでは,parport_pcモジュールとppdevモジュールがロードされるのではないでしょうか。最後はMTDデバイスが「SmartMedia/xD FTL」デバイスだったらsm_ftlモジュールをロードしています。

SUBSYSTEM変数とは別にSUBSYSTEMS変数もあります。後者の変数には,そのデバイスがつながっているサブシステムのさらに祖先のサブシステムがすべて記録されています。

ファイルの最後はLABEL変数です。GOTOはLABEL変数がセットされている値と一致する場所までジャンプします。

LABEL="drivers_end"

著者プロフィール

柴田充也(しばたみつや)

Ubuntu Japanese Team Member株式会社 創夢所属。数年前にLaunchpad上でStellariumの翻訳をしたことがきっかけで,Ubuntuの翻訳にも関わるようになりました。