Jak poprawić czas uruchamiania systemu Linux: systemd-analyze i sprzątanie usług

0
5
Rate this post

Nawigacja:

Punkt wyjścia – co oznacza „szybki start” systemu Linux

Czas do ekranu logowania a rzeczywista gotowość systemu

Wiele osób patrzy tylko na czas, po którym pojawia się ekran logowania lub pulpit. To jednak dopiero część historii. System może wyświetlać menedżera logowania (GDM, SDDM, LightDM), a w tle nadal startują usługi sieciowe, indeksery plików czy montowane są zdalne zasoby.

Z punktu widzenia użytkownika liczą się co najmniej dwa momenty:

  • czas do ekranu logowania / pulpitu – kiedy można się zalogować lub zobaczyć środowisko graficzne,
  • czas do pełnej gotowości – kiedy sieć działa stabilnie, dyski są zamontowane, aplikacje startują bez opóźnień.

Systemd-analyze mierzy głównie czas do „userspace” i startu targetu (np. graphical.target), czyli pierwszego momentu, kiedy zasadnicze usługi zostały podniesione. To w praktyce zbliża się do czasu pojawienia się ekranu logowania, ale nie jest z nim tożsame. Dlatego podczas optymalizacji warto sprawdzać nie tylko liczby z systemd-analyze, ale też subiektywne odczucie płynności tuż po starcie.

Realne czasy uruchamiania na HDD, SSD i NVMe

Sprzęt ma ogromne znaczenie. Twarde dyski talerzowe drastycznie spowalniają start, szczególnie jeśli initramfs i katalogi systemowe są rozrzucone po różnych sektorach. SSD i NVMe minimalizują opóźnienia dostępu, przez co wąskim gardłem staje się głównie ilość usług i ich zależności.

Orientacyjne, realne poziomy (przy typowych dystrybucjach, bez ekstremalnego tuningu):

  • HDD – 20–60 s do pulpitu graficznego, pełna gotowość często powyżej 60 s przy ciężkim środowisku (np. GNOME + dużo usług).
  • SSD (SATA) – 10–25 s do pulpitu, przy rozsądnym sprzątaniu usług zejście w okolice 8–15 s jest jak najbardziej możliwe.
  • NVMe – 5–15 s do pulpitu, przy lekkim środowisku i zachowawczym podejściu do usług 3–7 s do używalnego systemu nie jest niczym rzadkim.

Nie ma sensu oczekiwać od starego HDD czasu startu jak na NVMe – lepiej wtedy skupić się na stabilności i wygodzie niż na śrubowaniu każdej sekundy. Przy nowoczesnych dyskach ogromne zyski daje usunięcie zbędnych usług i skrócenie krytycznego łańcucha startu.

Co faktycznie da się przyspieszyć, a czego lepiej nie ruszać

Cały łańcuch startu można podzielić na kilka etapów. Nie wszystkie poddają się tej samej optymalizacji. Najłatwiej ruszyć warstwę userspace zarządzaną przez systemd, czyli to, co mierzy i pokazuje systemd-analyze blame oraz critical-chain.

Można sensownie przyspieszyć:

  • liczbę i konfigurację usług systemd (sprzątanie unitów, zmiana trybu startu),
  • intensywność operacji dyskowych w pierwszych sekundach (indeksery, skanery, inicjalizacja snap/flatpak),
  • opóźnienia sieciowe (szczególnie DHCP i montowanie zdalnych zasobów),
  • pewne parametry initramfs i jądra (niepotrzebne hooki, zbędne moduły ładowane na starcie).

Trudniej ruszyć lub zwykle nie ma sensu ingerować w:

  • czas firmware/UEFI (chyba że w BIOS można wyłączyć skanowanie nieużywanych urządzeń, fast boot itp.),
  • czas ładowania samego jądra – poza aktualizacją, doborem odpowiedniego kernela lub minimalnym tuningiem parametrów startowych,
  • czas bootloadera (GRUB) – można go skrócić zmniejszając timeout, ale to kwestia sekund.

Największy wpływ na praktyczny czas do gotowego systemu ma to, co dzieje się w userspace po starcie systemd, czyli usługi, mounty, timery i zależności między nimi.

Rola firmware, bootloadera i jądra w całym łańcuchu

Łańcuch startu można podsumować tak:

  1. Firmware (BIOS/UEFI) – testuje sprzęt, inicjuje urządzenia, szuka bootowalnego dysku.
  2. Bootloader (np. GRUB, systemd-boot) – prezentuje menu wyboru systemu, ładuje kernel i initramfs.
  3. Jądro (kernel) – inicjalizuje sterowniki, montuje rootfs (często poprzez initramfs), uruchamia proces PID 1 (systemd).
  4. Init (systemd) – startuje unit-y, targety, montuje dodatkowe systemy plików, uruchamia sieć, loginy, środowisko graficzne.

