Le nombre majeur et mineur est-il unique

11

Le major, minornombre est-il unique?

Avons-nous des citations et des références à cela?

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
la source
maj est matériel, mineur est sous-division du matériel majeur
Kiwy

Réponses:

20

Depuis l' interface de programmation Linux , §14.1

Chaque fichier de périphérique a un numéro d'identification majeur et un numéro d'identification mineur. L'ID principal identifie la classe générale de périphérique et est utilisé par le noyau pour rechercher le pilote approprié pour ce type de périphérique. L'ID mineur identifie de manière unique un périphérique particulier au sein d'une classe générale. Les ID majeur et mineur d'un fichier de périphérique sont affichés par la commande ls -l.

[...]

Chaque pilote de périphérique enregistre son association avec un ID de périphérique majeur spécifique, et cette association fournit la connexion entre le fichier spécial de périphérique et le périphérique. Le nom du fichier de périphérique n'a aucune pertinence lorsque le noyau recherche le pilote de périphérique.

Voir également cet ancien chapitre (2001) Linux Device Drivers (2e) .

c'est-à-dire que l'intention est de fournir un mappage unique de majeur: mineur à périphérique: instance pour chaque type de périphérique. Strictement, vous pouvez avoir deux appareils distincts avec le même majeur: mineur, tant que l'un est char et l'autre est bloc:

# 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

Sous Linux, à tout moment sur un système, les principaux: les numéros mineurs pour chaque type d'appareil sont uniques. Les nombres peuvent cependant changer avec le temps, et n'ont pas besoin d'être les mêmes sur différents systèmes Linux (même la même distribution, le même noyau et le même matériel). Notez que les périphériques caractère et bloc ont des espaces de numérotation distincts, par exemple le bloc majeur 1 est affecté aux disques RAM, le caractère majeur 1 est affecté à un ensemble de périphériques noyau, y compris null et zéro.

Historiquement, les majors de périphériques étaient (principalement) alloués statiquement via un registre (également toujours présent, bien que non entretenu, dans la source du noyau Documentation/devices.txt). De nos jours, de nombreux appareils sont alloués dynamiquement, cela est géré par udev et les mappages sont visibles dans /proc/devices. Les appareils fixes existent toujours dans incude/uapi/linux/major.h(récemment déplacé de include/major.h)

Maintenant, bien que la combinaison majeur: mineur identifie de manière unique des instances de périphérique spécifiques, rien ne vous empêche de créer plusieurs nœuds (fichiers) de périphériques qui font référence au même périphérique. Ils n'ont même pas besoin d'être créés dans /dev(mais ils doivent être sur un système de fichiers qui prend en charge la création de nœuds de périphérique et n'est pas monté avec l' nodevoption).

Une utilisation courante consiste à créer des périphériques zéro, nul et aléatoire en double dans un 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

Les noms ne sont que des alias, le noyau ne se soucie pas beaucoup de la plupart des noms ou des emplacements, il se soucie du numéro majeur pour qu'il puisse sélectionner le bon pilote, et le pilote se soucie (généralement) du numéro mineur pour pouvoir sélectionner le bonne instance.

La plupart des noms sont simplement conventionnels (bien que certains soient définis par POSIX ). Notez également qu'un seul périphérique peut s'inscrire pour plusieurs numéros principaux, vérifiez le sdpilote /proc/devices; un nom de module de pilote ( .ko) ne doit pas nécessairement être le même que le nom de périphérique, et pas nécessairement le même que le nœud de périphérique /dev, et un seul module de pilote peut gérer plusieurs périphériques logiques / physiques ou noms de périphérique.


Pour récapituler: vous pouvez avoir deux ou plusieurs nœuds de périphérique (dans /dev/ou ailleurs) qui ont le même majeur: des numéros mineurs, mais s'ils sont du même type, ils se réfèrent au même périphérique. Vous pouvez avoir un pilote qui peut gérer plusieurs instances majeures, mais au sein du noyau et au sein du pilote, pour chaque type (caractère ou bloc), le numéro majeur: mineur est pris pour faire référence à un périphérique spécifique (majeur) et à une instance spécifique ( mineur) de l'appareil.

