Handbook:Parts/Working/Initscripts/it

Avviare il sistema
Quando il sistema viene avviato, molto testo inizia a scorrere. Quando si presta attenzione, si noterà che quel testo (di solito) è lo stesso ogni volta che si riavvia il sistema. La sequenza di tutte queste azioni è chiamata sequenza di avvio ed è (più o meno) staticamente definita.

Innanzitutto, l'avviatore (bootloader) carica l'immagine del kernel definita nella configurazione del bootloader. Quindi, l'avviatore indica alla CPU di eseguire il kernel. Quando il kernel viene caricato ed eseguito, esso inizializza tutte le strutture e le attività specifiche del kernel ed avvia il processo di init.

Questo processo assicura poi che tutti i filesystem (definiti in ) siano montati e pronti per l'uso. Poi passa ad eseguire i diversi script situati in, che avvieranno i servizi necessari affinché il sistema sia avviato correttamente.

Infine, quando tutti gli script sono eseguiti, init attiva i terminali (nella maggior parte dei casi sono console virtuali nascoste e richiamabili con +, +, ecc.) associandogli un processo speciale chiamato. Questo processo assicurerà poi gli utenti di poter accedere attraverso questi terminali eseguendo il login (accesso).

Gli script di init
Ora init non esegue solamente gli script in a caso. Anzi, nemmeno esegue tutti gli script in, ma solo gli script che è stato detto di eseguire. Esso decide quali script eseguire ispezionando il contenuto di.

Per prima cosa, init esegue gli script dentro che hanno collegamenti simbolici con i file in. Solitamente, esso avvierà gli script in ordine alfabetico, ma alcuni script contengono informazioni sulle dipendenze, che dicono al sistema che un altro script deve essere eseguito prima di poter partire.

Quanto tutti gli script con un riferimento su sono stati eseguiti, init prosegue con gli script che hanno un collegamento simbolico verso. Ed ancora, sarà usato l'ordine alfabetico per decidere quale script eseguire prima, a meno che uno script abbia informazioni sulle sue dipendenze, in tal caso l'ordine sarà modificato per fornire una valida sequenza di avvio. Quest'ultima è anche la ragione per cui i comandi usati durante l'installazione di Gentoo Linux usano, come in.

Come funziona init
Certamente init non decide tutto da solo. Esso necessita di un file di configurazione che specifica quali azioni devono essere compiute. Questo file di configurazione è.

Tenere a mente la sequenza di avvio che è stata appena descritta - la prima azione di init è montare tutti i filesystem. Ciò viene definito con la seguente linea su :

Questa linea dice ad init che deve eseguire per inizializzare il sistema. Lo script si prende cura dell'inizializzazione, così uno potrebbe pensare che init non fa molto - esso delega l'attività di inizializzazione del sistema ad un altro processo.

Come seconda cosa, init esegue tutti gli script che hanno collegamenti simbolici dentro. Ciò viene definito con la seguente linea:

Nuovamente, lo script openrc esegue le attività necessarie. Notare che l'opzione data ad openrc (boot) è uguale alla sottodirectory di che viene usata.

Adesso init controlla il suo file di configurazione per vedere quale livello di esecuzione (runlevel) va eseguito. Per decidere ciò, legge la seguente riga da :

In questo caso (che userà la maggior parte degli utenti Gentoo), l'ID del runlevel è 3. Usando queste informazioni, init controlla cosa deve essere eseguito per avviare il runlevel 3:

La linea che definisce il livello 3, nuovamente, usa lo script openrc per avviare i servizi (ora con argomento ). Ancora una volta si noti che l'argomento openrc è uguale alla sotto cartella in.

Quando openrc finisce, init decide quali console virtuali devono essere attivate e quali comandi devono essere eseguiti su ciascuna console:

Livelli di esecuzione disponibili
In una sezione precedente, abbiamo visto che init usa uno schema di numerazione per decidere quale livello di esecuzione (runlevel) vada eseguito. Un livello di esecuzione è uno stato nel quale il sistema sta funzionando e contiene una collezione di script (script di runlevel o init script) che devono essere eseguiti quando si entra dentro o si lascia un livello di esecuzione.

In Gentoo, ci sono sette livelli di esecuzione definiti: tre livelli di esecuzione interni, e quattro definiti dall'utente. I livelli di esecuzione interni sono chiamati sysinit, shutdown e reboot e fanno esattamente ciò che i loro nomi implicano: inizializzano il sistema, spengono il sistema e lo riavviano.

