udev − динамическое управление устройствами
udev предоставляет системному программному обеспечению события устройств, управляет правами доступа к файлам устройств и может создавать дополнительные символические ссылки в каталоге /dev, или переименовывать сетевые интерфейсы. Ядро обычно просто назначает непредсказуемые имена устройств, основываясь на порядке обнаружения. Смысл символических ссылок и имён сетевых устройств позволяют надёжно идентифицировать устройства, основываясь на их свойствах или текущей конфигурации.
Демон udev, systemd−udevd.service(8), принимает события устройства прямо от ядра, каждый раз при добавлении или удалении устройства из системы или при изменении его состояния. Когда udev принимает событие устройства, оно сравнивается с настроенным набором правил на предмет совпадения различных атрибутов устройства, идентифицирующих его. Совпадающие правила могут предоставлять дополнительную информацию об устройстве, хранящуюся в базе данных udev или используемую для создания осмысленных имён символических ссылок.
Вся обработанная udev информация сохраняется в базе данных udev и отправляется возможным подписчикам на событие. Доступ ко всем сохранённым данным и исходным событиям предоставляется библиотекой libudev.
Правила udev читаются из файлов, находящихся в системном каталоге правил /lib/udev/rules.d/, из особого каталога правил /run/udev/rules.d/ и из местного каталога администрирования /etc/udev/rules.d/. Все файлы правил совместно сортируются и обрабатываются в алфавитном порядке, вне зависимости от каталога, из которого они взяты. Однако, файлы с одинаковыми именами заменяют друг друга. Файлы в каталоге /etc имеют наивысший приоритет, файлы в каталоге /run имеют приоритет над файлами с таким же именем из каталога /lib. Это используется чтобы при необходимости заменить системные файлы правил на местные; символические ссылки в каталоге /etc с именем как у файла правил из каталога /lib, указывающие на /dev/null, целиком отключают файл правил. Файлы правил должны иметь расширение .rules, а другие расширения игнорируются.
Каждая строка в файле правил содержит по меньшей мере одну пару ключ−значение. Исключение − пустые строки и строки, начинающиеся с символа "#", которые игнорируются. Есть два вида ключей: сравнения и назначения. Если все сравнивающие ключи совпадают с их значениями, то правило применяется и назначает ключам указанные назначаемые значения.
Совпадающие правила могут переименовать сетевой интерфейс, добавить символическую ссылку, указывающую на файл устройства, или запустить указанную программу для обработки события.
Правило может состоять из списка из одной и более пар ключ−значение, разделённых запятыми. Каждый ключ обладает определённым действием, зависящим от используемого оператора. Правильными операторами являются:
"=="
Сравнить на равенство.
"!="
Сравнить на неравенство.
"="
Назначить значение ключу. Ключи, которые представляются списком, сбрасываются, их значением становится единственное указанное значение.
"+="
Добавляет значение к ключу, который содержит список элементов.
":="
Назначает ключу окончательное значение, запрещая дальнейшие изменения.
Следующие имена ключей могут использоваться для совпадения со свойствами устройства. Некоторые из ключей также совпадают со свойствами родительских устройств в sysfs, не только с устройством, которое произвело событие. Если в одном правиле указано несколько ключей, совпадающих с родительским устройством, все эти ключи должны совпадать с ним или с родительским устройством.
ACTION
Совпадает с именем произошедшего события.
DEVPATH
Совпадает с путём к файлу устройства для данного события.
KERNEL
Совпадает с названием устройства в событии.
NAME
Совпадает с именем узла или сетевого интерфейса. Ключ NAME может использоваться сразу после установки в одном из предыдущих правил.
SYMLINK
Совпадает с именем символической ссылки, указывающей на файл устройства. Может использоваться сразу после установки SYMLINK одним из предыдущих правил. Здесь может быть несколько символических ссылок, но достаточно только одного совпадения.
SUBSYSTEM
Совпадает с подсистемой, в которой произошло событие на устройстве.
DRIVER
Совпадает с именем дрйвера, на котором произошло событие. Совпадают только те устройства, которые были подключены к драйверу в момент генерации события.
ATTR{имя_файла}
Совпадает со значениями атрибута sysfs из события на устройстве. Завершающие пробельные символы в значениях атрибутов игнорируются, если указанное подходящее значение само не содержит пробельный символ.
KERNELS
Восходящий поиск подходящего имени устройства в пути к устройству.
SUBSYSTEMS
Восходящий поиск подходящего имени подсистемы в пути к устройству.
DRIVERS
Восходящий поиск подходящего названия драйвера в пути к устройству.
ATTRS{имя_файла}
Восходящий поиск значений атрибутов в sysfs в пути к устройству. Если указано несколько условий совпадения ATTRS, то все они должны совпадать с одним и тем же устройством. Завершающие пробельные символы в значениях атрибутов игнорируются, если указанное подходящее значение само не содержит пробельный символ.
TAGS
Восходящий поиск подходящей метки устройства в пути к устройству.
ENV{ключ}
Совпадает со значением свойства устройства.
TAG
Совпадает с меткой устройства.
TEST{восьмеричная_маска_доступа}
Проверить существование файла. Если необходимо, может быть указана восьмеричная маска доступа.
PROGRAM
Выполнить внешнюю программу для определения наличия совпадения. Ключ − истина, если программа завершается успешно. Все свойства устройства доступны выполняемой программе через переменные окружения. Стандартный вывод программы доступен в ключе RESULT.
Может использоваться только для очень быстро работающих интерактивных задач. За деталями обратитесь к RUN.
RESULT
Совпадение со строкой, возвращённой последним вызовом PROGRAM. Этот ключ может использоваться в том же или в любом более позднем правиле после вызова PROGRAM.
Большинство полей поддерживают совпадение с шаблонами в стиле shell. Поддерживаются следующие символы шаблонов:
"*"
Совпадает с нулём или любым количеством символов.
"?"
Совпадает с любым единственным символом.
"[]"
Совпадает с любым из символов, указанным внутри квадратных скобок. Например, строка с шаблоном ´tty[SR]´ будет совпадать с ´ttyS´ или ´ttyR´. Также шаблоном поддерживаются диапазоны, которые задаются символом ´−´. Например, для совпадения с любой цифрой можно использовать шаблон [0−9]. Если первый символ, следующий за ´[´ − это ´!´, совпадают любые символы вне диапазона.
Следующие ключи могут принимать назначаемые значения:
NAME
Имя для сетевого интерфейса. Обратитесь к systemd.link(5) за описанием вышеуровневого механизма настройки имени интерфейса. Имя файла устройства не может быть изменено udev, но он может создать дополнительные символические ссылки.
SYMLINK
Имя символической ссылки, указывающей на файл устройства. Каждое подходящее правило добавляет это значение к списку создаваемых символических ссылок.
Набор символов для имени символических ссылок ограничен. Разрешены символы "0−9A−Za−z#+−.:=@_/", правильные последовательности символов UTF−8 и шестнадцатеричное кодирование "\x00". Все остальные символы заменяются символом "_".
Можно указать несколько символических ссылок, разделив их символом пробела. В случае нескольких устройств, претендующих на одно и то же имя, ссылка всегда будет указывать на устройство с наивысшим приоритетом link_priority. Если текущее устройство пропадает, ссылки будут вычислены заново и владельцем ссылки станет устройство со следующим наибольшим значением приоритета link_priority. Если приоритет ссылки link_priority не указан, порядок устройств (и которое из них будет владеть ссылкой) не определён.
Символические ссылки никогда не должны конфликтовать с именами устройств, назначаемыми ядром по умолчанию, поскольку это может привести к непредсказуемому поведению.
OWNER, GROUP, MODE
Права доступа к файлу устройства. Каждое из указанных значений заменяет значения по−умолчанию, заданные в процессе компиляции.
SECLABEL{модуль}
Применить указанную метку модуля безопасности Linux (Linux Security Module) к указанному фаул устройства.
ATTR{ключ}
Значение должно быть записано в атрибут sysfs события устройства.
ENV{ключ}
Задать значение свойства устройства. Имена свойств, начинающиеся с "." не сохраняются в базе данных и не экспортируются в событие или внешние утилиты (запущенные, например, ключом совпадения PROGRAM).
TAG
Присоединить метку к устройству. Полезно для фильтрации событий пользователями функций наблюдения libudev или для нумерации групп помеченных устройств. Реализация может работать эффективно только если к устройству присоединены небольшое количество меток. Метки подходят для использования в контексте фильтрации особенных устройств, но не в качестве флага для обычного использования. Чрезмерное использование может привести к неэффективности обработки событий.
IMPORT{тип}
Добавить программу к списку программ, выполняемых после обработки всех правил для указанного события, в зависимости от "типа".
"program"
Выполнить внешнюю программу, указанную в качестве назначаемого значения. Если не указан абсолютный путь, ожидается что программа находится в /lib/udev; в противном случае должен быть указан абсолютный путь.
По умолчанию, если не указан тип.
"builtin"
Как и в случае program, но использовать встроенную программу вместо внешней.
Имя программы и последующие агрументы разделяются пробелами. Если аргументы содержат пробелы, можно использовать одиночные кавычки.
Может использоваться только для быстро работающих интерактивных задач. Запуск обработки события на долгий период времени может заблокировать все последующие события на этом или зависимом устройстве.
udev не подходит для запуска демонов или других долго работающих процессов; разделившиеся процессы, отсоединившиеся или нет, безусловно завершаются после завершения обработки события.
LABEL
Именованная метка, на которую можно перейти из GOTO.
GOTO
Переход на следующую метку LABEL с совпадающим именем.
IMPORT{тип}
Импорт множества переменных как свойств устройства, в зависимости от типа:
"program"
Выполнить внешнюю программу, указанную в значении, и импортировать её вывод, который должен иметь формат переменных окружения. Указание пути, разделение команды и аргументов и кавычки обрабатываются как в случае RUN.
"builtin"
Подобно "program", но использует встроенную программу вместо внешней.
"file"
Импортировать текстовый файл, указанный в значении, содержимое которого должно соответствовать формату переменных окружения.
"db"
Импортировать одно свойство, указанное в качестве назначаемого значения из базы данных текущего устройства. Работает только в случае если база данных уже заполнена предыдущим событием.
"cmdline"
Импортировать одно свойство из командной строки ядра. В случае простых флагов свойству присваивается значение "1".
"parent"
Импортировать сохранённые ключи из родительского устройства, прочитав базу данных родительского устройства. Значение, присваиваемое IMPORT{parent}, используется в качестве фильтра имён импортируемых ключей (в том же стиле, в котором происходит сравнение с шаблонами shell).
Может использоваться только для быстро работающих интерактивных задач. За подробностями обратитесь к RUN.
WAIT_FOR
Подождать, когда файл станет доступным или когда истекут 10 секунд. Путь относителен устройства sysfs. Если путь не указан, ожидать появления атрибута.
OPTIONS
Правило и опции устройства:
link_priority=значение
Указывает приоритет созданных символических ссылок. Устройства с более высоким приоритетом заменяют существующие символические ссылки других устройств. По умолчанию 0.
event_timeout=
Количество секунд ожидания завершения действий по обработке события, до собственного завершения.
string_escape=none|replace
Обычно управляющие и другие потенциально небезопасные символы заменяются в строке, используемой для именования устройства. Режим замены можно указать с помощью данной опции.
static_node=
Применить права, указанные в правиле к статическому файлу стройства с указанным именем. Также, для каждой указанной в правиле метки, создать символическую ссылку в каталоге /run/udev/static_node−tags/метка, указывающую на статический файл устройства с указанным именем. Создание файла статического устройства производится systemd−tmpfiles перед запуском systemd−udevd. Статические файлы устройств могут не иметь соответствующего устройства в ядре, они используются для автоматической загрузки модуля ядра при доступе к таким файлам устройств.
watch
Наблюдать за файлом устройства при помощи inotify. Когда файл устройства будет закрыт после того, как он был открытым для записи, синтезировать событие uevent об изменении.
nowatch
Отключить наблюдение за файлом устройства через inotify.
Поля NAME, SYMLINK, PROGRAM, OWNER, GROUP, MODE и RUN поддерживают простую подстановку. Подстановка в RUN производится после обработки всех правил, но перед запуском программы. Это позволяет использовать полный набор свойств устройства, совпавших с более ранними правилами. Для всех других полей подстановка выполняется в процессе обработки правила. Доступны следующие подстановки:
$kernel, %k
Имя, выданное ядром данному устройству.
$number, %n
Номер, выданный ядром данному устройству. Например, ´sda3´ имеет номер ´3´.
$devpath, %p
Путь к устройству.
$id, %b
Имя устройства, совпавшее в процессе восходящего поиска в пути к устройству с SUBSYSTEMS, KERNELS, DRIVERS и ATTRS.
$driver
Имя драйвера устройства, совпавшего в процессе восходящего поиска в пути к устройству с SUBSYSTEMS, KERNELS, DRIVERS и ATTRS.
$attr{файл}, %s{файл}
Значение атрибута устройства, найденное в sysfs, где все ключи в правиле совпали. Если все совпадающие устройства не имеют такого атрибута, а предыдущие проверки KERNELS, SUBSYSTEMS, DRIVERS или ATTRS выбрали родительское устройство, то будет использоваться атрибут родительского устройства.
Если атрибут − это символическая ссылка, в качестве значения возвращается последний элемент цели символической ссылки.
$env{ключ}, %E{ключ}
Значение свойства устройства.
$major, %M
Старший номер, выданный устройству ядром.
$minor, %m
Младший номер, выданный устройству ядром.
$result, %c
Строка, возвращённая внешней программой, вызванной из PROGRAM. Одна часть строки, отделённая пробелом, может быть выбрана указанием номера части в виде атрибута: %c{N+}. Если за числом следует символ "+", в результирующую строку будут подставлены эта часть и все, следующие за ней: %c{N+}
$parent, %P
Имя файла родительского устройства.
$name
Текущее имя файла устройства. Если имя не было изменено правилом, то это имя устройства, данное ядром.
$links
Список текущих символических ссылок, разделённых пробелами. Значение назначается только в процессе события удаления или если предыдущее правило назначило значение.
$root, %r
Значение udev_root.
$sys, %S
Точка монтирования sysfs.
$devnode, %N
Имя файла устройства.
%%
Символ процента − "%".
$$
Символ доллара − "$".
Файлы hwdb читаются из файлов, находящихся в системном каталоге hwdb /lib/udev/hwdb.d, в каталоге, изменяемом в процессе работы − /run/udev/hwdb.d и в локальном каталоге администрирования − /etc/udev/hwdb.d. Все файлы hwdb совместно сортируются и обрабатываются в алфавитном порядке, вне зависимости от каталога, в которых они лежат. Однако, файлы с одинаковыми именами заменяют друг друга. Файлы в каталоге /etc имеют наивысший приоритет, файлы в каталоге /run предпочитаются файлам с таким же именем в каталоге /lib. При необходимости они могут использоваться для замены файлов hwdb, предоставляемых системой, на локальные файлы. Символическая ссылка в каталоге /etc с таким же именем как hwdb−файл в каталоге /lib, указывающая на /dev/null, отключает hwdb−файл целиком. hwdb−файлы должны иметь расширение .hwdb, а другие расширения игнорируются.
Файлы hwdb содержат записи данных, состоящие из сопоставляющих и назначающих пар ключ−значение. Каждая запись в hwdb начинается с одной или более строк совпадения, указывающих шаблон оболочки shell для сравнения с базой данных строки поиска. Несколько строк сопоставления указываются в дополнительных последующих строках. Каждая строка совпадения сравнивается индивидуально, они комбинируются логической операцией ИЛИ. Каждая совпадающая строка должна начинаться на первом символе строки.
Совпадающие строки продолжаются одной или более строками с парами ключ−значение, которые распознаются по ведущему символу пробела. Имя ключа и имя значения разделяются символом "=". Пустые строки обозначают конец записи. Строки, начинающиеся с символа "#", игнорируются.
Содержимое всех файлов hwdb читается udevadm(8) и компилируется в двоичный файл базы данных, находящейся в файле /etc/udev/hwdb.bin или в файле /lib/udev/hwdb.bin, если нужно поместить скомпилированную базу данных в неизменяемый образ. В процессе работы используется только двоичная база данных.
systemd−udevd.service(8), udevadm(8)systemd.link(5)
Перевод на русский язык выполнил Владимир Ступин <vladimir@stupin.su>.