Avviare Spegnere o Riavviare il Sistema

14 / 100

Introduzione

Una caratteristica comune tra i sistemi operativi che seguono i principi di progettazione Unix è l’impiego di processi separati per controllare funzioni distinte del sistema.

Questi processi, chiamati demoni (daemon o, più in generale, servizi), sono anche responsabili di funzionalità estese alla base del sistema operativo, come servizi di applicazioni di rete (server HTTP, condivisione file, e-mail, ecc.), database, configurazioni su richiesta, ecc. Sebbene Linux utilizzi un kernel monolitico, molti suoi aspetti a basso livello sono influenzati dai demoni, come il bilanciamento del carico e la configurazione del firewall.

A seconda dello scopo di funzionamento del sistema avremo attivi alcuni demoni invece di altri. Anche il set di demoni attivi dovrebbe essere modificabile in fase di esecuzione, in modo che i servizi possano essere avviati o arrestati senza dover riavviare l’intero sistema. Per affrontare questo problema, ogni principale distribuzione Linux offre una qualche forma di utilità di gestione dei servizi per gestire il sistema.

I servizi possono essere controllati da script di shell o da un programma e dai suoi file di configurazione di supporto. Il primo metodo è implementato dallo standard SysVinit, noto anche come System V o semplicemente SysV. Il secondo metodo è implementato da systemd e Upstart. Storicamente, i gestori di servizi basati su SysV erano i più utilizzati dalle distribuzioni Linux. Oggi, i gestori di servizi basati su systemd sono largamente implementati nella maggior parte delle distribuzioni Linux. Il service manager è il primo programma lanciato dal kernel durante il processo di avvio, quindi il suo PID (Process Identification Number) sarà sempre 1.

SysVinit

Un gestore di servizi basato sullo standard SysVinit fornirà set predefiniti di stati di sistema, chiamati runlevel, e i relativi file di script di servizio da eseguire. I runlevel sono numerati da “0” a “6”, in genere assegnati ai seguenti scopi:

Runlevel 0

Spegnimento del sistema.

Runlevel 1, s o single

Modalità utente singolo, senza rete e altre funzionalità non essenziali (modalità manutenzione).

Runlevel 2, 3 o 4

Modalità multiutente. Gli utenti possono accedere tramite console o rete. I runlevel 2 e 4 non sono usati spesso.

Runlevel 5

Modalità multiutente. È equivalente a 3, oltre al login in modalità grafica.

Runlevel 6

Riavvio del sistema.

Il programma responsabile della gestione dei runlevel e dei demoni/risorse associati è /sbin/init. Durante l’inizializzazione del sistema, il programma init identifica il runlevel richiesto, definito da un parametro del kernel o nel file /etc/inittab, e carica gli script associati ivi elencati per il runlevel dato. Ogni runlevel può avere molti file di servizio associati, di solito script nella directory /etc/init.d/. Poiché non tutti i runlevel sono equivalenti attraverso diverse distribuzioni Linux, una breve descrizione dello scopo del runlevel può anche essere trovata nelle distribuzioni basate su SysV.

La sintassi del file / etc/inittab usa questo formato:

id:runlevels:action:process

“Id” è un nome generico di massimo quattro caratteri utilizzato per identificare la voce. La voce runlevels è un elenco di numeri di runlevel per i quali deve essere eseguita un’azione specifica. Il termine action definisce come init eseguirà il processo indicato dal termine process.

Le azioni disponibili sono:

boot

Il processo verrà eseguito durante l’inizializzazione del sistema. Il campo runlevels viene ignorato.

bootwait

Il processo verrà eseguito durante l’inizializzazione del sistema e init attenderà fino al termine per continuare. Il campo runlevels viene ignorato.

sysinit

Il processo verrà eseguito dopo l’inizializzazione del sistema, indipendentemente dal runlevel. Il campo runlevel viene ignorato.wait

Il processo verrà eseguito per i runlevel indicati e init attenderà fino al termine per continuare.

respawn

Il processo verrà riavviato se viene terminato.

ctrlaltdel

Il processo verrà eseguito quando il processo init riceve il segnale SIGINT, attivato quando viene premuta la sequenza di tasti Ctrl+Alt+Canc.

Il runlevel predefinito — quello che verrà scelto se nessun altro viene dato come parametro del kernel — è anche definito in /etc/inittab, nella voce id:x:initdefaultx è il numero del runlevel predefinito. Questo numero non dovrebbe mai essere 0 o 6, dato che causerebbe l’arresto o il riavvio del sistema non appena termina il processo di avvio.

Di seguito è mostrato un tipico file /etc/inittab:

# Default runlevel
id:3:initdefault:

# Configuration script executed during boot
si::sysinit:/etc/init.d/rcS

# Action taken on runlevel S (single user)
~:S:wait:/sbin/sulogin

# Configuration for each execution level
l0:0:wait:/etc/init.d/rc 0
l1:1:wait:/etc/init.d/rc 1
l2:2:wait:/etc/init.d/rc 2
l3:3:wait:/etc/init.d/rc 3
l4:4:wait:/etc/init.d/rc 4
l5:5:wait:/etc/init.d/rc 5
l6:6:wait:/etc/init.d/rc 6

# Action taken upon ctrl+alt+del keystroke
ca::ctrlaltdel:/sbin/shutdown -r now

# Enable consoles for runlevels 2 and 3
1:23:respawn:/sbin/getty tty1 VC linux
2:23:respawn:/sbin/getty tty2 VC linux
3:23:respawn:/sbin/getty tty3 VC linux
4:23:respawn:/sbin/getty tty4 VC linux

# For runlevel 3, also enable serial
# terminals ttyS0 and ttyS1 (modem) consoles
S0:3:respawn:/sbin/getty -L 9600 ttyS0 vt320
S1:3:respawn:/sbin/mgetty -x0 -D ttyS1

Il comando telinit q dovrebbe essere eseguito ogni volta che il file /etc/inittab viene modificato. L’argomento q (o Q) dice a init di ricaricare la sua configurazione. Tale passaggio è importante per evitare l’arresto del sistema a causa di una configurazione errata in /etc/inittab.

Gli script usati da init per impostare ciascun runlevel sono memorizzati nella directory /etc/init.d/ `.

Ogni runlevel ha una directory associata in `/etc/, chiamata /etc/rc0.d//etc/rc1.d//etc/rc2.d/, ecc., con all’interno gli script che dovrebbero essere eseguiti all’avvio del runlevel corrispondente.

Poiché lo stesso script può essere utilizzato da runlevel diversi, i file in quelle directory sono solo collegamenti simbolici agli script effettivi in ​​/etc/init.d/. Inoltre, la prima lettera del nome file del collegamento nella directory del runlevel indica se il servizio deve essere avviato o terminato per il runlevel corrispondente.

Il nome file di un collegamento che inizia con la lettera K determina che il servizio verrà terminato(kill) quando si accede al runlevel. Iniziando con la lettera S, il servizio verrà avviato(start) quando si accede al runlevel. La directory /etc/rc1.d/, per esempio, avrà molti collegamenti agli script di rete che iniziano con la lettera K, considerando che il runlevel 1 è il runlevel per singolo utente, senza connettività di rete.

Il comando runlevel mostra il runlevel corrente per il sistema in uso. Il comando runlevel mostra due valori, il primo è il runlevel precedente e il secondo è il runlevel corrente:

$ runlevel
N 3

La lettera N nell’output mostra che il runlevel non è cambiato dall’ultimo avvio. Nell’esempio, il runlevel 3 è l’attuale runlevel del sistema.

Lo stesso programma init può essere usato per alternare i runlevel in un sistema in esecuzione, senza la necessità di riavviare. Il comando telinit può anche essere usato per alternare tra i runlevel. Per esempio, i comandi telinit 1telinit s o telinit S cambieranno il sistema al runlevel 1.

Systemd

Attualmente, systemd è il set di strumenti più utilizzato per gestire risorse e servizi di sistema, che vengono definiti come units da systemd. Un’unità è composta da un nome, un tipo e un file di configurazione corrispondente. Per esempio, l’unità per un processo del server httpd (come il web server Apache) sarà httpd.service nelle distribuzioni basate su Red Hat e anche il suo file di configurazione sarà chiamato httpd.service (nelle distribuzioni basate su Debian questa unità è chiamata apache2.service).

Esistono sette tipi distinti di unità systemd:service

Il tipo di unità più comune, per risorse di sistema attive che possono essere avviate, interrotte e ricaricate.

socket

Il tipo di unità socket può essere un socket del filesystem o un socket di rete. Tutte le unità socket hanno un’unità di servizio corrispondente, caricata quando il socket riceve una richiesta.

device

Un’unità device è associata a un dispositivo hardware identificato dal kernel. Un device verrà preso come unità di sistema solo se esiste una regola udev per questo scopo. Un’unità device può essere utilizzata per risolvere le dipendenze di configurazione quando viene rilevato un determinato hardware, dato che le proprietà della regola udev possono essere utilizzate come parametri per l’unità device.

mount

Un’unità mount è una definizione del punto mount nel filesystem, simile a una voce in /etc/fstab.automount