Systemd-analyze pozwala zmierzyć osobno sekcje firmware, loader, kernel i userspace. Z punktu widzenia optymalizacji przy użyciu systemd-analyze i „sprzątania usług” interesuje głównie userspace, ale warto mieć świadomość, czy dużym problemem nie jest np. bardzo długo startujący firmware.

Jak działa rozruch systemd – minimum teorii potrzebne do praktyki

Fazy rozruchu: od firmware do systemd

Po wybraniu systemu w bootloaderze kontrolę przejmuje jądro, które po inicjalizacji uruchamia proces PID 1. W większości nowoczesnych dystrybucji jest to systemd. Od tego momentu to systemd odpowiada za start usług, montowanie systemów plików, aktywację gniazd, timerów i przygotowanie środowiska do logowania.

Systemd nie odpala wszystkiego po kolei w jednej linii. Używa modelu jednostek (unitów) i targetów, aby równolegle uruchamiać wiele zadań, pilnując jedynie zadeklarowanych zależności. Dlatego nawet niewielka zmiana w zależnościach potrafi mocno skrócić lub wydłużyć czas startu.

Podstawowe pojęcia: unit, target, dependency, service, timer, mount

W systemd kluczowe jest zrozumienie kilku typów jednostek:

  • service – klasyczna usługa/demon (np. sshd.service, NetworkManager.service).
  • socket – gniazdo sieciowe lub UNIX, które może wybudzić usługę (socket activation).
  • target – grupa jednostek, logiczny punkt w procesie startu (np. multi-user.target, graphical.target).
  • mount – montowanie systemów plików (np. /home, /var, sieciowe zasoby).
  • timer – odpowiednik crona w świecie systemd (planowane zadania, np. aktualizacje, sprzątanie logów).

Pomiędzy unitami definiowane są zależności (dependencies):

  • Requires= – twarda zależność, bez niej target/usługa nie ruszy.
  • Wants= – miękka zależność, sugerowana, ale nie krytyczna.
  • Before=/After= – kolejność, niekoniecznie zależność istnienia.

Czas rozruchu w dużej mierze zależy od tego, jak te zależności są ustawione. Jeżeli wiele usług ma After=network-online.target, a sieć długo negocjuje DHCP, łańcuch krytyczny rozciąga się z powodu jednego wąskiego gardła.

Równoległe uruchamianie usług i wpływ zależności

Systemd domyślnie uruchamia usługi równolegle, wszędzie tam, gdzie to bezpieczne. To ogromna przewaga nad starymi systemami typu SysVinit, gdzie wszystko szło bardziej liniowo. Jednak błędnie skonfigurowane zależności potrafią to zniweczyć.

Jeśli jakaś usługa ma After= i jednocześnie Requires= do innej wolno startującej jednostki, staje się od niej bezpośrednio zależna. Jeżeli dodatkowo powiązany jest z nią target docelowy (np. graphical.target), to cała ścieżka musi się zakończyć, zanim pojawi się pulpit.

Optymalizacja polega często na:

  • usunięciu zbędnych Requires= na rzecz Wants=,
  • odsunięciu części usług poza krytyczny łańcuch,
  • konfiguracji tak, by usługi uruchamiały się tylko wtedy, gdy naprawdę są potrzebne.

Rola default.target: multi-user.target vs graphical.target

Docelowy stan systemu określa default.target. W typowej stacji roboczej będzie to graphical.target, co oznacza, że system ma podnieść usługi wieloużytkownikowe oraz środowisko graficzne. Na serwerze bardzo często defaultem jest multi-user.target (odpowiednik „runlevel 3” – bez X-ów).

Można sprawdzić aktualny target:

systemctl get-default

Zmiana docelowego targetu na multi-user.target na desktopie ma sens tylko wtedy, gdy naprawdę nie potrzebujesz środowiska graficznego przy starcie, a uruchamiasz je ręcznie (np. startx). W innych przypadkach optymalizacja odbywa się w obrębie wybranego targetu, głównie poprzez redukcję usług włączonych w tym stanie.

Zbliżenie na nowoczesną płytę główną z mikrochipami i ścieżkami
Źródło: Pexels | Autor: Johannes Plenio

Podstawowe narzędzia pomiaru – systemd-analyze w praktyce

systemd-analyze time: firmware, loader, kernel, userspace

Polecenie, od którego zwykle zaczyna się diagnostykę:

systemd-analyze time

Przykładowy wynik:

Startup finished in 3.5s (firmware) + 1.2s (loader) + 1.8s (kernel) + 6.4s (userspace) = 12.9s

Interpretacja:

  • firmware – działania BIOS/UEFI, testy POST, skanowanie urządzeń.
  • loader – czas spędzony w bootloaderze (np. ekran GRUB, odliczanie).
  • kernel – inicjalizacja jądra, sterowników, rootfs.
  • userspace – wszystko, co robi systemd i reszta usług po starcie kernela.

