Алексей Федорчук
Необходимость в этой заметке я ощутил во время сочинения интермедии в цикле про DragonFly, конкретно — про модели именования её устройств. Поскольку в этой операционке, как и в Linux’е, номенклатура дисковых накопителей давно уже не сводится к каноническим именам так называемого «верхнего уровня» (/dev/sd?#
в Linux’е, /dev/ad#
или /dev/da#
— во FreeBSD и DragonFly), о которых повествуется в «толстых» книжках (тем более что последним из таковых на русском языка скоро стукнет десять лет).
На истории «номенклатурного вопроса» в Linux’е останавливаться не буду — она достаточно подробно изложена в книжке по истории мира FOSS, которая (всё ещё) готовится к размещению в Библиотеке Блогосайта. Которое сложилось вследствие внедрения udev
и последующей разработки объединённой подсистемы ATA-SCSI, поддерживающей любые накопители — PATA, SATA, eSATA, SCSI, SAS, USB. И её рамках номенклатура накопителей в Linux полностью унифицировалась. Вне зависимости от типа их интерфейса, внешнего или внутреннего исполнения, файл дискового устройства стал выглядеть как /dev/sd?
, где ?
— литера (латинского алфавита) в порядке подключения к дисковому контроллеру:
- сначала к внутренним SATA-разъёмам,
- затем к дополнительному PATA-разъёму,
- и наконец, к внешним разъёмам eSATA и USB.
Правила нумерации разделов на дисках при использовании разметки в стиле msdos остались без изменения:
- файлы устройств первичных разделов, включая и тот, которому присвоен идентификатор расширенного, носят имена (например) от
/dev/sda1
до/dev/sda4
; - логические разделы в Extended partition по прежнему именуются от
/dev/sda5
и далее.
А при начавшей распространяться схеме разметки GPT с именами дисковых разделов стало и того проще: они получали просто сквозную нумерацию, без всякого разделения на первичные, расширенные и логическими разделы.
Некоторые очередные коррективы в номенклатуру накопителей внесло появление интерфейса SATA-III: она оказалась зависимой от его реализации в чипсетах материнских плат или внешних контроллеров. Поскольку в чипсетах Intel 7-й серии из шести каналов SATA только два поддерживают SATA-III, оказалось, что последовательность устройств зависит от режима работы SATA-контроллера. В режиме эмуляции IDE диск на первом канале SATA-III получает имя /dev/sda
, диск на первом канале SATA-II — /dev/sdb
, диск на втором канале SATA-III — /dev/sdc
. Диски на остальных каналах SATA-II маркируются в алфавитном порядке.
При переключении же SATA-контроллера в «родной» режим AHCI маркировка дисков становится сквозной: /dev/sda
и /dev/sdb
— диски на каналах SATA-III, /dev/sdc
и так далее — на каналах SATA-II.
Отмеченные разночтения в именовании накопителей в десктопных конфигурациях с одним-двумя дисками обычно не создают проблем для пользователя, хотя при добавлении новых накопителей или «перетасовке» имеющихся могут возникнуть некоторые осложнения, требующие перенастройки загрузчика и (или) правки файла /etc/fstab
. Потенциально проблемным может быть и обновление системы. Однако на практике с этим приходилось сталкиваться не часто. Да и с распространением Intel’овских чипсетов 8-й серии и отмиранием режима эмуляции IDE проблема вообще теряет актуальность.
Однако нынче в Linux’е применяются не только традиционные файловых системы, но и интегрированные системы размещения данных, такие, как btrfs и ZFS on Linux. Поскольку они также исполняют роль менеджеров мультидисковых устройств (подобных автономным softRAID и LVM), однозначность именования задействованных в них накопителей оказывается критически важной. Видимо, (в том числе и) поэтому наряду с «классической» номенклатурой накопителей (она именуется моделью имён верхнего уровня и поддерживается непосредственно ядром) всё более широко применяются иные модели именования. Хотя однозначность соответствия дисковых устройств их именам не менее важна и для упомянутых выше программного RAID и LVM.
Благо, правила менеджера устройств udev
позволяют определять и другие модели идентификации накопителей. В частности, штатными средствами дисковой разметки некоторых дистрибутивов (в частности, системой YaST в openSUSE) предусмотрены такие варианты, как идентификация по:
- метке тома (
by-label
), - идентификатору диска (
by-id
), - пути к дисковому устройству (
by-path
), - наконец, по пресловутому универсальному уникальному идентификатору, Universally Unique IDentifier (
by-uuid
).
Есть ещё несколько моделей идентификации накопителей, вроде by-partlabel
или by-partuuid
, но с примерами практического использования их я не сталкивался, и говорить не буду.
С идентификацией по метке тома, вероятно, многие из читателей моего сочинения знакомы — этот метод использовался задолго до появления не только udev
, но даже devfs
. Метка (label
— не путать с disk label, то есть схемой дисковой разметки) — это просто некоторое условное имя, желательно мнемонически прозрачное. Оно присваивается дисковым разделам — либо пользователем вручную при разметке, либо генерируется автоматически инсталляторами некоторых дистрибутивов. Список «помеченных» разделов в системе можно просмотреть так:
# ls -l /dev/disk/by-label lrwxrwxrwx ... raidboot -> ../../md0 lrwxrwxrwx ... raidroot -> ../../md1
Из этого вывода легко понять, что метки (как и все остальные имена устройств, о которых речь пойдёт ниже)— это символические ссылки на файл «верхнего уровня» (в примере — на программные RAID).
Метки тома является атрибутом раздела и не зависят от изменения имён верхнего уровня при реконфигурировании машины. Поэтому во многих случаях их удобно использовать для автоматического монтирования файловых систем, фигурирующих в файле /etc/fstab
. Однако по умолчанию, насколько я знаю, ни в одном дистрибутиве Linux они не используются.
В последние годы большинство пользователей имели удовольствие ознакомиться и с идентификацией дисков и разделов по UUID — с лёгкой руки разработчиков Ubuntu по умолчанию именно они используются для описания автоматически монтируемых файловых систем во многих современных дистрибутивах.
UUID’ы представляют собой зубодробительные 128-битные числа, генерируемые для накопителей и их разделов по правилам, описываемым в библиотеке libuuid
, и выглядят (в шестнадцатеричной системе счисления) примерно так:
# ls -l /dev/disk/by-uuid итого 0 lrwxrwxrwx ... 1218e946-7f6b-4e27-beea-07fc6c06bf7a -> ../../sdc2 lrwxrwxrwx ... 2eec0b23-343f-4e3d-8507-dd042c876a60 -> ../../md0 lrwxrwxrwx ... 329f123c-17d6-4431-b4f1-583a7f59d8db -> ../../sdd1 lrwxrwxrwx ... 380c1570-d039-4ac6-ac6a-81321ea465d9 -> ../../sdc4 lrwxrwxrwx ... 9a76161d-ef7b-4a0d-afc8-c54e68857fee -> ../../sdc5 lrwxrwxrwx ... e63a68da-eb73-490b-b056-01c4945dca13 -> ../../md1 lrwxrwxrwx ... e8304d6c-a136-4c97-87d4-cb9a456af791 -> ../../sdc3
Общее количество уникальных идентификаторов исчисляется величиной 2128, что гарантирует от случайного их повторения, откуда и его название. Однако для человеческого восприятия UUID весьма сложны, и лишены всякой мнемоники. Почему их и нельзя считать самыми удобными средствами именования носителей. Кстати, в ZFS UUID’ы, по каким-то причинам, не используются.
Если с моделями именования by-label
и by-uuid
, как я уже говорил, мой потенциальный читатель наверняка так или иначе сталкивался, то рискну предположить, что с идентификацией by-path
и by-id
дела, скорее всего, не общался. Я, например, долгое время знал о них только по наслышке — пока не начал плотное знакомство.
Модель именования by-path
использует имена устройств, привязанные к их положению на шине PCI и включающие номер шины и канала на ней, примерно по тому же принципу, что и при использовании devfs
(кто помнит, как оно было). Практически это выглядит примерно так:
# ls -l /dev/disk/by-path итого 0 lrwxrwxrwx ... pci-0000:00:1f.2-scsi-0:0:0:0 -> ../../sda lrwxrwxrwx ... pci-0000:00:1f.2-scsi-0:0:0:0-part1 -> ../../sda1 lrwxrwxrwx ... pci-0000:00:1f.2-scsi-0:0:0:0-part2 -> ../../sda2 lrwxrwxrwx ... pci-0000:00:1f.2-scsi-0:0:0:0-part3 -> ../../sda3 lrwxrwxrwx ... pci-0000:00:1f.2-scsi-1:0:0:0 -> ../../sdb lrwxrwxrwx ... pci-0000:00:1f.2-scsi-1:0:0:0-part1 -> ../../sdb1 lrwxrwxrwx ... pci-0000:00:1f.2-scsi-1:0:0:0-part2 -> ../../sdb2 lrwxrwxrwx ... pci-0000:00:1f.2-scsi-1:0:0:0-part3 -> ../../sdb3
Легко догадаться, что дисковые разделы маркируются добавлением к имени устройства суффикса part#
.
Модель именования by-path
идентифицирует устройства вполне однозначно, и особенно эффективна при наличии более чем одного дискового контроллера. Однако сами имена и устройств, и разделов описываются довольно сложной для восприятия последовательностью (хотя, в отличие от UUID, и не лишённой простой человеческой логики).
Модель идентификации by-id
представляет имена носителей информации в форме, наиболее доступной для людского понимания. Они образованы из названия интерфейса, имени производителя, номера модели, серийного номера устройства и, при наличии раздела, номера такового:
# ls -l /dev/disk/by-id 22:07 pts/4 итого 0 lrwxrwxrwx 1 ... ata-SanDisk_SDSSDX120GG25_120823400863 -> ../../sda lrwxrwxrwx 1 ... ata-SanDisk_SDSSDX120GG25_120823400863-part1 -> ../../sda1 lrwxrwxrwx 1 ... ata-SanDisk_SDSSDX120GG25_120823400863-part2 -> ../../sda2 lrwxrwxrwx 1 ... ata-SanDisk_SDSSDX120GG25_120823400863-part3 -> ../../sda3 lrwxrwxrwx 1 ... ata-SanDisk_SDSSDX120GG25_120823402786 -> ../../sdb lrwxrwxrwx 1 ... ata-SanDisk_SDSSDX120GG25_120823402786-part1 -> ../../sdb1 lrwxrwxrwx 1 ... ata-SanDisk_SDSSDX120GG25_120823402786-part2 -> ../../sdb2 lrwxrwxrwx 1 ... ata-SanDisk_SDSSDX120GG25_120823402786-part3 -> ../../sdb3
Таким образом, все компоненты имени устройства в модели by-id
не определяются условиями его подключения и не вычисляются по каким-то заумным правилам, а определяются производителем и жёстко прошиты в «железе». Более того, они практически не зависят и от операционной системы — в этом легко убедиться, сравнив имена устройств by-id
в Linux’е и DragonFly. А потому эта модель является наиболее однозначной для именования устройств. Что немаловажно, она строится по понятной человеку логике и относительно легко укладывается в нормальной голове. Не случайно именно она принята по умолчанию, например, в модуле дисковой разметки системы YaST2 дистрибутива openSUSE — самом мощном и логичном из высокоуровневых инструментов этого назначения.