Table of Contents

Systemd

systemd è il nuovo sistema di avvio dei servizi adottato a partire da da Debian 8 Jessie. Sostituisce il vecchio 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:

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

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