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 :

Infine, per chiedere quali dipendenze il servizio interrogato richiede, ma queste risultano mancanti:

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:

Both  and   should be used in start and stop functions. If the service does not create a pidfile, then use  if possible, though it is recommended to test this to be sure. Otherwise, don't use pidfiles. It is also possible to add  to the start-stop-daemon options, but this is not recommended unless the service is extremely verbose. Using  may hinder debugging if the service fails to start.

Another notable setting used in the above example is to check the contents of the RC_CMD variable. Unlike the previous init script system, the newer OpenRC system does not support script-specific restart functionality. Instead, the script needs to check the contents of the RC_CMD variable to see if a function (be it  or  ) is called as part of a restart or not.

For more examples of the  function, please read the source code of the available init scripts in the  directory.

Another function that can (but does not have to) be defined is. The init system is intelligent enough to fill in this function by itself if start-stop-daemon is used.

If the service runs some other script (for example, Bash, Python, or Perl), and this script later changes names (for example, to foo), then it is necessary to add   to start-stop-daemon. This must specify the name that the script will be changed to. In this example, a service starts, which changes names to foo:

start-stop-daemon has an excellent man page available if more information is needed:

Gentoo's init script syntax is based on the POSIX Shell so people are free to use sh-compatible constructs inside their init scripts. Keep other constructs, like bash-specific ones, out of the init scripts to ensure that the scripts remain functional regardless of the change Gentoo might do on its init system.

Adding custom options
If the initscript needs to support more options than the ones we have already encountered, then add the option to the extra_commands variable, and create a function with the same name as the option. For instance, to support an option called :

Service configuration variables
In order to support configuration files in, no specifics need to be implemented: when the init script is executed, the following files are automatically sourced (i.e. the variables are available to use):



Also, if the init script provides a virtual dependency (such as net), the file associated with that dependency (such as ) will be sourced too.

Who might benefit
Many laptop users know the situation: at home they need to start net.eth0, but they don't want to start net.eth0 while on the road (as there is no network available). With Gentoo the runlevel behaviour can be altered at will.

For instance, a second "default" runlevel can be created which can be booted that has other init scripts assigned to it. At boottime, the user can then select what default runlevel to use.

Using softlevel
First of all, create the runlevel directory for the second "default" runlevel. As an example we create the offline runlevel:

Add the necessary init scripts to the newly created runlevel. For instance, to have an exact copy of the current default runlevel but without net.eth0:

Even though net.eth0 has been removed from the offline runlevel, udev might want to attempt to start any devices it detects and launch the appropriate services, a functionality that is called hotplugging. By default, Gentoo does not enable hotplugging.

To enable hotplugging, but only for a selected set of scripts, use the rc_hotplug variable in :

Edit the bootloader configuration and add a new entry for the offline runlevel. In that entry, add  as a boot parameter.

Using bootlevel
Using bootlevel is completely analogous to softlevel. The only difference here is that a second "boot" runlevel is defined instead of a second "default" runlevel.