Jeśli firmware zajmuje 8–10 sekund, a userspace 4 sekundy, praca nad usługami da ograniczone efekty. Gdy natomiast userspace trwa kilkanaście sekund lub więcej, systemd-analyze blame i critical-chain stają się podstawowym narzędziem.

systemd-analyze blame: lista najwolniejszych usług

Kolejny krok:

systemd-analyze blame

Wyświetla listę usług i jednostek wraz z ich czasem startu, posortowaną malejąco. Fragment takiej listy może wyglądać tak:

10.123s NetworkManager-wait-online.service
 4.567s plymouth-quit-wait.service
 2.345s snapd.service
 1.234s apt-daily.service
 ...

Blame jest tylko listą najdłużej trwających unitów, niekoniecznie odpowiedzialnych za opóźnienie całego systemu. Usługa może startować długo, ale robić to równolegle i w ogóle nie leżeć w krytycznym łańcuchu. Dlatego blame to filtr wstępny, a nie wyrocznia.

systemd-analyze critical-chain: prawdziwy łańcuch blokujący

Kluczowe narzędzie do wykrywania, co naprawdę opóźnia osiągnięcie docelowego targetu:

systemd-analyze critical-chain

Wynik pokazuje usługi w kolejności istotnej dla osiągnięcia targetu, wraz z opóźnieniami i relacjami After=. Przykładowy fragment:

graphical.target @10.345s
└─multi-user.target @10.344s
  └─network-online.target @8.000s
    └─NetworkManager-wait-online.service @2.000s +6.000s
      └─NetworkManager.service @1.000s +1.000s
        └─...

Tutaj od razu widać, że NetworkManager-wait-online.service i network-online.target leżą w krytycznym łańcuchu i blokują przejście do multi-user.target, a przez to także do graphical.target. To dużo ważniejsze niż sama informacja z blame, że dana usługa trwa 6 sekund.

Przykładowa sesja analizy – pierwszy przegląd problemów

Praktyczna sekwencja dla nowego systemu, który startuje wolniej niż oczekiwano:

  • Uruchom system, nie rób nic poza zalogowaniem się do terminala (lokalnie lub przez TTY).
  • Sprawdź czas:
    systemd-analyze time
  • Przejrzyj listę długotrwających unitów:
    systemd-analyze blame | head -n 20
  • Sprawdź krytyczny łańcuch:
    systemd-analyze critical-chain

Celem jest wyłapanie kilku pierwszych usług, które:

  • pojawiają się zarówno wysoko w blame,
  • jak i leżą w critical-chain przed multi-user.target lub graphical.target.

Na tej podstawie wybiera się pierwszych kandydatów do analizy i ewentualnego wyłączenia lub zmiany konfiguracji.

Wizualizacja startu – systemd-analyze plot i narzędzia pokrewne

systemd-analyze plot: generowanie wykresu SVG

Do głębszej analizy przydaje się graficzne przedstawienie startu:

Eksport wykresu startu do pliku SVG

Podstawowe polecenie do wygenerowania wykresu:

systemd-analyze plot > boot.svg

Plik SVG można otworzyć w przeglądarce lub edytorze grafiki wektorowej. Oś pozioma to czas od startu jądra, pionowa – kolejne unity. Kolorowe paski pokazują, kiedy dana jednostka jest uruchamiana i ile to trwa.

Długi, szeroki pasek w pierwszych sekundach, który kończy się tuż przed multi-user.target/graphical.target, to zwykle dobry kandydat do analizy. Szczególnie gdy jednocześnie pojawia się wysoko w systemd-analyze blame.

Jak czytać wykres systemd-analyze plot

Na wykresie widać kilka charakterystycznych elementów:

  • krótkie, gęsto ułożone paski – typowe, szybkie usługi startujące równolegle,
  • pojedyncze, bardzo szerokie paski – usługi blokujące, czekające na sieć, dysk, time-out,
  • przerwy / „dziury” – czas, gdy systemd czeka na zakończenie zależności.

Jeśli np. NetworkManager-wait-online.service ciągnie się na kilka sekund i kończy tuż przed momentem osiągnięcia targetu, widać, że bezpośrednio wpływa na czas, w którym dostępny jest system do pracy.

Dobrym nawykiem jest zrobienie „zrzutu” SVG przed i po zmianach w usługach. Różnica w wykresie pozwala łatwo ocenić realny efekt sprzątania.

Inne narzędzia do wizualizacji i profilowania

Poza systemd-analyze plot przydają się:

  • systemd-analyze plot --man=no – prostszy wykres bez odnośników do stron man,
  • systemd-analyze dot – generuje graf zależności w formacie DOT (Graphviz),
  • bootchartd (w niektórych dystrybucjach) – alternatywny wykres obciążenia CPU/dysku podczas startu.

Graf z systemd-analyze dot jest przydatny, gdy trzeba zrozumieć skomplikowane zależności. Można go przetworzyć np.:

