udev ルールの書き方

by Daniel Drake (dsd)
version 0.5.5

訳: MUNEDA Takahiro<mail address>
2006 12 12

訳者が追記した行をわかりやすくするために,行頭に縦棒を記してある.

この文章の最新版はいつも以下の場所にある:
http://www.reactivated.net/udevrules.php (英文オリジナル)
http://mux03.panda64.net/docs/udevrules_ja.html (和訳版)

英文オリジナルは更新されてしまったため,古い版数はこちらを参照してください.
http://kernel.org/git/?p=linux/hotplug/udev.git;a=blob_plain;h=9396184366fee2bc342346bcce292c02a70f308f;f=docs/writing_udev_rules/index.html (オリジナル0.55版)

追記 : 2005 06 19
このドキュメントは古くなっています.gentoo jp にて五十嵐さんが0.6版の翻訳をされているのでそちらを見てください.
この文章は,どうしても古い版数の udev を使わないといけない人のために残しておきますが,内容については補償しません.

追記 : 2006 12 12
なお,英文オリジナル版の最新は 0.72 版です.残念ながら日本語版はまだありません.

内容

  1. この文章について
  2. 更新履歴
  3. 執筆時点でのソフトウェアのバージョン
  4. 用語: devfs, sysfs, nodes など
  5. どうしてルールを書かないといけないのか? (この文章の目的)
  6. ルールの書き方の基本
  7. NAME と SYMLINK パラメータのための追加設定
  8. キーで shell 風パターンマッチングを使う
  9. キーの基本の書き方
  10. 基本キーを使ったデバイスの特定方法
  11. SYSFS ファイルを使ったデバイスの特定方法
  12. 例: 私の USB プリンタ向けのルールの書き方
  13. 例: 私の USB マスストレージタイプ対応のデジカメ向けのルールの書き方
  14. USB ストレージ向けのルールの書き方に対する追加注意
  15. 例: 私の CD ドライブ向けの便利なルールの書き方
  16. 例: 私のネットワークインターフェイスに名前を付けるためにルールを書く
  17. SYSFS で適切な場所を探すためのコツ
  18. 複数 SYMLINK 形式ルールの使い方
  19. udev と Nvidia のグラフィックドライバ
  20. 著者と著作権表示
  21. 更新履歴

1. この文章について

udev は Linux Kernel 2.6 やそれ以上のバージョンにおいて, 不変なデバイス名付けを用いて,ユーザスペースで /dev ディレクトリを動的に提供するための方法を提供することを目標としている.既存の /dev の実装であった devfs は今では非推奨であり, udev はその後継者と見られている. udev と devfs を比較は最新の注意を払うべき分野の議論である - 比較をする前にこちらの文章を読むべきである.

udev はよく考えられた手法であるが,私は最初,どのようにして自分のシステムをカスタマイズしたらいいのかかなり悩んだ.この文章はルールの書き方手順を少しでもわかりやすくしようとしている.

私はフィードバックを受け付けている - コメント,問題,改善の提案などあればどうか連絡して欲しい

この文章は,読者が udev と hotplug のインストールと標準の設定での利用が問題ないことを想定している.もし udev の設定や利用がまだなのであれば,この想定する段階に到達するためにDecibel udev 入門書を理解することをお勧めする(Gentoo Linux固有のこともいくらか含まれているが,他のディストリビューションにおいても役に立つに違いない).

2. 更新履歴

2004 06 20 v0.55: 複数 symlinks についての情報追加といくつかの細かい変更とアップデート

2004 04 26 v0.54: Debian の情報をいくつか追加.細かい修正.ルールファイルに対して何が呼ばれるかについて再度元の情報に戻した.ネットワークインターフェイスの名前付けについての情報を追加.

2004 04 15 v0.53: 細かい修正.NAME{all_pertitions} についての情報を追加.udevinfoの仕組みについてその他の情報を追加.

2004 04 14 v0.52: 標準の udev が他のファイルの参照を許可するまで, "udev.rules" を使うように提案を戻した.

2004 04 06 v0.51: "udev.rules" に追記するよりも自分の "local.rules" ファイルを使うようユーザに勧める.

2004 04 03 v0.5: 細かな清書と udev 配布物に含まれてもいいようにするための準備

2004 03 20 v0.4: 全般的に改良,明確化,清書. USB ストレージのルールの書き方についてさらに情報を追加.