Un’unità di automount è anche una definizione del punto di montaggio nel filesystem, ma montata automaticamente. Ogni unità di automount ha un’unità di montaggio corrispondente, che viene avviata quando si accede al punto di montaggio di montaggio automatico.

target

Un’unità target è un raggruppamento di altre unità, gestite come una singola unità.

snapshot

Un’unità snapshot è uno stato salvato del gestore di systemd (non disponibile su ogni distribuzione Linux).

Il comando principale per il controllo delle unità systemd è systemctl. Il comando systemctl viene utilizzato per eseguire tutte le attività relative all’attivazione, disattivazione, esecuzione, interruzione, monitoraggio, ecc. delle unità. Per un’unità fittizia chiamata unit.service, per esempio, le azioni systemctl più comuni saranno:systemctl start unit.service

Avvia unit.systemctl stop unit.service

Interrompi unit.systemctl restart unit.service

Riavvia unit.systemctl status unit.service

Mostra lo stato di unit, anche se è in esecuzione o meno.

systemctl is-active unit.service

Mostra se unit è in esecuzione o meno.

systemctl enable unit.service

Abilita unit, ovvero, unit verrà avviato durante l’inizializzazione del sistema.systemctl disable unit.service

unit non si avvierà insieme al sistema.

systemctl is-enabled unit.service

Verifica se unit si avvia con il sistema. La risposta è memorizzata nella variabile $?. Il valore 0 indica che unit si avvia con il sistema e il valore 1 indica che unit non avvia con il sistema.

NoteLe installazioni più recenti di systemd elencheranno effettivamente la configurazione di un’unità relativamente alla fase di boot. Per esempio:$ systemctl is-enabled apparmor.service enabled

Se nel sistema non esistono altre unità con lo stesso nome, è possibile eliminare il suffisso dopo il punto. Se, per esempio, c’è una sola unità httpd di tipo service, allora è sufficiente solo httpd come parametro di unità per systemctl.

Il comando systemctl può anche controllare system targets. L’unità multi-user.target, per esempio, combina tutte le unità richieste dall’ambiente di sistema multiutente. È simile al runlevel numero 3 in un sistema che utilizza SysV.

Il comando systemctl isolate si rende utile per passare tra un target e l’altro. Quindi, per passare manualmente al target multi-user:

# systemctl isolate multi-user.target

Esistono target corrispondenti ai runlevel SysV, a partire da runlevelO.target fino a runlevel6.target. Comunque, systemd non usa il file /etc/inittab. Per cambiare la destinazione di sistema predefinita, l’opzione systemd.unit può essere aggiunta all’elenco dei parametri del kernel. Per esempio, per usare multi-user.target come destinazione standard, il parametro del kernel dovrebbe essere systemd.unit = multi-user.target. Tutti i parametri del kernel possono essere resi persistenti modificando la configurazione del bootloader.

Un altro modo per cambiare la destinazione predefinita è modificare il collegamento simbolico /etc/systemd/system/default.target in modo che punti alla destinazione desiderata. La ridefinizione del collegamento può essere fatta automaticamente attraverso il comando systemctl:

# systemctl set-default multi-user.target

Allo stesso modo, puoi determinare quale sia la destinazione di avvio predefinita del tuo sistema con il seguente comando:

$ systemctl get-default
graphical.target

Similmente ai sistemi che adottano SysV, la destinazione predefinita non dovrebbe mai puntare a shutdown.target, poiché corrisponde al runlevel 0 (shutdown).

I file di configurazione associati ad ogni unità si trovano nella directory /lib/systemd/system/. Il comando systemctl list-unit-files elenca tutte le unità disponibili e mostra se sono abilitate all’avvio del sistema. L’opzione --type selezionerà solo le unità per un dato tipo, come in systemctl list-unit-files --type=service e systemctl list-unit-files --type=target.

Le unità attive o che sono state attive durante la sessione di sistema corrente possono essere elencate con il comando systemctl list-units. Come l’opzione list-unit-files, il comando systemctl list-units --type=service mostrerà solo le unità di tipo service mentre il comando systemctl list-units --type=target lo farà solo con le unità di tipo “target”.

