Знакомство с udev в ubuntu

После лекции по подсистеме udev решил посмотреть на то как устроена udev в Ubuntu. Дело в том, что преподаватель всегда рассказывает о классическом варианте той или иной службы или подсистемы. Некоторые вещи в более современных дистибутивах (в той же Ubuntu) обстоят немного по другому. udev также не стала исключением.

Повторять материал конспекта Лекция №30 - Подсистема udev не буду, остановлюсь только на отличиях, которые нашел на настоящий момент. А находил я эти отличия, пытаясь выполнить очень простую задачу - отключить автомонтирование определенной флешки и сделать так, чтобы в каталоге /dev не появлялся файл-устройство, отображающий флешку.

В Ubuntu 9.10 файлы правил для подсистемы udev лежат в двух каталогах: /lib/udev/rules.d/ и /etc/udev/rules.d/. Почти все файлы правил находятся в первом каталоге. Если необходимо изменить правило, то делать это нужно следующим образом. Скопировать файл в котором нужно изменить правило (например, 50-udev-default.rules) из /lib/udev/rules.d/ в /etc/udev/rules.d/:

1
sudo cp /lib/udev/rules.d/50-udev-default.rules /etc/udev/rules.d/

И редактировать скопированный файл в каталоге /etc/udev/rules.d/. Все дело в том, что файлы которые находятся в каталоге /etc/udev/rules.d/ имеют приоритет над файлами из каталога /lib/udev/rules.d/. Если подсистема udev увидит в двух каталогах файл с одинаковым именем, то обрабатываться будет файл из каталога /etc/udev/rules.d. Поэтому, редактировать файлы с правилами настоятельно рекомендуется именно таким образом. К тому же если вдруг, что-то пойдет не так всегда можно удалить скопированный файл, и все вернется на свои места.

Если же нужно создать свой файл правил, то делать это также рекомендуется в каталоге /etc/udev/rules.d/. Названия файлов начинаются с чисел. Числа нужны, чтобы упорядочить файлы. Именно в таком порядке их просматривает udev.

Для работы с udev в ubuntu предназначена утилита udevadm. Справку об этой утилите можно получить по команде man udevadm. Например, чтобы получить информацию из базы данных udev об устройстве (в данном случае о флешке) нужно использовать команду udevadm info. Скомпоновав две команды udevadm info можно получить полную информацию об устройстве (в данном примере о флешке):

1
udevadm info -a -p $(udevadm info -q path -n sde)

Получаем длинный список свойств устройства sde, которое представляет собой флешку. Меня интересовала вот эта часть результатов:

1
2
3
4
5
...
    ATTRS{manufacturer}=="JetFlash"
...
    ATTRS{serial}=="5A3UNLIS"
...

На основании этих данный будет производится идентификация флешки.

Прочитав man udev решил сделать следующим образом. Сначала создаю файл в котором будет написано правило:

1
sudo nano /etc/udev/rules.d/20-myudev.rules

Затем было перепробовано несколько вариантов правил. Но в полном объеме задачу решило следующее:

1
ATTRS{manufacturer}=="JetFlash", ATTRS{serial}=="5A3UNLIS", OPTIONS:="ignore_device"

Запись OPTIONS:=”ignore_device” говорит о том, что данное устройство должно быть проигнорировано подсистемой udev.

После того как правило записано и файл сохранен, нужно выполнить рестарт подсистемы udev:

1
sudo restart udev

Теперь, если вставить флешку и посмотреть каталог /dev, то устройства sde мы там не увидим:

1
2
3
4
ls /dev/sd*
/dev/sda   /dev/sda3  /dev/sda6  /dev/sdb1  /dev/sdb4  /dev/sdc
/dev/sda1  /dev/sda4  /dev/sda7  /dev/sdb2  /dev/sdb5  /dev/sdc1
/dev/sda2  /dev/sda5  /dev/sdb   /dev/sdb3  /dev/sdb6  /dev/sdd

Что и требовалось получить.

Хочу также упомянуть о команде udevadm monitor и udevadm test. Первая команда позволяет просматривать в режиме реального времени события, которые генерируются ядром и самой подсистемой udev во время подключения и отключения устройств. Вот небольшой фрагмент событий при подключении флешки:

1
2
3
4
5
6
7
8
9
10
11
udevadm monitor
monitor will print the received events for:
UDEV - the event which udev sends out after rule processing
KERNEL - the kernel uevent

KERNEL add      /devices/pci0000:00/0000:00:1d.7/usb1/1-7 (usb)
KERNEL add      /devices/pci0000:00/0000:00:1d.7/usb1/1-7/1-7:1.0 (usb)
UDEV add      /devices/pci0000:00/0000:00:1d.7/usb1/1-7 (usb)
KERNEL add      /module/usb_storage (module)
UDEV add      /devices/pci0000:00/0000:00:1d.7/usb1/1-7/1-7:1.0 (usb)
...

Команда udevadm test позволяет просмотреть, какие действия будет выполнять udev при подключении/отключении устройств. Но для использования этой программы нужно хорошо ориентироваться в каталоге /sys. Так как именно отсюда следует брать имена устройств для команды udevadm test. Также можно воспользоваться командой udevadm monitor, чтобы взять путь из результата вывода.

