Десять лет назад был анонсирован systemd, который устроил революцию в управлении системой дистрибутивов Linux, тем самым разделив пользователей Linux на несколько лагерей. Качество и природа дебатов не сильно улучшилась со времён пламенных войн 2012-2014 годов, и systemd всё ещё остаётся не до конца понятым и изученным инструментом и с технической, и с общественной стороны, несмотря на пристальное внимание к нему сообщества.

Это пост не совсем о том, как пользоваться systemd. Тут, скорее, будет говориться об истории его возникновения, о его компонентах в целом, и о том, как понять систему, которая начиналось как просто PID 1 и стала тем, что я бы назвал middleware современного дистрибутива Linux.

А может, это просто набор крайне вольных переводов различных материалов с блогов, каналов и статей на Arch wiki. Вам решать.

Я, как пользователь и ранее сисадмин, питаю много нежных чувств к systemd, поэтому материал написан с весомой долей предвзятости, за что прошу прощения.

Но прежде чем начать речь о systemd, хочу рассказать об init.

init


В седьмом издании UNIX (1979) задача init — это выполнить при старте /etc/rc и создавать процессы инициализации терминала (getty) и логина (login).

Затем постепенно добавлялись новые задачи. Например, перехват ничейных процессов. Или очистка каталога /tmp. Или монтирование файловых систем.

Так, сегодня основная задача init — привести систему из состояния «ядро запущено» к «система готова к работе». Запустить userspace, другими словами.

Время шло, появился интернет, а вместе с ним — приложения, базы данных, кэши, веб-серверы, и много чего ещё. Материализовалось понятие сервиса, как набор тесно связанных демонов или целых систем, выполняющих одну цель.

И /etc/rc со скриптами, конечно, могут запустить всё, что нужно, но что, если, скажем, надо просто перезапустить какой-то демон? Вышедший в 1983-м UNIX System V, который ввёл понятие runlevel, или уровень выполнения, частично решал эту проблему и позволял таким образом управлять целыми группами демонов.

Linux перенял у UNIX интерфейс инициализации (sysvinit), и в целом, всех всё устраивало, но тем не менее, были пользователи, которых sysvinit стеснял. Так, Matthias S. Brinkmann однажды написал в своём блоге заметку «Почему sysvinit — отстой». Оригинал удалён, поскольку, по мнению Матьяса «sysvinit уже мёртв», но вольно переведу вкратце найденную в интернете перепечатку:

  • Если у вас нет чёрного пояса в микадо, вы быстро потеряетесь в инсталляции sysvinit. Большинство скриптов имеет, по крайней мере, три репрезентации на диске: скрипт, симлинк запуска и симлинк остановки.
  • Надо самостоятельно настраивать порядок запуска сервисов. Для всех. Без исключений. Но серьёзно, какая разница, что запускается раньше — инициализация клавиатуры или системные часы? Если вы хотите это контролировать, то ладно, но SysVinit принуждает вас к контролю всего.
  • Нет управления зависимостями. Да, можно дать скрипту номер 100, а его завиимости — 99, но иногда этого недостаточно. Что, если сервис B требует сервис A в запущенном состоянии, а тот упал после запуска? SysVinit всё равно запустит сервис B! Таким образом, вы рискуете получить систему, где что-то провалилось, скажем, файловая система не примонтировалась и от этого часть системы отвалилась, но программа SysVinit runlevel весело отрапортует, что всё запущено, и у вас есть X сервер с сетью.
  • Его тяжело редактировать: иначе зачем люди пишут красивые GUI для автоматизации добавления-удаления скриптов из уровней выполнения? Потому что вручную управлять дюжиной симлинков, где каждая опечатка может привести к сломанной системе, это безумие.
  • Он плохо масштабируется. Взгляните на Linux From Scratch: он использует три числа для обозначения последовательности запуска. Говорит о многом про систему с только десятком загрузочных скриптов, не так ли? Проблема в том, что когда вам надо добавить новый скрипт, его надо уместить в последовательность загрузки и, возможно, переиндексировать все скрипты инициализации. Вообще, это напоминает мне о временах BASIC с номерами строк, когда надо было уместить больше девяти строк между строкой N и строкой N+10. К счастью, в BASIC есть команда renum. А в SysVinit, конечно, вы сами можете написать скрипт, который сделает переупорядочивание за вас. Админы SysVinit любят упражнения.
  • Он не очень уживается в автоматических инсталляциях и системах, где пакеты поставляются со своими загрузочными скриптами. Допустим, пользователь создал свой загрузочный скрипт с номером N. А потом решил поставить пакет FTP-сервера, который идёт со своим скриптом с тем же номером. Привет, конфликт.
  • В SysVinit невозможно тестировать изменения. Чтобы протестировать последовательность загрузки SysVinit и выполнение уровней, надо выполнять потенциально опасные команды. Иногда требуется несколько циклов перезагрузки, прежде чем всё заработает.
  • Небезопасный шатдаун. SysVinit полагается исключительно на загрузочные скрипты, чтобы отмонтировать файловые системы и остановить процессы. Это крайне небезопасно и может вылиться в потерю данных в худших случаях.

