Знакомство с devmaster

В нашей прошлой статье (https://openscaler.ru/2024/03/25/sysmaster/) мы рассмотрели sysmaster – «облегчённую» версию systemd, предназначенную для использования во встраиваемых устройствах. Сегодня мы рассмотрим devmaster — дополнение к sysmaster, представляющее из себя диспетчер устройств (аналог systemd-udev), предназначенное для управления устройствами в каталоге /dev.

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

Как программное обеспечение, devmaster состоит из демона, клиентского инструмента и динамической библиотеки. Демон devmaster использует механизмы ядра, такие как netlink, notify и sysfs, для мониторинга событий устройства и запуска задач обработки правил.

Клиентский инструмент devctl предоставляет набор команд CLI и общедоступных интерфейсов для отладки правил, управления демонами и запроса состояния устройства.

На следующем рисунке показана общая архитектура dev master:

devmaster написан на языке программирования Rust, обеспечивающем наиболее безопасное управление памятью.

Основные функции devmaster следующие:

1. Операции управляемые событиями: Механизмы кэширования очередей и рабочего пула используются для удовлетворения требований к событиям устройств с высокой степенью параллелизма. Кроме того, процессы пользовательского режима могут динамически уведомляться о готовности устройств.

2. Разделение механизмов и политик: Логика обработки устройств определяется как правила заданные в конфигурационных файлах, а не жестко задана в сервисном коде, что позволяет настраивать по требованию и гибко комбинировать.

3. Совместимость с экосистемой: dev master совместим с синтаксисом udev и широковещательным протоколом пользовательского режима udev. Существующие сервисы могут быть мигрированы на использование devmaster с низкими затратами.

Ну, довольно теории, переходим к практике!

Проверяем devmaster в деле

Все наши манипуляции мы проводим на OpenScaler 22.03 LTS SP3 (x86_64), на котором у нас уже установлена (смотри предыдущую статью) система инициализации sysmaster.

Для начала. давайте собственно установим devmaster и для этого выполним команду:

dnf install devmaster

 

И после этого сразу запустим devmaster с использованием знакомой нам уже утилиты sysmaster:

sctl enable devmaster.service
sctl start devmaster.service

 

После запуска devmaster создаст свою базу данных устройств (представляющую собой набор текстовых файлов) в каталоге /run/devmaster/data. Мы можем просмотреть её используя привычные консольные утилиты.

Давайте теперь попробуем поработать с devmaster также, как мы привыкли работать с udev.

Для того, чтобы узнать в каких каталогах нам следует размещать наши самописные файлы rules обратимся к конфигурационному файлу /etc/devmaster/config.toml

Из него мы узнаём, что devmaster ищет файлы с rules в каталогах:

rules_d = ["/etc/devmaster/rules.d", "/lib/devmaster/rules.d", "/etc/udev/rules.d", "/run/udev/rules.d", "/lib/udev/rules.d"]

Давайте теперь обратимся к утилите devctl. Если запустить её с подкомандой help, то мы можем увидеть привычные нам по udevadm команды, такие как: info, monitor, trigger и т. д.

Давайте попробуем посмотреть информацию по какому-нибудь устройству:

# devctl info /dev/zero

P: /devices/virtual/mem/zero

M: zero

U: mem

D: c 1:5

N: zero

L: 0

E: MAJOR=1

E: DEVNAME=/dev/zero

E: TAGS=:devmaster:

E: DEVMODE=0666

E: SUBSYSTEM=mem

E: CURRENT_TAGS=:devmaster:

E: DEVPATH=/devices/virtual/mem/zero

E: MINOR=5

E: USEC_INITIALIZED=1711621744

 

и ещё вот так:

# devctl info --attribute-walk /dev/zero

Devctl info starts with the device specified by the devpath and then

walks up the chain of parent devices. It prints for every device

found, all possible attributes in the devmaster rules key format.

A rule to match, can be composed by the attributes of the device

and the attributes from one single parent device.

looking at device '/devices/virtual/mem/zero':

KERNEL=="zero"

SUBSYSTEM=="mem"

DRIVER==""

ATTR{power/control}=="auto"

ATTR{power/runtime_active_time}=="0"

ATTR{power/runtime_status}=="unsupported"

ATTR{power/runtime_suspended_time}=="0"

 

Да, мы видим такую же информацию, как если бы запускали udevadm.

Мы также можем запустить в отдельной консоли команду:

devctl monitor

 

А в другой попробовать триггернуть какое-нибудь устройство для проверки.

К примеру, тот же /dev/zero:

devctl trigger /dev/zero

 

И увидеть, что в monitor появились об этом сообщения вида:

KERNEL - the kernel uevent
USERSPACE - broadcasted by devmaster after successful process on device

KERNEL [] >> change /devices/virtual/mem/zero (mem)
USERSPACE [] >> change /devices/virtual/mem/zero (mem)

 

Давайте теперь, для примера, создадим своё собственное правило, по которому в каталоге /dev/test поместим символьные ссылки на блочные устройства, присутствующее в нашей системе.

Для этого нам предстоит написать своё правило (rule), которое мы должны разместить в каталоге /etc/devmaster/rules.d/

Приступим.

Создаём файл /etc/devmaster/rules.d/00-persist-storage.rules с содержимым:

SUBSYSTEM!="block", GOTO="end"

IMPORT{builtin}=="blkid"

ENV{ID_FS_UUID_ENC}=="?*", SYMLINK+="test/$env{ID_FS_UUID_ENC}"

LABEL="end"

 

В этом правиле мы используем встроенную команду blkid для считывания UUID блочного устройства и создания программной ссылки для блочного устройства на основе UUID.

После запуска события устройства, имеющего файловую систему, в каталоге /dev/test генерируется программная ссылка, соответствующая устройству.

Теперь нам надо перезапустить devmaster:

sctl stop devmaster

sctl start devmaster

 

(или мы можем воспользоваться одной командой: sctl restart devmaster)

Проверим, что каталога /dev/test пока ещё не существует.

Теперь давайте триггернём устройство /dev/sda1

# devctl trigger /dev/sda1

 

И проверяем каталог /dev/test

# ls -l /dev/test/

lrwxrwxrwx 1 root root 7 мар 29 13:56 9344-4BBC -> ../sda1

 

Да, у нас появилась символьная ссылка на /dev/sda1, где именем ссылки выступает UUID из вывода команды blkid.

Теперь давайте триггернём /dev/sda2

# devctl trigger /dev/sda2

# ls -l /dev/test/

lrwxrwxrwx 1 root root 7 мар 29 13:57 8b880b42-b0e6-4076-bf8d-77f7dd889c5a -> ../sda2

lrwxrwxrwx 1 root root 7 мар 29 13:56 9344-4BBC -> ../sda1

 

А теперь давайте перезагрузим весь сервер, на котором мы проводим наши испытания.

После перезагрузки смотрим содержимое каталога /dev/test:

# ls -l /dev/test/

итого 0

lrwxrwxrwx 1 root root 7 мар 29 14:01 2bcae3e7-a422-4242-a36b-0cae357fc375 -> ../dm-1

lrwxrwxrwx 1 root root 7 мар 29 14:01 8b880b42-b0e6-4076-bf8d-77f7dd889c5a -> ../sda2

lrwxrwxrwx 1 root root 7 мар 29 14:01 8b97acbf-2dff-483f-b2dc-ff247d6453eb -> ../dm-0

lrwxrwxrwx 1 root root 7 мар 29 14:01 9344-4BBC -> ../sda1

lrwxrwxrwx 1 root root 7 мар 29 14:01 jrQ6UA-IOdT-O2Yo-YpR5-ckvT-6MLX-wzIfOa -> ../sda3

 

Как мы видим, при старте devmaster проверил все устройства и согласно правилу создал для них символьные ссылки.

Подводим итог

Сегодня мы рассмотрели devmaster, который является компонентом системы инициализации sysmaster и тоже, в свою очередь, заточен на применение в случаях, где и без того небольшой размер оперативной памяти является местом борьбы за оптимизацию и эффективность её использования. Поэтому, devmaster можно смело рассматривать (совместно с sysmaster) для применения на embedded устройствах.

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