systemd-analyze dot | dot -Tsvg -o deps.svg
Zbliżenie potrójnego chłodzenia wodnego komputera na żółtym tle
Źródło: Pexels | Autor: Andrey Matveev

Identyfikacja zbędnych lub spowalniających usług

Rozpoznawanie usług naprawdę potrzebnych

Zanim cokolwiek wyłączysz, trzeba ustalić, czego faktycznie używasz. Inny zestaw usług ma sens na laptopie do pracy biurowej, inny na małym serwerze domowym.

Kilka prostych pytań pomaga odsiać kandydatów:

  • czy korzystasz z drukarki lokalnej lub sieciowej? (cups.service)
  • czy używasz Snap/Flatpak/AppImage? (snapd.service, flatpak-related)
  • czy w ogóle logujesz się graficznie? (display manager, np. gdm, sddm, lightdm)
  • czy używasz Bluetooth, modemu 3G/LTE, Samby, NFS, Avahi?

Po przejściu takiej listy często okazuje się, że kilka usług spokojnie może być uruchamianych tylko ręcznie lub wcale.

Przegląd aktywnych i włączonych unitów

Podstawowa lista uruchomionych usług:

systemctl --type=service --state=running

Lista usług włączonych przy starcie (enabled):

systemctl list-unit-files --type=service

Do szybkiego filtrowania przydaje się grep:

systemctl list-unit-files --type=service | grep enabled

Warto przyjrzeć się pozycjom, które są enabled, ale niekoniecznie running po starcie – często są wyzwalane tylko w określonych sytuacjach (np. przez socket activation) i nie są głównym źródłem opóźnień.

Łączenie blame/critical-chain z listą usług

Skuteczne podejście to połączenie trzech źródeł:

  1. systemd-analyze blame – które usługi trwają najdłużej,
  2. systemd-analyze critical-chain – które leżą na ścieżce krytycznej,
  3. systemctl list-unit-files – które są w ogóle włączone przy starcie.

Jeśli dany unit:

  • jest enabled,
  • pojawia się wysoko w blame,
  • i leży przed multi-user.target/graphical.target w critical-chain,

to jest dobrym kandydatem do optymalizacji konfiguracji lub wyłączenia.

Wyłapywanie usług od dystrybucji i oprogramowania dodatkowego

Część usług pochodzi z samego systemu, część z dodatkowych pakietów (np. Snap, Docker, VirtualBox, oprogramowanie vendorów). Bywa, że po deinstalacji aplikacji usługa nadal jest enabled.

Przykłady typowych „niespodzianek”:

  • apt-daily.service, apt-daily-upgrade.service – automatyczne aktualizacje w Ubuntu/Debianie,
  • fwupd.service – aktualizacje firmware,
  • ModemManager.service, bluetooth.service – jeśli nie używasz modemu ani BT,
  • avahi-daemon.service – wykrywanie usług w sieci lokalnej,
  • snapd.service – jeśli nie używasz aplikacji Snap.

Z takimi usługami warto postępować ostrożnie: czasem lepiej je opóźnić lub ograniczyć, niż całkowicie wyłączyć. Do tego potrzebne są podstawowe narzędzia „sprzątania”.

Sprzątanie usług – disable, mask, stop i ich konsekwencje

Różnice między stop, disable, mask

Trzy najczęściej używane akcje:

  • systemctl stop nazwa.service – zatrzymuje usługę w bieżącej sesji, nie zmienia ustawień startu,
  • systemctl disable nazwa.service – wyłącza automatyczny start z odpowiednich targetów,
  • systemctl mask nazwa.service – całkowicie blokuje start (również ręczny i przez zależności), unit jest powiązany z /dev/null.

Stop jest bezpieczny do testów „na żywym organizmie”. Disable wyłącza usługę przy następnym starcie, ale nadal można ją uruchomić ręcznie. Mask to twardy zakaz, stosowany głównie, gdy inna jednostka uparcie próbuje coś uruchamiać.

Bezpieczne testowanie: najpierw stop, potem disable

Przy pracy na maszynie produkcyjnej lub głównym laptopie lepiej zmiany wprowadzać małymi krokami. Typowy schemat:

  1. Zatrzymaj usługę:
    sudo systemctl stop nazwa.service
  2. Sprawdź, czy nic istotnego nie przestało działać (sieć, logowanie, dyski, drukowanie).
  3. Jeśli wszystko jest w porządku, wyłącz auto-start:
    sudo systemctl disable nazwa.service
  4. Zrób reboot i upewnij się, że system wstaje poprawnie.

Dopiero gdy jakaś usługa uparcie wraca, można rozważyć mask.

Kiedy użyć mask zamiast disable

Przykładowe sytuacje:

  • usługa jest wywoływana przez inne unity (Requires=, Wants=) mimo disable,
  • menedżer pakietów lub skrypt vendorowy włącza ją z powrotem,
  • chcesz mieć gwarancję, że coś nigdy nie wstanie (np. konfliktowy daemon sieciowy).