2004 02 23 v0.3: どのようにして sysfs 名前付けが機能するのか,どのようにして sysfs 名前付けが合うのかを重要視するためにいくつかの点を書き直した. udev 018 の新しい SYSFS{filename} 名前付け機能を説明するためにルールの書き方をアップデート.セクション割りを改善し,多くの点を明確にした. KDE についての情報を追加.

2004 02 18 v0.2: 例での小さな漏れを修正.マスストレージデバイスセクションのアップデート.nvidiaセクションのアップデート.

2004 02 15 v0.1: 初稿

3. 執筆時点でのソフトウェアのバージョン

Linux Kernel 2.6.7
udev 027
hotplug 20040401

4. 用語: devfs, sysfs, nodes など

基本の紹介だけであり,全体としては正確ではないかもしれない.

一般的な linux ベースのシステムでは, /dev ディレクトリはシステム内のあるデバイスを参照するためのデバイスノードのようなファイルを格納するために使われる.それぞれのノードはシステムの一部(デバイス)を指し示す.そのデバイスは存在するかもしれないし,しないかもしれない.ユーザ空間のアプリケーションはシステムのハードウェアのインターフェイスとしてこれらのデバイスノードを利用しする.たとえば, XFree86 は /dev/input/mise を監視し,ユーザのマウスの動きをマウスポインタの動きと対応づける.

元々の /dev ディレクトリには,システムに存在する可能性のあるすべてのデバイスに対しデバイスノードが存在していた.このために通常 /dev ディレクトリは大変大きかった. devfs は,他の機能たちと同様に,より管理しやすい手法(システムにつながれているデバイスだけが /dev に存在する)を提供しようとしてたが,システムは簡単には直せない問題が存在していることを示していた.

udev は /dev ディレクトリを管理するための "新しい" 方法で,以前の /dev 実装でのいくつかの問題を解決するよう設計されており,今後へのしっかりとした路を提供する.システムに存在しているデバイスに対応する /dev デバイスノードを作り名前付けするために, udev は sysfs とユーザによって提供されているルールの一致情報を利用している.この文章では,ユーザが(やりたければ)行うであろう唯一の udev に関連する作業である,ルールの書き方の詳細な手順を説明することが目的である.

sysfs は 2.6 カーネル向けの新しいファイルシステムである.カーネルによって管理され,現在システムにつながれているデバイスについての基本的な情報を提供する. udev はハードウェアに対応するデバイスノードを作るためにこの情報を利用する. sysfs は /sys にマウントされ,見ることができる.この文章中で /sysfs と SYSFS という用語は同じ意味で用いる.

5. どうしてルールを書かないといけないのか?

上で述べたように, udev のルールを書くことはオプション的な手順である.デバイスをつなぐと,標準でも以前の /dev 実装のように適切なデバイスノードが /dev に存在する(たとえば, USB マスストレージデバイス用に /dev/sda).

でも, udev はデバイスノードの名前付けをカスタマイズすることができる.カスタマイズしたいなと思うのには 2 つの理由がある : 便利さと不変な名前付けである.

udev を利用した例をあげてみると,プリンタは接続されると /dev/printer といつもの /dev/lp0 というように名前が付けられる.これは便利な(例, "printer" を "lp0" に相対するものとして読んで,解釈する)だけでなく,可変の名前付けの解決方法である.私はプリンタを 2 つ持っている, HP のレーザープリンタと Epson のインクジェットプリンタである.そのどちらもつないで電源を入れた時には, /dev/lp0 と /dev/lp1 ができる.どうすればどのノードがどのプリンタを参照しているのか分かるのだろうか?これは難しい.最初につながれたプリンタが "lp0" ,あとにつながれたものが "lp1" と名付けられる.プリンタを違う順番でつなぐと名前があべこべになり,いつも HP のレーザプリンタが lp1 であると期待しているスクリプトは間違えてしまう.

しかし,もし HP のレーザープリンタが(lpX みたいに) lp_hp と名付けられ,もう一方のプリンタが(lpY みたいに) lp_epson と名付けられれば,スクリプトはそれらの名前を正しく参照できる. udev はこれを制御でき,私が意図したようにこれらの不変の名前がデバイスを指し示すことを保証する.

外部マスストレージデバイス(例, USB ハードディスク)においては,不変の名前付けは /etc/fstab にデバイスパスを厳密に決め打ちすることができるという点でとても役に立つ.

6. ルールの書き方の基本