Позже, разработчик Busybox Денис Власенко опубликовал в своём блоге запись SysV init must die, и, несмотря на то, что сразу делается оговорка, что это шутка, да и вообще пост сделан в формате диалога, а не конфликта, претензии к системе были.

Подытоживая, sysvinit был разработан больше 30 лет назад со старыми концепциями, которые уже не решали задачи XXI века. Мало того, система не развивалась и не вводила новые идеи.

В атмосфере беспорядочного хаоса было предприняты несколько попыток решить проблемы sysvinit:


Но на сегодня самой известной альтернативой (кроме systemd) является, пожалуй, Upstart.

Upstart


Часть проблем sysvinit вызвался решить Upstart (также известный как ReplacementInit), альтернативная система инициализации, выпущенная в 2006-м году Canonical, разработчиками Ubuntu. Его главная концепция — event-driven подход. Запуск системы — это событие, новое устройство — событие, запуск демона — событие. Процессы могли подписываться на события и запускаться только при явной необходимости.

Upstart совместим с sysvinit-скриптами, благодаря этому он был быстро интегрирован во многие дистрибутивы Linux. Тем не менее, после того, как большинство дистрибутивов Linux по тем или иным причинам перешли на systemd, разработка сошла на нет: последний релиз был в 2014-м году, и сегодня Upstart используется только в Chrome OS.

Новый init


«we are experimenting with a new init system and it is fun»

Весной 2010 года в блоге Леннарта Поттеринга вышел материал Rethinking PID 1, в которой он описал своё видение эффективной системы инициализации.

По его мнению, эффективный init должен обладать следующими характеристиками:

  • Запускать меньше демонов. Точнее говоря, запускать только то, что требуется: подключили сеть — включаем сетевые демоны, зашёл пользователь — включаем его персональные демоны, и так далее.
  • Запускать ещё меньше демонов! Что, если не запускать sshd сразу, а начинать «слушать» TCP-сокет вместо него и при первом подключении запускать sshd, передавая ему дескриптор сокета.
  • Запускать больше демонов параллельно. Например, какая разница, кого запускать первым — sshd, cupsd или httpd, если можно запустить все вместе?
  • Быть динамичным. init должен реагировать на изменения как в демонах, так и в «железе», и запускать (и иногда останавливать) соответствущие службы.

В то же время Поттеринг подчёркивает, что эти идеи не новые, и уже известна система с такими возможностями — launchd от Apple, система инициализации в macOS. launchd имеет схожие с Upstart event-driven идеи, но более того, он вобрал в себя задачи других системных сервисов, таких, как cron и inetd.

Другая идея, которую можно почерпнуть из процесса загрузки macOS: shell-скрипты — это зло. Их легко написать, но трудно поддерживать, и они медленно выполняются: каждый вызов grep/awk/sed/cut в одном скрипте — это запуск процесса, подгрузка его библиотек, операции типа локализации вывода, и так далее. И так с каждым init-скриптом. В контексте запуска системы выполнение множества консольных команд тормозит весь процесс.

