Являются ли основной, младший номер уникальным


11

Является 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 

maj - аппаратное обеспечение, второстепенное - подразделение основного аппаратного обеспечения
Kiwy

Ответы:


20

Из интерфейса программирования Linux , §14.1

Каждый файл устройства имеет основной идентификационный номер и вспомогательный идентификационный номер. Основной идентификатор идентифицирует общий класс устройства и используется ядром для поиска соответствующего драйвера для этого типа устройства. Дополнительный идентификатор однозначно идентифицирует конкретное устройство в общем классе. Основные и второстепенные идентификаторы файла устройства отображаются командой ls -l.

[...]

Каждый драйвер устройства регистрирует свою связь с конкретным идентификатором основного устройства, и эта связь обеспечивает соединение между специальным файлом устройства и устройством. Имя файла устройства не имеет значения, когда ядро ​​ищет драйвер устройства.

См. Также эту старую (2001 г. ) главу « Драйверы устройств Linux» (2e) .

то есть цель состоит в том, чтобы обеспечить уникальное сопоставление основных: второстепенных для устройства: экземпляра для каждого типа устройства. Строго говоря, у вас может быть два разных устройства с одним и тем же мажором: второстепенное, если одно - char, а другое - 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

В Linux в любой момент времени на одной системе главное: младшие номера для каждого типа устройства уникальны. Однако числа могут меняться со временем и не обязательно должны быть одинаковыми в разных системах Linux (даже в одном и том же дистрибутиве, ядре и оборудовании). Обратите внимание, что символьные и блочные устройства имеют разные пространства нумерации, например, основной номер 1 назначен дискам RAM, основной номер 1 назначен набору устройств ядра, включая ноль и ноль.

Исторически основные устройства были (в основном) статически распределены через реестр (также все еще присутствует, хотя и не поддерживается, в исходном коде ядра Documentation/devices.txt). В наши дни многие устройства распределяются динамически, этим управляет udev и отображаемые в них отображения /proc/devices. Фиксированные устройства все еще существуют incude/uapi/linux/major.h(недавно перенесены из include/major.h)

Теперь, хотя основная и второстепенная комбинации однозначно идентифицируют конкретные экземпляры устройства, ничто не мешает вам создать несколько узлов (файлов) устройств, которые ссылаются на одно и то же устройство. Их даже не нужно создавать /dev(но они должны быть в файловой системе, которая поддерживает создание узлов устройства и не монтируется с nodevопцией).

Обычно используется создание дублирующих нулевых, нулевых и случайных устройств в 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

Имена являются просто псевдонимами, ядро ​​не заботится о большинстве имен или расположений, оно заботится о старшем номере, чтобы оно могло выбрать правильный драйвер, а драйвер (обычно) заботится о младшем номере, чтобы он мог выбрать правильный экземпляр.

Большинство имен просто условны (хотя некоторые определены в POSIX ). Также обратите внимание, что одно устройство может зарегистрироваться для нескольких основных номеров, проверьте sdдрайвер в /proc/devices; имя модуля драйвера ( .ko) не обязательно должно совпадать с именем устройства и не должно совпадать с именем узла устройства /dev, а один модуль драйвера может управлять несколькими логическими / физическими устройствами или именами устройств.


Напомним: у вас может быть два или более узла устройства (внутри /dev/или в другом месте), которые имеют одинаковые основные: второстепенные номера, но если они одного типа, они относятся к одному и тому же устройству. Вы можете иметь один драйвер, который может обрабатывать несколько основных экземпляров, но внутри ядра и внутри драйвера, для каждого типа (символ или блок) основной: младший номер используется для ссылки на конкретное устройство (основной) и конкретный экземпляр ( несовершеннолетний) устройства.

У вас не может быть двух узлов устройств с одинаковым типом и основным: второстепенным и ожидающим, что они получат доступ к двум различным логическим или физическим устройствам. Когда к устройству обращаются, ядро ​​выбирает один драйвер на основе типа и основного номера (а не на основании имени узла устройства), и по соглашению младший номер детерминистически выбирает конкретный экземпляр или подфункцию.


Обновление Немного интересной истории и перспективы * BSD можно найти в презентации BSDCon от Poul-Henning Kamp's 2002 : https://www.usenix.org/legacy/events/bsdcon/full_papers/kamp/kamp_html/

Если вы вернетесь назад во времени к 1978 году (любезно предоставлено Alcatel-Lucent, Технический журнал Bell System, июль-август 1978 года), « Система разделения времени Unix » четко излагает это (p1937):

Устройства характеризуются основным номером устройства, второстепенным номером устройства и классом (блок или символ). Для каждого класса имеется массив точек входа в драйверы устройств. Основной номер устройства используется для индексации массива при вызове кода для конкретного драйвера устройства. Дополнительный номер устройства передается драйверу устройства в качестве аргумента. Младший номер не имеет никакого значения, кроме того, что приписывается ему водителем. Обычно драйвер использует младший номер для доступа к одному из нескольких идентичных физических устройств.


Итак, можем ли мы иметь два устройства с одинаковой парой или MAJ:Minномером
Dipak Ingole

1
Да, с ограничениями. Обновлено.
mr.spuratic

2

Когда файл устройства создается mknode, то majorи minorномера поставляются. Вот как Linux идентифицирует основное аппаратное устройство, связанное с файлом устройства. В большинстве случаев их majorчисло идентифицирует драйвер, в то время как minorразличает различные устройства, которыми управляет драйвер.

Таким образом, номера должны быть уникальными для каждого устройства, иначе было бы невозможно создать правильные файлы устройства для всех них.


0

Нет, в 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процессом, отличается от псевдотерминала , созданного вторым процессом, но они имеют то же имя и старшие, младшие номера.

Чтобы однозначно идентифицировать псевдотерминал, вам нужно использовать их device:inodeкортеж или объединить номер устройства (в файловой системе devpts) с их major:minor. Проблема в том, что поле «tty» /proc/PID/stat(7-е, см. proc(5)Справочную страницу; именно там инструменты любят lsofили psполучают свою информацию) содержит только st_rdevtty (упакованный major:minor); если это pty-раб, нет никаких указаний для devptsфайловой системы, которая его предоставляет. Те же проблемы влияют на номер устройства, который можно получить с помощью TIOCGDEVioctl.

AFAICS Нет надежного способа идентифицировать управляющий терминал процесса в Linux. Исправления и предложения в противном случае приветствуются!

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.