I livelli di esecuzione definiti dall'utente sono quelli con una sotto cartella in di accompagnamento: boot, default, nonetwork e single. Il livello di esecuzione boot avvia tutti i servizi necessari al sistema utilizzati dagli altri livelli di esecuzione. I rimanenti tre livelli differiscono in base ai servizi avviati: default è usato per le operazioni quotidiane, nonetwork è usato nel caso in cui la rete deve risultare sconnessa, e single è usato quando il sistema deve essere riparato.

Lavorare con gli script di init
Gli script che openrc processa all'avvio sono chiamati script di init. Ogni script in può essere eseguito con gli argomenti ,  ,  ,  ,  ,  ,  ,  ,  , or.

Per avviare, fermare o riavviare un servizio (e tutti i servizi dipendenti), si devono usare gli argomenti,  , e  :

Per arrestare un servizio, ma non i servizi che dipendono da esso, usare l'opzione  insieme all'argomento  :

Per vedere in quale stato sta un servizio (avviato, arrestato, ...) usare l'argomento :

Se le informazioni sullo stato mostrano che il servizio è in esecuzione, ma in realtà non lo è, allora reimpostare le informazioni sullo stato su "stopped" con l'argomento :

Per chiedere inoltre quali dipendenze possiede il servizio, usare  o. Con  è possibile conoscere quali servizi sono effettivamente necessari per il corretto funzionamento del servizio. mostra invece quali servizi possono essere usati dal servizio, ma che non sono necessari al corretto funzionamento.

Analogamente, è possibile chiedere quali servizi richiedono il servizio interrogato o quali potrebbero usarlo :

rc-update
Il sistema init di Gentoo utilizza un albero delle dipendenze per decidere quale servizio vada avviato per primo. Siccome è un compito noioso e non vorremmo che i nostri utenti dovessero farlo manualmente, abbiamo creato strumenti che facilitano l'amministrazione dei livelli di esecuzione (runlevel) e degli script di init.

Con è possibile aggiungere o rimuovere script di init nei livelli di esecuzione. Lo strumento chiederà poi automaticamente allo script  di ricostruire l'albero delle dipendenze.

Aggiungere e rimuovere servizi
Nelle precedenti istruzioni, gli script di init sono stati già aggiunti al livello di esecuzione "default" (predefinito). Ciò che significa "default" è stato spiegato in precedenza nel documento. Affianco all'argomento runlevel, lo script richiede un secondo argomento che definisce l'azione:   (aggiungi),   (rimuovi), o   (mostra).

Per aggiungere o rimuovere uno script di init, basta dare a l'argomento   o , seguito dallo script di init e dal livello di esecuzione. Per esempio:

Il comando mostrerà tutti gli script di init disponibili ed elencherà a quali livelli di esecuzione saranno eseguiti:

È anche possibile eseguire (senza  ) per vedere giusto gli script di init abilitati ed i loro livelli di esecuzione.

Perché è necessaria una configurazione aggiuntiva
Gli script di init possono essere piuttosto complessi. Pertanto, non è auspicabile che gli utenti modifichino direttamente gli script di init, in quanto tale azione sarebbe più soggetta ad errori. Tuttavia è importante poter configurare un servizio. Ad esempio, gli utenti potrebbero voler attivare più opzioni per il servizio stesso.

Una seconda ragione per tenere questa configurazione fuori dallo script di init è poter aggiornare gli script di init senza il timore che le modifiche della configurazione dell'utente siano annullate.

La cartella conf.d
Gentoo fornisce un modo facile per configurare tale servizio: ogni script di init che può essere configurato possiede un file dentro. Per esempio, lo script di init (chiamato ) ha un file di configurazione chiamato, il quale può contenere le opzioni passate al server Apache 2 quando esso viene avviato:

Questo file di configurazione contiene solo le variabili (proprio come ), rendendo molto facile configurare i servizi. Esso ci permette anche di fornire più informazioni riguardo le variabili (tramite i commenti).

È necessario?
No, scrivere uno script di init solitamente non è necessario in quanto Gentoo fornisce script di init pronti all'uso per tutti i servizi forniti. Comunque, alcuni utenti potrebbero aver installato un servizio senza usare Portage, in tal caso essi dovranno molto probabilmente creare uno script di init.

Non usare lo script di init fornito dal servizio se esso non è esplicitamente scritto per Gentoo: gli script di init di Gentoo non sono compatibili con gli script di init usati da altre distribuzioni! Così è, eccetto se l'altra distribuzione sta usando OpenRC!

Schema
Di seguito, lo schema base di uno script di init:

Tutti gli script di init richiedono che la funzione  sia definita. Tutte le altre sezioni sono opzionali.