Vous ne pouvez pas avoir deux nœuds de périphérique de même type et majeur: mineur et attendez-vous à ce qu'ils accèdent à deux périphériques logiques ou physiques différents. Lorsqu'un périphérique est accédé, le noyau sélectionne un pilote en fonction du type et du numéro principal (et non en fonction du nom du nœud du périphérique), et par convention, le numéro mineur sélectionne de manière déterministe une instance ou une sous-fonction spécifique.


Mise à jour Une histoire intéressante et une certaine perspective * BSD peuvent être trouvées dans la présentation BSDCon 2002 de Poul-Henning Kamp : https://www.usenix.org/legacy/events/bsdcon/full_papers/kamp/kamp_html/

Si vous remontez dans le temps jusqu'en 1978 (avec la permission d'Alcatel-Lucent, le journal technique de Bell System juillet-août 1978), le « système de partage du temps Unix » le définit clairement (p1937):

Les périphériques sont caractérisés par un numéro de périphérique majeur, un numéro de périphérique mineur et une classe (bloc ou caractère). Pour chaque classe, il existe un tableau de points d'entrée dans les pilotes de périphérique. Le numéro de périphérique principal est utilisé pour indexer le tableau lors de l'appel du code d'un pilote de périphérique particulier. Le numéro de périphérique mineur est transmis au pilote de périphérique comme argument. Le numéro mineur n'a d'autre signification que celle que lui attribue le conducteur. Habituellement, le pilote utilise le numéro mineur pour accéder à l'un des plusieurs périphériques physiques identiques.

Mr Spuratic
la source
Alors pouvons-nous avoir deux appareils avec la même paire ou le même MAJ:Minnuméro
Dipak Ingole
1
Oui, avec des contraintes. Mise à jour.
mr.spuratic
2

Lorsqu'un fichier de périphérique est créé par mknode, les numéros majoret minorsont fournis. C'est ainsi que Linux identifie le périphérique matériel sous-jacent associé à un fichier de périphérique. Dans la plupart des cas, leur majornuméro identifie le pilote tandis que le minordistingue les différents appareils contrôlés par le pilote.

En tant que tels, les numéros doivent être uniques pour chaque appareil ou il ne serait pas possible de créer des fichiers d'appareil corrects pour chacun d'eux.

Graeme
la source
0

Non, sous Linux, ils ne sont pas toujours uniques.

Linux utilise un devptssystème de fichiers virtuel pour fournir des pseudoterminaux (ptys), et ce système de fichiers virtuel peut être monté plusieurs fois et à différents endroits, ce qui est pratique lors de la configuration de chroots ou de conteneurs d'espace de noms. Bien qu'un major:minortuple soit unique sur une devptsinstance de système de fichiers, il n'est pas unique sur un système en cours d'exécution:

# 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

Dans l'exemple ci-dessus, la script(1)commande crée un pseudo-terminal et exécute un shell à l'intérieur. Il est sacrément évident que le pseudo-terminal créé par le premier scriptprocessus n'est pas le même que celui créé par le second, mais ils ont le même nom et des numéros mineurs et majeurs.

Afin d'identifier de manière unique un pseudoterminal, vous devez utiliser leur device:inodetuple ou combiner le numéro de périphérique (du système de fichiers devpts) avec leur major:minor. Le problème est que le champ "tty" du /proc/PID/stat(le 7, voir la proc(5)page de manuel; c'est là que les outils aiment lsofou psobtiennent leurs informations) ne contient que le st_rdevdu tty (le packé major:minor); si c'est un esclave pty, il n'y a aucune indication sur le devptssystème de fichiers qui le fournit. Les mêmes problèmes affectent le numéro de périphérique pouvant être obtenu avec l' TIOCGDEVioctl.

AFAICS, il n'existe aucun moyen fiable d'identifier le terminal de contrôle d'un processus sous Linux. Corrections et suggestions sinon bienvenues!

mosvy
la source