Maskowanie:

sudo systemctl mask nazwa.service

Przy próbie startu pojawi się błąd. Odmaskowanie jest proste:

sudo systemctl unmask nazwa.service

Sprawdzanie, czy wyłączenie było skuteczne

Po disable warto zweryfikować stan:

systemctl is-enabled nazwa.service

Przydatne są też:

systemctl status nazwa.service
systemctl cat nazwa.service

Status pokaże, czy usługa nie została wystartowana przez socket lub timer. systemctl cat przydaje się, aby zobaczyć, w jakich targetach i z jakimi zależnościami jest zdefiniowana.

Zbliżenie ekranu laptopa z interfejsem do analizy kodu i danych
Źródło: Pexels | Autor: Daniil Komov

Praktyczne przykłady optymalizacji wybranych klas usług

Sieć: network-online.target i czekanie na DHCP

Najczęstsze źródło dużych opóźnień to usługi typu „wait-online”, które czekają, aż interfejs sieciowy dostanie adres (DHCP). Na desktopie zwykle nie ma potrzeby, aby cały system blokował się na tym etapie.

Typowy przykład:

systemd-analyze blame | head
 6.001s NetworkManager-wait-online.service

Pierwszy krok to sprawdzenie, co tak naprawdę wymaga network-online.target:

systemctl list-dependencies network-online.target

Jeżeli nie ma wśród nich krytycznych usług (np. mounty NFS potrzebne od razu przy starcie), można rozważyć:

  • wyłączenie samego NetworkManager-wait-online.service:
    sudo systemctl disable NetworkManager-wait-online.service
  • albo zmniejszenie timeoutu w jego konfiguracji (override w /etc/systemd/system/…d/override.conf).

Na serwerze z NFS lub iSCSI sytuacja jest inna – tam często lepiej poczekać, niż ryzykować, że zasoby nie będą zamontowane przy starcie kluczowych usług.

Usługi druku, skanowania i multimediów

Jeśli nie używasz drukarki ani skanera, wyłączenie CUPS potrafi przyspieszyć start, zwłaszcza w środowiskach, gdzie jest skanowane całe lokalne sieci w poszukiwaniu drukarek.

sudo systemctl disable --now cups.service cups-browsed.service

Podobnie z usługami multimedialnymi (serwery DLNA, serwery dźwięku sieciowego) – na prostym desktopie bez takich funkcji zwykle nie ma potrzeby, żeby startowały od razu.

Snap, Flatpak i inne systemy opakowań

Na niektórych systemach snapd.service potrafi znacząco wydłużyć start. Jeśli nie masz żadnej aplikacji zainstalowanej przez Snap, często rozsądniej jest całkowicie pozbyć się pakietu:

sudo systemctl disable --now snapd.service
sudo apt purge snapd   # przykład dla Debiana/Ubuntu

Flatpak zazwyczaj mniej wpływa na start, bo wiele rzeczy działa przez socket/timer activation, ale i tak warto przejrzeć listę unitów powiązanych z tym mechanizmem.

Bluetooth, modem, usługi sieciowe w tle

Na laptopie bez Bluetootha i modemu 3G/LTE spokojnie można wyłączyć:

sudo systemctl disable --now bluetooth.service ModemManager.service

Jeśli nie korzystasz z automatycznego wykrywania hostów w sieci lokalnej (np. drukarek przez Avahi), zwykle bez konsekwencji można wyłączyć:

sudo systemctl disable --now avahi-daemon.service

Po każdej takiej zmianie dobrze jest zrobić pełny restart i sprawdzić dzienniki:

journalctl -b -p warning

To szybki sposób na wykrycie oczywistych problemów po „sprzątaniu”.

Automatyczne aktualizacje i zadania okresowe

Usługi typu apt-daily.service czy apt-daily-upgrade.service nie muszą blokować startu. Można przesunąć je w czasie lub pozostawić jako timery, które odpalą się po kilku minutach od uruchomienia systemu.

Na systemach, gdzie zarządzasz aktualizacjami ręcznie, można rozważyć wyłączenie ich timerów:

sudo systemctl disable --now apt-daily.timer apt-daily-upgrade.timer

Podobnie z usługami sprzątającymi logi czy cache – jeśli mocno opóźniają start, lepiej uruchamiać je w nocy lub według własnego harmonogramu.

Zaawansowane techniki – on-demand, socket activation i parallel boot

Uruchamianie usług na żądanie (on-demand)

Nie wszystko musi startować przy bootowaniu. Dla części usług wystarczy tryb „on-demand”, czyli:

  • uruchamianie przy pierwszym użyciu (socket, path activation),
  • lub ręczne startowanie skryptem/aliasem.

Przykład: lokalny serwer WWW używany sporadycznie:

sudo systemctl disable apache2.service
# gdy potrzebny:
sudo systemctl start apache2.service

Jeśli korzystasz z niego rzadko, nie ma sensu, by blokował choćby kilka sekund startu systemu.

Socket activation – usługi wybudzane przez ruch

Socket activation polega na tym, że systemd nasłuchuje na gnieździe (TCP/UDP/UNIX), a usługę uruchamia dopiero przy pierwszym połączeniu. Użytkownik dostaje wrażenie, że usługa „zawsze jest”, a system nie trzyma demonów w pamięci bez potrzeby.

Aby zobaczyć aktywne sockety:

Przegląd i obsługa jednostek typu .socket

Podstawowy podgląd aktywnych socketów:

systemctl list-units --type=socket

Jeśli jakaś usługa ma odpowiadający jej socket, zwykle występuje w parze, np. cups.socket i cups.service. Gdy socket jest włączony (enabled), demon startuje dopiero przy pierwszym połączeniu.

Status konkretnego socketu:

systemctl status cups.socket
systemctl cat cups.socket

W systemctl cat widać m.in. opcję Service=cups.service – wskazuje, co zostanie uruchomione. Samą usługę można wtedy wyłączyć z automatycznego startu, pozostawiając tylko socket:

sudo systemctl disable cups.service
sudo systemctl enable cups.socket

Efekt: brak demona przy boocie, a jednocześnie drukowanie zadziała przy pierwszym użyciu.

Tworzenie prostego socket activation własnej usługi

Dla lekkich, własnych serwisów sieciowych czasem wystarczy para prostych jednostek:

# /etc/systemd/system/myserver.service
[Unit]
Description=Prosty serwer TCP

[Service]
ExecStart=/usr/local/bin/myserver
# /etc/systemd/system/myserver.socket
[Unit]
Description=Socket dla myserver

[Socket]
ListenStream=127.0.0.1:9000

[Install]
WantedBy=sockets.target

Aktywacja:

sudo systemctl daemon-reload
sudo systemctl enable --now myserver.socket

Sam myserver.service nie musi być włączony. Systemd uruchomi go przy pierwszym połączeniu na porcie 9000.

Path activation – usługi wyzwalane przez zmiany w systemie plików

Podobny mechanizm można zastosować dla zmian w katalogach/plikach. Przykład: skrypt generujący miniatury dla nowych zdjęć w katalogu użytkownika.

# /etc/systemd/system/thumbgen.service
[Unit]
Description=Generator miniatur

[Service]
ExecStart=/usr/local/bin/thumbgen %f
# /etc/systemd/system/thumbgen.path
[Unit]
Description=Monitorowanie katalogu ze zdjęciami

[Path]
PathModified=/home/user/Zdjecia

[Install]
WantedBy=multi-user.target

Po włączeniu thumbgen.path usługa wystartuje tylko, gdy coś w katalogu się zmieni. Nie trzyma procesu w pamięci bezczynnie, więc nie wpływa na boot.

Parallel boot – kontrola zależności i kolejkowania

Systemd domyślnie startuje jednostki równolegle, o ile nie blokują tego zależności (After=, Requires=, Wants=, Conflicts=). Problemy z czasem bootu często wynikają z niepotrzebnych blokad.

Dla problematycznej usługi warto przejrzeć jej zależności:

systemctl list-dependencies --reverse nazwa.service
systemctl show -p After,Wants,Requires nazwa.service

Jeśli jakiś własny unit ma zbyt szerokie After=network-online.target czy After=multi-user.target, a wcale nie musi czekać na pełną sieć lub cały tryb multi-user, można to skorygować w override:

sudo systemctl edit nazwa.service
[Unit]
After=
After=network.target

Takie nadpisanie czyści poprzednią listę After= i zostawia tylko niezbędne zależności, co często skraca czas oczekiwania.

Analiza grafu zależności – dot i diagramy

Przy bardziej skomplikowanych konfiguracjach przydaje się wizualizacja, które unity blokują start innych. Systemd potrafi generować graf w formacie dot:

systemd-analyze dot | dot -Tsvg > boot.svg

Powstały plik SVG można otworzyć w przeglądarce. Dobrze widać wtedy wąskie gardła – np. pojedynczy *.service, od którego zależy dużo innych jednostek i który długo startuje.

Jeżeli nie potrzeba pełnego grafu, można ograniczyć go do konkretnego targetu:

systemd-analyze dot default.target | dot -Tpng > default.png

Optymalizacja poza systemd – kernel, moduły, dyski, usługi dystrybucji

Kernel: parametry rozruchowe i wybór wersji

Na czas startu wpływa także sam kernel. Kilka praktycznych kierunków:

  • użycie aktualnej, stabilnej wersji z dystrybucji (często szybsza inicjalizacja sprzętu),
  • wyłączenie zbędnych funkcji przez parametry kernela, jeśli są jawnie problematyczne,
  • unikanie eksperymentalnych jąder debugowych na stacjach roboczych.