systemd è anche responsabile dell’attivazione e della risposta agli eventi correlati all’alimentazione. Il comando systemctl suspend metterà il sistema in modalità di sospensione (a basso consumo), mantenendo i dati correnti in memoria. Il comando systemctl hibernate copierà tutti i dati della memoria su disco, quindi lo stato corrente del sistema può essere ripristinato anche dopo essere stato spento. Le azioni associate a tali eventi sono definite nel file /etc/systemd/logind.conf o in file separati all’interno della directory /etc/systemd/logind.conf.d/. Tuttavia, questa funzione di systemd può essere usata solo quando non c’è nessun altro power manager in esecuzione nel sistema, come il demone acpid. Il demone acpid è il principale power manager per Linux e consente regolazioni più precise delle azioni a seguito di eventi relativi all’alimentazione, come la chiusura del coperchio del laptop, la batteria scarica o gli stati di carica della batteria.

Upstart

Gli script di inizializzazione utilizzati da Upstart si trovano nella directory /etc/init/. I servizi di sistema possono essere elencati con il comando initctl list, che mostra anche lo stato corrente dei servizi e, se disponibile, il loro identificativo PID.

# initctl list
avahi-cups-reload stop/waiting
avahi-daemon start/running, process 1123
mountall-net stop/waiting
mountnfs-bootclean.sh start/running
nmbd start/running, process 3085
passwd stop/waiting
rc stop/waiting
rsyslog start/running, process 1095
tty4 start/running, process 1761
udev start/running, process 1073
upstart-udev-bridge start/running, process 1066
console-setup stop/waiting
irqbalance start/running, process 1842
plymouth-log stop/waiting
smbd start/running, process 1457
tty5 start/running, process 1764
failsafe stop/waiting

Ogni azione Upstart ha il suo comando indipendente. Per esempio, il comando start può essere utilizzato per avviare un sesto terminale virtuale:

# start tty6

Lo stato corrente di una risorsa può essere verificato con il comando status:

# status tty6
tty6 start/running, process 3282

E l’interruzione di una risorsa può essere eseguita con il comando stop:

# stop tty6

Upstart non usa il file /etc/inittab per definire i runlevel, ma i comandi legacy runlevel e telinit possono ancora essere usati per verificare e alternare i vari runlevel.

NoteUpstart è stato sviluppato per la distribuzione Ubuntu Linux per facilitare l’avvio parallelo dei processi. Ubuntu ha smesso di usare Upstart dal 2015 quando è passato da Upstart a systemd.

Spegnimento e Riavvio

Un comando molto utilizzato per arrestare o riavviare il sistema è sorprendentemente chiamato shutdown. Il comando shutdown aggiunge funzioni extra al processo di spegnimento: avvisa automaticamente tutti gli utenti che hanno effettuato l’accesso con un messaggio di avviso nelle loro sessioni di shell e vengono impediti nuovi accessi. Il comando shutdown funge da intermediario per le procedure SysV o systemd, ovvero esegue l’azione richiesta chiamando l’azione corrispondente nel gestore servizi adottato dal sistema.

Dopo l’esecuzione di shutdown, tutti i processi ricevono un segnale SIGTERM, seguito dal segnale SIGKILL, quindi il sistema si spegne o cambia il suo runlevel. Per impostazione predefinita, quando non vengono utilizzate le opzioni -h o -r, il sistema si alterna al runlevel 1, ovvero alla modalità utente singolo. Per modificare le opzioni predefinite per shutdown, il comando dovrebbe essere eseguito con la seguente sintassi:

$ shutdown [option] time [message]

È richiesto solo il parametro time. Quest’ultimo definisce quando verrà eseguita l’azione richiesta, accettando i seguenti formati:hh:mm

Questo formato specifica il tempo di esecuzione come ora e minuti.+m

Questo formato specifica quanti minuti attendere prima dell’esecuzione.now or +0

Questo formato determina l’esecuzione immediata.

Il parametro message è il testo di avviso inviato a tutte le sessioni del terminale degli utenti che hanno effettuato l’accesso.

L’implementazione di SysV consente di limitare gli utenti che saranno in grado di riavviare la macchina premendo Ctrl+Alt+Canc. Questo è possibile posizionando l’opzione -a per il comando shutdown presente sulla riga riguardante ctrlaltdel nel file /etc/inittab. In questo modo, solo gli utenti i cui nomi utente si trovano nel file /etc/shutdown.allow saranno in grado di riavviare il sistema con la combinazione di tasti Ctrl+Alt+Canc.

Il comando systemctl può anche essere usato per spegnere o riavviare la macchina nei sistemi che utilizzano systemd. Per riavviare il sistema, si può usare il comando systemctl reboot. Per spegnere il sistema, si deve usare invece il comando `systemctl poweroff `. Entrambi i comandi richiedono per l’esecuzione i privilegi di root, poiché gli utenti ordinari non possono eseguire tali procedure.

