SSD Nodes Learn 🎉 VPS od $5.50/mies.
Przewodniki Matt ConnorAutor: Matt Connor · Zaktualizowano 2026-08-13

Dlaczego systemd wygrał i zastąpił SysV init

Analiza przyczyn dominacji systemd nad SysV init, Upstart oraz launchd. Wyjaśnienie roli cgroups w śledzeniu procesów oraz powody, dla których dystrybucje przeszły na ten system.

Dlaczego systemd wygrał

Historia systemd rozpoczyna się od dwóch kwestii, których SysV init nie potrafił obsłużyć. SysV init (System V init, system uruchomieniowy odziedziczony przez Linuxa z AT&T Unix) nie posiadał mechanizmu definiowania zależności usług ani sposobu na identyfikację procesów należących do danej usługi po jej uruchomieniu. systemd rozwiązał oba te problemy, wykorzystując funkcje jądra niedostępne dla skryptów powłoki: grupy kontrolne (cgroups) do śledzenia procesów oraz wstępnie otwarte gniazda nasłuchujące do zarządzania kolejnością startu. Dalsza część historii to proces rozprzestrzeniania się tych rozwiązań na pozostałe elementy przestrzeni użytkownika, co stało się zarzewiem kontrowersji. Wiele z podnoszonych wówczas zastrzeżeń było uzasadnionych.

Jak faktycznie działał SysV init

W systemie SysV proces PID 1 (identyfikator procesu 1, pierwszy proces uruchamiany przez jądro) odczytywał /etc/inittab, wybierał poziom uruchomienia (runlevel) i wykonywał skrypty przypisane do tego poziomu. Skrypty znajdowały się w /etc/init.d/. Dowiązania symboliczne w /etc/rc3.d/ decydowały o tym, które z nich zostaną uruchomione i w jakiej kolejności, zatem /etc/rc3.d/S20nginx wskazywało na /etc/init.d/nginx i było wywoływane z argumentem start.

#!/bin/sh
### BEGIN INIT INFO
# Provides:          nginx
# Required-Start:    $local_fs $remote_fs $network $syslog
# Required-Stop:     $local_fs $remote_fs $network $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
### END INIT INFO

case "$1" in
  start)
    start-stop-daemon --start --quiet --pidfile /run/nginx.pid \
      --exec /usr/sbin/nginx
    ;;
  stop)
    start-stop-daemon --stop --quiet --retry TERM/30/KILL/5 \
      --pidfile /run/nginx.pid
    ;;
esac

20 w S20nginx określa pozycję, a nie zależność. Informuje, że dany skrypt uruchamia się po S19, a przed S21. Nie wyjaśnia jednak przyczyny, więc żaden mechanizm nie może tego zweryfikować, a bezpieczne uruchomienie dwóch niezwiązanych ze sobą skryptów w tym samym czasie jest niemożliwe bez ręcznej decyzji administratora.

Program rc uruchamiał każdy skrypt po kolei i oczekiwał na jego zakończenie. Skrypt, który blokował się na trzydzieści sekund w oczekiwaniu na adres sieciowy, wstrzymywał cały proces rozruchu na trzydzieści sekund, nawet w przypadku usług, które w ogóle nie korzystają z sieci.

Nagłówek LSB (Linux Standard Base) na początku skryptu był próbą rozwiązania tego problemu od wewnątrz. W 2011 roku system Debian 6.0 uczynił insserv rozwiązaniem domyślnym: odczytywał on Required-Start z każdego skryptu, budował graf zależności i zmieniał numerację dowiązań symbolicznych. Dzięki temu Debian mógł uruchamiać niezależne skrypty równolegle za pomocą startpar. Pomogło to, ale nie rozwiązało głębszego problemu. Zależność nadal opierała się na zakończeniu działania skryptu. Kod powrotu S20nginx równy 0 oznacza jedynie, że funkcja powłoki zakończyła działanie. Nie oznacza to, że nginx faktycznie akceptuje połączenia.

