Sind die Haupt- und Nebenzahlen eindeutig?

11

Sind die major, minorNummern eindeutig?

Haben wir Zitate und Hinweise darauf?

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 
Dipak Ingole
quelle
Maj ist Hardware, Minor ist Unterteilung der großen Hardware
Kiwy

Antworten:

20

Von der Linux Programming Interface , §14.1

Jede Gerätedatei hat eine Haupt-ID-Nummer und eine Neben-ID-Nummer. Die Haupt-ID identifiziert die allgemeine Geräteklasse und wird vom Kernel verwendet, um den entsprechenden Treiber für diesen Gerätetyp zu suchen. Die Neben-ID identifiziert ein bestimmtes Gerät innerhalb einer allgemeinen Klasse eindeutig. Die Haupt- und Neben-IDs einer Gerätedatei werden mit dem Befehl ls -l angezeigt.

[...]

Jeder Gerätetreiber registriert seine Zuordnung zu einer bestimmten Hauptgeräte-ID, und diese Zuordnung stellt die Verbindung zwischen der Gerätespezialdatei und dem Gerät her. Der Name der Gerätedatei hat keine Relevanz, wenn der Kernel nach dem Gerätetreiber sucht.

Siehe auch dieses alte Kapitel (2001) Linux Device Drivers (2e) .

Das heißt, es ist beabsichtigt, für jeden Gerätetyp eine eindeutige Zuordnung von major: minor zu device: instance bereitzustellen. Streng genommen Sie können zwei verschiedene Geräte mit dem gleichen Haupt: minor, solange ein Zeichen ist und man ist Block:

# 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

Unter Linux sind zu jedem Zeitpunkt auf einem System die Haupt-: Nebenzahlen für jeden Gerätetyp eindeutig. Die Zahlen können sich jedoch im Laufe der Zeit ändern und müssen auf verschiedenen Linux-Systemen (sogar auf derselben Distribution, demselben Kernel und derselben Hardware) nicht gleich sein. Beachten Sie, dass Zeichen- und Blockgeräte unterschiedliche Nummerierungsräume haben, z. B. wird Block-Major 1 RAM-Datenträgern zugewiesen, Char-Major 1 wird einer Reihe von Kernel-Geräten zugewiesen, einschließlich Null und Null.

In der Vergangenheit wurden Geräte-Majors (meistens) statisch über eine Registrierung zugewiesen (die in der Kernel-Quelle ebenfalls noch vorhanden ist, obwohl sie nicht verwaltet wird Documentation/devices.txt). Heutzutage werden viele Geräte dynamisch zugewiesen, dies wird von udev verwaltet und die Zuordnungen können in angezeigt werden /proc/devices. Die festen Geräte sind noch vorhanden in incude/uapi/linux/major.h(kürzlich verschoben von include/major.h)

Obwohl die Kombination major: minor bestimmte Geräteinstanzen eindeutig identifiziert, hindert Sie nichts daran, mehrere Geräteknoten (Dateien) zu erstellen, die auf dasselbe Gerät verweisen. Sie müssen nicht einmal in erstellt werden /dev(sie müssen sich jedoch in einem Dateisystem befinden, das das Erstellen von Geräteknoten unterstützt und nicht mit der nodevOption bereitgestellt wird).

Eine häufige Verwendung ist das Erstellen doppelter Null-, Null- und Zufallsgeräte in einer Chroot:

# 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

Die Namen sind nur Aliase, der Kernel kümmert sich nicht viel um die meisten Namen oder Speicherorte, er kümmert sich um die Hauptnummer, damit er den richtigen Treiber auswählen kann, und der Treiber kümmert sich (normalerweise) um die Nebennummer, damit er die auswählen kann richtige Instanz.

Die meisten Namen sind einfach Konventionen (obwohl einige von POSIX definiert werden ). Beachten Sie auch, dass sich ein Gerät möglicherweise für mehrere Hauptnummern registriert. Checken Sie den sdTreiber ein /proc/devices. Ein Treibermodulname ( .ko) muss nicht mit dem Gerätenamen und nicht mit dem Geräteknoten identisch sein /dev, und ein einzelnes Treibermodul kann mehrere logische / physische Geräte oder Gerätenamen verwalten.


Um es noch einmal zusammenzufassen: Sie haben möglicherweise zwei oder mehr Geräteknoten (in /dev/oder anderswo), die die gleichen Haupt-: Nebennummern haben, aber wenn sie vom gleichen Typ sind, beziehen sie sich auf dasselbe Gerät. Sie können einen Treiber haben, der mehrere Hauptinstanzen verarbeiten kann, aber innerhalb des Kernels und innerhalb des Treibers wird für jeden Typ (char oder block) die Nummer major: minor verwendet, um auf ein bestimmtes Gerät (major) und eine bestimmte Instanz ( Moll) des Geräts.