/dev を作る時, udev は一連のルールファイルを解釈してどのノードを含めるべきか,どのように名前付けするかを決定する.

標準の udev ルールは /etc/udev/rules.d/50-udev.rules に格納されている.このファイルにザッと目を通せば,このファイルがおもしろいことに気がつくだろう - このファイルには,いくつかの例,さらにいくつかの devfs 形式の /dev レイアウトを提供するいくつかの標準ルールが含まれている.しかし,今後 インストールした udev のアップデートをする時に悩ませるものを減らすために,このファイルに直にルールを書き込むことはしてはならない.

/etc/udev/rules.d/ にあるファイルは辞書順で解析される. udev は検出されたハードウェアに対応するルールを見つけるとすぐに処理を止めてしまう.これは重要なことだが,自分のルールが udev 標準のモノよりも先に処理されるようにすること.さもないと自分の名前付け機能が意味をなさなくなる! /etc/udev/rules/10-local.rules (これは標準では存在しない,自分で作る)に自分のルールを書くことをお勧めする. 10 は 50 よりも先だから,あなたのルールが先に見つけられることになる.

自分のルールは /dev レイアウトを作成する標準の udev ルールをマスクして隠してしまうので,自分で書いたルールのために devfs 形式の名前やシンボリックリンクも指定するよう勧める.そうすれば目的にかなった標準+自分の名前付けを得ることができる.

ルールファイルでは, "#" で始まる行はコメントとして扱われる.ファイル中のすべての非コメント行はルールに相当する.

ルールの基本形式は:

key,[key,...] name [, symlink],
  1. 少なくともキーが 1 つ指定されていなければならない.キーはどのデバイスがルールに対応するのかを特定するために使われる.
  2. 名前パラメータも必要とされる.そのデバイスが /dev ツリーでどのように名前づけられるべきかを udev に伝える.これは NAME="X" という形式で記述され,ここでの X はノードが名前付けられる何かである.複数のシンボリックリンクもココで指定でき,複数のシンボリックリンクをスペースで区切ること.
  3. (オプションの)symlink パラメータは,このノードがリンクされる追加位置を示すことができる.

udev は 1 つのデバイスに対し 1 つのノードしか作らないことを覚えておくこと.もし複数のノードを使ってアクセスしたい場合,その他のノードを SYMLINK パラメータで指定しなければならない.

私はちょっとだけ変更を加えた udev のルールを用いてこれを説明する:

BUS="usb", SYSFS{serial}="HXOLL0012202323480", NAME="lp_epson", SYMLINK="printers/epson_stylus"

ここでのキーは BUS と SYSFS{serial} パラメータである. udev は USB バスでつながったデバイスとシリアル番号が HXOLL0012202323480 のデバイスに対してこのルールを対応付ける.注意,デバイスに名前を付けるためのルールを udev が使うためには,指定された(どれかではなく)すべてのキーが必ず合わないといけない.udev はこのノードを lp_epson と名付け,ノードは /dev/lp_epson に置かれる.udev は /dev/lp_epson へのシンボリックリンクも作成し, /dev/printers/epson_stylus(printers ディレクトリは自動的に作成される)に置く. /dev/printers/epson_stylus か /dev/lp_epson にデータを送信すれば Epson プリンタへ印刷することができる.

7. NAME と SYMLINK パラメータのための追加設定

ルールの NAME と SYMLINK パラメータには,デバイスの名前付けを補助するための基本的な演算子が使える.ハッカーには prinf みたいな文字列置換のようなこの種のものと分かるだろう. NAME/SYMLINK パラメータの一部もしくは全体を記述できる演算子がある.これらの演算子はデバイスに関係するカーネルデータを参照する.以下に例を示す:

BUS="usb", SYSFS{vendor}="FUJIFILM", SYSFS{model}="M100", NAME="camera%n"

%n 演算子は, camera0, camera1 などのような NAME を作るために,カメラデバイスのための "カーネル番号" に置き換えられる.

その他の代表的な演算子は %k である.これはカーネルがそのデバイスに付けようとしている名前を表す.たとえば "hda1" である.ハードウェアのデフォルト名を生成するために,よく NAME="%k" と書かれたルールを見るかもしれない.演算子を使ったルールでは,カスタマイズは一般的に SYMLINK パラメータを用いて行われる.

解説付きの全演算子のリストが udev man ページで見ることができる.

