Systemd este un sistem de inițializare a unei distribuții Linux, dar și un manager de sistem, care a fost introdus de Red Hat în Fedora (noiembrie 2010) și apoi adoptat ca un nou standard pentru distribuțiile Linux. Systemd înlocuiește vechile SysV și Upstart - zilele acestora din urmă s-au sfârșit (eventual doar nostalgicii și încăpățânații le mai folosesc). Pentru a putea să gestionezi cu ușurință un sistem Linux, sunt necesare câteva cunoștințe despre systemd și interacțiunea cu elementele sale.
De asemenea, orice certificare Linux necesită familiarizarea cu systemd, ceea ce implică și cunoașterea comenzii systemctl
, cea mai importantă unealtă pentru gestionarea sistemului de inițializare Linux.
Dar să vedem, pentru început, ce înseamnă inițializarea unui sistem Linux.
Inițializarea sistemului Linux
Stabilirea componentelor care pornesc după ce kernelul Linux bootează reprezintă fundamentul inițializării sistemului. Totodată, sistemul de inițializare este folosit pentru gestionarea serviciilor și daemonilor în orice moment al rulării sistemului.
În systemd, ținta celor mai multe acțiuni sunt "unitățile"; aceste unități sunt, de fapt, niște resurse pe care systemd știe cum să le gestioneze. Unitățile sunt împărțite pe categorii, în funcție de tipul de resursă pe care o reprezintă și sunt definite de niște fișiere, cunoscute ca unit files. O unitate poate solicita să fie încărcată înaintea alteia sau după alta și tot așa - acest aspecte sunt menționate în fișierele de configurare pentru fiecare unitate în parte.
Tipul fiecărei unități poate fi dedus după partea finală a numelui fișierului (sufix): service, target, device, etc.
Pentru a afișa toate tipurile de unități disponibile systemd
:
systemctl -t help
Pentru gestionarea serviciilor, unitățile țintă vor avea sufixul .service. În principiu, pentru comenzile de gestionare a serviciilor, putem omite sufixul .service - systemd este destul de deștept ca să-și dea seama că vrem să operăm un serviciu.
Gestionarea serviciilor
Pornirea și oprirea serviciilor
Pentru a porni un serviciu systemd și a executa instrucțiunile din fișierul care definește serviciul respectiv, folosim systemctl
însoțit de comanda start
. Dacă nu suntem logați ca superutilizator, trebuie să folosim sudo, deoarece afectăm starea sistemului.
systemctl start nume_serviciu.service
Dar putem să ignorăm sufixul .service, cum am menționat mai sus, iar comanda va avea forma:
systemctl start nume_serviciu
Pentru a opri un serviciu, folosim systemctl
cu comanda stop
:
systemctl stop nume_serviciu
Activarea și dezactivarea serviciilor
Comenzile de mai sus sunt utile pentru a porni și opri servicii doar pentru sesiunea curentă. Dar pentru ca un serviciu să fie pornit în același timp cu sistemul, acesta trebuie activat. Folosim systemctl cu comanda enable:
systemctl enable nume_serviciu
În acest fel, va fi creat un link simbolic către fișierul care definește serviciul (aceste fișiere se află, de regulă, în /lib/systemd/system sau /etc/systemd/system); legătura simbolică este creată în locul unde systemd se uită pentru fișierele programate pentru autostart - de regulă, în directorul /etc/systemd/system/nume_target.target.wants/)Ș
Pentru a dezactiva un anumit serviciu, folosim comanda de mai jos (va fi ștearsă legătura simbolică ce indică faptul că serviciul respectiv va porni automat):
systemctl disable nume_serviciu
# systemctl disable mongodb
Removed /etc/systemd/system/multi-user.target.wants/mongodb.service.
Cele două comenzi (de activare și pornire sau de dezactivare și oprire a unui serviciu) pot fi combinate într-una singură:
- pentru pornirea și activarea unui serviciu:
systemctl enable --now nume_serviciu
- pentru oprirea și dezactivarea unui serviciu:
systemctl disable --now nume_serviciu
Restartarea și reîncărcarea serviciilor
Pentru a restarta un serviciu care rulează, folosim comanda restart
:
systemctl restart nume_serviciu
Dacă aplicația în cauză este capabilă să-și reîncarce fișierul de configurare fără a fi necesar restartul (cum este cazul nginx), folosim comanda reload
:
systemctl reload nume_serviciu
În cazul în care nu știm exact dacă serviciul respectiv poate sau nu să-și reîncarce configurația fără restartare, folosim comanda reload-or-restart
- va încerca reîncărcarea configurației (dacă acest lucru este posibil), iar în caz contrar va restarta aplicația:
systemctl reload-or-restart nume_serviciu
Verificarea statusului unui serviciu
Pentru a verifica dacă un serviciu rulează sau nu, vom folosi systemctl
plus comanda status
:
systemctl status nume_serviciu
Această comandă ne oferă o privire de ansamblu asupra statusului serviciului respectiv, dar și primele linii din logul aferent. Aici putem fi notificați asupra unor probleme apărute, dar putem primi și sugestii despre cum putem remedia eventualele neajunsuri.
Există alte câteva metode pentru a verifica statusul unui serviciu la un moment dat:
- pentru a verifica dacă serviciul este activ (rulează) într-un anumit moment (va fi returnat statusul curent -
active
sauinactive
):
systemctl is-active nume_serviciu
- pentru a verifica dacă un anumit serviciu este activat și programat să pornească în același timp cu sistemul:
systemctl is-enabled nume_serviciu
- pentru a verifica dacă un anumit serviciu are starea failed (output-ul va fi
active
dacă serviciul rulează normal saufailed
dacă sunt probleme):
systemctl is-failed nume_serviciu
Privire de ansamblu asupra sistemului
Comenzile prezentate până acum sunt utile pentru a opera un singur serviciu, dar nu sunt folositoare dacă vrem să vedem starea generală a unui sistem. Există o serie de comenzi systemctl care ne oferă acest tip de informații.
Afișarea unităților din memoria sistemului
Afișarea tuturor unităților active din sistem se face prin folosirea comenzii list-units
- comanda încarcă doar informațiile care deja sunt în memoria sistemului:
systemctl list-units
Ieșirea are următoarele coloane:
- UNIT: numele unității systemd
- LOAD: dacă configurația unității respective a fost încărcată de systemd; configurația unității încărcate este păstrată în memorie
- ACTIVE: un status sumar asupra unității respective; ne spune dacă unitatea respectivă este activă
- SUB: mai multe informații despre unitatea respectivă; informațiile diferă în funcție de tipul unității
- DESCRIPTION: un mic text care descrie ceea ce face unitatea respectivă
Putem să-i spunem systemd să ne arate informații diferențiate prin adăugarea unor flag-uri comenzii de mai sus:
- pentru a vizualiza toate unitățile systemd, indiferent dacă acestea sunt active sau nu, ori dacă au fost încărcate sau nu de sistem:
systemctl list-units --all
- pentru a lista toate unitățile care sunt inactive:
systemctl list-units --all --state=inactive
- un filtru foarte des utilizat este cel care ne permite să afișăm unitățile în funcție de tipul lor (
--type
); în exemplul de mai jos am listat toate serviciile active din sistem:
systemctl list-units --type=service
- afișarea unităților de tip target, active și inactive:
systemctl list-units --type=target --all
Afișarea tuturor unităților din sistem
Dacă list-units
permitea doar afișarea informațiilor care deja au fost încărcate în memoria sistemului, comanda list-unit-files
ne permite să vedem informații despre toate unitățile disponibile din sistem, chiar dacă nu sunt încărcate:
systemctl list-unit-files
Unitățile sunt reprezentări ale resurselor de care știe systemd. Comanda de mai sus prezintă informații despre fișierele în sine. Ieșirea va avea 2 coloane:
- UNIT FILE: numele unității
- STATE: starea unității; poate avea valorile: enabled, disabled, static sau masked. În acest context, static înseamnă că unitatea respectivă nu poate fi instalată în sistem (nu are secțiune de instalare, care ar putea fi folosită pentru activarea sa) - aceste unități sunt folosite, de regulă, ca dependențe ale altor unități și nu rulează de sine stătător. Starea masked înseamnă că serviciul respectiv a fost complet dezactivat, nemaifiind posibilă pornirea lui - mai multe amănunte voi da mai jos.
Și comanda list-unit-files
poate fi folosită pentru a sorta anumite unități; de exemplu, cu comanda de mai jos putem vedea toate unitățile care sunt programate să pornească o dată cu sistemul (autostart):
systemctl list-unit-files | grep enabled
Gestionarea unităților
Până acum, am prezentat afișarea informațiilor despre servicii și unitățile systemd. Dar putem afla mai multe informații specifice despre fiecare unitate folosind câteva comenzi suplimentare:
Afișarea fișierului de configurare al unei unități
Combinând systemctl cu binecunoscuta comandă cat, putem citi fișierul care caracterizează fiecare unitate în parte:
systemctl cat nume_serviciu
# systemctl cat NetworkManager
[Service] Type=dbus
# /usr/lib/systemd/system/NetworkManager.service
[Unit] Description=Network Manager
Documentation=man:NetworkManager(8)
Wants=network.target
After=network-pre.target dbus.service
Before=network.target
BusName=org.freedesktop.NetworkManager
ExecReload=/usr/bin/dbus-send --print-reply --system --type=method_call --dest=org.freedesktop.NetworkManager /org/freedesktop/NetworkManager org.freedesktop.NetworkManager.Reload uint32:0
#ExecReload=/bin/kill -HUP $MAINPID
ExecStart=/usr/bin/NetworkManager --no-daemon
Restart=on-failure
# NM doesn't want systemd to kill its children for it
KillMode=process
CapabilityBoundingSet=CAP_NET_ADMIN CAP_DAC_OVERRIDE CAP_NET_RAW CAP_NET_BIND_SERVICE CAP_SETGID CAP_SETUID CAP_SYS_MODULE CAP_AUDIT_WRITE CAP_KILL CAP_SYS_CHROOT# ibft settings plugin calls iscsiadm which needs CAP_SYS_ADMIN
#CapabilityBoundingSet=CAP_SYS_ADMINProtectSystem=true
[Install] WantedBy=multi-user.target
ProtectHome=read-only
Alias=dbus-org.freedesktop.NetworkManager.service
Also=NetworkManager-dispatcher.service# /usr/lib/systemd/system/NetworkManager.service.d/NetworkManager-ovs.conf
[Unit] After=openvswitch.service
Ieșirea acestei comenzi este foarte importantă dacă dorim să edităm acest fișier: ne arată unde se află localizat, dar și multe alte informații suplimentare (tipul serviciului, de cine este cerut, ce cere el ca să se încarce, etc.).
Afișarea dependențelor
Pentru a vedea arborele de dependențe ale unei unități, se folosește systemctl cu comanda list-dependencies
:
systemctl list-dependencies nume_serviciu
# systemctl list-dependencies NetworkManager NetworkManager.service ● ├─dbus.socket ● ├─system.slice ● ├─network.target ● └─sysinit.target ● ├─dev-hugepages.mount ● ├─dev-mqueue.mount ● ├─kmod-static-nodes.service ● ├─ldconfig.service ● ├─lvm2-lvmetad.socket ● ├─lvm2-lvmpolld.socket ● ├─lvm2-monitor.service [...] | # systemctl list-dependencies sshd sshd.service ● ├─sshdgenkeys.service ● ├─system.slice ● └─sysinit.target ● ├─dev-hugepages.mount ● ├─dev-mqueue.mount ● ├─kmod-static-nodes.service ● ├─ldconfig.service ● ├─lvm2-lvmetad.socket ● ├─lvm2-lvmpolld.socket ● ├─lvm2-monitor.service ● ├─proc-sys-fs-binfmt_misc.automount [...] |
În cele două exemple de mai sus se observă ierarhia necesară pentru a porni unitatea în discuție (în cazul nostru, serviciul NetworkManager și serviciul ssh).
Verificarea proprietăților unei unități
Pentru a vedea proprietățile low-level ale unei unități, putem folosi systemctl
în combinație cu comanda show
. Va fi afișată o listă de proprietăți specifice unității respective, în formatul clasic cheie=valoare:
# systemctl show mongodb
Type=simple
Restart=no
NotifyAccess=none
RestartUSec=100ms
TimeoutStartUSec=1min 30s
TimeoutStopUSec=1min 30s
RuntimeMaxUSec=infinity
WatchdogUSec=0
WatchdogTimestamp=Sat 2018-03-03 08:12:54 EET
WatchdogTimestampMonotonic=21345794
PermissionsStartOnly=no
Id=mongodb.service
Names=mongodb.service
Requires=system.slice sysinit.target
WantedBy=multi-user.target
Conflicts=shutdown.target
[...]
Dacă vrem să afișăm o singură proprietate, folosim flag-ul -p urmat de numele proprietății respective:
systemctl show mongodb -p Conflicts
Conflicts=shutdown.target
Masking și Unmasking
Pe lângă posibilitatea de a opri sau dezactiva un serviciu, systemd are și abilitatea de a marca unitățile ca nefiind startabile, neexistând posibilitatea de a fi pornite, fiind create legături simbolice către /dev/null. Această acțiune se numește masking și este posibilă cu ajutorul comenzii mask
, iar serviciul respectiv nu va mai putea fi pornit, manual sau automat, atât timp cât va rămâne masked:
systemctl mask nume_serviciu
În imaginea de mai jos am mascat serviciul mongodb, iar la verificarea cu list-unit-files
vom vedea că este listat ca masked:
Dacă vom încerca să pornim serviciul respectiv, vom primi un mesaj asemănător cu cel de mai jos:
# systemctl start mongodb
Failed to start mongodb.service: Unit mongodb.service is masked.
Pentru a face serviciul disponibil din nou, folosim systemctl cu comanda unmask
:
systemctl unmask nume_serviciu
Serviciul respectiv va reveni în starea de dinainte de a fi folosită comanda mask
asupra lui.
Editarea unităților
De fapt, este vorba despre editarea fișierelor de configurarea pentru un anumit tip de unitate (serviciu, target, etc.). Editarea se poate face fie scriind direct în fișierul de configurare, fie folosind systemctl cu comanda edit
:
systemctl edit nume_serviciu
Se va deschide un fișier gol care poate fi folosit pentru a suprascrie sau adăuga directive definiției unității respective. Se va crea în /etc/systemd/system un director care conține numele unității cu sufixul .d; de exemplu, mongodb.service.d. În interiorul acestui director se va crea un mic fișier numit override.conf. Când unitatea este încărcată, systemd va suprascrie definiția inițială a unității cu ceea ce se află în override.conf. Trebuie menționat faptul că directivele din override.conf au prioritate față de cele din fișierul inițial de configurare al unității respective.
Dacă vrem să edităm direct fișierul de configurare pentru o unitate în loc să creăm fișierul override.conf, vom folosi opțiunea --full
:
systemctl edit --full nume_serviciu
În această ultimă situație, unitatea va fi încărcată în /etc/systemd/system și va avea prioritate față de fișierul inițial al unității, aflat, de regulă, în /lib/systemd/system. Pentru a șterge modificările făcute, ștergem fișierul nou-creat în /etc/systemd/system sau pe cel cu sufixul .d:
rm /etc/systemd/system/nume_serviciu.service
rm -r /etc/systemd/system/nume_serviciu.service.d
După ce ștergem un fișier sau un director, trebuie să reîncărcăm systemd, pentru a se reveni la referințele anterioare:
systemctl daemon-reload
Utilizarea target-urilor
Un target este o unitate specială care descrie o stare a sistemului. La fel ca alte unități systemd, fișierele care descriu un target pot fi identificate prin sufixul .target.
Ele pot fi solosite pentru a aduce un sistem Linux într-o anumită stare - sunt folosite ca referință pentru anumite funcții, care sunt disponibile doar într-o anumită stare a sistemului.
Listarea tuturor unităților target disponibile
Pentru a lista toate unitățile de tip target din sistem:
systemctl list-units --all --type=target
Să luăm, ca exemplu, sound.target, care indică faptul că placa de sunet este gata de a fi utilizată. Unitățile de care are nevoie sound.target pot fi menționate prin WantedBy=
sau RequiredBy=
sound.target
. Unitățile care au nevoie de sound.target se menționează prin Wants=
, Requires=
și After=
sound.target loaded active active Sound Card
Aflarea target-ului default
Procesul systemd are un target default care se folosește atunci când bootează sistemul. Îndeplinirea cascadei de dependențe a acestui target default are ca rezultat aducerea sistemului în starea dorită. Pentru a afla care este targetul default:
systemctl get-default
Pe sistemul meu Arch Linux (dar, de altfel, și pe majoritatea sistemelor Linux folosite ca desktop), targetul default este graphical.target:
# systemctl get-default
graphical.target
Pentru a seta un alt target default, se folosește comanda set-default
; astfel, dacă vrem să stabilim ca prestabilit targetul multi-user.target, dăm comanda:
systemctl set-default multi-user.target
Izolarea unui target
Sunt situații în care dorim să trecem într-un alt target, dar fără a-l seta ca default. Trecerea într-un alt target are ca efect pornirea tuturor unităților asociate cu noul target și oprirea celor care nu fac parte din arborele de dependențe.
De exemplu, dacă operăm în graphical.target și vrem să intrăm în multi-user.target (în care avem doar linia de comandă la care se pot conecta toți utilizatorii din sistem), folosim comanda isolate
:
systemctl isolate multi-user.target
Pentru a vedea toate dependențele multi-user.target:
#
systemctl list-dependencies multi-user.target
multi-user.target
● ├─avahi-daemon.service
● ├─cronie.service
● ├─dbus.service
● ├─dhcpcd.service
● ├─libvirtd.service
● ├─man-db.timer
● ├─mongodb.service
● ├─NetworkManager.service
● ├─ntpd.service
● ├─pamac-cleancache.timer
● ├─systemd-ask-password-wall.path
● ├─systemd-logind.service
● ├─systemd-user-sessions.service
● ├─updatedb.timer
● ├─basic.target
● │ ├─-.mount
● │ ├─tmp.mount
● │ ├─paths.target
● │ ├─slices.target
● │ │ ├─-.slice
● │ │ └─system.slice
● │ ├─sockets.target
● │ │ ├─avahi-daemon.socket
● │ │ ├─dbus.socket
● │ │ ├─dm-event.socket
[...]
Scurtături pentru evenimente importante
Există anumite targeturi definite pentru evenimente importante ale sistemului, cum ar fi oprirea sau restartul său. Systemctl
are anumite scurtături pentru a adăuga o funcționalitate mai mare acestor evenimente.
De exemplu, dacă vrem să trecem sistemul imediat în targetul rescue.target (single user mode), în loc de systemctl isolate rescue.target
, putem da comanda:
systemctl rescue
Penrtu full shutdown al sistemului, se dă comanda:
systemctl poweroff
Pentru a trece sistemul în starea halt:
systemctl halt
Penrtu restart:
systemctl reboot
Concluzii
În articol am prezentat, în principal, ce poate face systemctl
și interacțiunea cu unitățile systemd. Nu putem administra un sistem Linux fără să cunoaștem systemctl
și câteva comenzi.
Toate comenzile prezentate se regăsesc în cadrul examenului pentru certificarea RHCSA. Nu trebuie ținute minte toate comenzile și opțiunile - este suficient să știm că ele există și că pot fi găsite tastând doar câteva caractere în pagina man systemctl
.
O altă unealtă puternică a systemd, cu ajutorul căreia putem intra în interiorul sistemului de logging, este journalctl, despre care voi scrie într-un articol viitor.
victor a zis
Domnule Boses Aveti un har de profesor ...Eu care nu am inteles mare lucru din alte surse de aici intelg si ma aleg cu destul de multe lucruri .Va rog sa nu renuntati si din ce a-ti scris anterior sa faceti o arhiva ,sa nu le stergeti.in fiecare zi mai renunta unul la microsoft si are nevoie de sfaturi multi sant excelent pregatiti dar sant si altii care nu au inclinatii spre it in general si atunci...aici pot gasi cam tot ce le trebuie.
ps.Va rog sa nu sterge-ti nicuna din postarile dumneavoastra ,dincontra sa le strangeti inr-un loc .Multumesc
Şerban Stănescu a zis
Salut!
Mă bucur să văd că scrii în continuare! 🙂
Articolul mi se pare important, măcar în ideea că este util să ştim cum funcţionează sistemul nostru.
systemd, este metodologia folosită în foarte multe distribuţii şi în mod particular, în Linux Mint, pe care îl folosesc eu.
Pentru cine îşi administrează singur sistemul (cazul meu, de pildă) şi face mai mult decât "treburi uzuale", vine vremea când are nevoie să rezolve ceva. O problemă, un neajuns.
Uneori, există astfel de probleme, care depăşesc nivelul soluţiilor găsite pe internet. De pildă, asignarea IRQ-urilor la dispozitive. Într-o astfel de situaţie, doar cunoaşterea funcţionării calculatorului la nivelul systemd, poate oferi informaţiile de care avem nevoie pentru a construi o soluţie particulară.
în acest context, cred că articolul va ajuta măcar câţiva oameni să se lămurească dacă problema lor este abordabilă sau, e preferabil să apeleze la un om ca tine, care ştie despre ce este vorba, la un alt nivel de detaliere.
Mulţumesc pentru strădaina de a ne oferi informaţiile în limba Română! 🙂
Mult succes la orice certificare ţi-ai propus să obţii!
Bobses a zis
Salut și mulțumesc și eu.
Scriu mai puțin, căci timpul îmi este limitat.
Relaxion a zis
Yep...
Mulțumim pt tutorial, super bun, ca toate ale tale.
Bobses a zis
Mulțumesc și eu pentru apreciere.
Relaxion a zis
Nu toată lumea e fericită cu modul în care e folosit systemd
https://thenewstack.io/systemd-vs-linux-kernel/
https://fossbytes.com/systemd-vs-sys-v-vs-upstart/
Bobses a zis
Fericiți sau nu, cu asta defilăm și asta trebuie să știm să folosim...