«Так давайте избавимся от shell-скриптов в загрузке!» — воскликнул Леннарт. «Большая часть init-скриптинга сводится к тривиальному запуску-остановке демонов, и эту логику можно переписать на C и поместить или в отдельные исполняемые файлы, или в сами демоны, или просто в init».

Другие возможности, которыми должен обладать хороший, по мнению Поттеринга, PID 1:

  • Распараллеливание задач файловых систем. Проверка на ошибки, монтирование и квотирование. Что, если монтировать файловые системы одновременно, или только при доступе к ним?
  • Отслеживание процессов. Одна из задач системы управления сервисами — это мониторинг процессов. Перезапускать, если они упали. Собрать информацию, если они крашнулись. Кроме того, система должна уметь останавливать сервисы, что может быть непросто, если процесс сделал двойной вызов fork().
  • Управление ресурсами сервисов. В идеале, init должен настроить окружение updatedb (обновление БД команды locate) так, чтобы процесс выполнялся только при полном бездействии.
  • Логирование также является важной частью выполнения сервисов. Несмотря на то, что логи — сложная штука, простые сценарии типа вывода в stdout/stderr или обработка логов ядра (dmesg) должны решаться компонентами init.

Все перечисленные механики, как нетрудно догадаться, и были воплощены в systemd.

Почему бы просто не добавить всё это в Upstart, зачем изобретать по-новому? Или почему бы не портировать launchd? Ответ прост — на взгляд Леннарта, у Upstart, несмотря на event-driven подход, есть недостатки в архитектуре и дизайне. А launchd вряд ли хорошо прижился бы в Linux.

systemd


Анонсированный в Rethinking PID 1 прототип systemd, ранее известный как "BabyKit" (от process babysitter — нянька процессов), быстро получил доминирующий статус благодаря своей лёгкости.

Сегодня на странице проекта говорится уже не про PID 1, а про комплект базовых блоков для системы Linux.

Что под этим скрывается? systemd теперь называется конструктор из компонентов, каждый из которых отвечает за свою задачу, связанную с сервисами или системой в целом.

systemd — это система управления системой. Он берёт и объединяет в системный слой подсистемы, которые, с одной стороны, не забота ядра, а с другой — пользователю они редко интересны.

Восход к власти


Разработчики systemd не теряли времени на проповедование. Несмотря на пятна от помидоров в списке рассылки fedora-devel, systemd в июле 2010 года стал стандартом инициализации в Fedora Rawhide.

В обсуждениях разработки Fedora, связанных с systemd, Леннарт занимал боевую позицию, особенно в вопросах обратной совместимости: так, отвечая на беспокойства Мэтью Миллера касательно совместимости с inittab, он спрашивал: «Может, мы должны проверять ещё и AUTOEXEC.BAT?… Да, давайте снова вернёмся к теме inittab. Это было так весело!». Когда его спросили про необходимости исправлять пакеты из-за нововведений systemd, он ответил: «Круто, полагаю, теперь я стану разработчиком X (X-сервера).

Вероятно, если KMS сломан, мой долг — исправить это. Ура!»

Всё обсуждение демонстрировало в чём-то инфантильный недостаток внимания Леннарта к ситуации, в которой многие пакеты и подсистемы перед релизом Fedora 14 нужно было подготовить к работе с systemd. Естественно, эта мыльная опера появилась на LWN.

Как бы то ни было, амбиций у Леннарта было полно. В июле 2010 он был уверен, что дистрибутивы возьмут к себе systemd:

7) Перейдут ли другие дистрибутивы на systemd?
Ну, не так быстро, как Fedora, но похоже на то.

А в сентябре 2010 он чётко заявил кросс-дистрибутивную интеграцию как одну из целей systemd:

Мы намерены мягко подталкивать дистрибутивы в одном направлении, чтобы они прекратили поддерживать другие решения ...

В августе 2012 года Arch Linux переключился на systemd, хоть и с небольшой драмой.

Немного позже, в октябре того же года, благодаря упорству Леннарта, GNOME перешёл на systemd-logind. В октябре 2019 вышел GNOME 3.34 полностью интегрированный с systemd.