Pięć problemów, których nie rozwiąże żaden skrypt init

  • Równoległe uruchamianie. Kolejność oparta na nazwach plików wymusza pełne uporządkowanie wszystkich usług w systemie, przez co czas rozruchu jest sumą czasów startu poszczególnych komponentów.
  • Gotowość do pracy. Skrypt startowy kończy działanie w momencie uruchomienia procesu potomnego, a nie w chwili, gdy demon jest gotowy do obsługi żądań, co powoduje, że kolejne skrypty często startują zbyt wcześnie.
  • Nadzór. Demon wykonuje podwójne fork(), a proces nadrzędny kończy działanie, co odłącza usługę od terminala i przypisuje ją do PID 1. Proces init rejestruje zakończenie procesu potomnego i traci wiarygodne powiązanie z procesem, który pozostał w pamięci.
  • Uruchamianie na żądanie. inetd (internet super-server) mógł uruchomić demona w momencie nadejścia połączenia, jednak był to odrębny system z własną konfiguracją, który nie uwzględniał kolejności startu pozostałych usług.
  • Kontrola zasobów. Skrypty init nie pozwalały na ograniczenie zużycia pamięci ani przydziału czasu procesora dla usługi. ulimit dotyczyło tylko jednego procesu, a nice wpływało jedynie na planistę, więc procesy potomne wymykające się spod kontroli były traktowane przez system tak samo, jak każdy inny proces. nice

Luka w nadzorze była problemem najbardziej odczuwalnym w codziennej pracy. Obejściem były pliki PID: demon zapisywał swój identyfikator procesu w /run/nginx.pid, a funkcja stop odczytywała tę wartość. Jeśli demon został nagle ubity, plik pozostawał na dysku. Jądro systemu mogło przydzielić ten numer innemu procesowi, a start-stop-daemon --stop --pidfile wysyłało sygnał do niewłaściwego celu. Nieaktualny plik PID jest przyczyną, dla której skrypt init może zakończyć pracę nieodpowiedniego procesu.

launchd jako pierwszy rozwiązał problem gniazd

Apple wydało launchd w Mac OS X 10.4 w 2005 roku, a jego autorem był Dave Zarzycki. Jeden proces zastąpił init, rc, xinetd, crond oraz watchdogd.

Koncepcją wartą powielenia była aktywacja przez gniazda (socket activation). launchd tworzy wszystkie gniazda nasłuchujące w pierwszej kolejności, a dopiero potem uruchamia demony. Klient, który łączy się z demonem jeszcze nieuruchomionym, nie otrzymuje błędu odmowy połączenia, ponieważ jądro przetrzymuje połączenie w kolejce backlog danego gniazda, dopóki demon nie wywoła accept(). Kolejność uruchamiania między dwoma demonami przestaje być kwestią deklarowaną przez administratora. Zarządza nią gniazdo.

System launchd został zbudowany w oparciu o Mach IPC (inter-process communication), który jest częścią jądra XNU firmy Apple i nie posiada odpowiednika w systemie Linux. Przeniesienie tego kodu nigdy nie było realistyczne. Mimo to idea ta przeniknęła do innych rozwiązań.

Upstart uczynił zdarzenia jednostką pracy

Narzędzie Upstart firmy Canonical, stworzone przez Scotta Jamesa Remnanta, zostało wydane w Ubuntu 6.10 w październiku 2006 roku. Korzystały z niego systemy Fedora od wersji 9 do 14, a także RHEL 6 oraz Chrome OS. Zastąpiło ono poziomy uruchomieniowe (runlevel) zdarzeniami, a zadanie (job) określało, które zdarzenia mają je uruchamiać i zatrzymywać.

# /etc/init/example.conf
start on filesystem and net-device-up IFACE!=lo
stop on runlevel [!2345]
respawn
respawn limit 10 5
exec /usr/local/bin/exampled

