udev (Русский)

udev — работающая в пространстве пользователя система, с помощью которой системный администратор может создавать обработчики событий. События, получаемые udev, обычно генерируются ядром Linux в ответ на физические события, происходящие с периферийными устройствами. Например, при обнаружении периферийных устройств или "горячем" подключении udev может выполнить определённые действия, в том числе и вернуть управление ядру, если необходима загрузка модулей или прошивок.

Состояние перевода: На этой странице представлен перевод статьи udev. Дата последней синхронизации: 11 июля 2021. Вы можете помочь синхронизировать перевод, если в английской версии произошли изменения.

Подобно предшественникам, утилитам devfsd и hotplug, udev управляет файлами устройств в каталоге /dev, добавляя их, переименовывая и создавая символические ссылки. udev полностью замещает функционал hotplug и hwdetect.

Обработка событий в udev происходит параллельно, что теоретически улучшает производительность старых систем. С другой стороны, это может усложнить администрирование. Так, при перезапуске системы порядок загрузки модулей ядра может измениться, а при наличии в машине нескольких блочных устройств могут поменяться названия их файлов. Например, для системы с двумя жёсткими дисками файл /dev/sda после перезагрузки может превратиться в /dev/sdb.

Установка

udev входит в состав systemd и установлен по умолчанию. Подробнее см. systemd-udevd.service(8).

Существует также отдельный от systemd форк, который можно установить с пакетом eudevAUR или eudev-gitAUR.

О правилах udev

Создаваемые системным администратором правила udev хранятся в каталоге . Названия файлов правил должны заканчиваться суффиксом .rules. Правила из пакетов программ при установке помещаются в каталог . Если в каталогах и находятся два файла правил с одинаковыми именами, то файл в будет иметь приоритет.

Правила udev подробно описаны в руководстве udev(7). Также стоит изучить статью Создание правил udev (англ.) и приведённые в ней практические примеры: Создание правил udev - Примеры (англ.).

Пример правила udev

Ниже приведён пример правила, которое создаёт символическую ссылку /dev/video-cam, когда к компьютеру подключается веб-камера.

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

Мы используем параметры веб-камеры KERNEL=="video2" и , затем мы возьмем идентификаторы производителя и изделия родительского USB-устройства , и для сопоставления:

В примере мы создали символическую ссылку, используя параметр SYMLINK+="video-cam". Мы можем также легко задать владельца (), группу (), или установить права доступа к файлу ссылки ().

Если вы намереваетесь создать правило, которое делает что-нибудь при удалении устройства, имейте в виду, что атрибуты устройства могут стать недоступны. В этом случае вам необходимо использовать специальный набор переменных окружения. Чтобы отобразить эти переменные, выполните следующую команду при отсоединении устройства:

$ udevadm monitor --environment --udev

В выводе команды вы увидите значения параметров устройства, например, ID_VENDOR_ID и , которые соответствуют использованным ранее идентификаторам производителя и изделия. Правило, которое использует переменные окружения устройства, может выглядеть следующим образом:

Список атрибутов устройства

Чтобы вывести все атрибуты устройства, которые вы можете использовать в написании правил udev, выполните:

$ udevadm info --attribute-walk --name=имя_устройства

Замените текущим именем файла устройства, например, /dev/sda или .

Если вы не знаете имя файла устройства, вы можете также вывести все атрибуты по конкретному системному пути:

$ udevadm info --attribute-walk --path=/sys/class/backlight/acpi_video0

Чтобы сузить поле поиска, определите класс устройства и выполните:

$ ls /dev/класс/by-id

Найденную символическую ссылку (или файл, на который она указывает) можно использовать в параметре :

$ udevadm info --attribute-walk --name=/dev/input/by-id/usb-foostan_Corne-event-kbd

Проверка правил перед загрузкой

Используйте команду:

# udevadm test $(udevadm info -q path -n имя_устройства) 2>&1

Вы можете также указать прямой системный путь до устройства:

# udevadm test /sys/class/backlight/acpi_video0/

Загрузка новых правил

udev способен определять наличие изменений в файлах правил автоматически, поэтому изменения сразу вступают в силу без необходимости перезапуска udev. Однако, новые правила не будут применены сразу к уже подключенным устройствам. Устройства с возможностью горячей замены, например, устройства USB, могут быть просто переподключены для применения к ним новых правил. Также вы можете перезагрузить модули ядра ohci-hcd и , что автоматически приведет к перезагрузке всех драйверов для каждого USB-устройства.

Если правила не перезагружаются автоматически, выполните:

# udevadm control --reload-rules

Чтобы вручную заставить udev применить ваши правила, выполните:

# udevadm trigger

udisks

См. udisks.

Советы и рекомендации

Монтирование съёмных устройств

Монтировать съёмные устройства с помощью команды в правиле udev не стоит по двум причинам: (1) systemd по умолчанию запускает с отдельным "пространством имён монтирования" (см. namespaces(7)), что означает, что данное устройство не будет видно из остальной системы. (2) Чтобы этого не происходило, можно закомментировать параметры и в файле службы, но тогда проявится другая проблема: запускаемые udev процессы система будет убивать по истечении нескольких секунд. В случае файловых систем FUSE, вроде NTFS, "монтирование" запустит в пространстве пользователя процесс для работы с файловой системой; затем процесс будет уничтожен и при попытке доступа к ФС вы получите ошибку .

Есть несколько возможных решений:

  • Из правила udev запускается пользовательская служба systemd; служба запустит сценарий, который, в свою очередь, может породить любое количество долгосрочных процессов (вроде FUSE). В качестве примера можно использовать утилиту udev-media-automount, разработанную для быстрого и надёжного автоматического монтирования устройств. Другой вариант той же идеи предложен в этом сообщении.
  • В правилах udev вместо команды можно использовать , как рекомендуют разработчики systemd. Пример монтирования USB-дисков в каталоге :
ACTION=="add", SUBSYSTEMS=="usb", SUBSYSTEM=="block", ENV{ID_FS_USAGE}=="filesystem", RUN{program}+="/usr/bin/systemd-mount --no-block --automount=yes --collect $devnode /media"
Тем не менее, такой подход считается медленным и ненадёжным.
  • Программы вроде udisks или udiskie. Мощные утилиты, хоть и с довольно сложной настройкой. Нужно учитывать, что они работают для одного пользовательского сеанса: доступ к некоторым файловым системам предоставляется только тому пользователю, сеанс которого активен в данный момент.

Доступ к программаторам и виртуальным COM-портам

Следующий набор правил даст возможность пользователям, входящим в группу , получить доступ к USB-программаторам микроконтроллеров AVR USBtinyISP:

Идентификаторы производителя и изделия для других устройств можно узнать с помощью утилиты lsusb.

Выполнение команд при подключении VGA-монитора

Создайте правило со следующим содержимым, чтобы запускать при каждом подключении VGA-монитора:

KERNEL=="card0", SUBSYSTEM=="drm", ENV{DISPLAY}=":0", ENV{XAUTHORITY}="/home/username/.Xauthority", RUN+="/usr/bin/arandr"

Некоторые экранные менеджеры размещают файл вне домашнего каталога пользователя. В этом случае параметр ENV{XAUTHORITY} необходимо соответствующим образом изменить. Например, значение переменной для GNOME Display Manager:

Определение новых накопителей eSATA

Если ваш накопитель eSATA не был определен системой при подключении, вы можете перезагрузить систему, не отключая кабель устройства, либо, если перезагрузка нежелательна, выполнить:

# echo 0 0 0 | tee /sys/class/scsi_host/host*/scan

Еще один вариант заключается в использовании утилиты из AUR:

# scsiadd -s

Накопитель должен появиться в /dev. Если это не так, попробуйте выполнить:

# udevadm monitor

до и после вышеприведенных команд и посмотреть, происходит ли что-нибудь.

Определение внутренних портов SATA как внешних

Если вы подключили eSATA-адаптер, система все еще будет распоздавать его как внутренний SATA-накопитель. GNOME и KDE будут постоянно запрашивать пароль администратора. Следующее правило помечает все указанные SATA-порты как порты eSATA, благодаря чему обычные пользователи смогут подключать свой накопитель eSATA к этому порту как USB-накопитель без запроса пароля администратора:

Примечание: Узнать правильное значение параметра DEVPATH вы можете с помощью следующих команд (вместо /dev/sdb укажите ваше устройство):
$ udevadm info --query=path /dev/sdb
/devices/pci0000:00/0000:00:1f.2/host4/target4:0:0/4:0:0:0/block/sdb
$ find /sys/devices/ -name sdb
/sys/devices/pci0000:00/0000:00:1f.2/host4/target4:0:0/4:0:0:0/block/sdb

Установка постоянных имен устройств

Из-за асинхронного способа загрузки модулей, они инициализируются в разном порядке от загрузки к загрузке. Это приводит к случайному переименованию устройств при каждом запуске. Чтобы задать постоянные имена вашим устройствам, можно создать специальное правило udev. Смотрите также статьи Постоянные имена для блочных устройств и Настройка сети#Смена имени интерфейса.