На момент 2013 и 2014 годов Debian и Ubuntu были последними, среди ведущих дистрибутивов, не принявших systemd.

Josselin Mouette в октябре 2013, будучи мейнтейнером пакета GNOME в Debian, заявил в списке рассылки Debian следующее:

systemd становится де-факто стандартом в дистрибутивах Linux (по крайней мере в Fedora, SuSE и Arch) и получает превосходную поддержку во множестве пакетов. До сих пор только Gentoo использует OpenRC, и только Ubuntu использует Upstart. Поэтому использование OpenRC бы означало необходимость в поддержке множества собственных патчей, а использование Upstart бы значило, что мы становимся апстримом Ubuntu.

… Завершая, я скажу как мейнтейнер пакета GNOME. GNOME-у в Jessie понадобится systemd как система инициализации для работы всего функционала так же, как ему требуется NetworkManager для работы конфигурирования сети.


Более того, в декабре 2013, в изложении ситуации с init в Debian за авторством Расса Олбери, в разделе «3.1. Реальность экосистемы», сказал, что разговор идёт уже не о «systemd-против-альтернатив», а о «как-много-будет-systemd»:

Одним из опущенных в процессе обсуждения моментов, который было бы важно подчеркнуть, заключается в том, что все в целом согласны, что Debian примет части systemd. Systemd — это всеобъемлющий проект, включающий в себя множество компонентов, и некоторые из них более значимы, чем другие. Большинство этих частей явно превосходят всё, что мы имеем сейчас на платформе Linux, и они будут использоваться далее в дистрибутиве.

Другими словами, это дебат не о systemd против upstart в обычном смысле. Вопрос, скорее, в том, принимаем ли мы systemd со всеми его составляющими, включая систему инициализации, или же мы берём его подсистемы, но в качестве системы инициализации выбираем upstart. В любом случае, будет работать udev, logind, timedated и другие службы.

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


Это и произошло. Debian Jessie вышла с systemd в качестве менеджера системы, и вслед за Debian systemd был включён в Ubuntu 15.04.

По правда говоря, это пост не о войнах systemd. Если хотите почитать ещё, но лень копаться в списках рассылки, то держите чей-то материал, который отчасти вдохновил меня на этот пост.

Компоненты systemd


System manager


systemd как менеджер системы вводит в систему множество концепций, и основная — это юнит. Юнит является абстрактной сущностью, которая содержит имя, описание и те или иные завимости.

Под каждым юнитом скрывается конфигурационный файл, во многом похожий на Windows .ini файлы.

На момент systemd 234 юниты делятся на 13 типов, вкратце:

  • service. Содержит набор команд и настроек, необходимых для работы демона. Или не демона — в сервисе можно запускать и короткоживущие команды или скрипты. Типичный пример сервиса — sshd.service, демон ssh. Интересный факт: сервисы можно запустить без определения текстового файла через systemd-run.
  • target. Аналог runlevel в sysvinit. Некая точка в жизненном цикле системы, к которой могут «цепляться» другие юниты.
  • timer. С некоторым интервалом запускает связанный с ним юнит. Аналог задач в cron, однако с поддержкой гораздо более богатого синтаксиса правил дат, который можно посмотреть в man systemd.time.
  • mount. Аналог записи в /etc/fstab, даже более того — systemd самостоятельно парсит fstab и динамически создаёт на его основе юнит-файлы. Так, например, через systemctl cat -- -.mount можно увидеть, какой юнит-файл создаётся для корневого раздела.
  • automount. То же самое, что и mount, только монтируется «лениво», при первом доступе.
  • socket. Позволяет запустить связанный с ним сервис отложенно: systemd при запуске сети начинает слушать сокет, а при первом пакете или подключении запускает сервис, передавая ему объект сокета. Требует дополнительной доработки в сервисе (интеграции с libsystemd или с systemd-socket-proxyd).
  • path. Запускает связанный с ним юнит при доступе или изменения пути, будь то файл или каталог.
  • swap. Особый вариант mount, содержит информацию о файле или разделе, выделенный под swap.
  • slice. Концепция подсистемы управления ресурсами systemd. Подробнее можно почитать в посте Red Hat.
  • scope. Внутренняя часть systemd. Этот юнит создаётся при запуске сервиса и используется для объединения процессов в группы и управления ресурсами сервиса.
  • snapshot. У этого юнита, как и у scope, нет конфигурационного файла, он создаётся динамически при выполнении команды systemctl snapshot. Созданный «снимок» будет содержать статус всех юнитов на данный момент, впоследствии на него можно «откатиться» командой systemctl isolate после запуска/остановки сервисов и других юнитов.
  • device. Юнит устройства, такого, как блочное или сетевого устройство. Тесно связан с sysfs/systemd-udevd.
  • nspawn. Юнит systemd-контейнера, о которых чуть позже.

