major, minor
番号は一意ですか?
引用と参照がありますか?
NAME MAJ:MIN RM SIZE RO MOUNTPOINT
sda 8:0 0 465.8G 0
├─sda1 8:1 0 298.2M 0
├─sda2 8:2 0 3G 0
├─sda3 8:3 0 458.7G 0 /
├─sda4 8:4 0 1K 0
└─sda5 8:5 0 3.8G 0
sr0 11:0 1 1024M 0
The Linux Programming Interface から、§14.1
各デバイスファイルには、メジャーID番号とマイナーID番号があります。メジャーIDはデバイスの一般的なクラスを識別し、このタイプのデバイスに適切なドライバーを検索するためにカーネルによって使用されます。マイナーIDは、一般クラス内の特定のデバイスを一意に識別します。デバイスファイルのメジャーIDとマイナーIDは、ls -lコマンドで表示されます。
[...]
各デバイスドライバーは、特定のメジャーデバイスIDとの関連付けを登録します。この関連付けにより、デバイス特殊ファイルとデバイス間の接続が提供されます。カーネルがデバイスドライバーを探す場合、デバイスファイルの名前は関係ありません。
この古い(2001) Linux Device Drivers(2e)の章 も参照してください。
つまり、デバイスのタイプごとにメジャー:マイナーからデバイス:インスタンスへの一意のマッピングを提供することを目的としています。厳密に言えば、あなたは同じメジャーを持つ2つの異なるデバイスを持つことができます1つがcharで、1つがブロックである限り、マイナー:
# ls -l /dev/ram1 /dev/mem
crw-r----- 1 root kmem 1, 1 Jan 1 1970 /dev/mem
brw-rw---- 1 root disk 1, 1 Jan 1 1970 /dev/ram1
Linuxでは、1つのシステムの任意の時点で各タイプのデバイスのメジャー:マイナー番号は一意です。ただし、数値は時間の経過とともに変化する可能性があり、異なるLinuxシステム間で同じである必要はありません(同じディストリビューション、カーネル、ハードウェアでも)。文字デバイスとブロックデバイスには異なる番号付けスペースがあることに注意してください。ブロックメジャー1はRAM=ディスクに割り当てられ、charメジャー1はnullとゼロを含むカーネルデバイスのセットに割り当てられます。
歴史的に、デバイスメジャーは(主に)静的にa registry を通じて割り当てられていました(カーネルソースDocumentation/devices.txt
にも維持されていませんが、まだ存在しています)。最近、多くのデバイスが動的に割り当てられ、これは dev によって管理され、マッピングは/proc/devices
で表示できます。修正されたデバイスは incude/uapi/linux/major.h
にまだ存在します(最近include/major.h
から移動されました)
ここで、major:minorの組み合わせは特定のデバイスインスタンスを一意に識別しますが、同じデバイスを参照する複数のデバイスノード(ファイル)の作成を妨げるものは何もありません。 /dev
で作成する必要はありません(ただし、デバイスノードの作成をサポートするファイルシステム上にある必要があり、nodev
オプションでマウントされていません)。
一般的な使用法は、chrootに重複するゼロ、null、ランダムデバイスを作成することです。
# find /dev /var/chroot -regextype posix-extended -regex ".*/(zero|null|random)" -type c |
xargs ls -l
crwxrwxrwx 1 root root 1, 3 2012-11-21 03:22 /dev/null
crw-rw-r-- 1 root root 1, 8 2012-05-07 10:35 /dev/random
crw-rw-rw- 1 root root 1, 5 2012-11-21 03:22 /dev/zero
crwxrwxrwx 1 root root 1, 3 2012-11-21 03:22 /var/chroot/sendmail/dev/null
crw-rw-r-- 1 root root 1, 8 2012-05-07 10:35 /var/chroot/sendmail/dev/random
crw-rw-rw- 1 root root 1, 5 2012-11-21 03:22 /var/chroot/sendmail/dev/zero
名前は単なるエイリアスであり、カーネルはほとんどの名前や場所をあまり気にしません。正しいドライバーを選択できるようにメジャー番号を気にし、ドライバーは通常、マイナー番号を気にします。正しいインスタンス。
ほとんどの名前は単なる規則です(ただし 一部はPOSIXで定義されています )。また、1つのデバイスが複数のメジャー番号に登録する場合があることに注意してください。/proc/devices
のsd
ドライバーを確認してください。ドライバーモジュール名(.ko
)はデバイス名と同じである必要はなく、/dev
のデバイスノードと同じである必要もありません。単一のドライバーモジュールで複数の論理/物理デバイスを管理できます。またはデバイス名。
要約すると:同じメジャー:マイナー番号を持つ2つ以上のデバイスノード(/dev/
または他の場所)がある場合がありますが、それらが同じタイプの場合、同じデバイスを参照します。複数のメジャーインスタンスを処理できる1つのドライバーを持つことができますが、カーネル内およびドライバー内では、タイプ(charまたはブロック)ごとに、major:minor番号が特定のデバイス(major)および特定のインスタンス(デバイスのマイナー)。
同じタイプとmajor:minorの2つのデバイスノードを使用して、2つの異なる論理デバイスまたは物理デバイスにアクセスすることはできません。デバイスがアクセスされている場合、カーネルはタイプとメジャー番号に基づいて1つのドライバーを選択し(デバイスノード名に基づいてではなく)、慣例により、マイナー番号を確定的に選択します。特定のインスタンスまたはサブ関数を選択します。
更新Poul-Henning Kampの2002BSDConプレゼンテーションには、興味深い歴史といくつかの* BSDの展望があります。 : https://www.usenix.org/legacy/events/bsdcon/full_papers/kamp/kamp_html/
もしあなたが 1978年までの時間で跳躍 (Alcatel-Lucentの厚意により、Bell System Technical JournalJul-Aug 1978) 'Unix Time Sharing System 'はそれを明確に示しています(p1937):
デバイスは、メジャーデバイス番号、マイナーデバイス番号、およびクラス(ブロックまたは文字)によって特徴付けられます。クラスごとに、デバイスドライバーへのエントリポイントの配列があります。メジャーデバイス番号は、特定のデバイスドライバーのコードを呼び出すときに配列にインデックスを付けるために使用されます。マイナーデバイス番号は、引数としてデバイスドライバーに渡されます。マイナー番号は、ドライバーがマイナー番号に起因するもの以外に重要性はありません。通常、ドライバーはマイナー番号を使用して、いくつかの同一の物理デバイスの1つにアクセスします。
mknode
によってデバイスファイルが作成されると、major
およびminor
番号が提供されます。 Linuxは、デバイスファイルに関連付けられたハードウェアデバイスを識別する方法です。ほとんどの場合、major
番号はドライバーを識別し、minor
はドライバーが制御するさまざまなデバイスを区別します。
そのため、番号はデバイスごとに一意である必要があります。そうでない場合、それらすべてに対して正しいデバイスファイルを作成することはできません。
SCSIディスクのメジャー番号は8です。
ディスクタイプごとに個別のメジャー番号があります。
@Kiwyがコメントで述べたように、メジャー番号はディスクタイプを識別するために使用され、マイナー番号はメジャーハードウェアディスクのサブディビジョンを表します。
上のスクリーンショットでは、暗号化されたlvmパーティションのメジャー番号が通常のパーティションと異なることがわかります。
いいえ、Linuxでは、それらは常に一意であるとは限りません。
Linuxはdevpts
仮想ファイルシステムを使用して疑似端末(ptys)を提供し、その仮想ファイルシステムは複数回、異なる場所にマウントできます。これは、chrootまたは名前空間コンテナーを設定するときに実用的です。 _major:minor
_タプルはdevpts
ファイルシステムインスタンスで一意ですが、実行中のシステムでは一意ではありません。
_# mount -t devpts devpts /dev/pts
# script -q /dev/null
# stat -c '%n %t:%T %d:%i' `tty`
/dev/pts/0 88:0 34:3
# mount -t devpts devpts /dev/pts
# script -q /dev/null
# stat -c '%n %t:%T %d:%i' `tty`
/dev/pts/0 88:0 35:3
_
上記の例では、script(1)
コマンドは疑似端末を作成し、その中でシェルを実行します。最初のscript
プロセスによって作成された疑似ターミナルが2番目のプロセスによって作成されたものと同じではないことは明らかですが、それらは同じ名前とメジャー、マイナー番号を持っています。
疑似端末を一意に識別するには、それらの_device:inode
_タプルを使用するか、(devptsファイルシステムの)デバイス番号を_major:minor
_と組み合わせる必要があります。問題は、_/proc/PID/stat
_の「tty」フィールドです(7番目、proc(5)
のマンページを参照してください。ここで、lsof
やps
などのツールがinfo from)には、ttyの_st_rdev
_(パックされた_major:minor
_)のみが含まれます。それがptyスレーブである場合、それを提供するdevpts
ファイルシステムへの指示はありません。同じ問題が、TIOCGDEV
ioctlで取得できるデバイス番号に影響します。
AFAICSは、Linux上のプロセスの制御端末を識別する信頼できる方法はありません。それ以外の場合の修正と提案は歓迎します!