udev: обнаружение устройств
udev: как система находит устройства и наполняет /dev.
Где мы в цепочке загрузки
К этому моменту система уже прошла путь firmware -> загрузчик -> kernel
(ядро) -> initramfs. На UEFI загрузчика может и не быть: ядро с
EFI stub грузится напрямую прошивкой. Дальше systemd развёл targets по
зависимостям (graphical -> multi-user -> basic -> sysinit), и
система поднялась.
Осталось разобраться с железом. Диски, сетевые карты, USB-флешки, звуковые
чипы: для каждого устройства в каталоге /dev должен появиться узел, через
который с ним работают программы. Кто и когда его создаёт?
Кто наполняет /dev
Ответ: udev. udev — это пользовательский демон (daemon, фоновый процесс),
который следит за устройствами и создаёт для них узлы в /dev. Внутри
systemd он живёт как сервис systemd-udevd.
$ systemctl status systemd-udevd
● systemd-udevd.service - Rule-based Manager for Device Events and Files
Loaded: loaded (/lib/systemd/system/systemd-udevd.service; static)
Active: active (running) since Sat 09:00:04 UTC; 2h ago
Обрати внимание на строку Active: это обычный процесс с PID, а не код внутри kernel. Ядро только сообщает о событиях, решения принимает udev в user space.
Как это работает
Когда ядро обнаруживает устройство (воткнули флешку, поднялась сетевая карта), оно отправляет событие uevent. Это сообщение о том, что устройство появилось, исчезло или изменилось. udev слушает поток таких событий.
Получив uevent, udev создаёт узел в /dev, а затем применяет правила
udev: текстовые файлы, которые описывают, что делать с устройством. Через
правила задают имя, права доступа, владельца, дополнительные симлинки.
$ udevadm monitor --udev
monitor will print the received events
UDEV [1204.51] add /devices/.../block/sdb (block)
UDEV [1204.53] add /devices/.../block/sdb/sdb1 (block)
Здесь видно, как при подключении диска приходят события add, и udev на
них реагирует.
Правила udev
Правила лежат в /lib/udev/rules.d/ (системные) и
/etc/udev/rules.d/ (твои, они переопределяют системные). Файл — набор
строк, каждая сопоставляет условия и действия.
# /etc/udev/rules.d/70-usb-serial.rules
# для USB-адаптера с таким VID:PID выставить права и добавить симлинк
SUBSYSTEM=="tty", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", \
MODE="0660", GROUP="dialout", SYMLINK+="ftdi0"
Слева от == условия сопоставления, справа от = действия. Строка выше
означает: для tty-устройства от этого производителя выставить режим 0660,
группу dialout и создать симлинк /dev/ftdi0. После правки правил их
перечитывают:
udevadm control --reload # перечитать правила
udevadm trigger # прогнать события заново для уже подключённых
Правилами удобно давать сетевой карте предсказуемое имя вместо eth0,
которое зависит от порядка обнаружения. Так появляются имена вроде
enp3s0.
Симлинки by-uuid и by-id
Имя диска (/dev/sda, /dev/sdb) зависит от порядка обнаружения и может
меняться между загрузками. Поэтому udev создаёт стабильные симлинки по
UUID и серийному номеру:
$ ls -l /dev/disk/by-uuid/
lrwxrwxrwx 1 root root 10 a1b2c3d4-... -> ../../sda1
lrwxrwxrwx 1 root root 10 e5f6a7b8-... -> ../../sdb1
Именно такой UUID пишут в /etc/fstab: он не зависит от того, каким по
счёту опросили диск.
Осмотреть устройство
Команда udevadm info показывает всё, что udev знает про узел:
атрибуты, симлинки, значения для условий в правилах.
$ udevadm info /dev/sdb1
P: /devices/pci0000:00/.../block/sdb/sdb1
N: sdb1
S: disk/by-uuid/e5f6a7b8-1234-5678-9abc-def012345678
E: DEVNAME=/dev/sdb1
E: ID_FS_TYPE=ext4
E: ID_FS_UUID=e5f6a7b8-1234-5678-9abc-def012345678
Строки S: — симлинки, которые создал udev. Строки E: содержат
переменные, которые правила могут проверять условиями (ID_FS_TYPE,
ID_FS_UUID).
Две ловушки
Первое заблуждение: файлы в /dev статичные и лежат на диске. На самом
деле /dev монтируется как devtmpfs в оперативной памяти и наполняется
на лету при каждой загрузке.
$ mount | grep ' /dev '
devtmpfs on /dev type devtmpfs (rw,nosuid,relatime,size=...)
Второе: udev работает внутри ядра. Нет. Ядро лишь шлёт uevent, а разбирает
их и создаёт узлы отдельный процесс systemd-udevd в user space (вспомни
вывод systemctl status выше).
Что важно запомнить
udev — пользовательский демон, который наполняет /dev, а не часть kernel.
Ядро при появлении устройства шлёт событие uevent, udev его ловит.
Правила udev задают имя, права и симлинки; лежат в /etc/udev/rules.d/.
/dev/disk/by-uuid/ — стабильные ссылки, которые не зависят от порядка
обнаружения; их и пишут в /etc/fstab.
udevadm info показывает атрибуты устройства и созданные симлинки.
Дальше — короткий квиз по треку загрузки.
Прошли материал до конца? Отметьте урок пройденным.
Прогресс сохранён в этом браузере
Почистишь историю или откроешь с телефона, и отметки пропадут. Оставь почту, они переедут в аккаунт. Пароль придумывать не нужно.
Готово. теперь в аккаунте: прогресс виден с любого устройства. Мой прогресс