Видеоустройства

Процедура установки веб-камеры описана в статье Webcam setup.

При загрузке веб-камерам присваиваются случайные имена вида . Рекомендуемое решение состоит в создании символических ссылок с использованием правила udev (подобно правилу в разделе #Пример правила udev):

Принтеры

Если у вас несколько принтеров, им будут случайным образом присвоены имена вида , что, например, может помешать серверу CUPS правильно настроить устройства. Вы можете создать следующее правило, которое будет создавать постоянные символические ссылки в каталогах и подобно схеме, приведенной в статье Постоянные имена для блочных устройств:

/etc/udev/rules.d/60-persistent-printer.rules
ACTION=="remove", GOTO="persistent_printer_end"
# Это не должно понадобиться
#KERNEL!="lp*", GOTO="persistent_printer_end"

SUBSYSTEMS=="usb", IMPORT{builtin}="usb_id"
ENV{ID_TYPE}!="printer", GOTO="persistent_printer_end"

ENV{ID_SERIAL}=="?*", SYMLINK+="lp/by-id/$env{ID_BUS}-$env{ID_SERIAL}"

IMPORT{builtin}="path_id"
ENV{ID_PATH}=="?*", SYMLINK+="lp/by-path/$env{ID_PATH}"

LABEL="persistent_printer_end"

Определение диска по серийному номеру

Действия с дисковыми устройствами можно выполнять на основании серийного номера , который можно узнать из вывода команды . Примерное правило udev для этого случая приведено ниже. В параметре RUN сценарию передаётся имя устройства; это сделано исключительно в иллюстративных целях:

Пробуждение при активности USB-устройства

С помощью правила udev можно настроить систему выходить из режима сна при активности USB-устройств, например, мыши или клавиатуры.

Первым делом определите идентификаторы производителя и изделия для вашего устройства:

Затем найдите, куда данное устройство подключено:

Наконец, создайте правило, которое при подключении будет изменять атрибут как для устройства, так и для USB-контроллера, к которому оно подключено:

Генерирование событий

Может быть полезно сгенерировать различные события udev. Например, вы хотите симулировать отключение USB-устройства на удалённой машине. В таких случаях, используйте udevadm trigger:

# udevadm trigger --verbose --type=subsystems --action=remove --subsystem-match=usb --attr-match="idVendor=abcd"

Эта команда симулирует отключение всех USB-устройств с указанным идентификатором поставщика .

Уведомления на рабочем столе

Заставить правильно работать из правила udev сценарий, содержащий команду , может оказаться непростой задачей, потому что уведомления не будут выводиться на рабочий стол. Ниже показано, какие файлы, команды и переменные окружения необходимо задйствовать, чтобы работала как положено.

1) Следующее правило udev запускает сценарий, создающий графическое и звуковое уведомление, когда яркость экрана меняется в зависимости от способа питания ноутбука:

/etc/udev/rules.d/99-backlight_notification.rules
# Правило на случай переключения на работу от батареи
ACTION=="change", SUBSYSTEM=="power_supply", ATTR{type}=="Mains", ATTR{online}=="0", ENV{DISPLAY}=":0", ENV{XAUTHORITY}="/home/USERNAME/.Xauthority" RUN+="/usr/bin/su USERNAME_TO_RUN_SCRIPT_AS -c /usr/local/bin/brightness_notification.sh"
# Правило на случай переключения на работу от кабеля
ACTION=="change", SUBSYSTEM=="power_supply", ATTR{type}=="Mains", ATTR{online}=="1", ENV{DISPLAY}=":0", ENV{XAUTHORITY}="/home/USERNAME/.Xauthority" RUN+="/usr/bin/su USERNAME_TO_RUN_SCRIPT_AS -c /usr/local/bin/brightness_notification.sh"
  • и необходимо заменить на имя пользователя, который запустил графический сеанс;
  • сценарий должен запускаться командой , чтобы его владельцем считался не root, а пользователь, который запустил графический сеанс и для которого будут выводиться уведомления.

2) Содержимое сценария, который запускается правилом udev:

  • , и необходимо заменить на имя и идентификатор пользователя, запустившего графический сеанс;
  • команда /usr/bin/sudo воспроизводит звуковое уведомление с помощью pulseaudio;
  • для пользователя, запустившего графический сеанс, в котором будут отображаться уведомления, необходимо определить и экспортировать три переменные окружения (, и ).