Повторюсь, что каждый юнит содержит секцию зависимостей. Так, сервис может зависеть от статуса target, таргет, в свою очередь, от другого таргета, ещё один сервис может зависеть от таймера, тот — от таргета, и так далее.

journald


Пожалуй, одна из самых популярных частей systemd. В journalctl можно посмотреть всё, что произошло с системой: логи sshd, логи ядра и его драйверов, сообщения о крахах, и многое другое.

История journald: syslog

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

Целью демона syslog является, как понятно из названия, логирование процессов системы. Демон получает от приложений и сервисов сообщения в относительно свободной форме и сохраняет их на диске. Как правило, единственные метаданные сообщения — это facility (примеры: ядро, почта, сеть, и т.д.) и приоритет, а также timestamp, тег процесса и его PID. Большинство этих полей опционально, и точный синтаксис варьируется от реализации к реализации.

syslog не принуждает заполнять все поля, что делает его лёгким в использовании и в то же время мощным в плане расширяемости. В то же время, это его изъян — syslog имеет на руках некоторый беспорядок без строгого формата, и такой результат трудно парсить.

Система syslog уже 30 лет (на момент появления journald), благодаря своей простоте, является незаменимым инструментом администраторов. Однако число ограничений солидно, и со временем они стали заметными проблемами:

  1. В целом, данные сообщений не проходят аутентификацию: любой локальный процесс может заявить, что он Apache с PID 4711, и syslog поверит ему.
  2. Данные записываются в вольном формате. Анализаторы логов должны парсить человеческий язык, чтобы a) опознать тип сообщения, и b) извлечь из него параметры. Это выливается в т.н. «regex horrors» и многие другие неприятные последствия, в том числе для разработчиков программ, которые пишут эти самые логи.
  3. Временные метки не обязаны содержать информацию о временной зоне, даже при том, что новые спецификации дают возможность их передавать.
  4. syslog, хоть и является стандартом, лишь одна из многих систем логирования. Отдельные логи держат utmp/wtmp, lastlog, audit, ядро, логи прошивок, и много других подсистем и приложений.
  5. Чтение логов простое, но крайне неэффективное. Большинство операций с логами имеет сложность O(n). Индексация невозможна.
  6. Сетевой протокол syslog простой, но также крайне ограниченный. Он поддерживает только push-модель, и не применяет модель хранения-передачи, что вытекает в проблемы типа Thundering Herd или потери данных, которые затрудняют использование syslog.
  7. Контроль доступа отсутствует как таковой. Если отставить в сторону всякий скриптинг, администратор может дать пользователю или полный доступ, или ничего.
  8. Автоматическая ротация логов есть, но далека от идеала в большинстве реализаций. Вместо того, чтобы непрерывно мониторить использование диска и реагировать на заполнение, ротация происходит лишь через некоторые интервалы времени. Что открывает дорогу различным DoS-атакам.
  9. Ограничение пропускной способности (rate limit) есть в некоторых реализациях, однако в целом использование диска не учитывается.
  10. Сжатие структуры логов на диске, в целом, присутствует, но, как правило, это просто эффект ротации и ничего хорошего в плане производительности поиска не даёт.
  11. Классический syslog бесполезен в сценариях логирования запуска или остановки системы, впрочем, последние улучшения (в т.ч. и в systemd) улучшили положение дел.
  12. Нельзя логировать бинарные данные, что может быть необходимо в некоторых сценариях (дампы прошивок, блобы ATA SMART или SCSI)