8. キーで shell 風パターンマッチングを使う

より柔軟なキーを記述するため, shell 風パターンマッチングを利用することができる.デフォルトの udev ルールを取り上げる:

KERNEL="ts*", NAME="input/%k"

ここでは * 演算子が使われている,これは完全にどのようなものでもマッチする.0 もしくは 1 もしくはそれ以上個のどんな種類の文字でも.このルールは事実上以下のとおりである:

カーネルに,名前が "ts" から始まって,オプションで任意の文字が続いているもの,と特定されたデバイスにマッチし,input ディレクトリ配下にカーネル名の (%k) と名付けられる

? 演算子は似ていて, 任意の 1 文字にマッチする(ただし 0 文字のモノにはマッチしない).

大括弧 [ ] も任意の 1 文字にマッチする. udev man ページからのそのままの引用:

たとえば,パターン文字列 "tty[SR]" は "ttyS" もしくは "ttyR" のいずれかにマッチする.

マッチさせるモノの範囲を指定することもできる.たとえば, [0-9] は任意の 1 つの数字にマッチする.標準でインストールされる udev のルールを例に使う:

KERNEL="fd[0-9]*", NAME="floppy/%n"

このルールは

カーネルに,名前が "fd" から始まって,次に任意の数字 1 つが続き,追加で任意の文字列が続いているもの,と特定されたデバイスにマッチする.floppy ディレクトリ配下に,そのデバイスのカーネル番号 (%n) と名付けられる.

これらのワイルドカードもしくはパターンのマッチングを,基本キーと sysfs ベースの識別子のどちらも含む任意のキーでも使うことができる(キーの種類については後述の説明を参照のこと).

私はこのトピックでのいくつかの情報(とくに [ ] 演算子を使った時の柔軟性)をわざと残したままにしているが,それは基本的な udev ルールの書き方の対象から外れているためである.このトピックでのこれ以上の情報は udev man ページで見ることができる.

9. キーの基本の書き方

udev はいくつかの基本のキーマッチング方法を提供し,さらに SYSFS にも柔軟なマッチング方法を提供している.一般的なルールは通常のキー(たとえば BUS と KERNEL)のどちらにもマッチし,同様に SYSFS キーは同じポートに挿された異なるハードウェアを識別する.

"どうやってプリンタのシリアル番号を調べるのか,このカメラのモデル名は何" と思っているかもしれない.ルールを書くことはそれを調べることほど難しくない.最もトリッキーな部分は /sys でそのデバイスを探すことで,どの情報を使うか決めることだ.

10. 基本キーを使ったデバイスの特定方法

これらのキーについての追加情報は udev man ページを見ること.

有効なキーは:

ID と PLACE キーはきっとそれぞれの用法があるのだがルールではあまり使われていない.この文章では BUS と KERNEL キーの利用に着目する, SYSFS={...} キーも同様である.これらのキーの使い方を例を用いて示す.

さらなる柔軟性のために, udev は外部スクリプトを呼びその結果を使うキーも提供しているが,これはこの文章の範囲外である.詳細は udev man ページを見ること.

11. SYSFS ファイルを使ったデバイスの特定方法

予備知識: SYSFS はハードウェアの情報を提供するツリーディレクトリの配下に,小さなファイルをたくさん持っている.通常1つのファイルには1つの情報のみが含まれている.たとえば,デバイス名だったり,製造者名,もしくは製品IDなど.

注意,SYSFS{...} キーはこれまでの章で説明されてきた基本的なキーと一緒に使われるかもしれない.

SYSFS からの特別な情報にマッチさせるために SYSFS{filename} キーを使うことができる.ここでの filename は SYSFS ツリー内のファイルに対応する.たとえば,カメラが接続されると "USB 2.0M DSC" という内容の /sys/block/sda/device/model というファイルが存在する.これにマッチさせるには,以下のキーを使うことができる:

SYSFS{model}="USB 2.0M DSC"

注意,この方法では sysfs 配下のどのようなファイルにでもマッチさせられるが,もし(複数キーを用いて)一つ以上のファイルにマッチさせたい時は,その後,同じ名前のディレクトリに存在するファイルにのみマッチさせなければならない.通常,一つのデバイスに対していくつかの情報を提供するディレクトリが存在する.それらを混ぜてマッチさせてはいけない(以下に例を示す).