Wraz ze wzrostem liczby zadań pojawiły się dwa problemy. Pierwszym jest kierunek zależności. Zadanie deklaruje: „uruchom mnie, gdy wydarzy się to”, więc wiedza o tym, co od czego zależy, znajduje się w niewłaściwym pliku: usługa wie, czego potrzebuje, ale nie może wiedzieć, kto będzie jej potrzebował w przyszłości. Dodanie usługi często wiązało się z edycją istniejącego zadania, aby emitowało ono nowe zdarzenie.

Drugim problemem jest śledzenie procesów. Upstart śledził demony typu forking poprzez zliczanie wywołań fork() za pomocą ptrace, co konfigurowano jako expect fork lub expect daemon. Błędne określenie liczby forków powodowało, że Upstart nadzorował proces, który już zakończył działanie, lub oczekiwał na fork, który już nastąpił. Objawem było zawieszanie się initctl start bez żadnego błędu, czego plik zadania nie pozwalał w żaden sposób wyjaśnić.

Upstart wymagał również od współtwórców podpisania umowy o współpracy z Canonical. Nie był to błąd inżynieryjny, jednak wpłynęło to na to, kto pracował nad tym projektem.

Przemyślenie PID 1, kwiecień 2010

30 kwietnia 2010 roku Lennart Poettering opublikował wpis pod tytułem "Rethinking PID 1". Kay Sievers pracował nad tym projektem wspólnie z nim. Argumentacja składała się z czterech części.

  • Uruchamiaj mniej. Wiele usług może czekać, aż faktycznie zostaną wywołane.
  • Przestań deklarować kolejność tam, gdzie może ją sugerować gniazdo. Otwórz wszystkie gniazda w jednym przebiegu, a następnie uruchom wszystko jednocześnie.
  • Śledź procesy za pomocą grup kontrolnych (cgroups) zamiast plików PID.
  • Opisuj usługę w pliku deklaratywnym, aby jeden opis działał w każdej dystrybucji.

Pierwsze wydanie ukazało się w tym samym roku. Fedora 14 udostępniła systemd jako opcję w listopadzie 2010 roku, a Fedora 15 uczyniła go domyślnym rozwiązaniem w maju 2011 roku.

Dlaczego cgroups zapewniły niezawodność nadzoru

Cgroup (control group) to funkcja jądra służąca do grupowania procesów, wprowadzona do Linux 2.6.24 w 2008 roku. systemd umieszcza każdą usługę w jej własnej grupie cgroup. Proces potomny dziedziczy cgroup po procesie nadrzędnym, a proces bez uprawnień nie może samodzielnie opuścić przypisanej grupy. Podwójne forkowanie nie ukrywa więc żadnych procesów: PID 1 posiada w każdej chwili dokładny zestaw procesów należących do danej jednostki. Zatrzymanie usługi oznacza zabicie wszystkiego, co znajduje się w jej cgroup, co jest działaniem domyślnym KillMode=control-group.

systemctl status wyświetla tę grupę:

● nginx.service - A high performance web server and a reverse proxy server
     Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; preset: enabled)
     Active: active (running) since Tue 2026-08-11 09:14:22 UTC; 3min ago
   Main PID: 1042 (nginx)
      Tasks: 3 (limit: 4653)
     Memory: 6.1M (peak: 7.4M)
     CGroup: /system.slice/nginx.service
             ├─1042 "nginx: master process /usr/sbin/nginx"
             ├─1043 "nginx: worker process"
             └─1044 "nginx: worker process"

Ten blok stanowi pełną odpowiedź na problem nieaktualnych plików PID. Nie istnieje żaden plik, który mógłby stać się nieaktualny, ponieważ lista ta jest stanem jądra.

To samo drzewo przenosi limity, ponieważ cgroups zostały stworzone do celów rozliczeniowych, zanim ktokolwiek zaczął ich używać do śledzenia procesów. MemoryMax=, CPUQuota= oraz TasksMax= to pojedyncze linie konfiguracji. Nałożenie twardego limitu pamięci i CPU na usługę jest obecnie realizowane za pomocą pliku typu drop-in, podczas gdy w 2009 roku wymagałoby to napisania poprawki do skryptu powłoki, czego nikt nie zrobił.