С целью решить эти проблемы и был представлен journald:

  1. Сообщения проходят аутентификацию. Кроме того, метаданные вроде PID или команды процесса journald добавляет самостоятельно, у процесса нет возможности представиться кем-то другим.
  2. Данные структурированы: запись журнала состоит из key-value полей, что упрощает их последующую обработку.
  3. Временные метки состоят из монотонного времени и realtime времени, причём realtime метки хранятся в наносекундах с UNIX epoch в UTC, чтобы избежать проблем с таймзонами.
  4. Функционал journald достаточно универсален, чтобы решить большинство сценариев логирования демонов и приложений.
  5. Журналы хранятся в бинарном виде. Это упрощает хранение, ротацию и индексацию.
  6. Сетевой протокол journald сделан с оглядкой на огрехи существующих систем.
  7. Файлы журналов разделены по пользователям и у каждого свои права доступа. Так, обычный пользователь имеет доступ к логам своих процессов, и не может открыть журнал системы.
  8. Журналы ротируются автоматически при превышении определённых пределов использования места.
  9. По умолчанию логи процессов, которые пишут, скажем, гигабайты отладочных сообщений, подвергаются rate limit-у. При этом делается это аккуратно и исходя из ресурсов файловой системы, оставляя при возможности сообщения с более высоким уровнем.
  10. Данные сжимаются по полям, это обеспечивает хорошие показатели компрессии.
  11. Одна из идей journald — это объединить все различные технологии логирования, такие, как wtmp, логгеры загрузки, логи ядра, и даже логи подсистемы аудита.
  12. Несмотря на то, что основной фокус сделан на ASCII-сообщения в логах, бинарные данные в полях тоже поддерживаются.

О journald

Базовая интеграция с journald элементарна: процессу достаточно писать в stdout/stderr, а дальше подсистема сама разберётся, какой это сервис, сессия пользователя, исполняемая команда и прочие атрибуты.

Для более тесной интеграции понадобится использовать библиотеки: так, например, для Python есть модуль pystemd.journal библиотеки pystemd.

Подробнее про то, как работать с journald, можно узнать из поста Selectel и в man journalctl.

Документ за авторством Леннарта с описанием journald и его тонкостей можно почитать тут.

machined


systemd-machined — часть systemd-nspawn, платформы контейнеров systemd. По концепции контейнеры systemd далеки от, скажем, Docker: когда как Docker — прежде всего, платформа stateless контейнеров, systemd-nspawn является просто способом запустить systemd в stateful контейнере. nspawn гораздо проще Docker: тут нет REST API, нет labels, нет управления сетями, volume и прочим. С одной стороны, это минус контейнеров systemd, с другой — они подойдут тем, кто привык настраивать сеть и окружение самостоятельно.

Главное преимущество systemd-nspawn — это тесная интеграция с экосистемой systemd. Для каждого контейнера создаётся слайс и сервис, ресурсы можно настроить через systemctl set-property, и внутри контейнера systemd работает без проблем.

Подробнее о systemd-nspawn можно почитать на Arch wiki или в посте Selectel.

Другие известные компоненты


  • coredump. systemd-coredump перехватывает крахи процессов и записывает их дампы памяти в свою базу для дальнейшего анализа.
  • logind. systemd-logind управляет жизненным циклом пользователей и их сессиями: создаёт slice под каждого пользователя, запускает getty для логина из консоли, обрабатывает кнопки включения-выключения системы, и прочее.
  • udevd. Отвечает за аппаратную часть системы в userspace: названия сетевых интерфейсов и блочных устройств.
  • hostnamed. Крохотный демон, который отвечает за предоставление имени системы и связанных с системой данных (тип корпуса, ОС, архитектура и т.д.) другим приложениям.
  • timedated и timesyncd управляют настройками, связанными со временем: датой-временем системы, временной зоной, переводом времени и прочим.
  • localed занимается такими параметрами, как язык системы и раскладка клавиатуры.
  • networkd и resolved. Неплохая альтернатива NetworkManager и dnsmasq в сценариях, когда их функционал избыточен.
  • systemd-boot. Простой загрузчик ОС, принципиально совместимый только с UEFI.
  • systemd-homed. Принципиально новый подход к управлению домашними каталогами, настолько новый, что кроме статьи в Arch wiki ничего по нему найти не смог.

