Тестирование системы инициализации sysmaster

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

На сегодняшний день доминирующей системой инициализации в Linux системах является systemd. Времена споров по целесообразности её внедрения и хейта в её адрес в основном уже в прошлом. Все давно научились с ней работать и просто воспринимают её как данность. Но, справедливости ради, стоит признать, что systemd на данный момент представляет из себя довольно объёмный и многокомпонентный проект и, если мы хотим использовать его на embedded устройствах с небольшим количеством оперативной памяти, то у нас могут возникнуть сложности с оптимальным использованием столь ценного ресурса. Поэтому и возникла потребность в создании ещё одной ультра легковесной системы инициализации, заточенной на использование во встраиваемых системах. Памятуя о том, что все уже и так научились пользоваться systemd, то создавать ещё одну, непохожую ни на что систему инициализации, было бы по меньшей мере странно. Тогда, в сообществе OpenEuler и было принято решение о создании максимально близкой к systemd по использованию и настройке системы инициализации, которая бы могла успешно использоваться в тех случаях, где ресурсы системы необходимо использовать крайне рачительным способом и от системы инициализации требуются в основном только базовые функции, а богатый функционал systemd может стать её недостатком и быть попросту избыточным.

Итак, переходя от слов к делу, вашему вниманию представляется проект sysmaster (ссылка на исходники: https://gitee.com/openeuler/sysmaster ). Минималистичная, ультра-лёгкая система инициализации, призванная составить конкуренцию systemd на embedded устройствах, в облачных вычислениях и даже серверах.

Архитектуру sysmaster можно увидеть на схеме (взята с https://docs.openeuler.org/en/docs/22.03_LTS_SP3/docs/sysMaster/overview.html)

sysMaster

Схема компонентов sysmaster

sysMaster состоит из трех компонентов:

  • sysmaster-init, новая реализация PID 1, применима к встраиваемым системам с такими функциями, как инициализация системы, мониторинг поддержания работоспособности сервисов.

  • sysmaster-core выполняет основные функции управления сервисами и включает в себя надёжную платформу, обеспечивающую оперативное обновление и быстрое самовосстановление в случае сбоев, обеспечивая доступность сервиса в режиме 24/7.

  • sysmaster-exts предлагает набор компонентов (таких как devMaster для управления устройствами и busMaster для обмена данными по шине), которые обеспечивают ключевые системные функции. Вы можете выбрать компоненты для использования по мере необходимости.

Сегодня, в данной статье мы постараемся сделать беглый обзор этой новой системы инициализации и ознакомится с базовыми сценариями её применения.

Установка

Мы будем тестировать данную технологию на виртуальной машине (архитектура x86_64), на которой развёрнут дистрибутив OpenScaler 22.03 LTS SP3.

Установка пакета происходит привычным способом:

# dnf install sysmaster

В системе появляется пакет sysmaster-0.5.1-8.os2203sp3.x86_64.

Давайте посмотрим, что именно в ходит в состав пакета и насколько он «легковесный»:

# rpm -ql sysmaster-0.5.1-8.os2203sp3.x86_64
/etc/ima/digest_lists.tlv/0-metadata_list-compact_tlv-sysmaster-0.5.1-8.os2203sp3.x86_64
/etc/ima/digest_lists/0-metadata_list-compact-sysmaster-0.5.1-8.os2203sp3.x86_64
/etc/sysmaster
/etc/sysmaster/system
/etc/sysmaster/system.conf
/etc/sysmaster/system/multi-user.target.wants
/etc/sysmaster/system/multi-user.target.wants/NetworkManager.service
/etc/sysmaster/system/multi-user.target.wants/dbus.service
/etc/sysmaster/system/multi-user.target.wants/fstab.service
/etc/sysmaster/system/multi-user.target.wants/getty.target
/etc/sysmaster/system/multi-user.target.wants/hostname-setup.service
/etc/sysmaster/system/multi-user.target.wants/sshd.service
/etc/sysmaster/system/sysinit.target.wants
/etc/sysmaster/system/sysinit.target.wants/udev-trigger.service
/etc/sysmaster/system/sysinit.target.wants/udevd.service
/usr/bin/sctl
/usr/lib/sysmaster
/usr/lib/sysmaster/fstab
/usr/lib/sysmaster/hostname_setup
/usr/lib/sysmaster/init
/usr/lib/sysmaster/random_seed
/usr/lib/sysmaster/rc-local-generator
/usr/lib/sysmaster/sysmaster
/usr/lib/sysmaster/sysmonitor
/usr/lib/sysmaster/system
/usr/lib/sysmaster/system-generators/getty-generator
/usr/lib/sysmaster/system/NetworkManager.service
/usr/lib/sysmaster/system/basic.target
/usr/lib/sysmaster/system/dbus.service
/usr/lib/sysmaster/system/dbus.socket
/usr/lib/sysmaster/system/fstab.service
/usr/lib/sysmaster/system/getty.target
/usr/lib/sysmaster/system/getty@.service
/usr/lib/sysmaster/system/hostname-setup.service
/usr/lib/sysmaster/system/multi-user.target
/usr/lib/sysmaster/system/serial-getty@.service
/usr/lib/sysmaster/system/shutdown.target
/usr/lib/sysmaster/system/sockets.target
/usr/lib/sysmaster/system/sshd-keygen.target
/usr/lib/sysmaster/system/sshd-keygen@.service
/usr/lib/sysmaster/system/sshd.service
/usr/lib/sysmaster/system/sysctl.service
/usr/lib/sysmaster/system/sysinit.target
/usr/lib/sysmaster/system/syslog.socket
/usr/lib/sysmaster/system/syslog.target
/usr/lib/sysmaster/system/udev-trigger.service
/usr/lib/sysmaster/system/udevd-control.socket
/usr/lib/sysmaster/system/udevd-kernel.socket
/usr/lib/sysmaster/system/udevd.service
/usr/lib/udev/rules.d/99-sysmaster.rules

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

Давайте продолжим установку и создадим initrd образ без модулей systemd командой:

# dracut -f --omit "systemd systemd-initrd systemd-networkd dracut-systemd" /boot/initrd_withoutsd.img

Теперь, чтобы загрузиться с использованием этого initrd поправим вручную файл с конфигурацией GRUB (/boot/efi/EFI/openScaler/grub.cfg) и пропишем туда новую секцию:

menuentry 'openScaler sysmaster' --class openscaler --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'os-sysmaster' {
        load_video
        set gfxpayload=keep
        insmod gzio
        insmod part_gpt
        insmod ext2
        set root='hd0,gpt2'
        if [ x$feature_platform_search_hint = xy ]; then
          search --no-floppy --fs-uuid --set=root --hint-bios=hd0,gpt2 --hint-efi=hd0,gpt2 --hint-baremetal=ahci0,gpt2  8b880b42-b0e6-4076-bf8d-77f7dd889c5a
        else
          search --no-floppy --fs-uuid --set=root 8b880b42-b0e6-4076-bf8d-77f7dd889c5a
        fi
        echo    'Loading Linux 5.10.0-182.0.0.95.os2203sp3.x86_64 ...'
        linux   /vmlinuz-5.10.0-182.0.0.95.os2203sp3.x86_64 root=/dev/mapper/openscaler-root rw resume=/dev/mapper/openscaler-swap rd.lvm.lv=openscaler/root rd.lvm.lv=openscaler/swap cgroup_disable=files apparmor=0 crashkernel=1024M,high smmu.bypassdev=0x1000:0x17 smmu.bypassdev=0x1000:0x15 panic=3 nmi_watchdog=1 plymouth.enable=0 init=/usr/lib/sysmaster/init
        echo    'Loading initial ramdisk ...'
        initrd  /initrd_withoutsd.img
}

В которой мы добавили параметр ядру "init=/usr/lib/sysmaster/init", отключили plymouth.enable и поменяли путь "initrd /initrd_withoutsd.img".

Перезагружаем нашу виртуальную машину, дожидаемся загрузки и заходим пользователем root в консоль.

Проверка работы

Давайте проверим базовый функционал sysmaster с использованием её утилиты sctl.

Для тренировки мы выберем сервис sshd и давайте сразу ознакомимся с содержимым файла с конфигурацией этого сервиса:

# cat /usr/lib/sysmaster/system/sshd.service 
[Unit]
Description=OpenSSH server daemon
Documentation=man:sshd(8) man:sshd_config(5)
After=sshd-keygen.target
Wants=sshd-keygen.target

[Service]
Type=notify"
EnvironmentFile=-/etc/sysconfig/sshd
ExecStart=/usr/sbin/sshd -D $OPTIONS
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
RestartSec=42

[Install]
WantedBy=multi-user.target

И да, вас не обманывает зрение — это привычный синтаксис systemd. Все директивы, которые можно использовать при настройке сервиса вы можете увидеть в документации http://sysmaster.online/man/core/service/#limitcorelimitnofilelimitnproc

Давайте ознакомимся с базовыми действиями, которые предоставляет утилита sctl:

sctl 0.5.1
parse program arguments

USAGE:
sctl [OPTIONS] <SUBCOMMAND>

OPTIONS:
-c, --count <COUNT> Number of times [default: 1]
-h, --help Print help information
-V, --version Print version information

SUBCOMMANDS:
isolate `[unit]` Isolate one or more units
reload `[unit]` Reload one or more units
reset-failed `[unit]` Reset the failed state of one or more units
restart `[unit]` Restart one or more units
status `[unit]` Show the status of one or more units
start `[unit]` Start one or more units
stop `[unit]` Stop one or more units
daemon-reload `[manager]` Reload sysmaster manager configuration
daemon-reexec `[manager]` Reexecute sysmaster manager
list-units `[manager]` List all units
halt `[system]` Halt the system
poweroff `[system]` Poweroff the system
reboot `[system]` Reboot the system
shutdown `[system]` Shutdown the system
switch-root `[system]` Switch to other root file system
enable `[unit-file]` Enable one or more units
disable `[unit-file]` Disable one or more units
mask `[unit-file]` Mask one or more units
unmask `[unit-file]` Unmask one or more units
help Print this message or the help of the given subcommand(s)

И опять-таки, мы видим все привычные подкоманды из знакомой нам утилиты systemctl.

Давайте остановим сервис sshd и отключим его из автозагрузки:

# sctl stop sshd
# sctl disable sshd

После выполнения этих команд, сервис sshd действительно остановился и был удалён файл /etc/sysmaster/system/multi-user.target.wants/sshd.service (который тоже, по аналогии с systemd являлся символьной ссылкой на /usr/lib/sysmaster/system/sshd.service) Давайте включим сервис обратно и вновь активируем его автозагрузку:

# sctl start sshd

# sctl enable sshd

Проверяем, файл вновь на месте:

# ls -l /etc/sysmaster/system/multi-user.target.wants/sshd.service

lrwxrwxrwx 1 root root 38 мар 25 12:11 /etc/sysmaster/system/multi-user.target.wants/sshd.service -> /usr/lib/sysmaster/system/sshd.service

Напоследок, можно привести листинг всех юнитов, управляемых sysmaster:

# sctl list-units
 UNIT                         LOAD  ACTIVE    SUB        DESCRIPTION                           
 getty@tty6.service           true  active    running    Getty on tty6                         
 fstab.service                true  inactive  dead       automount fstab device                
 udevd.service                true  active    running    udevd.service                         
 getty@tty3.service           true  active    running    Getty on tty3                         
 hostname-setup.service       true  active    exited     hostname setup                        
 sysctl.service               true  inactive  dead       Configure sysctl.conf                 
 getty@tty5.service           true  active    running    Getty on tty5                         
 sshd-keygen@ecdsa.service    true  inactive  dead       OpenSSH ecdsa Server Key Generation   
 sshd-keygen@ed25519.service  true  inactive  dead       OpenSSH ed25519 Server Key Generation 
 sshd.service                 true  active    running    OpenSSH server daemon                 
 getty@tty4.service           true  active    running    Getty on tty4                         
 NetworkManager.service       true  active    running    Network Manager Service               
 getty@tty2.service           true  active    running    Getty on tty2                         
 udev-trigger.service         true  active    exited     udev-trigger.service                  
 getty@tty1.service           true  active    running    Getty on tty1                         
 sshd-keygen@rsa.service      true  inactive  dead       OpenSSH rsa Server Key Generation     
 dbus.service                 true  active    running    D-Bus Service                         
 getty.target                 true  active    active     Login Prompts                         
 sshd-keygen.target           true  active    active     sshd-keygen.target                    
 basic.target                 true  active    active     Basic System                          
 syslog.target                true  active    active     Initialize syslog                     
 sockets.target               true  inactive  statemax   Sockets target                        
 sysinit.target               true  active    active     system initialization target          
 shutdown.target              true  inactive  statemax   shutdown target                       
 multi-user.target            true  active    active     Multi user target                     
 dbus.socket                  true  active    listening  D-Bus Socket                          
 udevd-control.socket         true  active    listening  udevd-control.socket                  
 udevd-kernel.socket          true  active    running    udevd-kernel.socket 

Сравнение с systemd по использованию памяти

В заключении можно продемонстрировать сравнение размеров занимаемых в оперативной памяти systemd и sysmaster.

Замеры systemd производили на аналогичной по ресурсам и установленным компонентам системе:

VIRT=165,9 Mb

RES=16,3 Mb

SHR=8,8 Mb

Теперь посмотрим на размеры в памяти sysmaster:

VIRT=3,0 Mb

RES=1,8 Mb

SHR=1,7 Mb

Как говорится, комментарии излишни.

Выводы:

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

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