[successivo] [precedente] [inizio] [fine] [indice generale] [violazione GPL] [translators] [docinfo] [indice analitico] [volume] [parte]
Quando GNU/Linux viene avviato, il kernel si prende cura di avviare il processo iniziale, Init, a partire dal quale vengono poi generati tutti gli altri. Di solito si utilizza un meccanismo di inizializzazione derivato dallo UNIX System V.
Init determina quali siano i processi da avviare successivamente, in base al contenuto di /etc/inittab
il quale a sua volta fa riferimento a una serie di script contenuti normalmente all'interno della directory /etc/rc.d/
o in un'altra analoga.
All'interno di /etc/inittab
si distinguono azioni diverse in funzione del livello di esecuzione (run level), di solito un numero da zero a sei. Per convenzione, il livello zero identifica le azioni necessarie per fermare l'attività del sistema, in modo da permetterne lo spegnimento; il livello sei riavvia il sistema; il livello uno mette il sistema in condizione di funzionare in modalità monoutente.
Nei capitoli 357 e 355 viene descritto in modo un po' più dettagliato come è organizzata questa procedura nelle distribuzioni Red Hat e Debian, ma si tratta comunque di informazioni non aggiornate.
Init è il processo principale che genera tutti gli altri. All'avvio del sistema legge il file /etc/inittab
il quale contiene le informazioni per attivare gli altri processi necessari, compresa la gestione dei terminali. Per prima cosa viene determinato il livello di esecuzione iniziale, ottenendo l'informazione dalla direttiva initdefault di /etc/inittab
. Quindi vengono attivati i processi essenziali al funzionamento del sistema e infine i processi che combaciano con il livello di esecuzione attivato.
init [opzioni]
L'eseguibile init può essere invocato dall'utente root durante il funzionamento del sistema, per cambiare il livello di esecuzione, oppure ottenere il riesame del suo file di configurazione (/etc/inittab
).
-t secondi
Stabilisce il numero di secondi di attesa prima di cambiare il livello di esecuzione. In mancanza si intende 20 secondi.
0 | 1 | 2 | 3 | 4 | 5 | 6
Un numero da zero a sei stabilisce il livello di esecuzione a cui si vuole passare.
a | b | c
Una lettera a, b o c richiede di eseguire soltanto i processi indicati all'interno di /etc/inittab
che hanno un livello di esecuzione pari alla lettera specificata. In pratica, una lettera non indica un livello di esecuzione vero e proprio, in quanto si tratta di una possibilità di configurazione del file /etc/inittab
per definire i cosiddetti livelli «a richiesta» (on demand).
Q | q
Richiede di riesaminare il file /etc/inittab
(dopo che questo è stato modificato).
S | s
Richiede di passare alla modalità monoutente, ma non è pensato per essere utilizzato direttamente, in quanto per questo si preferisce selezionare il livello di esecuzione numero uno.
#
init 1
Pone il sistema al livello di esecuzione uno: monoutente.
#
init 0
Pone il sistema al livello di esecuzione zero: arresto del sistema. Equivale (in linea di massima) all'esecuzione di shutdown -h now.
#
init 6
Pone il sistema al livello di esecuzione sei: riavvio. Equivale (in linea di massima) all'esecuzione di shutdown -r now.
Il file inittab
descrive quali processi vengono avviati al momento dell'avvio del sistema e durante il funzionamento normale di questo. Init, il processo principale, distingue diversi livelli di esecuzione, per ognuno dei quali può essere stabilito un gruppo diverso di processi da avviare.
La struttura dei record che compongono le direttive di questo file può essere schematizzata nel modo seguente:
id:livelli_di_esecuzione:azione:processo
id -- è una sequenza unica di due caratteri che identifica il record (la riga) all'interno di inittab;
livelli_di_esecuzione -- elenca i livelli di esecuzione con cui l'azione indicata deve essere eseguita;
azione -- indica l'azione da eseguire;
processo -- specifica il processo da eseguire.
Se il nome del processo inizia con un simbolo +, Init non eseguirà l'aggiornamento di /var/run/utmp
e /var/log/wtmp
per quel processo; ciò è utile quando il processo stesso provvede da solo a questa operazione (la descrizione del significato e dell'importanza di questi due file si trova nel capitolo 53).
Il penultimo campo dei record di questo file, identifica l'azione da compiere. Questa viene rappresentata attraverso una parola chiave, come descritto dall'elenco seguente.
respawn
Quando il processo termina, viene riavviato.
wait
Il processo viene avviato una volta (sempre che il livello di esecuzione lo consenta) e Init attende che termini prima di eseguirne degli altri.
once
Il processo viene eseguito una volta quando il livello di esecuzione lo consente.
boot
Il processo viene eseguito al momento dell'avvio del sistema. Il campo del livello di esecuzione viene ignorato.
bootwait
Il processo viene eseguito al momento dell'avvio del sistema e Init attende la fine del processo prima di proseguire. Il campo del livello di esecuzione viene ignorato.
off
Non fa alcunché.
ondemand
Si tratta dei record «a richiesta» che vengono presi in considerazione quando viene richiamato Init seguito da una lettera a, b o c, che rappresentano appunto tre possibili livelli di esecuzione on demand. a, b o c non sono livelli di esecuzione, ma solo un modo per selezionare una serie di processi on demand indicati all'interno del file inittab
.
initdefault
Permette di definire il livello di esecuzione predefinito per l'avvio del sistema. Se non viene specificato, Init richiede l'inserimento di questo valore attraverso la console.
sysinit
Il processo viene eseguito al momento dell'avvio del sistema, prima di quelli indicati come boot e bootwait. Il campo del livello di esecuzione viene ignorato.
powerwait
Il processo viene eseguito quando Init riceve il segnale SIGPWR che indica un problema con l'alimentazione elettrica. Init attende la fine del processo prima di proseguire.
powerfail
Il processo viene eseguito quando Init riceve il segnale SIGPWR che indica un problema con l'alimentazione elettrica. Init non attende la fine del processo.
powerokwait
Il processo viene eseguito quando Init ha ricevuto il segnale SIGPWR, che indica un problema con l'alimentazione elettrica, ed è anche presente il file /etc/powerstatus
contenente la parola OK. Ciò significa che l'alimentazione elettrica è tornata allo stato di normalità.
ctrlaltdel
Il processo viene eseguito quando Init riceve il segnale SIGINT. Ciò significa che è stata premuta la combinazione di tasti [Ctrl+Alt+Canc] ([Ctrl+Alt+Del] nelle tastiere inglesi).
kbrequest
Il processo viene eseguito quando Init riceve un segnale dal gestore della tastiera che sta a indicare la pressione di una combinazione speciale di tasti sulla tastiera della console.
Il secondo campo, quello dei livelli di esecuzione, può contenere diversi caratteri che stanno a indicare diversi livelli di esecuzione possibili. Per esempio, la stringa 123 indica che il processo specificato verrà eseguito indifferentemente per tutti i livelli di esecuzione da uno a tre. Questo campo può contenere anche una lettera dell'alfabeto: a, b o c che sta a indicare un livello a richiesta. Nel caso di azioni del tipo sysinit, boot e bootwait, il campo del livello di esecuzione viene ignorato.
Negli esempi seguenti, si mostra prima un record del file /etc/inittab
e quindi, sotto, la sua descrizione.
id:5:initdefault:
Definisce il livello di esecuzione iniziale: cinque.
si::sysinit:/etc/rc.d/rc.sysinit
Inizializzazione del sistema: è la prima cosa a essere eseguita dopo l'avvio del sistema stesso. In pratica viene avviato lo script /etc/rc.d/rc.sysinit
(Red Hat).
l1:1:wait:/etc/rc.d/rc 1
Indica di eseguire /etc/rc.d/rc
, con l'argomento 1, nel caso in cui il livello di esecuzione sia pari a uno: singolo utente (Red Hat)
rc:123456:wait:/etc/rc.d/rc.M
Indica lo script (/etc/rc.d/rc.M
) da eseguire per tutti i livelli di esecuzione da uno a sei (Slackware).
ca::ctrlaltdel:/sbin/shutdown -t5 -rfn now
Indica il programma da eseguire in caso di pressione della combinazione [Ctrl+Alt+Canc]. Il livello di esecuzione non viene indicato perché è indifferente (Slackware).
l0:0:wait:/etc/rc.d/rc 0
Indica di eseguire /etc/rc.d/rc
, con l'argomento 0, nel caso in cui il livello di esecuzione sia pari a zero: arresto del sistema (Red Hat).
l6:6:wait:/etc/rc.d/rc 6
Indica di eseguire /etc/rc.d/rc
, con l'argomento 6, nel caso in cui il livello di esecuzione sia pari a sei: riavvio (Red Hat).
pf::powerfail:/sbin/shutdown -f +5 "THE POWER IS FAILING"
Indica il programma da eseguire quando si verifica un problema con l'alimentazione elettrica (Slackware).
pg:0123456:powerokwait:/sbin/shutdown -c "THE POWER IS BACK"
Indica il programma da eseguire se l'alimentazione elettrica torna normale prima del completamento del processo avviato quando si era verificato il problema (Slackware).
1:12345:respawn:/sbin/mingetty tty1 2:2345:respawn:/sbin/mingetty tty2 3:2345:respawn:/sbin/mingetty tty3 4:2345:respawn:/sbin/mingetty tty4 5:2345:respawn:/sbin/mingetty tty5 6:2345:respawn:/sbin/mingetty tty6
Si tratta dell'elenco di console virtuali utilizzabili. La prima si attiva per tutti i livelli di esecuzione da uno a cinque, le altre solo per i livelli superiori a uno. In questo caso è mingetty a essere responsabile dell'attivazione delle console virtuali (Red Hat).
s1:45:respawn:/sbin/agetty 19200 ttyS0 vt100
Indica l'attivazione di un terminale connesso sulla prima porta seriale. Si attiva solo con i livelli di esecuzione quattro o cinque (Slackware).
d2:45:respawn:/sbin/agetty -mt60 38400,19200,9600,2400,1200 ttyS1 vt100
Indica l'attivazione di un terminale remoto connesso via modem sulla seconda porta seriale. Si attiva solo con i livelli di esecuzione quattro o cinque (Slackware).
x:5:respawn:/usr/bin/X11/xdm -nodaemon
Nel caso il livello di esecuzione sia pari a cinque, esegue /usr/bin/X11/xdm
che si occupa di avviare una procedura di accesso (login) all'interno dell'ambiente grafico X (Red Hat).
/etc/initscript id livello_di_esecuzione azione processo
Quando lo script di shell /etc/initscript
esiste, viene utilizzato da Init per avviare i processi indicati all'interno del file /etc/inittab
.
Di solito questo script non è presente, tuttavia potrebbe essere utile per definire delle variabili di ambiente e altre impostazioni che riguardano l'interpretazione degli script della procedura di inizializzazione del sistema. La documentazione initscript(5) mostra un esempio simile a quello seguente, che dovrebbe chiarire il senso di questa possibilità.
# initscript Executed by init(8) for every program it # wants to spawn like this: # # /bin/sh /etc/initscript <id> <level> <action> <process> # # Set umask to safe level, and enable core dumps. umask 022 PATH=/bin:/sbin:/usr/bin:/usr/sbin export PATH # Execute the program. eval exec "$4"
Come si vede anche dai commenti dell'esempio, initscript riceve da Init una serie di argomenti che rappresentano tutti i campi contenuti nel record corrispondente di /etc/inittab
.
La prima differenza importante che distingue le varie distribuzioni GNU/Linux sta nell'organizzazione degli script della procedura di inizializzazione del sistema. Il punto di riferimento comune è Init con il suo /etc/inittab
, dal quale si intende quali siano il comandi avviati in presenza di un livello di esecuzione determinato; quello che c'è dopo costituisce il problema più grosso.
Volendo semplificare molto le cose, si può pensare al fatto che ci dovrebbe essere una directory specifica, contenente un gruppetto di script utilizzato esclusivamente per questi scopi. Volendo fare un esempio preciso, nel caso della distribuzione Red Hat, tale directory è /etc/rc.d/
; dagli esempi visti riguardo al file /etc/inittab
, si può notare che all'interno di questa directory si trovano gli script rc.sysinit e rc.
Per una convenzione diffusa, lo script rc.local che dovrebbe essere contenuto in questa directory (/etc/rc.d/
, o altra directory a seconda della propria distribuzione GNU/Linux), viene eseguito alla fine della procedura di inizializzazione del sistema e viene lasciato a disposizione dell'amministratore che può modificarlo come crede. Volendo fare un'associazione con il sistema Dos, si potrebbe paragonare questo script al file AUTOEXEC.BAT
.(1)
Le motivazioni che spingono a un'impostazione differente di questi script della procedura di inizializzazione del sistema, possono essere varie. Anche la collocazione di tale directory è controversa, a cominciare dal fatto che la directory /etc/
non dovrebbe contenere programmi e nemmeno script. Infatti, a questo proposito, la distribuzione SuSE colloca questi script nella directory /sbin/init.d/
.
Gli script della procedura di inizializzazione del sistema hanno il compito di avviare il sistema operativo e di fermarlo, attivando e disattivando tutti i servizi necessari, cioè intervenendo nell'avvio e nella conclusione del funzionamento dei demoni relativi.
Si può intuire che non sia possibile realizzare uno o più script del genere per avviare tutti i tipi di demone che possono essere presenti nel proprio sistema, anche perché ci possono essere dei servizi installati che però non si vogliono gestire. Di conseguenza, nella situazione più banale, quando si intende installare e gestire un nuovo servizio, occorre anche modificare la procedura di inizializzazione del sistema per attivare il demone relativo e per disattivarlo nel momento dell'arresto del sistema. Una cosa del genere può andare bene per una persona esperta, ma si tratta sempre di un'impostazione piuttosto scomoda.
Nel tempo si è diffuso uno standard per risolvere questo problema, ed è ciò che viene descritto nelle sezioni seguenti.
Secondo una convenzione diffusa, per facilitare l'avvio e la conclusione dei servizi si definisce una directory specifica, che potrebbe essere /etc/rc.d/init.d/
, o /etc/init.d/
, o ancora /sbin/init.d/
, all'interno della quale si possono inserire degli script che hanno una sintassi uniforme.
nome_servizio {start|stop}
In pratica, il nome dello script tende a corrispondere a quello del servizio che si intende controllare; l'argomento costituito dalla parola chiave start fa sì che lo script avvii il servizio, mentre la parola chiave stop serve a concluderlo.
Questi script possono essere più o meno raffinati, per esempio possono accettare anche altri tipi di ordini (come restart, allo scopo di riavviare un servizio), ma la cosa più importante è che dovrebbero evitare di avviare dei doppioni, controllando prima di avviare qualcosa, se per caso questo risulta già attivo. Naturalmente, un servizio può essere ottenuto con l'avvio di diversi programmi demone e in questo è molto comodo tale sistema di script specifici.
A titolo di esempio viene mostrato come potrebbe essere composto uno script del genere, per l'avvio del servizio ipotetico denominato pippo, che si avvale del programma omonimo per gestirlo. Per semplicità, non vengono indicati accorgimenti particolari per controllare che il servizio sia già attivo o meno.
#!/bin/sh # # init.d/pippo {start|stop|restart} # # Analisi dell'argomento usato nella chiamata. case "$1" in start) echo -n "Avvio del servizio Pippo: " /usr/sbin/pippo & echo ;; stop) echo -n "Disattivazione del servizio Pippo: " killall pippo echo ;; restart) killall -HUP pippo ;; *) echo "Utilizzo: pippo {start|stop|restart}" exit 1 esac exit 0
Lo scopo e la vera utilità di questi script sta nel facilitare una standardizzazione della procedura di inizializzazione del sistema; tuttavia si può intuire la possibilità di sfruttarli anche per attivare e disattivare manualmente un servizio, senza intervenire direttamente sui programmi relativi.
Procedendo intuitivamente, si potrebbe pensare di fare in modo che la procedura di inizializzazione del sistema, provveda a eseguire tutti gli script di controllo dei servizi, utilizzando l'argomento start all'avvio e l'argomento stop allo spegnimento. Una cosa del genere è molto semplice da realizzare, ma si pongono due problemi: alcuni servizi potrebbero essere a disposizione, senza che la procedura di inizializzazione del sistema debba avviarli automaticamente; inoltre la sequenza di attivazione e di disattivazione dei servizi potrebbe essere importante.
In pratica, si utilizza un meccanismo molto semplice: si predispongono tante directory quanti sono i livelli di esecuzione gestiti attraverso il file /etc/inittab
. Queste directory hanno il nome rcn.d/
, dove n rappresenta il numero del livello di esecuzione corrispondente. La loro collocazione effettiva potrebbe essere /etc/rcn.d/
, /etc/rc.d/rcn.d/
o anche /sbin/init.d/rcn.d/
. All'interno di queste directory si inseriscono dei collegamenti simbolici che puntano agli script descritti nella sezione precedente, in modo che siano presenti i riferimenti ai servizi desiderati per ogni livello di esecuzione (distinto in base alla directory rcn.d/
particolare).
I nomi di questi collegamenti iniziano in modo speciale: Knn
e Snn
. I collegamenti che iniziano con la lettera «S» (Start) servono per individuare gli script da utilizzare per l'attivazione dei servizi, vengono avviati con l'argomento start, in ordine alfabetico, in base alla sequenza fissata con le due cifre numeriche successive che servono proprio a distinguerne la sequenza. I collegamenti che iniziano con la lettera «K» (Kill) servono per individuare gli script da utilizzare per la disattivazione dei servizi, vengono avviati con l'argomento stop, anche questi in ordine alfabetico.
Ecco, a titolo di esempio, cosa potrebbe contenere una di queste directory.
lrwxrwxrwx 1 root root 13 13:39 K15gpm -> ../init.d/gpm lrwxrwxrwx 1 root root 13 13:39 K60atd -> ../init.d/atd lrwxrwxrwx 1 root root 15 13:39 K60crond -> ../init.d/crond lrwxrwxrwx 1 root root 16 13:39 K96pcmcia -> ../init.d/pcmcia lrwxrwxrwx 1 root root 17 13:39 S01kerneld -> ../init.d/kerneld lrwxrwxrwx 1 root root 17 13:39 S10network -> ../init.d/network lrwxrwxrwx 1 root root 15 13:39 S15nfsfs -> ../init.d/nfsfs lrwxrwxrwx 1 root root 16 13:39 S20random -> ../init.d/random lrwxrwxrwx 1 root root 16 13:39 S30syslog -> ../init.d/syslog lrwxrwxrwx 1 root root 14 13:39 S50inet -> ../init.d/inet lrwxrwxrwx 1 root root 18 13:39 S75keytable -> ../init.d/keytable
Osservando i servizi syslog e inet, si può notare il numero attribuito per l'avvio, che serve a fare in modo che il servizio syslog sia avviato prima di inet.
Sempre a titolo di esempio, viene mostrato un pezzo di uno script, per una shell Bourne o derivata, fatto per scandire un elenco di collegamenti del genere, allo scopo di attivare e di disattivare i servizi, a partire dai collegamenti contenuti nella directory /etc/rc.d/rc3.d/
. Per un lettore inesperto, questo potrebbe essere un po' difficile da leggere, ma l'esempio viene aggiunto per completare l'argomento.
#!/bin/sh #... # Attivazione dei servizi del livello di esecuzione 3. for I in /etc/rc.d/rc3.d/K*; do # Disattiva il servizio. $I stop done for I in /etc/rc.d/rc3.d/S*; do # Attiva il servizio. $I start done
In pratica, prima si disattivano i servizi corrispondenti ai collegamenti che iniziano con la lettera «K», quindi si attivano quelli che hanno la lettera «S». Si può intuire che le directory rc0.d/
e rc6.d/
contengano prevalentemente, o esclusivamente, riferimenti che iniziano con la lettera «K», dal momento che i livelli di esecuzione corrispondenti portano all'arresto del sistema o al suo riavvio.
daniele @ swlibero.org
1) La distribuzione GNU/Linux Debian non prevede la presenza di questo script. Tuttavia, tale mancanza non costituisce un limite, dal momento che nulla vieta di realizzarne uno analogo da collocare nella directory /etc/init.d/
, da collegare poi nelle directory /etc/rcn.d/
.
Dovrebbe essere possibile fare riferimento a questa pagina anche con il nome procedura_di_inizializzazione_del_sistema_system_nbsp_v.html
[successivo] [precedente] [inizio] [fine] [indice generale] [violazione GPL] [translators] [docinfo] [indice analitico]