幸いにも,ルール記述の手順は SYSFS 内の数百万のファイルを探す必要はなく, udevinfo ユーティリティが困難な仕事をやってくれる.このプログラムは udev 配布物に含まれている.

最初にすべきことは, "dev" と名付けられたファイルを含む,ハードウェアに対応する /sys 内のディレクトリを探すことで, udevinfo はこの種のディレクトリのみで機能するためである.これらのディレクトリのすべてが /sys/block もしくは /sys/class 配下で見つけることができる.ココ以外の場所を見る必要はない!しかし, udevinfo はこのディレクトリのリンクをたどり, sysfs 内の他のセクションから情報を読み取る.

いったんこの種のファイルを見つけると, udev ルールのためのキー作成で役に立つ以下のコマンドを使える.

# udevinfo -a -p /sys/path/to/hardware/info

udevinfo を実行するための /sys ディレクトリの正確な場所を探すのは,賢明でないこと分かるだろう.ただ接続しているデバイスにはすでにデバイスノード(たとえば, /dev/sda)がすでに作られているので,そのような場合に udevinfo は役に立つ!私の /dev/sda ノードを例に取る.以下のコマンドを実行すると sysfs の適当な位置を示す:

# udevinfo -q path -n /dev/sda
 /block/sda

(上に書かれている)コマンドの出力は sysfs のパスが /sys/block/sda から始まっていることを示す.今 "udevinfo -a -p /sys/block/sda" を実行したいとする.これらのコマンドを一緒につなげることができて,このようにできる:

# udevinfo -a -p `udevinfo -q path -n /dev/sda`

ルールの書き方に移り, "udevinfo -a -p /sys/block/sda" コマンドの結果をいくらか略したものを以下に色付きで示す:

follow the class device's "device"
  looking at the device chain at '/sys/devices/pci0000:00/0000:00:02.1/usb3/3-3/3-3:1.0/host0/0:0:0:0':
    BUS="scsi"
    ID="0:0:0:0"
    SYSFS{detach_state}="0"
    SYSFS{type}="0"
    SYSFS{max_sectors}="240"
    SYSFS{device_blocked}="0"
    SYSFS{queue_depth}="1"
    SYSFS{scsi_level}="3"
    SYSFS{vendor}="        "
    SYSFS{model}="USB 2.0M DSC    "
    SYSFS{rev}="1.00"
    SYSFS{online}="1"
  
  looking at the device chain at '/sys/devices/pci0000:00/0000:00:02.1/usb3/3-3':
    BUS="usb"
    ID="3-3"
    SYSFS{detach_state}="0"
    SYSFS{bNumInterfaces}=" 1"
    SYSFS{bConfigurationValue}="1"
    SYSFS{bmAttributes}="c0"
    SYSFS{bMaxPower}="  0mA"
    SYSFS{idVendor}="052b"
    SYSFS{idProduct}="1514"
    SYSFS{bcdDevice}="0100"
    SYSFS{bDeviceClass}="00"
    SYSFS{bDeviceSubClass}="00"
    SYSFS{bDeviceProtocol}="00"
    SYSFS{bNumConfigurations}="1"
    SYSFS{speed}="12"
    SYSFS{manufacturer}="Tekom Technologies, Inc"
    SYSFS{product}="USB 2.0M DSC"

udevinfo ツールは, udev ルールとして単にコピ&ペーストすればよいだけの大量の情報を提供する.私が上の情報を色づけした理由は,異なる部分からの udevinfo の出力は基本的に混ぜてマッチさせてはいけないということを示すためである.上の出力では,違う色のセクションからの情報は混ぜられない−これはそれぞれのセクションの出力が SYSFS の異なるディレクトリを参照しているためである.たとえば,以下のルールは動かないだろう:

BUS="scsi", SYSFS{manufacturer}="Tekom Technologies, Inc", NAME="%k"

BUS="scsi" から始まるセクション(緑)で見つかる情報と,青のセクションでのみ見つかる情報とを組み合わせているため,このルールは動かない.もし上の青色のセクションにのみついている情報である BUS="usb" を使えば,このルールはうまく動く.

多くの情報は基本ルールを書くのに関係がないことに気づくだろうから(そういうのがホントたくさんある!),内容を理解し,きっと変わらないと知っている情報(たとえばモデル名)を一般的に探すべきである.

注意,デバイスを特定するために自分だけのルールを書くなら,標準の devfs 風のルールは役に立たない!NAME="%k" を使い,自身の追加の名前を SYMLINK と記述するのは一般的で実用的で,そうすれば標準の気が利いた名前を失うこともない.

