Nebojte se systemd: jednotky

30. 5. 2016
Doba čtení: 7 minut

Sdílet

Už jsme si řekli, že systemd pracuje s jednotkami několika druhů. Dnes si představíme, jak se s nimi pracuje obecně. V dalších článcích pak rozebereme jednotlivé typy do hloubky.

Systemd má zabudovanou podporu pro administraci strojů přes SSH. Stačí k následujícím příkazům připojit --host=[username@]hostname[:container]. Například pokud budeme chtít na našem serveru jednorázově synchronizovat čas pomocí NTP protokolu, není nic jednoduššího než použít příkaz systemctl start ntpd --host root@example.com. Vše běží přes SSH, proto samozřejmě můžeme použít autentizaci přes veřejný klíč a můžeme spravovat vzdálený server bez hesla, jako kdybychom operovali s lokálním.

Pokud na počítači běží nějaké virtuální stroje, každý z nich má svůj vlastní init. Pokud je to systemd, můžeme jej řídit zvenku. Seznam běžící strojů získáme příkazem machinectl. Pro ovládání nějakého virtuálního stroje stačí pak použít parametr --machine. Předchozí příklad bychom mohli spustit na virtuálním stroji příkazem systemctl start ntpd --machine jmeno_stroje. Pokud se chceme připojit přes ssh k nějakému virtuálnímu stroji, stačí přidat dvojtečku a jméno stroje za adresu serveru. Nastavení virtuálních strojů je nad rámec tohoto seriálu, čtenář se může dozvědět více v  man systemd-machined.

Výpis seznamu jednotek

Pro práci s jednotkami slouží příkaz systemctl. Spustíme-li tento příkaz samotný, dostaneme výpis všech aktivních jednotek (popř. těch, které by měly být aktivní, ale z nějakého důvodu selhaly) automaticky předaný výchozímu stránkovacímu příkazu.

● systemd-modules-load.service               loaded failed failed    Load Kernel Modules
  systemd-random-seed.service                loaded active exited    Load/Save Random Seed
  systemd-remount-fs.service                 loaded active exited    Remount Root and Kernel File Systems
  systemd-sysctl.service                     loaded active exited    Apply Kernel Variables
  systemd-tmpfiles-setup-dev.service         loaded active exited    Create Static Device Nodes in /dev
  systemd-tmpfiles-setup.service             loaded active exited    Create Volatile Files and Directories
  systemd-udev-trigger.service               loaded active exited    udev Coldplug all Devices

Formát výpisu je všeříkající. V prvním sloupci je jméno jednotky, uprostřed stav a v posledním její popis, který slouží pouze pro lepší orientaci správce.

Stav nám říká tři informace. První je stav načtení jednotky. Ten je pro každou obecně loaded, pak je jednotka v pořádku přečtena z disku, nebo je v nějakém chybovém stavu jako např. not-found. Druhý je stav běhu jednotky. Každá obecně může být active, pak běží alespoň jeden proces, inactive, kdy všechny procesy již skončily, a failed, kdy návratový kód hlavního procesu je nenulový. Popř. může být ve stavu, ve kterém přechází mezi třemi předchozími, tedy např. reloading či  deactivating.

Poslední informace je charakteristická pro každý typ jednotky. Více o nich se dozvíme v následujících částech seriálu.

Ve výpisu můžeme ovlivnit, které jednotky budou vypsány:

--all
Zobrazí i neaktivní jednotky.
--type {typy oddělené čárkami}
Zobrazí jen konkrétní typy, –type help zobrazí všechny možné hodnoty.
--state {stavy oddělené čárkami}
--state help opět zobrazí možnosti.

Užitečný je příkaz systemctl --all --type service, který zobrazí všechny služby, tedy jednotky typu service, což jsou ekvivalenty démonů, jak jsme si řekli v minulém dílu.

Jednotky mohou být spouštěny ve dvojím režimu. Systémovém (výchozí) a uživatelském. Pro práci s jednotkami v uživatelském režimu stačí ke každému příkazu přidat přepínač --user. Uživatelský mód slouží pro jednotky, které jsou určeny jen pro jednoho konkrétního uživatele. Každý může mít nastavenu vlastní sadu jednotek, které se budou spouštět. Také není třeba pro operaci s nimi oprávnění superuživatele, protože vlastník procesů je přímo uživatel. Tyto jednotky jsou spuštěny až po přihlášení uživatele, kdy je spuštěn příkaz systemd --user, který se následně postará o samotné spuštění.

Hezkým příkladem je program mpd, což je server pro přehrávání hudby. Stačí mu nastavit složky s hudbou a pak již jen vzdáleně řídíme frontu přehrávání buď z aktuálního počítače, nebo jakéhokoliv jiného zařízení. Výhodou je, že se startuje sám po startu a má malé systémové nároky. Spouštět takového démona pod superuživatelem není nejlepší. Jednak jej někteří uživatelé nemusí využívat, především ale pro přehrávání hudby není potřeba žádné speciálních oprávnění. Proto má mpd jednotku pro uživatelský režim. Jako uživateli nám stačí spustit systemctl --user enable mpd a od příštího přihlášení se již bude mpd spouštět na pozadí. K této aktivaci navíc nepotřebujeme žádná speciální oprávnění.

Práce s jednotkami

Pozn.: Dále v textu bude příkaz odkazovat na příkaz systemd, tedy každý příkaz se použije jako první argument  systemctl.