Dipendenze
Ci sono due impostazioni similmente capaci di dipendenze che possono essere definite e che influenzano l'avvio o la sequenza degli script di init:  e. Accanto a questi due, ci sono anche due metodi che influenzano l'ordinamento chiamati  (prima) ed   (dopo). Questi ultimi due non hanno dipendenze se considerati da soli: servono a non far fallire lo script di init originale se quello selezionato non è programmato per avviarsi (o fallisce nell'avvio).


 * L'impostazione  informa il sistema di init che tale script usa funzionalità offerte da uno script selezionato, ma non dipende direttamente da esso. Un buon esempio potrebbe essere   o  . Se quei servizi sono disponibili, verranno usati, ma se il sistema non ha un logger o un server DNS, il servizio continuerà a funzionare. Se i servizi esistono, allora saranno avviati prima che lo script li usi.
 * L'impostazione  è una dipendenza rigida. Ciò significa che lo script che dipende da un altro script non sarà avviato finché l'altro script non sarà eseguito con successo. Inoltre, se quell'altro script viene riavviato, allora anche il primo sarà riavviato.
 * Quando si usa, allora lo script selezionato viene eseguito prima, ma solo se quello selezionato è posto nello stesso livello di init. Così uno script di init come xdm che definisce   avvierà prima lo script alsasound, ma solo se alsasound è programmato per l'avvio nel medesimo livello di init. Se alsasound non è stato programmato per l'avvio, questa particolare impostazione non genera effetti e xdm verrà avviato quando il sistema di init lo riterrà più appropriato.
 * Analogamente,  informa il sistema di init che lo script dovrebbe essere eseguito dopo quello selezionato e solo se quello selezionato è posto nello stesso livello di init. Se così non è, allora l'impostazione non genera effetti e lo script verrà avviato quando il sistema di init lo riterrà più appropriato.

Dovrebbe essere chiaro, stando a quanto detto, che  è la sola "vera" impostazione per le dipendenze in quanto determina se lo script sarà avviato o meno. Tutte le altre sono solo puntatori nel sistema di init che chiariscono in quale ordine gli script possono (o dovrebbero) essere eseguiti.

Ora, guardiamo ai tanti script di init disponibili su Gentoo e notiamo che alcuni hanno delle dipendenze da cose che non sono script di init. Queste "cose" si chiamano virtuali.

Una dipendenza dai virtuali è una dipendenza che un servizio fornisce, ma non è fornita solamente da quel servizio. Uno script di init può dipendere da un logger (registratore di eventi) di sistema, ma ci sono molti logger di sistema disponibili (metalogd, syslog-ng, sysklogd, ...). Siccome uno script non può aver bisogno di ciascuno di essi (nessun sistema ragionevole ha tutti questi logger di sistema installati e funzionanti) ci assicuriamo che tutti questi servizi forniscano una dipendenza virtuale.

Per esempio, diamo un'occhiata alle informazioni sulle dipendenze di postfix:

Come si può vedere, il servizio postfix:


 * Richiede la dipendenza (virtuale) della rete (la quale è fornita, per esempio, da ).
 * Usa la dipendenza (virtuale) logger (la quale è fornita, per esempio, da ).
 * Usa la dipendenza (virtuale) dns (la quale è fornita, per esempio, da )
 * Fornisce la dipendenza (virtuale) mta (la quale è comune a tutti i server di posta)

Controllare l'ordinamento
Come descritto nella precedente sezione, è possibile dire al sistema di init quale ordine dovrebbe seguire per avviare (o arrestare) gli script. Questo ordinamento è gestito sia attraverso le impostazioni delle dipendenze use (usa) e need (richiedi), ma anche attraverso le impostazione per l'ordine before (prima) ed after (dopo). Così come abbiamo descritto questi, diamo un'occhiata al servizio portmap come esempio per questi script di init.

È possibile utilizzare l'asterisco "*" per intercettare tutti i servizi sullo stesso livello di esecuzione (runlevel), sebbene ciò non sia consigliabile.

Se il servizio deve scrivere sui dischi locali, dovrebbe richiedere localmount. Se si colloca qualsiasi cosa in come file pid, allora dovrebbe avviarsi dopo bootmisc:

Funzioni standard
Accanto alla funzione, è necessario definire anche la funzione. Questa contiene tutti i comandi necessari per inizializzare il servizio. Si consiglia di utilizzare le funzioni  e   per informare l'utente su ciò che sta accadendo:

Sia  che   dovrebbero essere usati nelle funzioni start e stop. Se il servizio non crea un file pid, usare  se possibile, ed è consigliabile verificare che lo crei per essere sicuri. Altrimenti, non si usino file pid. È anche possibile aggiungere  (silenzioso) alle opzioni di start-stop-daemon, ma ciò non è raccomandato a meno che il servizio sia estremamente verboso. L'utilizzo di  può ostacolare l'individuazione di errori (debug) qualora il servizio fallisca l'avvio.

Un'altra rilevante impostazione utilizzata nell'esempio precedente è il controllo del contenuto della variabile RC_CMD. A differenza del precedente sistema di script di init, il nuovo sistema OpenRC non supporta la funzionalità di riavvio specifica per lo script. Piuttosto, lo script deve controllare il contenuto della variabile RC_CMD per vedere se una funzione (come  o  ) vada invocata o meno come parte del riavvio.

Per avere più esempi sulla funzione , si legga il codice sorgente degli script di init disponibili nella cartella.

Un'altra funzione che può (anche se non deve) essere definita è. Il sistema di init è abbastanza intelligente da compilare questa funzione da solo se viene usato start-stop-daemon.

Se il servizio esegue qualche altro script (per esempio, Bash, Python, o Perl) e questo script in seguito cambia i nomi (ad esempio, da a foo), allora è necessario aggiungere   a start-stop-daemon. Si deve specificare il nome con cui verrà modificato lo script. In questo esempio, un servizio avvia, il quale cambia i nomi in foo:

start-stop-daemon mette a disposizione un'eccellente pagina manuale se maggiori informazioni sono necessarie:

La sintassi degli script di init di Gentoo si basa sulla shell POSIX, così le persone sono libere di usare costrutti sh-compatibili all'interno dei loro script di init. Si evitino altri costrutti, come quelli specifici di bash, negli script di init per essere sicuri che gli script rimangano funzionanti indipendentemente dai cambiamenti che Gentoo potrebbe ricevere al suo sistema di init.

Aggiungere opzioni personalizzate
Se lo script di init necessita di supportare più opzioni di quelle già incontrate, si aggiunga l'opzione alla variabile extra_commands e si crei una funzione con lo stesso nome dell'opzione. Ad esempio, per supportare un'opzione chiamata  (riavvio con ritardo):


 * extra_commands - Command is available with the service in any state
 * extra_started_commands - Command is available when the service is started
 * extra_stopped_commands - Command is available when the service is stopped

Variabili di configurazione del servizio
Per supportare i file di configurazione in, non è necessario implementare specifiche: quando viene eseguito lo script di init, i seguenti file vengono automaticamente acquisiti (ovvero le variabili sono disponibili per l'uso):



Inoltre, se lo script di init fornisce una dipendenza virtuale (come net), verrà generato anche il file (come ) associato a tale dipendenza.

Chi potrebbe beneficiarne
Molti utenti di portatili conoscono tale situazione: a casa hanno bisogno di avviare net.eth0, ma non vogliono avviare net.eth0 mentre sono in viaggio (dato che non ci sarà una rete disponibile). Con Gentoo il comportamento del livello di esecuzione (runlevel) può essere modificato a piacere.

Per esempio, è possibile creare un secondo livello di esecuzione (runlevel) "predefinito" che può essere avviato con altri script di init ad esso assegnati. Al momento dell'avvio, l'utente può quindi selezionare il livello di esecuzione predefinito da utilizzare.

Usare softlevel
Prima di tutto, creare la cartella del livello di esecuzione per il secondo livello "predefinito". Ad esempio, creiamo il livello di esecuzione "offline":

Aggiungere gli script di init necessari al livello di esecuzione appena creato. Ad esempio, per avere una copia esatta del livello di esecuzione corrente predefinito, ma senza net.eth0:

Anche se net.eth0 è stato rimosso dal livello di esecuzione offline, udev potrebbe tentare di avviare qualsiasi dispositivo rilevato ed avviare i servizi appropriati, una funzionalità chiamata hotplugging (collegamento "a caldo"). Per impostazione predefinita, Gentoo non abilita l'hotplugging.

Per abilitare l'hotplugging, ma solo per un insieme di script selezionati, usare la variabile rc_hotplug in :

Modificare la configurazione dell'avviatore (bootloader) e aggiungere una nuova voce per il livello di esecuzione (runlevel) offline. Per quella voce, aggiungere  come parametro di avvio.

Usare bootlevel
Usare il livello di avvio (bootlevel) è del tutto analogo al livello soft (softlevel). L'unica differenza qui è che viene definito un secondo livello di esecuzione "di avvio" ("boot" runlevel) invece di un secondo livello di esecuzione "predefinito" ("default" runlevel).