私は udevinfo の出力を使ったルールの書き方の手順を以下に 3 つ示す.その後正しい情報位置のための,いくつかのデバイス依存のヒントやコツを記入することにする.

ある読者が知らせてくれたのだが,彼は KDE のコントロールセンタがルールを書くのに役に立つことを見つけた.見たところでは, USB デバイス(そのほかも)の情報が KDE コントロールセンタの "Info Centre" セクションで見つけられる.このインターフェイスは,シリアル番号,ベンダー ID などの情報を表示する.もし GUI でのやり方を好むのであれば,これを調べてみるのもいいかもしれない.

gnome-volume-manager の現在のリリース版ではシンボリックリンクのノードを実在のデバイスのようには扱うことができない.上に述べたものとは逆に,自身の名前付けを NAME パラメータに %k を SYMLINK パラメータに記述したくなるかもしれない.

標準のルールを自分のルールで隠してしまう動作は,複数 SYMLINK スタイルルールを書くことで克服できる.

12. 例: 私の USB プリンタ向けのルールの書き方

私のプリンタをつないだら,使い始めるために適切な /sys ディレクトリを探すことを始める.私はそれがどこか分からなかったが,プリンタに /dev/lp0 が割り当てられたことが分かった. udevinfo は有益なパスを提供してくれる:

 # udevinfo -q path -n /dev/lp0
 /class/usb/lp0

"udevinfo -q path -n /dev/lp0" を実行すると,通常たくさんの情報が得られる.特徴的なデバイス識別のために適切なモノを取り上げてみた:

 looking at the device chain at 'sys/devices/pci0000:00/0000:00:02.1/usb3/3-3':
 BUS="usb"
 SYSFS{manufacturer}="EPSON"
 SYSFS{product}="USB Printer"
 SYSFS{serial}="L72010011070626380"

私の udev ルールはこのようになった:

BUS="usb", SYSFS{serial}="L72010011070626380", NAME="%k", SYMLINK="epson_680"

これによって,私のプリンタノードは /dev/lp0(または,もし他のプリンタが先に挿さっていたら /dev/lp1)と /dev/epson_680 とが存在し,いつも特定のプリンタのためのデバイスノードを指し示す.

13. 例: 私の USB マスストレージタイプ対応のデジカメ向けのルールの書き方

簡単な序論:私のカメラは自身を外部 SCSI ディスクと識別する(これは USB ハードディスクやフラッシュカードリーダなどのデバイスのように USB ストレージドライバを使う).そのパーティションをマウントして画像をコピーしたりできる.すべてのカメラがこのように動くわけではない−多くのカメラは写真にアクセスできるようにするために外部ソフトウェア(たとえば gphoto2)を必要とする.

この方法はちょっとトリッキーである.私のカメラを接続すると,標準でいくつかのノードが作られる: /dev/sda と /dev/sda1 場合によっては /dev/sg1 までも.これは特定が重要であるという例である−もしルールが十分に固有なものでないなら上の 3 つのノードのどれかがマッチするかもしれない.

sda1 は私が /dev/camera としたいノードで,マウントされるものである. udevinfo は sda, sda1, sg1 の間に有効な違いを示さない.これらの 3 つのノードの違いを明らかにする方法は KERNEL 名を見ることだと決めた.

KERNEL="sd?1" のようなキーは "sda1", "sdb1", "sdc1" のような KERNEL 名にマッチし,同じくらい重要なことに, sda, sdb, sg1 のような KERNEL 名にはマッチしない.このキーの目的は /dev/sda や /dev/sg1 を無視することである.このデバイスはデジタルカメラであり, fdisk みたいなことをしようと思うことは全然ないので,これらの 2 つのノードは私にとってまったく意味がない.キーが捕まえようとしている /dev/sda1 ノードはマウント可能であるためとても使える!

このノード(sda1)はブロックデバイスとして扱われるため, /sys/block は調べ始めるのにいい場所である.

私の /sys/block 配下には, sda と名付けられたディレクトリがある. /sys/block/sda 配下には, sda1 と名付けられたデバイスがある.どちらのディレクトリにも dev ファイルが存在するので udevinfo を実行するのに適している.以下を実行すると私のカメラとカメラがつながれている USB ポートについての大量の情報を出力する.

# udevinfo -a -p /sys/block/sda/sda1