Например, вот фрагмент вывода команды udevadm monitor при подключении bluetooth-адаптера:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
KERNEL add /devices/pci0000:00/0000:00:1d.3/usb5/5-1 (usb)
KERNEL add /devices/pci0000:00/0000:00:1d.3/usb5/5-1/5-1:1.0 (usb)
KERNEL add /devices/pci0000:00/0000:00:1d.3/usb5/5-1/5-1:1.0/bluetooth/hci0 (bluetooth)
KERNEL add /devices/pci0000:00/0000:00:1d.3/usb5/5-1/5-1:1.0/bluetooth/hci0/rfkill1 (rfkill)
KERNEL add /devices/pci0000:00/0000:00:1d.3/usb5/5-1/5-1:1.1 (usb)
KERNEL add /devices/pci0000:00/0000:00:1d.3/usb5/5-1/5-1:1.2 (usb)
KERNEL change /devices/pci0000:00/0000:00:1d.3/usb5/5-1/5-1:1.0/bluetooth/hci0/rfkill1 (rfkill)
UDEV add /devices/pci0000:00/0000:00:1d.3/usb5/5-1 (usb)
UDEV add /devices/pci0000:00/0000:00:1d.3/usb5/5-1/5-1:1.0 (usb)
UDEV add /devices/pci0000:00/0000:00:1d.3/usb5/5-1/5-1:1.1 (usb)
UDEV add /devices/pci0000:00/0000:00:1d.3/usb5/5-1/5-1:1.2 (usb)
UDEV add /devices/pci0000:00/0000:00:1d.3/usb5/5-1/5-1:1.0/bluetooth/hci0 (bluetooth)
UDEV add /devices/pci0000:00/0000:00:1d.3/usb5/5-1/5-1:1.0/bluetooth/hci0/rfkill1 (rfkill)
UDEV change /devices/pci0000:00/0000:00:1d.3/usb5/5-1/5-1:1.0/bluetooth/hci0/rfkill1 (rfkill)

Затем берем любой путь и пишем команду:

1
2
3
4
5
6
7
8
udevadm test /sys/devices/pci0000:00/0000:00:1d.3/usb5/5-1/5-1:1.0/bluetooth/hci0

...
udev_rules_apply_to_event: RUN 'socket:@/org/freedesktop/hal/udev_event'
                                       /lib/udev/rules.d/90-hal.rules:2
udev_rules_apply_to_event: RUN '/usr/sbin/bluetoothd --udev'
                                       /lib/udev/rules.d/97-bluetooth.rules:3
...

Вывод команды сокращен для экономии места. Оставил для примера строки в которых написано какие строки и из каких файлов правил будут выполнены для данного устройства.

Еще хочу упомянуть о команде udevadm info с ключом -e:

1
udevadm info -e

Данная команда выгружает содержимое базы данных udev. Строк в выводе много поэтому можно перенаправить вывод в комнду less и уже там через поиск найти нужные устройства и информацию о них. Или воспользоваться командой grep. Способов много. Вот, например, как я вывел информацию о сетевом устройстве eth0:

Сначала нашел путь в каталоге /sys

1
2
3
find /sys -name eth0
/sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/net/eth0
/sys/class/net/eth0

А затем этот путь подставил в следующую команду:

1
udevadm info -a -p $(udevadm info -q path -p /sys/class/net/eth0)

и получил всю необходимую информацию для построения правил для сетевого интерфейса eth0. Кстати, когда-то встречал информацию в интернете, что как раз через правила udev можно четко привязать наименования сетевых интерфейсов к самим устройствам по их MAC-адресу. Это иногда необходимо когда есть несколько сетевых интерфейсов и после перезагрузки меняются их имена: eth0 на eth1, а eth1 на eth0. Но я тогда еще не знал о udev и не совсем разобрался в сути описанных действий, хотя сейчас понятно, что для этого нужно идентифицировать интерфейс по MAC-адресу и присвоить нужное имя. Например так:

1
SUBSYSTEM=="net", ATTR{address}=="00:16:xx:xx:xx:xx", NAME:="eth1"

Где 00:16:xx:xx:xx:xx - это MAC-адрес сетевой платы.

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

Статьи и новости схожей тематики:

Комментариев: 5

  1. ruslan:

    спасибо за полезную инфу.

    Ответить

  2. Serg Bormant:

    Для привязки сетевых устройств по MAC уже используется
    /etc/udev/rules.d/70-persistent-net.rules

    а оптических приводов — 70-persistent-cd.rules там же.

    Ответить

  3. Андрей:

    В убунте по умолчанию cd монтируется без разрешения запускать программы. Можно ли в udev поправить чтобы диски монтировались с опцией exec? И где?

    Ответить

  4. Евгений:

    Прочитав man udev решил сделать следующим образом. Сначала создаю файл в котором будет написано правило:
    1 sudo mkdir /etc/udev/rules.d/20-myudev.rules

    тут опечатка, наверное? Нужно
    1 sudo touch /etc/udev/rules.d/20-myudev.rules )))

    Ответить

    Igorka Reply:

    Спасибо. Исправил.

    Ответить

Оставьте свой отзыв