NoteAlcune distribuzioni Linux collegheranno poweroff e reboot a systemctl come singoli comandi. Per esempio:$ sudo which poweroff /usr/sbin/poweroff $ sudo ls -l /usr/sbin/poweroff lrwxrwxrwx 1 root root 14 Aug 20 07:50 /usr/sbin/poweroff -> /bin/systemctl

Non tutte le attività di manutenzione richiedono che il sistema sia spento o riavviato. Tuttavia, quando è necessario passare allo stato del sistema in modalità utente singolo, è importante avvisare gli utenti che hanno effettuato l’accesso in modo che non vengano danneggiati da una brusca interruzione.

Simile a quello che fa il comando shutdown quando si spegne o si riavvia il sistema, il comando wall è in grado di inviare un messaggio alle sessioni terminale di tutti gli utenti che hanno effettuato l’accesso. Per fare ciò, l’amministratore di sistema deve solo fornire un file o scrivere direttamente il messaggio come parametro del comando wall.

Esercizi Guidati

  1. Come si può usare il comando telinit per riavviare il sistema?
  2. Cosa accadrà ai servizi relativi al file /etc/rc1.d/K90network quando il sistema entra nel runlevel 1?
  3. Usando il comando systemctl, come può un utente verificare se l’unità sshd.service è in esecuzione?
  4. In un sistema basato su systemd, quale comando deve essere eseguito per abilitare l’attivazione dell’unità sshd.service durante l’avvio del sistema?

Esercizi Esplorativi

  1. In un sistema basato su SysV, supponiamo che il runlevel predefinito indicato in /etc/inittab sia 3, ma il sistema si avvii sempre nel runlevel 1. Qual è la causa più probabile?
  2. Sebbene il file /sbin/init possa essere trovato nei sistemi basati su systemd, è solo un collegamento simbolico a un altro file eseguibile. In tali sistemi, qual è il file indicato da /sbin/init?
  3. Come può essere verificato il target di sistema predefinito in un sistema basato su systemd?
  4. Come si può cancellare un riavvio del sistema programmato con il comando shutdown?

Sommario

Questa lezione tratta le principali utility utilizzate come gestori di servizi dalle distribuzioni Linux. Le utility SysVinit, systemd e Upstart hanno ciascuna il proprio approccio al controllo dei servizi e degli stati del sistema. La lezione affronta i seguenti argomenti:

  • Quali sono i servizi di sistema e il loro ruolo nel sistema operativo.
  • Concetti e utilizzo di base dei comandi in SysVinit, systemd e Upstart.
  • Come avviare, arrestare e riavviare correttamente i servizi di sistema e il sistema stesso.

I comandi e le procedure trattate erano:

  • Comandi e file relativi a SysVinit, come init/etc/inittab e telinit.
  • Il comando principale di systemd: systemctl.
  • Comandi Upstart: initctlstatusstartstop.
  • Comandi tradizionali di gestione, come shutdown, e wall.

Risposte agli Esercizi Guidati

  1. Come si può usare il comando telinit per riavviare il sistema?Il comando telinit 6 passerà il sistema a runlevel 6, ovvero riavvia il sistema.
  2. Cosa accadrà ai servizi relativi al file /etc/rc1.d/K90network quando il sistema entra nel runlevel 1?A causa della lettera “K” all’inizio del nome del file, i relativi servizi verranno interrotti.
  3. Usando il comando systemctl, come può un utente verificare se l’unità sshd.service è in esecuzione?Con il comando systemctl status sshd.service o systemctl is-active sshd.service.
  4. In un sistema basato su systemd, quale comando deve essere eseguito per abilitare l’attivazione dell’unità sshd.service durante l’avvio del sistema?Il comando systemctl enable sshd.service, eseguito da un’utenza con i privilegi di root.

Risposte agli Esercizi Guidati

  1. In un sistema basato su SysV, supponiamo che il runlevel predefinito indicato in /etc/inittab sia 3, ma il sistema si avvii sempre nel runlevel 1. Qual è la causa più probabile?I parametri 1 o S possono essere presenti nell’elenco dei parametri del kernel.
  2. Sebbene il file /sbin/init possa essere trovato nei sistemi basati su systemd, è solo un collegamento simbolico a un altro file eseguibile. In tali sistemi, qual è il file indicato da /sbin/init?Il comando principale di systemd: /lib/systemd/systemd.
  3. Come può essere verificato il target di sistema predefinito in un sistema basato su systemd?Il collegamento simbolico /etc/systemd/system/default.target punterà al file unit indicato come target predefinito. Può anche essere usato il comando systemctl get-default.
  4. Come si può cancellare un riavvio del sistema programmato con il comando shutdown?Dovrebbe essere usato il comando shutdown -c.