udevinfo の出力の中に,ちょっと使えそうで理解可能な情報があることに気づいた:

SYSFS{product}="USB 2.0M DSC"

それにより私のルールができた.完璧にするため, BUS キーも含めることにした(これも udevinfo の出力中に見つけた).

BUS="usb", SYSFS{product}="USB 2.0M DSC", KENREL="sd?1", NAME="%k", SYMLINK="camera"

今では,私のカメラをつなぐと, /dev/sda1(または, sda1 が使えない時には /dev/sdb1 と呼ばれるかもしれない)と名付けられ,いつも /dev/camera から正しくリンクされる. /dev/sda(もしくは sdb) ノードは普通に見えるが,重要なことは私のカスタマイズした永続的な "camera" シンボリックリンクがマウント可能なパーティションを指し示していることだ.

14. USB ストレージ向けのルールの書き方に対する追加注意

大容量 USB ハードディスクの所有者である, Carl Streeter が私のデジタルカメラの例とは違う /dev/sda ノードが彼にとって使える例を書いて説明してくれた.彼はたまに fdisk や hdparm のようなツールを使う必要があることを示してくれた.

Carl のルールは:

BUS="usb", KERNEL="sd*", SYSFS{product}="USB 2.0 Strage Device", NAME="%k", SYMLINK="subhd%n"

このルールは以下のようなシンボリックリンクを作成する:

マウント不可能な /dev/sda ノードが必要か必要でないかは時と場合によることが分かった.どちらでもあなたが一番思う方を使うとよい.

そのほかの難しい場合は,複数スロットを備えた USB ストレージカードリーダである.このタイプのデバイスは一般的に新しいカードが追加削除されたことを USB ホストに通知しないので,リーダがつながれている時に未使用のスロットにカードを挿入してもマウントのために必要な追加のデバイスノードは作成されない!

この問題は他の USB ディスクにも当てはまる−たとえば,もし新しいパーティションを作っても,新しいパーティションのノードはデバイスを再挿入するまで現れない.

udev には解決法がある−ブロックデバイスのすべてのパーティションのためにノードを作成できる.指定した全てのルールにおいて,ブロックデバイスでは 16 すべてのノードが作られる.これをするためには,下に示すようにちょっと NAME キーを編集するだけでよい:

BUS="usb", SYSFS={product}="USB 2.0 Stroage Device", NAME{all_partitions}="usbdb"

これで usbhd, usbhd1, usbhd2, usbhd3, ..., usbhd15 とデバイスノードを名付けることができる.

15. 例: 私の CD ドライブ向けの便利なルールの書き方

私のパソコンには, DVD リーダと CD ライタの 2 つのドライブがある. DVD は hdc , CDRW は hdd である.手動でケーブル接続の変更をしないかぎり,変わって欲しくない.

それでも,何人か(私自身も含まれる)は便利な /dev/dvd や /dev/cdrw のようなノードが合った方がいい.これらのデバイスに対する "hdX" は分かるので,ルールを書くのは簡単だ.以下の例はそれ自身が解説だ.

BUS="ide", KERNEL="hdc", NAME="%k", SYMLINK="dvd cdroms/cdrom%n"
 BUS="ide", KERNEL="hdd", NAME="%k", SYMLINK="cdrw cdroms/cdrom%n"

標準の 50-udev.rules ファイルには,ブロックデバイスのための名前生成スクリプトを実行するルールが含まれていることに気づいているかもしれない.これに惑わされてはいけない−通常,自前ルールはデフォルトルールファイルよりも先に処理されるよう置かれているため,自分でルールを書いているデバイスの名前付けをする時にはデフォルトは使われない.

16. 例: 私のネットワークインターフェイスに名前を付けるためにルールを書く

最近のバージョン udev のおもしろく新しい機能がネットワークインターフェイスを名付けるための機能である.ネットワークインターフェイスは /dev 配下には現れないが,一般的に名前で参照される(たとえば ifconfig を使って).この違いにもかかわらず,ルールの書き方はだいたい同じである.

いつも, udevinfo はルールを書くのに助けになる.例は, "eth0" ネットワークデバイスの名前を変えたいとする(以下の出力は断片的なもの)

# udevinfo -a -p /sys/class/net/eth0/
  looking at class device '/sys/class/net/eth0':
    SYSFS{address}="00:52:8b:d5:04:48"