Мифы о systemd


systemd монолитен

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

Комплект из почти сотни бинарников назвать монолитным непросто. Впрочем, все релизы systemd распространяются в едином tar-архиве и находятся в одном git-репозитории с единым циклом выпуска.

systemd сложный

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

Конечно, у systemd есть кривая обучения. Она есть у любого софта. Но systemd всё равно остаётся проще больших shell-скриптов, да и проще синтаксиса shell в целом.

В целом, systemd, возможно, настолько прост, насколько системный менеджер может быть простым.

systemd — продукт синдрома «not invented here»

Это неправда. До того, как приступить к systemd, Поттеринг продвигал Upstart, впрочем, потом он пришёл к заключению, что дизайн Upstart неидеален: вместо того, чтобы самой решать проблему зависимостей, система оставляла это администратору. Но это лишь одна из причин.

systemd — это не UNIX

В этом есть некоторая правда: в исходных кодах systemd нет ни одной строки из UNIX. Но разработчики черпают вдохновение из UNIX, взгляните на те же десятки файлов, каждый из которых делает свою задачу. Кроме того, способ ведения проекта (т.е. развитие в одном git-репозитории) во многом похож на модель BSD (который настоящий UNIX, в отличии от Linux).

Вообще, UNIX для каждого значит своё. Для Леннарта Поттеринга и других разработчиков это источник вдохновения, а для кого-то это религия, и, как и у других мировых религий, есть разные трактовки и понимания UNIX: под ним можно понимать стиль кода, набор команд и API, а кто-то считает, что UNIX — это набор логик и поведений.

Конечно, сделать всех этих людей счастливыми просто невозможно.

systemd раздут, это зоопарк разных фич и изменения ради изменений.

systemd наверняка покрывает больше задач, чем должен был. Это давно не просто система инициализации, это система для построения операционной системы.

В то же время, разработчики стараются поддерживать оптимальные размеры systemd, выделять общий код в библиотеки, и сохранять модульность: можно во время сборки выбрать компоненты, которые необходимы, а какие не нужны. То же самое с зависимостями: у systemd меньше десяти обязательных зависимостей, включая систему сборки.

Таким образом, пользователи могут выбирать тот уровень «раздутости» и набор фич, который им необходим.

Кстати, собирается systemd на удивление быстро: на моём i7-8550U сборка ядра v245 заняла 43 секунды.

systemd нестабилен и забагован

Вовсе нет. Мейнтейнеры, по мнению Леннарта, внимательно относятся к issues на GitHub, мониторят багтрекеры дистрибутивов Linux и, надо сказать, число багов довольно мало для такого ключевого компонента ОС.

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

Использование systemd dbus-а вместо сокетов делает его интерфейс непрозрачным

Это утверждение противоречит себе: dbus — это просто стандарт сериализации сообщений поверх обычных сокетов. Формат сообщений документирован и понятен, и к dbus есть множество библиотек для разных языков.

В отличии от различных классических UNIX-демонов, у каждого из которых свои протоколы и форматы.

Я перевёл лишь самую, на мой взгляд, интересную часть мифов. Остальные можете почитать здесь.

В заключение


Сегодня systemd — это больше, чем PID 1: это прослойка между kernel space и приложениями, которая обладает всем, что может понадобиться для работы дистрибутива Linux:

  • Широкий набор инструментов для решения большинства, если не любого, типа задач, связанных с управлением системой.
  • dbus API: почти каждый компонент systemd предоставляет интерфейсы в dbus, системе межпроцессного взаимодействия. Подробнее о dbus можно почитать тут и тут.
  • Модульность: пользователь дистрибутива или его разработчик может убрать, скажем, networkd и resolved, поставить на их место NetworkManager и dnsmasq, и всё будет работать.

Но для меня лично systemd это даже больше, чем middleware: это новая эпоха в истории экосистемы Linux, в одном ряду с KVM, Wine, Kubernetes и другими технологиями.