さらに言えば、/dev
にある一連の静的ファイルの何が問題だったのでしょうか。開発者がこのホイールを私のカウントで3回再発明するのは明らかに不十分であり(devfs
-> udev + HAL
-> udev
)、今では明らかに大統一理論に入っています。 Init Programも、4回です。
何年も前にLinuxを使い始めたとき、「すべてがファイルである」という主張にもかかわらず、/dev/eth0
がないことに驚いたことを覚えています(charまたはblockデバイスではないため、後で意味がありますが、 「パケット」デバイスタイプは興味深いでしょう...)。それを考えると、charおよびblockデバイスファイルツリーを処理するプログラムがネットワークデバイスも担当するのはなぜですか? 「柔軟性」への漠然とした言及を見てきましたが、これは、たとえば、/proc/net/dev
を調べるだけでifconfig(8)が行うことを何に追加しますか?たとえば、NetworkManagerはudev
に依存しているため、どちらのチームも書きたくないので、すぐにNetまたはOpenBSDに入る予定はありません。私が理解していないのは、少なくとも名目上は/dev
ツリーを管理するプログラムがネットワークデバイスを公開する唯一の方法である理由ですカーネルによってすでに複数の方法で公開されています (そしてそれらのどれも/dev
にありません!)。
ホットプラグのせいだけですか?カーネルが物理バスをリッスンし、「デバイスが追加されました」というメッセージに適切なモジュールをロードするだけで問題が発生しましたか?または、神は禁じています、実際の管理者はそうしていますか? 2000年代の初めに、サーバーが予期しない順序でネットワークカードを初期化することがあったことを覚えています。その名前をユーザーランドで決定することは理にかなっていると思います(当時はそれほど難しくはありませんでしたが)。これはゴキブリのスレッジハンマーのようです。 (あるいは、その問題は、私の経験であるラックマウント型サーバーやPCよりもそれほど難しいことを考えていないユースケースに当てはまるかもしれません。)
それで、私の質問をわかりやすく述べると、udevは実際にどのような問題を解決し、devfs、HAL、および/または単純な古いファイルはどのようにそれらを解決できなかったのでしょうか?多くの異なるもの(ホットプラグ、一般的なデバイス管理、ネットワークデバイス管理、デバイスの命名、ドライバーの優先順位など)がすべて1つのプログラムになる特別な理由はありますか?
さらに2つのことがあります。Linuxがエンタープライズサーバーやその他の大規模サーバーに移行したことで、静的な/dev
が壊れることになりました。消費者と企業の両方で技術の進歩は、静的な/ devを冗談として公開していました。 [この回答は、特にdevfsがudevに置き換えられた理由ではなく、より多くの裏話を埋めています]。
/dev
ファイルは、カーネル内でメジャー番号とマイナー番号で識別されます。カーネルは実際に名前を気にかけたことはありません(たとえば、mv /dev/sda /dev/disk-1
を使用すると、引き続き機能しますが、もちろんプログラムは名前の場所を知りません)。
静的な/dev
を使用すると、存在する可能性のあるすべての潜在的なデバイスにメジャー/マイナー番号を割り当てる必要があります。これらの番号は、オンデマンドで作成されるのではなく、ディストリビューションの一部として出荷されるため、グローバルに一意である必要があります。問題は、それらがそれぞれ8ビットの数値であるということです。範囲は0〜255です。
たとえば、元々、Linuxは8,0がsda、8,1がsda1、8,16がsdbなどで始まりました。しかし、特にファイバーチャネルなどを考えると、人々はマシンにディスクを追加し続けました。そのため、ある時点で、より多くのディスクにメジャー番号65〜71が追加されました。その後、メジャー番号128〜135。それでも人々はもっと多くのディスクを欲し続けました...
また、GPTのようなパーティションテーブル形式が登場し、ディスクあたりのパーティション数が増えました。そしてもちろん、さまざまなRAIDコントローラー、論理ボリューム管理など、他のデバイスが数のスペースを食いつぶしていました。
最終結果は LANANA Linuxデバイスリスト で見ることができます。 2.6リスト(まだそこにある唯一のリスト)を見ると、200までのブロックメジャー番号(最大:255)が多く使用されています。明らかに、数は尽きていただろう。
大きな数字に変更するのは簡単ではありませんでした。カーネルABIを変更します。ファイルシステムに応じて、ディスク上のレイアウトが変更されます。しかし、もちろん、これらのデバイスのほとんどは、(たとえば)SCSIディスクが不足しているシステムでさえ、どのシステムにも存在しませんでした。無料のものがたくさんありました。たとえば、IBM XTハードディスクは必要なかったでしょう。
動的な/dev
を使用すると、ディストリビューションはデバイス番号を発送する必要がありません。それらはもはやグローバルに一意である必要はありません。ブーツ全体で一意である必要はありません。
以前は、すべてに番号を割り当てるのは非常に簡単でした。ボードには2つのIDEチャネルがありました。各IDEチャネルは1つのマスターと1つのスレーブをサポートしていました。チャネルの順序、およびマスター、次にスレーブの順序で割り当てることができます。 。したがって、hda
は最初のチャネル、マスター、hdb
最初のチャネル、スレーブ、hdc
2番目のチャネル、マスターなどになります。これらは予測可能で安定していました。追加すると変更される可能性があります。新しいドライブ、またはドライブを削除しますが、ハードウェアの変更がないため、静的でした。
/dev/hda1
を/etc/fstab
に入れて、少なくともハードウェアの変更がない限り、動作し続けると確信することができます。
IDEはそのように機能しました。その後は何もしません。
SATAは単純に見えます:1つのポート、1つのディスク。しかし、そうではありません。ポートマルチプライヤが可能です。そしてそれはホットスワップを可能にします。それでも、ハードウェアの変更がなくても、実際にはマッピングを機能させ続けることができます。
USBははるかに悪いです。ホットスワップを可能にするだけでなく、一般的です。人々は常にUSBフラッシュドライブを接続します。さらに、デバイスはプローブするのに時間がかかる場合があり、実際には、デバイスが気に入るときはいつでも変更できます(たとえば、電話のUSBストレージモードをオンまたはオフにするとき)。 Firewireも同様です。どちらも使用しないと、安定したマッピングを思い付くことができません。
ネットワークに接続されたディスクには、固有のポート順序はありません。カーネルが使用する唯一の順序は、それらが出現した順序です。論理ボリュームと同じです。
起動速度の追求も事態を悪化させました。もともと、カーネルは喜んで座って、たとえばすべてのUSBデバイスが初期化されるまでかなり長い時間待機していました。すべてのSCSIバスなどを完全にプローブするため。これらのプローブはバックグラウンドタスクになりました。ブートはもはやそれらを待ちません。プローブが完了すると、デバイスが追加されます。
そのため、カーネルには、多かれ少なかれ、「表示される順序が何であれ」が残されていました。これは、多くの種類のデバイスが起動ごとに順序を変更できることを意味しました。ある起動/dev/sdb
にあったものは別の起動/dev/sdc
にありました。これは、静的な/dev
のアイデアを冗談にします。
予測できないデバイスプローブの順序のために静的/dev
の組み合わせがますます無意味になり、静的メジャー/マイナー番号を割り当て続けると、実質的な作業が不足しないようになるため、Linuxの開発者がに切り替えることを選択した理由が明らかになります。動的な/dev
。
良い質問。
ある意味で、この議論は好転する可能性があります。カーネル2.6.13がuevent
の新しいバージョンを導入したため、devfs
を利用するには書き直す必要があることになりました。インターフェイスの新機能の。したがって、ある意味で、問題はなぜカーネルが変更されたのかということです。
しかし、それを額面通りに受け取ると、あなたの質問は このウィキペディアの記事 で答えられます:
/ devディレクトリ内のデバイスノードが静的なファイルセットである従来のUnixシステムとは異なり、Linux udevデバイスマネージャは、システムに実際に存在するデバイスのノードのみを動的に提供します。 devfsは以前は同様の機能を提供していましたが、Greg Kroah-Hartmanは、devfsよりも実装を好む理由をいくつか挙げています。
1)udevは永続的なデバイスの命名をサポートします。これは、たとえば、デバイスがシステムに接続されている順序に依存しません。デフォルトのudevセットアップは、ストレージデバイスの永続的な名前を提供します。ハードディスクは、一意のファイルシステムID、ディスクの名前、および接続されているハードウェア上の物理的な場所によって認識されます。
2)udevは、devfsのカーネル空間ではなく、完全にユーザー空間で実行されます。結果の1つは、ノードが作成される前に、udevが名前付けポリシーをカーネルから移動し、任意のプログラムを実行して、デバイスのプロパティからデバイスの名前を作成できることです。そこでは、プロセス全体も中断可能であり、より低い優先度で実行されます。
Udevを使用すると、基本的にdevfsとhotplugのデバイスの名前付けを損なうrace condition
の可能性が回避されることを追加する必要があります。言い換えると、devfsでは、左端のイーサネットポートがeth0
と呼ばれ、右端のイーサネットポートがeth1
と呼ばれるようにする方法がなく、(純粋な例として)ルーター(1つのポート)を設定します。 WANへ、LANへの1つのポート)実装が困難です。
GUIDに基づくディスクの命名スキームの採用は別のプラスであり、プロセス全体をユーザースペースにさらに大きなものに移動します。このサイトを検索して、何人の人が書いているかを確認しましたか?独自のudevルール?
ユーザースペースにudevを配置することに固有の利点の簡単な例として、このサイトで この質問 または この他の質問 を確認してください。