すべてのネットワークアダプタは一意な MAC アドレスを持っているので,ルールを書くのにこれを使うことにした.これはネットワークカードが変わらない限り変更されることはない.ルールの例を以下に示す:

KERNEL="eth*", SYSFS{address}="00:52:8b:d5:04:48", NAME="lan"

このルールを有効にするためにはネットワークカードのドライバを再読込する必要がある.モジュールを一旦外してして再度読み込みさせてもいいし,単純にシステムを再起動させてもよい.システムが "eth0" ではなく "lan" を使うように再設定する必要もある. eth0 に対する参照が完全に終了するまで,これがうまくいくまでにいくつかの問題(インターフェイスの名前がずっと変わらない)があった.

その後, ifconfig や類似のユーティリティを使う時にいいて "lan" を "eth0" の変わりに使うことができる.

17. SYSFS で適切な場所を探すためのコツ

私はもっとデバイス固有のコツを探している.もし知っているのなら私まで教えてください

18. 複数 SYMLINK 形式ルールの使い方

もう 1 つの最近の機能は, NAME を特定せずに単に SYMLINK キーで特定するルールが書けることである.これは独自ルールの影響で udev 標準のルールがマスクされる問題を避けることを可能にする.

ルールは:

KERNEL="hdc", SYMLINK="dvd"

udev がこのルールを見つけると,これを記憶しておく. NAME パラメータを含む同じデバイスにマッチする他のデバイスを探す時に, udev は両方のルールの NAME パラメータで示されるノードを作成するのに加え, SYMLINK パラメータで示されたシンボリックリンクを作成する.

実際の条件に当てはめてみると, udev が hdc デバイスに名前を付ける時に,いつものようにブロックデバイスに標準のルールを使い,さらに追加で個人的なシンボリックリンクである "dvd" を作る.

一般的なルールと同様に,この種のルールは udev が NAME パラメータを使って特定するルールを見つける前に見つけたときにのみ有効になる.

19. udev と Nvidia のグラフィックドライバ

このセクションはこのドキュメントの目的には適していないが, google から得たヒントを元に,これは最新話題である,と判断した.

Nvidia のグラフィックドライバ(クローズドソースで, XFree に含まれてはいない)は標準の udev のインストールでは動かない − X を起動できない. nvidia モジュールは X によってロードされるが, /dev/nvidia* が十分早くには作られないので,X は起動をあきらめる.

この問題を解決するには, nvidia モジュールを起動時に自動的に組み込むことである.そう, − これをするように勧められている − NVidia FAQ はこれを確認している. devfs ベースのシステムでは, どっちみち devfs がこれを自動的に起動時に行っている.あなたが使っている Linux ディストリビューションはファイルを作成し,起動時に組み込ませるモジュールを列挙できる(たとえば Gentoo では /etc/modules.autoload.d/kernel-2.6, Debian では /etc/modules).

これだけではない − いくつかの基本情報を SYSFS にしゅつりょくするために nvidia カーネルインターフェイスにパッチを当てる必要がある.そうすることで udev は device をつくることができる. Martin Schlemmer nvidia ドライバの 1.0.5336 版に対するパッチを書いた,それはここで見つけることができる. Gentoo のパッケージ nvidia-kernel-1.0.5336-r4 はこのパッチを含んでいる.

他の解決法は単純に起動時に nvidia 固有のノードを作ることである. X は必要になった時にモジュールを組み込み,ノードはすでに存在しているので,上で述べた問題は起きない.起動時に自動的に実行されるファイルにこれらのコマンドを記述する(Gentoo では /etc/conf.d/local.start):

mknod /dev/nvidia c 195 0
mknod /dev/nvidiactl c 195 255

今や X を問題なく使うことができる.

20. 著者と著作権表示

この文章は Daniel Drake <dan@reactivated.net> が書きました.
MUNEDA Takahiro <mail address>が日本語に訳しました.
恥ずかしがらずにフィードバックを送ってください.

感謝:

Copyright(C) 2003-2004 Daniel Drake
This document is licensed under the GNU General Public License, Version2.

Copyright(C) 2005-2006 MUNEDA Takahiro

更新履歴

2006 12 12 - 第3版
訳でおかしかった部分を修正.まだまだ残っているので徐々にですが修正していきます.
オリジナル版 0.55 へのリンクを追加

2005 06 19 - 第2版
オリジナル版が更新されたので注意書きを追加

2005 04 08 - 初版
新規作成