101.3 Lezione 1
Certificazione: |
LPIC-1 |
---|---|
Versione: |
5.0 |
Argomento: |
101 L’Architettura di Sistema |
Obiettivo: |
101.3 Cambiare runlevel / Avviare target e Spegnere o Riavviare il Sistema |
Lezione: |
1 di 1 |
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 camporunlevels
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:initdefault
. x
è 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 1
, telinit 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 valore0
indica cheunit
si avvia con il sistema e il valore1
indica cheunit
non avvia con il sistema.
Note
|
Le 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.
Note
|
Upstart è 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.
Note
|
Alcune distribuzioni Linux collegheranno $ 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
-
Come si può usare il comando
telinit
per riavviare il sistema? -
Cosa accadrà ai servizi relativi al file
/etc/rc1.d/K90network
quando il sistema entra nel runlevel 1? -
Usando il comando
systemctl
, come può un utente verificare se l’unitàsshd.service
è in esecuzione? -
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
-
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? -
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
? -
Come può essere verificato il target di sistema predefinito in un sistema basato su systemd?
-
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
etelinit
. -
Il comando principale di systemd:
systemctl
. -
Comandi Upstart:
initctl
,status
,start
,stop
. -
Comandi tradizionali di gestione, come
shutdown
, ewall
.
Risposte agli Esercizi Guidati
-
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. -
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.
-
Usando il comando
systemctl
, come può un utente verificare se l’unitàsshd.service
è in esecuzione?Con il comando
systemctl status sshd.service
osystemctl is-active sshd.service
. -
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
-
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
oS
possono essere presenti nell’elenco dei parametri del kernel. -
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
. -
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 comandosystemctl get-default
. -
Come si può cancellare un riavvio del sistema programmato con il comando
shutdown
?Dovrebbe essere usato il comando
shutdown -c
.