Device File System ガイド
1.
devfsとは?
かつての(すばらしかった?)時代
警告:
devfsは廃止され、2.6.13リリースにおいて安定版2.6系カーネルから削除されました。
2.6系カーネルユーザは、これによってudevへ切り替えるように勧められます。
udevのより詳しい情報については、Gentoo udev Guide(日本語訳)を参照してください。
|
伝統的なLinuxの実装では、ユーザーに /dev と呼ばれる抽象的なデバイス・パスを提供しています。このパスの中に、システム内のデバイスを表すスペシャル・ファイルである、デバイス・ノードがあります。例えば、 /dev/hda はシステム内の最初のIDEデバイスを表します。デバイス・ファイルの提供によって、ユーザーは特別なAPIを使わずに、まるでハードウェアが一般的なファイルであるかのようにハードウェアに作用するプログラムを作成することができます。
デバイス・ファイルは、キャラクター・デバイスとブロック・デバイスと呼ばれる2つのグループにわけることができます。最初のグループは、読み込み/書き込みでバッファされないハードウェアで構成されます。2つ目のグループは、もちろん、読み込み/書き込みでバッファされるグループです。両方のデバイスとも、一度にもしくはブロック内に1つのキャラクターとして読み込まれます。そのために、この名称は混乱しているように思えますし、そして、実際に良くありません。
あるデバイス・ファイルに目を通してみると、このようなものに気付くでしょう:
コード表示 1.1: デバイス・ファイルの情報の確認 |
# ls -l /dev/hda
brw-rw---- 1 root disk 3, 0 Jul 5 2000 /dev/hda
|
上の例では、 /dev/hda がブロック・デバイスであることが分かります。しかし、もっと重要なことは、このデバイスが 3, 0 という割り当てられた2つの特別な番号を持っていることです。この組合せは、 major-minor ペアと呼ばれています。これは、デバイス・ファイルを実際のデバイスに割り振るために、カーネルによって用いられます。major(メジャー番号)はあるデバイスと対応し、minor(マイナー番号)はサブデバイスと対応します。混乱してきましたか?
/dev/hda4 と /dev/tty5 という2の例を示します。最初のデバイス・ファイルは、第一IDEデバイスの4番目のパーティションに対応します。このmajor-minorペアは 3, 4 です。言い替えれば、minorはmajorが対応するデバイスにあるパーティションに対応します。2つ目の例では、major-minorペアとして 4, 5 を持っています。この場合には、majorはターミナルドライバーに対応します。一方、minorはターミナルの番号に対応します(この場合は、5番目のターミナル)。
問題点
もし、 /dev について簡単な確認を行ったなら、あなたのすべてのデバイスだけでなく、あなたが想像できるすべての利用可能なデバイスを見つけることでしょう。言い替えるなら、あなたの持っていないデバイスに対するデバイス・ファイルを持っているということです。このようなデバイスグループを管理することは、控えめに言ったとしても厄介なことです。システム内に対応するデバイスのある、すべてのデバイス・ファイルのパーミッションを変更しなければならなず、そして、残りのデバイス・ファイルをそのままにして置く場合のことを想像してみてください。
新しいハードウェアをシステムに追加し、このハードウェアがあらかじめデバイス・ファイルをもっていなかった場合には、デバイス・ファイルを作成しなければならないことになるでしょう。技術の高いユーザーは、この作業が /dev ツリー内にある ./MAKEDEV を使えば終わることを知っていますが、あなたはどのデバイスを作成するべきか即座に分かりますか?
read-writeでマウントする必要がない場合でも、デバイス・ファイルを用いるハードウェアに作用するプログラムがあると、rootパーティションをread onlyでマウントすることができません。また、別のパーティションに /dev を置くこともできません。これは、 mount がパーティションをマウントするために /dev を必要とするためです。
解決策
あなたの想像どおり、カーネルハッカーたちは前述の問題に対して極めて多くの解決策を見つけ出しました。しかし、それらの多くは http://www.atnf.csiro.au/people/rgooch/linux/docs/devfs.html#faq-why に記述されているように他の欠点を抱えていました。今は、これらの実装について話そうとしているのではなく、オフィシャルなカーネルソースで問題を解決させたひとつの実装である devfs について焦点をしぼろうとしています。
devfsはすべてにおける勝者なのか?
devfsは全ての報告された問題に取り組みました。それは、ユーザーに対して存在するデバイスを提供するに留まらず、新たなデバイスが見つかると新しいノードを加え、さらにrootファイルシステムをread onlyでマウントすることを可能にしました。そして、ユーザーにとって面白いものではないために、ここでは取り上げなかった他の問題にも解決をもたらしました。
例えば、 devfsを使えば major/minorペアを気にする必要がありません。これは、まだ(下位互換として)サポートされているものの、必要ではありません。このことは、Linuxにさらに多くのデバイスのサポートを可能にさせました。なぜなら、これ以上に制限するものがないためです(数にはいつも限界がありますが :)
まだ、devfsの使用は、それ自身が引き起こす問題を抱えています。利用者には、この問題は本当に目につきませんが、カーネルメンテナーには、この問題は大きく、devfsを廃止にし、 udevを支持しています。もちろんGentooもサポートし、2.6系カーネルを使用し始めた2005.0リリースから、ほとんどのアーキテクチャで標準で使用しています。
devfsがなぜ廃止になったかという詳細な情報については、udev FAQやudev versus devfs documentをお読みください。
2.
デバイス・ツリーのご案内
ディレクトリ
注意しなければならない重要なことのひとつに、devfs がデバイスを一まとめにするためにディレクトリを用いていることがあります。このことは、判読性を向上させました。なぜなら、今では、すべての関連するデバイスが共通のディレクトリの中にあるからです。
例えば、すべてのIDEに関連するデバイスが /dev/ide/ デバイス・ディレクトリの中にあり、SCSIに関連するデバイスが /dev/scsi/ 内にあります。SCSIとIDEディスクは同じように認識でき、これは両者が同じサブディレクトリ構造を持ったことを意味しています。
IDEとSCSIディスクは、 host と呼ばれる(オンボード、もしくは、分離したカードの)アダプターによってコントロールされます。それぞれのアダプターは、数個のチャンネルを持つことができます。このチャンネルは、 bus と呼ばれています。それぞれのチャンネルでは、数個のIDを保持することができます。このようなひとつのIDは、ひとつのディスクを特定します。このIDは target と呼ばれます。いくつかのSCSIデバイスは、 複数の luns (Logical Unit Numbers) を持つことができます。例えば、同時に多様なメディアを処理するデバイス(ハイエンドのテープデバイス)などです。多くの場合は、単一の lun lun0/ のみです。
そうです、以前は /dev/hda4 が使われていたのに対して、今は /dev/ide/host0/bus0/target0/lun0/part4 を用いているのです。これは、はるかに簡単です。反論しないでください、、、とにかく簡単なのです!:)
注意:
ハードディスクに対して c0b0t0u0p2 のような、よりUnixライクなデバイス・ファイルの命名法を用いることも可能です。これらは、 /dev/ide/hd や /dev/scsi/hd などで見つけることができます。
|
ディレクトリについての考え方をわかってもらうために、私のラップトップのディレクトリの一覧を示します:
コード表示 2.1: /dev 内のディレクトリ |
cdroms/ cpu/ discs/ floppy/
ide/ input/ loop/ misc/
netlink/ printers/ pts/ pty/
scsi/ sg/ shm/ sound/
sr/ usb/ vc/ vcc/
|
devfsdを用いた下位互換
この新しい機構を使うことは楽しそうに思えます。しかし、いくつかのツールとプログラムは以前の古い機構を利用します。すべてのシステムが崩壊しないことを確実にするために、 devfsd が作成されました。このデーモンは、新しいデバイス・ファイルを示す、古い名前のsymlinkを作成します。
コード表示 2.2: 作成されたsymlink |
$ ls -l /dev/hda4
lr-xr-xr-x 1 root root 33 Aug 25 12:08 /dev/hda4 -> ide/host0/bus0/target0/lun0/part4
|
devfsd を用いれば、さらに、パーミッションの設定、新しいデバデバイス・ファイルの作成、アクションの定義などをも行うことができます。これら全ては、次の章に書かれています。
3.
デバイス・ツリーの管理
devfsdの再起動
/etc/devfsd.conf ファイルを変更した場合やシステムに強制的に変更を加えたい場合に、再起動を行う必要はありません。あなたのやりたい事に応じて、次の2つのシグナルのどちらかを用いることができます:
SIGHUP は、 devfsd に、設定ファイルの再読み込みや共有オブジェクトの再ロード、そして、デバイス・ツリーの中のそれぞれのリーフノードに対するREGISTERイベントの生成をさせます。
SIGUSR1 は、同様に動作しますが、REGISTERイベントを生成しません。
シグナルを送るためには、単に kill もしくは killall を用いてください:
コード表示 3.1: devfsdにSIGHUPシグナルを送る |
# kill -s SIGHUP `pidof devfsd`
# killall -s SIGHUP devfsd
|
互換symlinkの除去
警告:
現在、Gentooは互換symlinkなしでは生きられません。
|
もし、 /dev を乱雑にする互換symlinkをGentooシステム(Gentooはデフォルトで動作させている)から除去したい場合は、 /etc/devfsd.conf を編集し、以下の2行を取り除いてください:
コード表示 3.2: /etc/devfsd.confの下位互換 |
REGISTER .* MKOLDCOMPAT
UNREGISTER .* RMOLDCOMPAT
|
この変更を適用するためには、システムを再起動させる必要があります。
自動ロード機能の除去
モジュールをロードした時、devfsは自動的にデバイス・ファイルを作成します。この動作を望まない場合には、 /etc/devfsd.conf から以下の行を除去してください:
コード表示 3.3: /etc/devfsd.conf, 自動ロード機能 |
LOOKUP .* MODLOAD
|
4.
アイテムに関連したパーミッション
devfsdによるパーミッションの設定と変更
注意:
これらの操作はpam_consoleが/etc/pam.d/system-authの中で無効になっている限り有効です。pam_consoleを有効にしている場合、PAMがパーミション上最終的に保証するものになります。
|
もし、/etc/devfsd.conf を用いてパーミッションの設定をしたいなら、次の例で用いられているシンタックスを利用してください:
コード表示 4.1: /etc/devfsd.conf でのパーミッション |
REGISTER ^cdroms/.* PERMISSIONS root.cdrom 0660
|
2番目の欄は、 /dev から始まるデバイス・グループです。これは正規表現で、ひとつのルールでいくつかのデバイスを選択可能です。
4番目の欄は、デバイス・ファイルの所有権です。
そして5番目の欄は、デバイス・ファイルのパーミッションを記述しています。
手動によるパーミッションの設定とdevfsdによるセーブ
これはGentooでは、デフォルトの動作です: もし、デバイス・ファイルを chown (CHange OWNer) や chmod (CHange MODe) した場合には、 devfsd は、再起動してもこの状態を維持するために、この情報をセーブします。この動作は、 /etc/devfsd.conf ファイルに以下の行が記述されているためです:
コード表示 4.2: /etc/devfsd.conf のパーミッションのセーブ |
REGISTER ^pt[sy]/.* IGNORE
CHANGE ^pt[sy]/.* IGNORE
CREATE ^pt[sy]/.* IGNORE
DELETE ^pt[sy] IGNORE
REGISTER ^log IGNORE
CHANGE ^log IGNORE
CREATE ^log IGNORE
DELETE ^log IGNORE
REGISTER .* COPY /lib/dev-state/$devname $devpath
CHANGE .* COPY $devpath /lib/dev-state/$devname
CREATE .* COPY $devpath /lib/dev-state/$devname
DELETE .* CFUNCTION GLOBAL unlink
/lib/dev-state/$devname
RESTORE /lib/dev-state
|
言い替えれば、変更されたデバイス・ファイルは変更が行われたときに /lib/dev-state へコピーされ、そしてシステムがブートされるとき /dev ファイルにコピーされます。
他の方法は、ブート時に /dev に /lib/dev-state をマウントすることです。これを行うためには、devfs が自動的にマウントされないことを確認しなければなりません(カーネルの再コンパイルをしなればならないことを意味します)。そして、 /dev/console が存在することも確認しなければなりません。そして、システムのブートスクリプトの最初のどこかに、以下を記述します:
コード表示 4.3: /dev の上部への /lib/dev-state のマウント |
mount --bind /dev /lib/dev-state
mount -t devfs none /dev
devfsd /dev
|
5.
情報源
devfsについてのこれ以上の情報は、以下の情報源を参照してください。
devfsd.confのmanページは /etc/devfsd.conf ファイルのシンタックスを解説しています。この情報を見るためには、man devfsd.conf と入力してください。
devfs FAQ
は、devfsについてのすべてことを解説しています。内部のdevfs構造やどのようにドライバーがdevfsをサポート可能にしているのかについての情報も含まれています。
LinuxJournal には、devfs for Management and Administration という興味深い記事があります。
Daniel Robbinsは、IBMのDeveloperWorks向けにアドバンスト・ファイルシステムについての一連の記事を書いています。これらのうちの3つがdevfsについてのものです:
このドキュメントの内容は
Creative Commons -
Attribution / Share Alikeライセンスです。
|