====== Systemd ======
**[[wp>Systemd|systemd]]** è il nuovo sistema di avvio dei servizi adottato a partire da da **Debian 8 Jessie**. Sostituisce il vecchio **[[https://wiki.debian.org/Debate/initsystem/sysvinit|sysvinit]]**.
===== Comandi di servizio =====
Quando si modifica qualche file di configurazione (ad esempio gli //unit files// in ''/lib/systemd/system/'' oppure gli script di compatibilità con il vecchio //sysvinit// contenuti in ''/etc/init.d/'') è necessario notificare ''systemd'' in modo che rilegga tutte le dipendenze, ecc:
systemctl daemon-reload
Per vedere lo stato di una //unit// (ad esempio di un servizio) ed anche le ultime righe di log:
systemctl status snmpd.service
● snmpd.service - LSB: SNMP agents
Loaded: loaded (/etc/init.d/snmpd)
Active: active (running) since Fri 2016-04-15 17:08:29 CEST; 3 weeks 6 days ago
Lo stato **loaded** significa che la //unit// è stata presa in carico da systemd, non che sia effettivamente avviata e in esecuzione.
Lo stato di attivazione **active** oppure **inactive** indica se il servizio sta girando oppure no. I tradizionali script di start/stop in ''/etc/init.d/'' consentono di passare da uno stato all'altro, ma il metodo suggerito è il nuovo:
systemctl stop snmpd.service
systemctl start snmpd.service
Per **disabilitare** o **abilitare** un servizio (quindi creare i vari link simbolici ''/etc/rc[0123456S].d/'' che attivano il processo ai vari runlevel:
systemctl disable snmpd.service
systemctl enable snmpd.service
Contrariamente a quanto si potrebbe immaginare i comandi **status** o **is-enabled** non mostrando se il servizio è abilitato o disabilitato. È necessario ispezionare la proprietà **Before** con il comando **show**, che è differente nei due casi:
systemctl disable snmpd
systemctl show snmpd.service | grep Before
Before=shutdown.target
systemctl enable snmpd
systemctl show snmpd.service | grep Before
Before=multi-user.target graphical.target shutdown.target
===== OpenVPN con systemd =====
Ci sono delle novità su come avviare da riga di comando una connessione OpenVPN su Debian 8 (Jessie).
Una configurazione tipica per una workstation è quella di NON attivare le vpn al bootstrap, mettendo in **''/etc/default/openvpn''**:
AUTOSTART="none"
Questa impostazione funziona ancora, ma con il nuovo **systemd** non è più possibile passare argomenti agli script start stop, quindi per avviare uno specifico tunnel **non funziona più** il comando
/etc/init.d/openvpn start VPN_NAME
Funzionano invece i seguenti comandi per attivare o disattivare la singola VPN:
systemctl start openvpn@VPN_NAME
systemctl stop openvpn@VPN_NAME
ATTENZIONE Se si modifica il file **''/etc/default/openvpn''**, non basta fermare e far ripartire il servizio, ma bisogna disabilitarlo e riabilitarlo:
systemctl stop openvpn
systemctl disable openvpn
systemctl enable openvpn
systemctl start openvpn
===== Unit file, service, device, target, ... =====
Nella terminologia di //systemd// una **unit** è genericamente una risorsa che il sistema sa gestire. Tali risorse sono definite da alcuni file chiamati appunto **unit file**.
Gli //unit file// vengono installati dai vari pacchetti nella directory **/lib/systemd/system/**. Se si desidera personalizzare qualcosa di uno unit file è opportuno farlo nella directory **/etc/systemd/system/**, che ha la precedenza su quella di sistema. Se si deve fornire solo dei piccoli snippet di configurazione è consigliato creare una cartella del tipo **/etc/systemd/system/example.service.d/** e metterci all'interno degli opportuni file **.conf**. Ricapitolando:
* **/lib/systemd/system/**
* **/etc/systemd/system/**
* **/etc/systemd/system/example.service.d/**
Uno //unit file// può descrivere diversi tipi di risorsa, indicato dall'estensione del file stesso. I più comuni sono:
^ .service | In genere una applicazione (demone) che fornisce un servizio. Contiene informazioni su quando attivarla, le dipendenze, ecc. |
^ .device | Un device viene gestito da systemd in genere se è attivato da **udev** o **sysfs**. |
^ .taget |
===== Servizi enabled, disabled, masked, ... =====
Le due condizioni più comuni per un servizio sono **enabled** o **disabled**, a seconda che debba essere avviato automaticamente al boot oppure no.
La condizione **masked** di alcuni **unit file** è equivalente a //disabled//, ma previene anche l'avvio manuale del servizio. Se un file è disabled i suoi link simbolici sono rimossi, se è masked esso viene linkato a ''/dev/null''.
===== Starting a service when a filesystem is available an mounted =====
This solution was tested on **Debian 9 Stretch**.
We have a filesystem on an **external USB disk**, which is not guaranteed to be present at bootstrap; to avoid hangs or errors during bootstrap, we have the following in **/etc/fstab**:
PARTUUID=92e84ecd-a306-44df-929b-... /data ext4 auto,nofail 0 2
If the USB disk is not plugged during bootstrap, the filesystem is not mounted and there are not blocking errors (due the **nofail** option). We want to start a service (actually the Kodi Media Center) only if the filesystem is mounted. The relevant lines in the unit file **/etc/systemd/system/kodi.service** are:
# See man systemd.unit for the following directives.
# This is equivalent of placing an "After" and "Requires" upon "data.mount";
RequiresMountsFor = /data
# When systemd starts or stops "data.mount", propagate action to this service.
PartOf = data.mount
In this way, the Kodi service is not started if the USB disk is not connected. If the device is connected at a later time, the filesystem is automatically mounted and the Kodi service is automatically started.
===== Modificare Ctrl-Alt-Del con Systemd =====
Con il vecchio sistema di init **sysvinit** l'azione predefinita dei tasti **Ctrl-Alt-Del** era impostata nel file **/etc/inittab**.
Nelle nuove versioni di Debian si utilizza **systemd** per l'init del sistema, il vecchio file di configurazione non esiste più. Ecco come associare un **poweroff** invece di un **reboot**:
ln -s /lib/systemd/system/poweroff.target /etc/systemd/system/ctrl-alt-del.target
=== Spiegazione ===
Le operazioni predefinite sono definite dai file contenuti in **/lib/systemd/system/**, ad esempio si vede che esiste il link simbolico:
ctrl-alt-del.target -> reboot.target
Non è necessario modificare il contenuto di questa directory, si può fare un override creando il link simbolico opportuno nella directory **/etc/systemd/system/**. Invece del **reboot.target** si utilizza l'esistente **poweroff.target**.
===== Timeout in attesa di un device =====
Può capitare che il processo di **bootstrap fallisce** perché un device elencato in **/etc/fstab** non risulta disponibile nei tempi richiesti (lentezza del disco? CPU troppo veloce?). In questi casi si può aggiungere in /etc/fstab una opzione di montaggio:
/dev/sda3 /home ext4 defaults,x-systemd.device-timeout=300s 0 2
===== Verifica Servizi =====
Alcuni comandi utili per **verificare il funzionamento** dei servizi gestiti da **systemd**.
Mostra lo stato di tutti i **servizi** e di tutte le **unit**:
systemctl --all --full status
Mostra le **unit** //required// e //wanted// dalla unit specificata:
systemctl --all list-dependencies ntp.service
===== Verifica dipendenze servizi =====
Generates textual **dependency graph** description in //dot// format:
systemd-analyze dot
systemd-analyze dot 'dhcpcd.*'
systemd-analyze dot dhcpcd.service
Prints an **SVG graphic** detailing **which system services have been started at what time**:
systemd-analyze plot > services-start-graph.svg
Shows units **required** and **wanted** by the specified units:
systemctl list-dependencies
systemctl list-dependencies dhcpcd.service
systemctl list-dependencies wpa_supplicant@..service
* **[[https://serverfault.com/questions/617398/is-there-a-way-to-see-the-execution-tree-of-systemd|Is there a way to see the execution tree of systemd?]]**
* **[[https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html|systemd.unit — Unit configuration]]**
* **[[https://www.freedesktop.org/software/systemd/man/latest/systemd.slice.html|systemd.slice — Slice unit configuration]]**
===== Alternativa allo script rc.local =====
Come eseguire uno script all'avvio di un sisetma Systemd.
Creare una unit Systemd **/etc/systemd/system/my-startup.service**:
# /etc/systemd/system/my-startup.service
#
# Service executed once the system has reached the multi-user status.
#
# Type=oneshot The unit is up after the main process exits.
# RemainAfterExit=yes The service shall be considered active even
# when all its processes exited.
#
# Eanble the service with:
# systemctl enable my-startup.service
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/local/sbin/my-startup-script
[Install]
WantedBy=multi-user.target
Abilitare la unit e predisporre lo script **/usr/local/sbin/my-startup-script**.
===== Riferimenti web =====
* **[[https://www.digitalocean.com/community/tutorials/understanding-systemd-units-and-unit-files|
Understanding Systemd Units and Unit Files]]**
* **[[https://askubuntu.com/questions/710420/why-are-some-systemd-services-in-the-masked-state|Why are some systemd services in the “masked” state?]]**