Parametry rozruchowe ustawia się zwykle w /etc/default/grub (dystrybucje z GRUB-em):

GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"

Dodanie opcji typu systemd.log_level=info pomaga w diagnostyce, ale nie przyspiesza startu. Z kolei różne „tuningowe” parametry z forów bywają ryzykowne – zanim coś trafi do CMDLINE, lepiej sprawdzić dokumentację kernela.

Moduły kernela i autoload

Przy specyficznym sprzęcie można ograniczyć ładowanie nieużywanych modułów. Informacje, co rzeczywiście jest używane:

lsmod

Wyłączanie modułów tylko po to, by zyskać ułamki sekundy przy starcie, zwykle nie ma sensu. Ma znaczenie głównie wtedy, gdy konkretny sterownik sprawia problemy (długi timeout, błędy).

Blokada problematycznego modułu:

echo "blacklist nazwa_modulu" | sudo tee /etc/modprobe.d/blacklist-nazwa.conf

Po takiej zmianie trzeba obserwować dmesg i journalctl -b, czy nie pojawią się nowe błędy sprzętowe.

System plików i montowanie dysków

Długi czas bootu często wynika z czekania na wolne lub niedostępne zasoby. Typowe miejsca:

  • zdalne systemy plików (NFS, CIFS),
  • zewnętrzne dyski USB wpisane w /etc/fstab,
  • stare UUID-y po wymianie dysku.

Przy nierównomiernie dostępnym storage (np. dysk USB, który czasem jest podłączony, a czasem nie) warto użyć opcji:

noauto,x-systemd.automount,x-systemd.device-timeout=5

Przykładowy wpis w /etc/fstab:

UUID=...  /media/usb  ext4  noauto,x-systemd.automount,x-systemd.device-timeout=5  0  2

Efekt: system nie będzie wisiał przy starcie, czekając długo na urządzenie. Punkt montowania zadziała przy pierwszym dostępie.

SSD, HDD i kolejkowanie I/O

Rodzaj dysku ma duży wpływ na subiektywny czas startu. Na SSD różnice wynikające ze „sprzątania usług” są często mniejsze niż przy HDD, ale nadal odczuwalne.

Kilka prostych kontroli:

  • sprawdzenie stanu dysku:
    sudo smartctl -a /dev/sda
    
  • weryfikacja, czy TRIM jest włączony (na obsługiwanym SSD):
    sudo systemctl status fstrim.timer
    

Zewnętrzne, wolne dyski USB wpięte do /etc/fstab łatwo potrafią dodać kilkanaście sekund na timeoutach. Często lepiej montować je ręcznie lub przez automount.

Specyfika dystrybucji – usługi vendorowe

Dystrybucje dodają własne warstwy usług, które nie zawsze są potrzebne na każdej maszynie. Kilka przykładów klas:

  • telemetria i raportowanie błędów (np. whoopsie, ubuntu-report),
  • narzędzia konfiguracyjne „all-in-one”,
  • integracje z chmurą dostawcy.

Dobrze jest zestawić listę własnych usług dostawcy:

systemctl list-unit-files | grep -i ubuntu
systemctl list-unit-files | grep -i fedora

Następnie, po kolei, zatrzymać podejrzane jednostki i sprawdzić, czy coś rzeczywiście z nich korzysta. Wiele stacji roboczych działa stabilnie nawet po wyłączeniu sporej części „kosmetycznych” demonów.

Usługi graficzne i środowisko desktopowe

Nowoczesne środowiska (GNOME, KDE Plasma) integrują się z systemd przez user services. Poza klasycznym default.target istnieje też sesja użytkownika:

systemctl --user list-units

Tam widać m.in. aplety, indeksery, serwisy powiadomień. Niektóre mogą opóźniać uzyskanie w pełni responsywnego pulpitu, mimo że „system” według systemd-analyze już wstał.

Mechanika jest podobna: można sprawdzić, co startuje w sesji użytkownika, wyłączyć zbędne usługi:

systemctl --user disable nazwa.service

i obserwować, czy środowisko zachowuje się poprawnie. U kogoś, kto nie korzysta z wyszukiwania pełnotekstowego, wyłączenie indeksera (Baloo/Tracker) potrafi uczynić desktop zauważalnie lżejszym zaraz po zalogowaniu.

Initramfs i wczesny etap rozruchu

Zanim wystartuje systemd, kernel ładuje initramfs. Jeśli ten etap trwa długo, optymalizacje samych usług nie przyniosą dużego efektu.

Na systemach z initramfs-tools albo dracut można ograniczyć moduły i hooki w obrazie initramfs. Przykład dla Debiana/Ubuntu:

grep HOOKS /etc/initramfs-tools/initramfs.conf

