У Linux існують спеціальні служби — демони, які працюють у фоновому режимі та обслуговують інші програми. Ініціалізація та управління демонами відбувається за допомогою спеціального процесу ініціалізації. Ядро відразу після свого завантаження запускає процес ініціалізації, який призводить до запуску всіх необхідних служб та програм. Для цього зчитується відповідний конфігураційний файл і на основі описаних в ньому параметрів починається запуск системи. Цей процес ініціалізації є головним (або “батьківським”) процесом, який переводить систему зі стану «ядро запущено» до стану «система готова до роботи».
Примітка: У системі ініціалізації SysV головним є процес init, а в системі ініціалізації systemd — (однойменний) процес systemd.
З часом у Linux з’явилася багато різних систем ініціалізації. У цій статті ми розглянемо найбільш популярні з них, а також порівняємо SysV та systemd.
Суперечки навколо систем ініціалізації Linux
System V init (або просто “SysV”) — це система ініціалізації, яка існує з часів операційної системи System V, реліз якої відбувся у 1983 році. SysV залишалася системою ініціалізації протягом майже трьох десятиліть (за деякими винятками). Багато IT-фахівців і програмістів через свою звичку не хотіли відмовлятися від SysV, та й до того ж вона була дуже простою для розуміння
Проблема з SysV полягала в тому, що в її основі лежали концепції, що існували багато років тому. SysV не вистачало можливості нативно обробляти такі речі, як виявлення знімних носіїв, коректне виявлення апаратного забезпечення та завантаження вбудованого ПЗ, завантаження різних модулів тощо. Крім того, при використанні даної системи, ініціалізація процесів відбувається послідовно, тобто одна задача запускається лише після успішного завершення попередньої. Часто це призводило до затримки та довгого завантаження. Задачі, подібні до монтування файлових систем, виконуються один раз під час завантаження, після чого “забуваються”. Але такого підходу недостатньо для автоматизованого управління сервісами, що потребують постійної уваги.
У спробі додати більше можливостей у процес ініціалізації Linux-систем, компанія Canonical у 2006 році разом із релізом Ubuntu 6.10 (Edgy Eft) випускає систему ініціалізації Upstart, яка спочатку розроблялася з урахуванням зворотної сумісності. Вона може запускати демони без будь-яких змін у їх скриптах запуску.
Іншою системою ініціалізації, коріння якої ведуть до операційної системи 4.4BSD, є rc.init. Вона застосовується у таких дистрибутивах, як: FreeBSD, NetBSD та Slackware. У 2007 році розробники Gentoo випустили покращений варіант даної системи ініціалізації, зробивши її модульною та назвавши OpenRC. Більшість інших дистрибутивів Linux історично продовжували використовувати SysV.
У 2010 році інженери компанії Red Hat Леннарт Поттерінг і Кей Сіверс розпочали розробку нової системи ініціалізації — systemd, в якій враховувалися недоліки SysV. До складу systemd, крім іншого, також входять і різні пакети, утиліти та бібліотеки, що дозволяють проводити паралельний запуск процесів, скорочуючи тим самим час завантаження системи та кількість необхідних обчислень. Весною того ж року Fedora 15 стала першим дистрибутивом, у якому за замовчуванням використовувалася система ініціалізації systemd. Після чого, протягом наступних трьох років, більшість дистрибутивів масово перейшли на systemd.
Але якщо всі інші дистрибутиви надають перевагу systemd та вважають її кращою системою ініціалізації, як для компаній, так і для звичайних користувачів, то чому так багато суперечок навколо неї?
systemd, в порівнянні з SysV та Upstart, містить велику кількість різних покращень, а також пропонує й інші компоненти, які мають більш тісну інтеграцію з системою, за допомогою яких розробники можуть зменшити обсяг роботи, що виконується. Що в цьому поганого? Ну, оскільки розробники створюють програмне забезпечення, яке залежить від systemd та/або від будь-якої з її численних служб (journald, udevd, consoled, logind або networkd), то таке програмне забезпечення стає менш сумісним із системами, в яких systemd не використовується. У міру того, як зростає кількість служб, що надає systemd, сама система ініціалізації systemd стає все більш залежною від них.
В результаті systemd стає самостійною платформою, і її широке розповсюдження ненавмисно перешкоджає розробці програмного забезпечення, яке є “переносним” і сумісним з операційними системами, що не підтримують systemd. Але чи насправді все настільки погано? Звичайно, що ні. Насамперед, це проект із відкритим вихідним кодом, і люди мають вибір: використовувати його чи ні. Користувачі та розробники можуть отримати вигоду з наявності кількох конкуруючих систем ініціалізації, і немає вини systemd у тому, що основні дистрибутиви переключилися на неї через її переваги.
Системи ініціалізації Linux
SysV
System V init (або просто “SysV”) — це система ініціалізації, яка існує з часів ОС System V.
Примітка: System V — це перша комерційна UNIX-подібна операційна система, реліз якої відбувся у 1983 році.
Процес init (від англ. “initialization”) — це перший процес, що запускається в системі (крім завантаження ядра), який є батьком (прямим або непрямим) всіх інших запущених процесів, і якому присвоюється PID=1.
Якщо процес init з будь-яких причин не зміг стартувати, то не відбудеться запуску наступних процесів і система перейде в особливий (викликаний появою критичної помилки) стан ядра, що називається Kernel Panic.
SysV має шість станів системи, відомих як рівні виконання (runlevels), і всім процесам та службам зіставляється певний рівень виконання. Дана система ініціалізації також пропонує прості у використанні команди та методи для управління рівнями виконання та пов’язаними з ними службами.
Runlevel 0 — завершує роботу системи.
Runlevel 1 — однокористувацький режим роботи. Найчастіше використовується з метою обслуговування та виконання інших адміністративних завдань. Цей рівень також може називатися Runlevel S (від англ. “Single-user”). Якщо вам коли-небудь доводилося скидати пароль на Linux, то ви, ймовірно, вже користувалися цим режимом.
Runlevel 2 — багатокористувацький режим роботи (англ. “multi-user”) без підтримки мережевих служб.
Runlevel 3 — багатокористувацький режим з підтримкою мережі, але без графічного інтерфейсу. Найчастіше серверні версії Linux працюють саме на цьому рівні виконання.
Runlevel 4 — не використовується. Користувач може налаштовувати цей рівень під свої потреби.
Runlevel 5 — схожий на режим 3, але тут запускається графічний інтерфейс. У цьому режимі працюють десктопні версії Linux.
Runlevel 6 — перезавантажує систему.
Значення для кожного рівня виконання змінюються залежно від дистрибутива Linux. Є дистрибутиви (наприклад, Ubuntu), які використовують Runlevel 2 для багатокористувацького графічного режиму з підтримкою мережі, інші дистрибутиви (наприклад, Fedora) для того ж самого використовують Runlevel 5.
В операційній системі, що використовує SysV, ядро запускає файл /sbin/init, який, у свою чергу, завантажує параметри та виконує директиви, визначені у конфігураційному файлі — /etc/inittab. Цей файл визначає рівні виконання для всієї системи та для яких терміналів слід створювати getty (процеси ініціалізації терміналу), запускає процеси входу в термінал, запускає скрипт /etc/init.d/rcS, а також впливає на порядок виконання інших runlevel-скриптів.
Запуск служб відбувається у заздалегідь визначеній послідовності. Наступний скрипт у ланцюжку запуску виконується лише у тому випадку, якщо було виконано попередній скрипт. Якщо під час свого виконання скрипт зависне, то наступному скрипту доведеться чекати, поки у поточного не закінчиться час очікування. Ця непередбачена затримка виконання скрипта робить весь процес ініціалізації системи менш ефективним і, зрештою, повільнішим.
Крім цього, SysV має проблеми з так званим “hot-plug” підключенням пристроїв: якщо операційна система вже завантажилася і перебуває в робочому стані, і ви підключаєте до неї USB-пристрій, то SysV не розпізнає цей USB-пристрій.
В ОС, що використовує систему ініціалізації SysV, зазвичай є спеціальна програма, яка використовується для управління службами під час роботи системи. Ви можете перевірити стан служби або всіх служб, а також запустити або зупинити службу за допомогою наступних команд:
# service <ім'я_служби> status (відображення статусу конкретної служби)
# service --status–all (відображення статусу всіх служб)
# service <ім'я_служби> start|stop (запуск/зупинка конкретної служби)
systemd
systemd — це відносно нова система ініціалізації Linux, що представляє собою набір утиліт для запуску та управління всіма типами процесів та служб (а також пристроями, сокетами, точками монтування, областю підкачки, модулями та ін.).
Основні цілі проектування даної системи ініціалізації, за словами Леннарта Поттерінга, провідного розробника systemd, полягають у тому, щоб “запускати менше, розпаралелювати більше”. Це означає, що ви запускаєте тільки ті процеси, які сто відсотків необхідні для приведення системи в робочий стан, і одночасно виконуєте якнайбільше подібних задач. Усі виклики, які раніше (при використанні SysV) були “розмазані” по безлічі різних скриптів, тепер виконуються одним файлом — lib/systemd/systemd. Спочатку система випускалася під ліцензією GNU GPL, але згодом її змінили на GNU LGPL.
Процес systemd (від англ. “system management daemon”) — це системний демон, який (подібно до процесу init) є батьком (прямим або непрямим) всіх інших процесів, і має PID=1. Разом з системою були введені і нові поняття:
Unit — це модуль, що відповідає за окремо взяту службу, точку монтування, підключений пристрій, файл підкачки, віртуальну машину тощо.
Target — це аналог рівнів виконання з SysV, який складається з декількох юнітів.
systemd виконує unit для досягнення target. Інструкції для кожного пристрою знаходяться в каталозі /lib/systemd/system/.
Для управління службами в systemd використовується спеціальна утиліта — systemctl. Наприклад:
# systemctl enable sshd (підключення sshd)
# systemctl start sshd (запуск sshd)
# systemctl stop sshd (зупинка sshd)
# systemctl status sshd (відображення стану sshd)
# systemctl list-units (відображення списку модулів)
Ще однією важливою програмою в наборі інструментів systemd є утиліта journalctl. Вона дозволяє переглядати та керувати демоном логів journald. Лог-файл systemd є двійковим файлом, і використання journalctl дуже спрощує роботу з ним. Ось кілька прикладів:
# journalctl –all (відображення змісту всього лог-файлу)
# journalctl -b (відображення даних лог-файлу з моменту останнього завантаження)
# journalctl -b -p err (відображення помилок при останньому завантаженні)
Плюси використання системи ініціалізації systemd:
Новий, сучасний та ефективний дизайн.
Простіший процес завантаження.
Паралельна обробка задач при завантаженні системи.
Покращений API.
Простий синтаксис unit-файлів.
Можливість видалення додаткових компонентів.
Низький рівень споживання ресурсів.
Покращений механізм залежностей.
Інструкція ініціалізації процесів зберігається у файлі конфігурації, а не в скрипті оболонки.
Планування задач з використанням systemd Calendar Timers.
Ведення лог-файлу за допомогою служби journald.
Лог-файли зберігаються у двійкових файлах.
Стан systemd може бути збережено для подальшого виклику в майбутньому.
Відслідковування виконуваного процесу через механізм контейнеризації cgroup.
Вхід користувачів у систему керується за допомогою systemd-logind.
Покращена інтеграція з GNOME для забезпечення сумісності.
Мінуси використання системи ініціалізації systemd:
Все зібрано в одному місці.
Не відповідає стандартам POSIX.
Відсутність кросплатформності (тобто “переносимості”).
| Дистрибутиви Linux | Інтеграція |
| Fedora | Так (це перший дистрибутив, який перейшов на systemd). |
| Arch | Так. |
| RHEL | Так. |
| CentOS | Так. |
| Debian | Так, починаючи з 8 версії. |
| OpenSUSE | Так. |
| Slackware | Ні. |
| Ubuntu | Так. |
Upstart
Upstart — це гібридна система ініціалізації (можуть використовуватися як скрипти запуску SysV, так і сценарії systemd), створена розробниками дистрибутива Ubuntu як заміна системи ініціалізації SysV. На відміну від SysV, яка створювалася для роботи у статичному середовищі, Upstart призначалася для роботи у більш гнучкому середовищі.
У порівнянні з SysV, в Upstart можна виділити три основні переваги: управління службами на основі подій (замість рівнів виконання), асинхронний запуск служб і автоматичний перезапуск аварійно завершених служб.
Основна відмінність від SysV полягає в тому, що Upstart реалізує керовану подіями модель, яка дозволяє асинхронно реагувати на основні етапи запуску служб по мірі їх виконання. Для цього в Upstart існують завдання, прописані у файлах /etc/init/*.conf, метою яких є виконання секції скрипта, яка відповідає за створення процесу. Таким чином, ініціалізація системи може бути виражена у вигляді послідовного набору правил “створювати процес X при настанні події Y”.
Коли відбувається будь-яка подія, Upstart виявляє цю подію і вносить необхідні зміни. Подією може бути все, що пов’язано з різними станами системи, наприклад: USB-накопичувач підключається/виймається із системи або запускається/зупиняється служба.
Але і дана система ініціалізації має свої мінуси. Оскільки в її основі закладено модель реагування на події, то замість виконання абсолютного мінімального обсягу роботи, необхідного для приведення системи в робочий стан, при спрацюванні події Upstart виконує всі завдання, які можуть бути наступними у черзі після події. Наприклад, якщо мережа запустилася, це ще не означає, що NFS (скор. від “Network File System”) також повинна запуститися. Насправді коректна послідовність є протилежною: коли користувач запитує доступ до загального ресурсу NFS, система повинна перевірити, що мережа запущена і працює.
Для управління рівнем запуску різних служб в Upstart використовується спеціальна утиліта — initctl, наприклад:
$ initctl status <job> (відображення стану служби)
$ initctl list (відображення списку служб)
# initctl start|stop <job> (запуск/зупинка служби)
OpenRC
OpenRC — це кросплатформна система ініціалізації на основі залежностей, яка сумісна з SysV. Незважаючи на те, що OpenRC вносить деякі покращення в SysV, вона не є її абсолютною заміною.
Особливості OpenRC:
Може працювати у багатьох дистрибутивах Linux, включно з Gentoo.
Скрипти ініціалізації з відслідковуванням стану.
Обмеження ресурсів кожної служби.
Завантаження на основі залежностей.
Запускається у вигляді демона.
Паралельний запуск служб та багато іншого.
runit
runit — також кросплатформна система ініціалізації, яка може працювати на Solaris, операційних системах сімейства BSD та macOS. Загалом дуже схожа на SysV. Може використовуватися сама по собі або як альтернатива для SysV, systemd, а також у поєднанні з OpenRC.
До основних переваг runit відносяться:
Швидке завантаження та вимкнення системи.
Логування результатів виконання процесу та ротації логів.
Автоматичне вимкнення та запуск сервісів при появі нових сервісів у списку, або видаленні старих зі списку.
Можливість ведення декількох незалежних списків сервісів одночасно (наприклад, для кожного користувача окремо і для систему в цілому).
Кросплатформність.
Порівняння SysV та systemd
| Функції | SysV | systemd |
| Залежність D-Bus | Ні | Так |
| Управління пристроями за допомогою udev | Ні | Так |
| Активація по таймеру | cron/at | Пропрієтарна |
| Управління квотами | Ні | Так |
| Автоматична обробка залежностей служб | Ні | Так |
| Завершення процесів користувачів при виході з системи | Ні | Так |
| Управління простором підкачки | Ні | Так |
| Інтеграція SELinux | Ні | Так |
| Підтримка шифрованих HDD | Ні | Так |
| Завантаження статичних модулів ядра | Ні | Так |
| Графічний інтерфейс користувача (GUI) | Ні | Так |
| Перерахування всіх дочірніх процесів | Ні | Так |
| Сумісність з SysV | Так | Так |
| Інтерактивне завантаження | Ні | Так |
| Кросплатформність (можливість використовуватися на відмінній від x86 архітектурі процесора) | Так | Ні |
| Паралельний запуск служб | Ні | Так |
| Обмеження ресурсів для кожної служби | Ні | Так |
| Скрипт автозавантаження, що легко розширюється | Так | Ні |
| Окремі код та файл конфігурації | Так | Ні |
| Автоматичний розрахунок залежностей | Ні | Так |
| Детальне виведення інформації відлагодження | Так | Ні |
| Кількість файлів | 75 файлів | 900 файлів + Glib + D-Bus |
Як визначити, яка система ініціалізації в мене?
Спосіб №1: Команда ps
За допомогою команди ps ми можемо відобразити інформацію про активний процес, а за допомогою команди grep вказати необхідні фільтри для визначення поточної системи ініціалізації:
# ps -p1 | grep "init\|upstart\|systemd"

Debian 11 (Testing)

Fedora 34 Workstation
Як ви можете бачити, у Debian та Fedora використовується система ініціалізації systemd.
У разі використання системи ініціалізації SysV, вивід команди буде наступним:

MX Linux 19.4
Якщо ж у вас використовується система ініціалізації Upstart, то ви побачите:
# ps -p1 | grep "init\|upstart\|systemd"
1 ? 00:00:00 upstart
Спосіб №2: Команда rpm
rpm (скор. від “Red Hat Package Manager”) — це потужна консольна утиліта управління пакетами у дистрибутивах RHEL, CentOS, Fedora, openSUSE та Mageia. Команда rpm дозволяє встановлювати, оновлювати, видаляти, запитувати та перевіряти програмне забезпечення.
Щоб дізнатися, яка система ініціалізації встановлена, потрібно виконати наступну команду:
# rpm -qf /sbin/init
Примітка: /usr/sbin/init або /sbin/init — це виконуваний файл, який запускає систему ініціалізації SysV. З міркувань сумісності при встановленні systemd файл /sbin/init є псевдонімом (або символьним посиланням) виконуваного файлу системи ініціалізації systemd.

Fedora 34 Workstation
У разі використання системи ініціалізації SysV, вивід буде наступним:
# rpm -qf /sbin/init
SysVinit-2.86-17.el5
У разі використання системи ініціалізації Upstart, вивід буде наступним:
# rpm -qf /sbin/init
upstart-0.6.5-16.el6.x86_64
Важлива примітка
Може статися так, що, використовуючи ОС з systemd в якості системи ініціалізації та набравши в терміналі команди pidof init та pidof systemd, ми побачимо наступний результат:

Debian 11 (Testing)
Тобто PID=1 призначено процесу init, а процес systemd має PID=909. Виходить, що ми використовуємо SysV? Але ж ми впевнені в тому, що встановлювали дистрибутив (Debian) із системою ініціалізації systemd! Це можна перевірити за допомогою наступної команди:
$ sudo ps -p1 | grep "init\|upstart\|systemd"

Debian 11 (Testing)
То чому ж виникла плутанина з pidof? Якщо ми перевіримо тип файлу /sbin/init (який є файлом, що запускає систему ініціалізації SysV), то побачимо, що в нашому випадку /sbin/init є символьним посиланням на /lib/systemd/systemd (головний файл системи ініціалізації systemd):

Debian 11 (Testing)
Таким чином у нашій ОС використовується саме systemd.
