Знакомство с 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 - поделитесь в комментариях.
ruslan:
спасибо за полезную инфу.
Ответить
30 декабря 2010, 23:49Serg Bormant:
Для привязки сетевых устройств по MAC уже используется
/etc/udev/rules.d/70-persistent-net.rules
а оптических приводов — 70-persistent-cd.rules там же.
Ответить
4 ноября 2011, 11:43Андрей:
В убунте по умолчанию cd монтируется без разрешения запускать программы. Можно ли в udev поправить чтобы диски монтировались с опцией exec? И где?
Ответить
24 января 2012, 21:33Евгений:
Прочитав man udev решил сделать следующим образом. Сначала создаю файл в котором будет написано правило:
1 sudo mkdir /etc/udev/rules.d/20-myudev.rules
тут опечатка, наверное? Нужно
1 sudo touch /etc/udev/rules.d/20-myudev.rules )))
Ответить
Igorka Reply:
августа 16, 2013 at 13:22
Спасибо. Исправил.
Ответить