Dříve sloužil pro spuštění démona příkaz /etc/init.d/jmeno start a pro ukončení jsme start nahradili stop. Problém je, že skript /etc/init.d/jmeno se musel pro každého démona vytvářet znovu. V systemd ovládáme běh pomocí příkazu systemctl PŘÍKAZ PATTERN, kde PATTERN je seznam jednotek ve tvaru JEDNOTKA[.TYP] oddělených mezerami. Pokud neuvedeme TYP, je kromě několika výjimek, u kterých na to upozorním, dosazen typ služba (service).

Příkaz pro spuštění a ukončení je start/stop/restart. K jednorázové synchronizaci času slouží systemctl start ntpd. Příkazem kill [--signal=SIGNAL] můžeme jednotce poslat signál. Toho se dá využít, pokud se nějaká jednotka zasekne. Pro její okamžité ukončení použijeme  systemctl kill --signal 9 jednotka.

Užitečný je také příkaz help, který zobrazí dokumentaci. Pokud chceme zobrazit dokumentaci k dbus, zjistíme že manuálová stránka dbus neexistuje. Abychom nemuseli tápat, jak se jmenuje, můžeme použít  systemctl help dbus.

Pro zjištování stavu konkrétních jednotek můžeme použít příkaz is-active/is-enabled/is-failed. Tyto příkazy navíc vrací jako návratový kód nulu, pokud je podmínka splněna pro alespoň jednu jednotku. Tento kód je dokumentovaný a navíc autoři slibují, že se v budoucnu nezmění, je tedy vhodný pro používání ve skriptech. Pokud bychom chtěli přehrát frontu písniček v případě, že je mpd spuštěný, můžeme použít systemctl --user is-active mpd > /dev/null && mpc play. Všimněme si, že mpd standardně běží jako uživatelská jednotka, proto ten parametr --user. Výstup přesměrováváme na /dev/null, protože nás zajímá jen návratový kód.

Pro zjištění obecného stavu jednotek včetně logu slouží příkaz status, který mimo jiné vypisuje i PID všech procesů, které daná jednotka vlastní. Tento výstup je vhodný pro čtení uživatelem. Není vhodné spoléhat na jeho formát, protože se může do budoucna velmi radikálně změnit. Výpis primárně určený pro skripty dostaneme příkazem show [--property=NAME], který vypisuje všechny vlastnosti v jednoduchém formátu. Každý řádek obsahuje jednu vlastnost ve tvaru  jmeno=hodnota.

Na výpisu níže vidíme, že mpd je aktivní, spuštěn byl před čtrnácti minutami. Dále vidíme, že vlastní jeden proces. Poslední dvě řádky jsou z logu.

 systemctl –user status mpd

● mpd.service - Music Player Daemon
   Loaded: loaded (/usr/lib/systemd/user/mpd.service; enabled; vendor preset: enabled)
   Active: active (running) since Ne 2016-04-17 12:33:25 CEST; 14min ago
 Main PID: 25453 (mpd)
   CGroup: /user.slice/user-1000.slice/user@1000.service/mpd.service
           └─25453 /usr/bin/mpd --no-daemon

dub 17 12:33:25 holly systemd[956]: Started Music Player Daemon.
dub 17 12:33:27 holly mpd[25453]: Apr 17 12:33 : server_socket: bind to '0.0.0.0:6600' failed: Address alredy in use (continuing anyway, because binding to '[::]:6600' succeeded)

Automatické spouštění

Pro automatické spuštění jednotek v sysvinit stačilo udělat symbolický odkaz na /etc/init.d/jednotka v adresáři pro danou běhovou úroveň. V systemd je podobný systém odkazů, jen pro ně existuje abstrakce a o vytvoření odkazů se postará systemd. Přesný mechanismus si popíšeme při vysvětlování jednotky typu cíl. Nyní nám stačí vědět, že pro povolení či zakázání spouštění jednotky slouží příkaz enable/disable. Při povolení se jednotka nastaví jako závislost cíle specifikovaného v konfiguraci jednotky a tedy při spouštění závislostí cíle se tato automaticky spustí. Většina běžných služeb má nastaven default.target, tedy se při povolení začnou pouštět po startu počítače. Při zakázání se tato závislost jednoduše odebere.

Pokud bychom chtěli nastavit čas automaticky při každém startu počítače, můžeme spustit příkaz systemctl enable ntpd a od následujícího startu se vždy ntpd spustí, protože se nastaví jako závislost cíle multi-user.target, který se standardně pouští.

Pro zjištění závislostí je možné použít příkaz list-dependencies [jednotka], který přehledně zobrazí všechny závislosti. Ve výchozím nastavení se rekurzivně zobrazují závislosti jen u jednotek typu cíl, pokud chceme zobrazovat rekurzivně všechny, můžeme použít přepínač --all. Pokud nespecifikujeme jednotku, pak se vypíší závislosti  default.target.

ict ve školství 24

Na závěr je ještě vhodné zmínit příkaz is-system-running, který vrátí nulu, pokud systém běží v naprostém pořádku. Pokud vrátí hodnotu větší než nula, vše neběží jak má (například stačí, aby selhala nějaká jednotka). Bližší popis v  man systemctl.

V dnešním článku jsme si popsali základy práce s ovládáním jednotek. Na shledanou u dalšího článku, ve kterém se seznámíme s konfigurací jednotek.

Autor článku

Autor studuje na Matematicko-fyzikální fakultě. Ve svém volném čase se kromě Linuxu věnuje také vlastní 3D tiskárně.