3) Загрузите/перезагрузите новое правило udev и проверьте, как оно работает, выдернув или подключив кабель питания ноутбука.

Создание долгосрочных процессов

Программы, запущенные udev, блокируют последующие события от данного устройства, а любые процессы, порождённые правилом udev, завершаются сразу после обработки события. Если вы хотите запустить долгосрочный процесс с помощью udev, то либо используйте (например, ваша_команда | at now или ), либо создайте юнит systemd, который можно запустить из правила udev.

Решение проблем

Добавление модулей в черный список

Иногда udev может ошибочно загружать неправильные модули ядра. Чтобы избежать этого, добавьте такие модули в чёрный список. Если модуль находится в чёрном списке, udev будет игнорировать его как при загрузке, так и при более позднем "горячем" подключении внешнего устройства (например, USB-носителя).

Отладочная печать

Если задать параметр ядра , то аппаратное обеспечение будет выдавать отладочную информацию. Другой способ — задать параметр

Чтобы добавить эту опцию в initramfs, укажите файл настроек udev в строке

/etc/mkinitcpio.conf
FILES="... /etc/udev/udev.conf"

после чего сгенерируйте initramfs.

udevd вылетает при загрузке

После миграции на LDAP или обновления системы, использующей LDAP, udevd может начать аварийно завершаться в момент загрузки системы с сообщением "Starting UDev Daemon". Обычно это происходит потому, что udevd пытается определить имя через LDAP, но не может, так как в этот момент еще не установлено подключение к сети.

Необходимо, чтобы все используемые в LDAP группы были продублированы локально. Получить имена групп, используемых в правилах udev, и имена групп, присутствующих в системе, можно командами:

# grep -Fr GROUP /etc/udev/rules.d/ /usr/lib/udev/rules.d/ | sed 's:.*GROUP="\([-a-z_]\{1,\}\)".*:\1:' | sort -u >udev_groups
# cut -d: -f1 /etc/gshadow /etc/group | sort -u >present_groups

Вывод будет записан в файлы и . Чтобы увидеть различия, выполните построчное сравнение командой diff:

# diff -y present_groups udev_groups
...
network							      <
nobody							      <
ntp							      <
optical								optical
power							      |	pcscd
rfkill							      <
root								root
scanner								scanner
smmsp							      <
storage								storage
...

В данном примере группа по какой-то причине отсутствует в системе. Все такие группы необходимо добавить в систему. Также убедитесь, что имена всех локальных ресурсов разрешены, прежде чем возвращаться к LDAP. Файл должен содержать следующую строку:

group: files ldap

Устройство является съемным, однако не признается таковым

Создайте правило udev для конкретного устройства. Чтобы получить подробную информацию об устройстве вы можете либо использовать , либо (не забудьте поменять /dev/sdb если нужно):

$ udevadm info /dev/sdb | grep ID_SERIAL

Теперь установите UDISKS_AUTO="1", чтобы пометить устройство для автоматического монтирования и , чтобы пометить устройство как съёмное. Подробнее см.

Перезагрузите правила udev командой . Теперь ваше устройство будет распознаваться как съёмное.

Проблемы с автоматической загрузкой модулей аудиоустройств

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

Примечание: Начиная с версии udev 171, модули эмуляции OSS (snd_seq_oss, snd_pcm_oss и snd_mixer_oss) больше не загружаются автоматически.

Поддержка дисководов IDE

Начиная с версии 170, udev не поддерживает устройства CD-ROM/DVD-ROM, загружаемые как обычные IDE дисководы модулем и отображаемые в системе как . Дисковод доступен только программам, которые обращаются к устройству напрямую, таким как cdparanoia, но невидим для более высокоуровневых программ вроде KDE.

Причина, по которой загрузка модуля имеет приоритет перед другими модулями, например, , может заключаться в том, что по какой-либо причине модуль загружается в вашем initramfs. В этом случае вы можете просто заменить его в файле на .

Оптические дисководы имеют неверный group ID

Если значение group ID вашего дисковода установлено как disk, но вы хотите, чтобы оно было , вам следует создать такое правило:

Смотрите также

gollark: And it apparently took me vaguely indicating support of some government intervention in markets as 43% supportive of a planned economy, which is very no.
gollark: The quiz seems to partly take me thinking it's somewhat inevitable as an endorsement of it.
gollark: Hard to avoid, but bad.
gollark: War is kind of bad?
gollark: … yes?
This article is issued from Archlinux. The text is licensed under Creative Commons - Attribution - Sharealike. Additional terms may apply for the media files.