Dlaczego wszystkie dystrybucje dokonały zmiany w latach 2011–2015

  • Fedora 15, maj 2011.
  • openSUSE 12.1, listopad 2011.
  • Mageia 2, maj 2012.
  • Arch Linux, domyślnie dla nowych instalacji od października 2012.
  • RHEL 7, czerwiec 2014.
  • SLES 12, październik 2014.
  • Debian 8, kwiecień 2015.
  • Ubuntu 15.04, kwiecień 2015.

Powody były w większości prozaiczne, co przyspieszyło proces migracji.

  • Jeden plik jednostki działa na każdej dystrybucji, więc projekty upstream zaczęły dostarczać plik .service, a dystrybucje przestały utrzymywać osobne skrypty powłoki dla każdego pakietu i wydania.
  • Śledzenie sesji użytkownika przeniesiono do systemd-logind po tym, jak około 2012 roku zaprzestano utrzymywania ConsoleKit. GNOME wymagało logind, więc dystrybucja bez systemd musiała znaleźć zamiennik. Tym zamiennikiem jest elogind, czyli wyodrębniony i osobno utrzymywany komponent logind z systemd.
  • udev, menedżer urządzeń, został scalony z drzewem źródeł systemd w kwietniu 2012 roku. Dystrybucje dostarczające udev zaczęły śledzić repozytorium systemd. W odpowiedzi Gentoo stworzyło fork eudev.
  • Kontenery zwiększyły znaczenie niezawodnego śledzenia procesów oraz limitów dla poszczególnych usług, ponieważ obie te funkcje opierają się na cgroups. Kwestia tego, który nadzorca zarządza procesem kontenera, pozostaje aktualna za każdym razem, gdy konfiguruje się automatyczne uruchamianie stosu Docker Compose po restarcie.

Decyzja Debiana była najbardziej kontrowersyjna. Komitet Techniczny głosował w lutym 2014 roku; głosy rozłożyły się po równo, a przewodniczący Bdale Garbee oddał decydujący głos na korzyść systemd. Kilka dni później Ubuntu ogłosiło, że podąży za Debianem, zamiast kontynuować rozwój Upstart. Grupa programistów Debiana utworzyła fork dystrybucji o nazwie Devuan w listopadzie 2014 roku i wydała wersję Devuan 1.0 w maju 2017 roku.

Obiekcje przedstawione rzetelnie

Zakres. Jeden projekt dostarcza obecnie PID 1, demona logowania, zarządzanie sesjami użytkowników, menedżer urządzeń, demona konfiguracji sieci, resolver DNS (domain name system), klienta NTP (network time protocol), środowisko uruchomieniowe kontenerów oraz bootloader. Typowa linia obrony, głosząca, że są to oddzielne pliki binarne, których nie trzeba instalować, jest prawdziwa, ale nie odpowiada na zarzut. Gdy środowisko graficzne wymaga logind, a logind jest wydawany w ramach drzewa systemd, wybór przestaje być dobrowolny. To właśnie oznaczało powiązanie (coupling) w tej dyskusji i to właśnie się wydarzyło.

Dziennik binarny. journald zapisuje dane w indeksowanym formacie binarnym zamiast w zwykłym tekście. Zyskuje się funkcje, których tekst nigdy nie oferował: filtrowanie według jednostki i priorytetu, pola strukturalne oraz metadane, których program wysyłający nie może sfałszować, ponieważ journald sam rejestruje jednostkę i cgroup. journalctl -u nginx -p err --since "-1h" zastępuje użycie grep z wyrażeniem regularnym daty. Koszt jest jednak realny. Na maszynie, która nie uruchamia się, nie można odczytać logów za pomocą less z powłoki ratunkowej. Należy wskazać journalctl zamontowany dysk:

sudo journalctl --directory /mnt/var/log/journal --boot -1 --priority err

Istnieje tu druga pułapka, w którą ludzie wpadają raz. journald przechowuje logi w /run/log/journal, czyli w pamięci, chyba że istnieje /var/log/journal. Na maszynie, na której ten katalog nie istnieje, journalctl -b -1 nie wyświetli nic po restarcie, czyli dokładnie w momencie, w którym jest to potrzebne. Należy to sprawdzić i naprawić:

journalctl --disk-usage
sudo mkdir -p /var/log/journal
sudo systemd-tmpfiles --create --prefix /var/log/journal
sudo systemctl restart systemd-journald

journalctl --disk-usage powinno teraz raportować zarchiwizowane dzienniki w /var/log/journal. Jeśli wymagany jest również zwykły tekst, należy ustawić ForwardToSyslog=yes w /etc/systemd/journald.conf i zachować zainstalowany rsyslog.

Możliwość debugowania procesu uruchamiania. Gdy jednostka zawiesza się, konsola wyświetla tylko jeden wiersz:

[  *** ] A start job is running for Wait for Network to be Configured (1min 32s / no limit)

Narzędzia do dalszej diagnostyki istnieją: systemctl list-jobs w trakcie zawieszenia, systemd-analyze blame oraz systemd-analyze critical-chain po fakcie, a także systemd.log_level=debug w wierszu poleceń jądra. Rzetelna wersja tego zarzutu brzmi: skrypt init mógł być odczytany od początku do końca przez każdego, kto znał sh, podczas gdy zawieszona jednostka wymaga wiedzy, po które z kilkunastu poleceń sięgnąć. Jest to realny koszt. Jest on ponoszony raz przez każdego administratora i wielu administratorów poniosło go w tym samym czasie.

Domyślne ustawienie zmieniające się dla wszystkich. W 2016 roku systemd 230 zmienił domyślne zachowanie logind tak, że pozostałe procesy użytkownika były kończone przy wylogowaniu. Odłączone sesje tmux i screen kończyły się, gdy kończyła się sesja, która je zainicjowała. Dystrybucje dostarczyły KillUserProcesses=no w /etc/systemd/logind.conf, a wspieraną odpowiedzią jest loginctl enable-linger <user>. Jedno domyślne ustawienie w jednym projekcie zmieniło nawyk, na którym polegały miliony ludzi, co w praktyce oznacza stwierdzenie „zbyt wiele elementów przestrzeni użytkownika w jednym miejscu”.

Domyślna zależność jako powierzchnia ataku. W marcu 2024 roku backdoor w xz-utils był wymierzony w sshd w systemach Debian i Ubuntu. Oryginalny OpenSSH nie linkuje libsystemd. Dystrybucje te dodały poprawkę, aby sshd mógł zgłaszać gotowość do systemd, a libsystemd pobrało liblzma, w której znajdował się backdoor. Sam protokół gotowości to pojedynczy datagram wysyłany do gniazda wskazanego w $NOTIFY_SOCKET, więc żadna biblioteka nie była do tego wymagana. Odpowiedzią systemd było ładowanie bibliotek kompresji za pomocą dlopen, dzięki czemu nie są one już domyślnie linkowane. Podobna klasa błędów wykazuje ten sam schemat: w 2017 roku wartość User= zaczynająca się od cyfry była traktowana jako nieprawidłowa, a jednostka uruchamiała się jako root zamiast zakończyć się błędem, więc literówka stała się eskalacją uprawnień. Nowsze wersje odmawiają uruchomienia takiej jednostki.

Historia w Twoim własnym wierszu poleceń systemctl

Każdy z powyższych problemów stanowi teraz jedną dyrektywę w pliku, który można odczytać.

  • Sekwencyjny start systemu stał się After= oraz Wants=, a systemd-analyze critical-chain pokazuje, co faktycznie wstrzymało proces uruchamiania.
  • Gotowość do pracy stała się Type=notify, gdzie usługa zapisuje READY=1 do $NOTIFY_SOCKET, gdy jest gotowa do obsługi żądań. Type=forking z PIDFile= nadal istnieje dla starych demonów i jest to typ, który kończy się niepowodzeniem z start operation timed out. Terminating., gdy plik PID nigdy się nie pojawia.
  • Nadzór stał się cgroup, więc Restart=on-failure z RestartSec= zastępuje skrypt opakowujący, a StartLimitBurst= zatrzymuje pętlę awarii przed działaniem w nieskończoność.
  • inetd stał się jednostką .socket umieszczoną obok jednostki .service.
  • ulimit stało się MemoryMax=, CPUQuota= oraz TasksMax=.
  • Linia su - appuser -c w skrypcie init stała się User=, NoNewPrivileges=yes oraz ProtectSystem=strict, dzięki czemu uruchamianie usługi jako użytkownik bez uprawnień jest domyślną formą jednostki, a nie dodatkową pracą.