Jeżeli initramfs zawiera obsługę LUKS, RAID, LVM, sieci i kilku innych warstw, a na maszynie używane jest tylko proste LVM na jednym dysku, da się ten zestaw odchudzić. Po każdej zmianie trzeba odbudować initramfs:

sudo update-initramfs -u

Efekt jest szczególnie widoczny na starszych maszynach z wolniejszym CPU.

Najczęściej zadawane pytania (FAQ)

Jak sprawdzić, ile faktycznie startuje mój Linux (firmware, kernel, userspace)?

Do podstawowego pomiaru użyj polecenia:

systemd-analyze
zwróci czas podzielony na firmware, loader, kernel i userspace. To szybki podgląd, co najbardziej spowalnia start: BIOS/UEFI, bootloader, jądro czy usługi systemd.

Dodatkowo przydaje się systemd-analyze blame, które pokazuje listę usług posortowanych według czasu startu, oraz systemd-analyze critical-chain, aby zobaczyć faktyczny łańcuch krytyczny rozruchu.

Dlaczego ekran logowania pojawia się szybko, ale system długo „dochodzi do siebie”?

Menedżer logowania lub pulpit może wystartować, zanim zakończą się wszystkie usługi w tle. W tym czasie dociągane są np. usługi sieciowe, montowane zasoby sieciowe, uruchamiane indeksowanie plików czy snap/flatpak.

Efekt jest taki, że ekran już jest, ale aplikacje startują wolno, sieć czasem nie działa od razu, a dysk mieli kilka minut po starcie. Trzeba wtedy patrzeć nie tylko na liczby z systemd-analyze, ale też na zachowanie systemu w pierwszych minutach po zalogowaniu.

Jakich czasów uruchamiania Linuxa mogę realnie oczekiwać na HDD, SSD i NVMe?

Na klasycznym HDD typowe są wartości rzędu 20–60 s do pulpitu, a pełna gotowość łatwo przekracza minutę przy ciężkim środowisku graficznym. Tu cudów się nie zrobi – największy zysk daje wymiana dysku.

Na SSD (SATA) normą jest 10–25 s do pulpitu. Po wyłączeniu zbędnych usług zejście do okolic 8–15 s jest realne. Na NVMe dobrze skonfigurowany system z lekkim środowiskiem graficznym często mieści się w 3–7 s do używalnego pulpitu.

Co najbardziej wpływa na czas startu systemu Linux i co warto optymalizować?

Największy wpływ ma warstwa userspace: usługi systemd, ich zależności, montowanie systemów plików i inicjalizacja sieci. To właśnie to, co mierzy systemd-analyze blame i critical-chain.

Praktycznie najszybciej odchudzić start można przez:

  • wyłączenie niepotrzebnych usług i timerów,
  • ograniczenie agresywnego indeksowania i skanowania dysku tuż po starcie,
  • skrócenie czasu negocjacji sieci (np. DHCP),
  • wyczyszczenie initramfs z nieużywanych hooków i modułów.

Czy zmiana multi-user.target / graphical.target przyspieszy start systemu?

Polecenie systemctl get-default pokaże, czy domyślny jest graphical.target (stacja robocza) czy multi-user.target (tryb tekstowy). Zmiana na tryb tekstowy przyspieszy start tylko wtedy, gdy naprawdę nie potrzebujesz automatycznie uruchamianego środowiska graficznego.

Na typowym desktopie optymalizacja polega raczej na sprzątnięciu usług w ramach aktualnego targetu niż na przełączaniu się na multi-user.target. Sens ma to głównie na serwerach lub maszynach, gdzie X-y uruchamia się ręcznie (np. startx).

Czego lepiej nie ruszać przy przyspieszaniu bootowania Linuxa?

Na ogół nie ma sensu agresywnie majstrować przy czasie firmware/UEFI, czasie ładowania jądra czy pracy bootloadera poza prostymi zmianami typu skrócenie timeout w GRUB-ie. Zyskasz tam pojedyncze sekundy albo mniej.

Najbardziej ryzykowne jest usuwanie „na ślepo” zależności typu Requires= oraz wyłączanie usług systemowych bez zrozumienia ich roli. Może się to skończyć tym, że system co prawda startuje szybciej, ale coś kluczowego (np. sieć, logowanie, montowanie /home) przestaje działać albo zawiesza start w innym miejscu.

Jak zależności usług systemd wpływają na czas uruchamiania?

Systemd uruchamia usługi równolegle tam, gdzie to możliwe. Jeżeli jednak dana jednostka ma Requires= i After= wobec wolno startującej usługi, staje się od niej twardo zależna i musi na nią czekać. Jeśli do tego ta ścieżka prowadzi do docelowego targetu (np. graphical.target), cały pulpit czeka na pojedynczą usługę.

Dlatego często lepszym wyborem jest Wants= zamiast Requires=, odsunięcie części usług poza krytyczny łańcuch startowy lub uruchamianie ich na żądanie (np. przez socket activation), zamiast blokować cały system podczas rozruchu.