Sie können nicht zwei Geräteknoten mit demselben Typ und Major haben: Minor und erwarten, dass sie auf zwei verschiedene logische oder physische Geräte zugreifen. Wenn auf ein Gerät zugegriffen wird, wählt der Kernel einen Treiber basierend auf dem Typ und der Hauptnummer (und nicht basierend auf dem Namen des Geräteknotens) aus, und gemäß Konvention wählt die Nebennummer deterministisch eine bestimmte Instanz oder Unterfunktion aus.


Update Eine interessante Geschichte und eine * BSD-Perspektive finden Sie in der BSDCon- Präsentation 2002 von Poul-Henning Kamp : https://www.usenix.org/legacy/events/bsdcon/full_papers/kamp/kamp_html/

Wenn Sie in die Zeit von 1978 zurückspringen (mit freundlicher Genehmigung von Alcatel-Lucent, dem Bell System Technical Journal, Juli-August 1978), wird dies im „ Unix Time Sharing System “ klar dargelegt (S. 1937):

Geräte sind durch eine Hauptgerätenummer, eine Nebengerätenummer und eine Klasse (Block oder Zeichen) gekennzeichnet. Für jede Klasse gibt es eine Reihe von Einstiegspunkten in die Gerätetreiber. Die Hauptgerätenummer wird verwendet, um das Array zu indizieren, wenn der Code für einen bestimmten Gerätetreiber aufgerufen wird. Die untergeordnete Gerätenummer wird als Argument an den Gerätetreiber übergeben. Die untergeordnete Zahl hat keine andere Bedeutung als die vom Fahrer zugeschriebene. Normalerweise verwendet der Treiber die untergeordnete Nummer, um auf eines von mehreren identischen physischen Geräten zuzugreifen.

mr.spuratic
quelle
MAJ:Min
Können
1
Ja, mit Einschränkungen. Aktualisiert.
mr.spuratic
2

Wenn eine Gerätedatei von erstellt wird mknode, werden die majorund minor-Nummern angegeben. Auf diese Weise identifiziert Linux das zugrunde liegende Hardwaregerät, das einer Gerätedatei zugeordnet ist. In den meisten Fällen majoridentifiziert die Nummer den Treiber, während minordie verschiedenen Geräte, die der Treiber steuert, unterschieden werden.

Daher müssen die Nummern für jedes Gerät eindeutig sein, da sonst nicht für alle Geräte die richtigen Gerätedateien erstellt werden können.

Graeme
quelle
0

Nein, unter Linux sind sie nicht immer eindeutig.

Linux verwendet ein devptsvirtuelles Dateisystem, um Pseudoterminals (ptys) bereitzustellen, und dieses virtuelle Dateisystem kann mehrmals und an verschiedenen Stellen bereitgestellt werden. Dies ist praktisch, wenn Chroots oder Namespace-Container eingerichtet werden. Während ein major:minorTupel auf einer devptsDateisysteminstanz eindeutig ist , ist es auf einem laufenden System nicht eindeutig:

# 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

Im obigen Beispiel script(1)erstellt der Befehl ein Pseudo-Terminal und führt darin eine Shell aus. Es ist verdammt offensichtlich, dass das vom ersten scriptProzess erzeugte Pseudo-Terminal nicht das gleiche ist wie das vom zweiten, aber sie haben den gleichen Namen und die gleichen Haupt- und Nebenzahlen.

Um ein Pseudoterminal eindeutig zu identifizieren, müssen Sie dessen device:inodeTupel verwenden oder die Gerätenummer (des devpts-Dateisystems) mit ihrem kombinieren major:minor. Das Problem ist, dass das "tty" -Feld des /proc/PID/stat(7., siehe proc(5)Manpage; dort mögen Tools lsofoder pserhalten ihre Informationen) nur das st_rdevdes tty (das gepackte major:minor) enthält; Wenn dies ein Pty-Slave ist, gibt es keinen Hinweis auf das devptsDateisystem, das ihn bereitstellt. Die gleichen Probleme betreffen die Gerätenummer, die mit dem TIOCGDEVioctl erhältlich ist.

AFAICS Es gibt keine zuverlässige Möglichkeit, das steuernde Terminal eines Prozesses unter Linux zu identifizieren. Korrekturen und Anregungen ansonsten willkommen!

Mosvy
quelle