[Unit]
Description=Example API
Wants=network-online.target
After=network-online.target postgresql.service
Requires=postgresql.service

[Service]
Type=notify
ExecStart=/usr/local/bin/exampled
Restart=on-failure
RestartSec=2
MemoryMax=512M
CPUQuota=50%
TasksMax=128
User=exampled
NoNewPrivileges=yes
PrivateTmp=yes
ProtectSystem=strict
StateDirectory=exampled

[Install]
WantedBy=multi-user.target

Jedna linia w tym pliku to błąd, który każdy popełnia przynajmniej raz. Requires=postgresql.service to wymaganie, a nie kolejność: oznacza, że jednostka kończy się niepowodzeniem, jeśli Postgres zawiedzie, i nie oznacza, że Postgres ma zostać uruchomiony jako pierwszy. Bez After=postgresql.service obie usługi startują w tym samym momencie, a Twoja usługa łączy się z portem, na którym jeszcze nikt nie nasłuchuje. Te dwie opcje są rozdzielone celowo, ponieważ czasami wymagana jest jedna bez drugiej. ProtectSystem=strict montuje system plików w trybie tylko do odczytu dla tej usługi, dlatego StateDirectory= jest obecne: zapewnia usłudze jedną ścieżkę z możliwością zapisu w /var/lib.

Najbardziej czytelnym miejscem, w którym można zobaczyć rozwiązania z 2005 roku na serwerze z 2026 roku, jest SSH w Ubuntu 24.04, który dostarcza systemd 255 według stanu na sierpień 2026. ssh.service jest domyślnie aktywowany przez gniazdo: ssh.socket przechowuje gniazdo nasłuchujące, a sshd uruchamia się, gdy nadejdzie połączenie. Zatem Port 2222 w /etc/ssh/sshd_config nie ma żadnego efektu, ponieważ sshd nie jest procesem, który otworzył port. Zmiana musi zostać wprowadzona w jednostce gniazda.

sudo systemctl edit ssh.socket
[Socket]
ListenStream=
ListenStream=2222

Puste ListenStream= czyści wartość odziedziczoną z jednostki pakietowej. Pozostawienie tego pola pustego spowoduje użycie obu portów, ponieważ systemd dopisuje wartości do listy, zamiast je zastępować. Następnie zastosuj zmiany i sprawdź wynik, utrzymując przez cały czas otwartą drugą sesję SSH:

sudo systemctl daemon-reload
sudo systemctl restart ssh.socket
sudo ss -lntp | grep 2222

ss powinno wyświetlić jedno gniazdo na porcie 2222 należące do systemd, a nie do sshd. To projekt launchd, dwadzieścia lat później, na Twoim VPS. Jeśli wolisz stare zachowanie, sudo systemctl disable --now ssh.socket, a następnie sudo systemctl enable --now ssh.service, zapewni Ci długo działający proces sshd, który ponownie odczytuje Port ze swojej własnej konfiguracji.

To, które z tych szczegółów napotkasz, zależy od wersji, której używasz, więc warto znać różnicę między wydaniem LTS a wydaniem przejściowym Ubuntu przed zaplanowaniem aktualizacji. W przypadku wielu maszyn fakt, że plik jednostki jest wszędzie identyczny, jest powodem, dla którego zarządzanie kilkoma serwerami z jednego miejsca jest obecnie problemem konfiguracyjnym, a nie problemem skryptów powłoki. A kiedy piszesz własne jednostki, para usługi i timera wykonuje zadanie, które w 2009 roku dzieliłbyś między skrypt init a linię cron.

FAQ

Dlaczego dystrybucje Linux zastąpiły SysV init systemem systemd?

Z dwóch powodów inżynieryjnych i jednego dotyczącego utrzymania. SysV init szeregował usługi według nazw plików, co było kwestią kolejności, a nie zależności. System ten tracił również kontrolę nad procesami potomnymi, co prowadziło do sytuacji, w których nieaktualne pliki PID mogły doprowadzić do zamknięcia niewłaściwego procesu. systemd rozwiązał problem kolejności poprzez aktywację gniazd (socket activation) i dyrektywy zależności, a problem śledzenia procesów poprzez grupy kontrolne (cgroups). Powód dotyczący utrzymania wpłynął na szybkość zmian: jeden plik jednostki działa na każdej dystrybucji, więc twórcy oprogramowania dostarczają plik .service, a opiekunowie pakietów przestali pisać osobne skrypty powłoki dla każdego z nich. Fedora 15 wprowadziła tę zmianę w maju 2011 roku, a Ubuntu 15.04 było ostatnią dużą dystrybucją, która przeszła na ten system w kwietniu 2015 roku.

Czy systemd to jeden wielki plik binarny?

Nie. Drzewo źródeł buduje wiele oddzielnych programów. PID 1 to /usr/lib/systemd/systemd, podczas gdy journald, logind i udevd to osobne procesy z własnymi plikami binarnymi; uruchom ls /usr/lib/systemd/, aby zobaczyć je na własnym systemie. Krytyka, która przetrwała, dotyczy powiązania wydań, a nie rozmiaru plików binarnych: programy te są wydawane razem i współdzielą prywatne interfejsy, więc dystrybucje zazwyczaj traktują je jako zestaw, a oprogramowanie takie jak GNOME zaczęło wymagać konkretnie logind.

Czy nadal mogę używać systemu Linux bez systemd?

Tak. Devuan dostarcza sysvinit, Gentoo domyślnie używa OpenRC, Void korzysta z runit, Alpine używa busybox init z OpenRC, a Slackware zachowuje skrypty w stylu BSD. Kosztem jest konieczność wykonania prac związanych z kompatybilnością. Oprogramowanie desktopowe wymagające logind potrzebuje elogind, czyli logind z systemd utrzymywanego jako samodzielny pakiet. Ponadto coraz więcej oprogramowania serwerowego dostarcza wyłącznie plik .service, więc skrypt startowy trzeba napisać i utrzymywać samodzielnie.

Dlaczego dziennik jest binarny, a nie w formacie zwykłego tekstu?

Ponieważ journald przechowuje ustrukturyzowane pola z indeksem, co umożliwia filtrowanie według jednostek, priorytetów oraz metadanych, których wysyłający program nie może sfałszować: journald rejestruje jednostkę, cgroup oraz rzeczywisty UID, zamiast ufać linii logu. Ceną jest konieczność użycia journalctl do odczytu, również w systemie ratunkowym, gdzie wskazuje się zamontowany dysk za pomocą journalctl --directory /mnt/var/log/journal. Jeśli wymagany jest również format tekstowy, należy ustawić ForwardToSyslog=yes w /etc/systemd/journald.conf.

Co zastąpiło edycję skryptów w /etc/init.d?

Pliki typu drop-in. Nie należy edytować jednostki w /usr/lib/systemd/system/, ponieważ aktualizacja pakietu nadpisze zmiany. Uruchom sudo systemctl edit nginx.service, a systemd utworzy /etc/systemd/system/nginx.service.d/override.conf, który zostanie scalony z jednostką z pakietu. systemctl cat nginx.service wyświetla scalony wynik, a systemd-delta wymienia wszystkie nadpisania w systemie. Po każdej ręcznej edycji należy uruchomić sudo systemctl daemon-reload, w przeciwnym razie kolejne polecenie wyświetli Warning: The unit file, source configuration file or drop-ins of nginx.service changed on disk.

#systemd#linux#init#sysvinit#history