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  :

To stop a service, but not the services that depend on it, use the  option together with the   argument:

To see what status a service has (started, stopped, ...) use the  argument:

If the status information shows that the service is running, but in reality it is not, then reset the status information to "stopped" with the  argument:

To also ask what dependencies the service has, use  or. With  it is possible to see the services that are really necessary for the correct functioning of the service. on the other hand shows the services that can be used by the service, but are not necessary for the correct functioning.

Similarly, it is possible to ask what services require the service or can use it :

Finally, to ask what dependencies the service requires that are missing:

rc-update
Gentoo's init system uses a dependency-tree to decide what service needs to be started first. As this is a tedious task that we wouldn't want our users to have to do manually, we have created tools that ease the administration of the runlevels and init scripts.

With it is possible to add and remove init scripts to a runlevel. The tool will then automatically ask the  script to rebuild the dependency tree.

Adding and removing services
In earlier instructions, init scripts have already been added to the "default" runlevel. What "default" means has been explained earlier in this document. Next to the runlevel, the script requires a second argument that defines the action: ,  , or.

To add or remove an init script, just give the   or   argument, followed by the init script and the runlevel. For instance:

The command will show all the available init scripts and list at which runlevels they will execute:

It is also possible to run (without  ) to just view enabled init scripts and their runlevels.

Why additional configuration is needed
Init scripts can be quite complex. It is therefore not really desirable to have the users edit the init script directly, as it would make it more error-prone. It is however important to be able to configure such a service. For instance, users might want to give more options to the service itself.

A second reason to have this configuration outside the init script is to be able to update the init scripts without the fear that the user's configuration changes will be undone.

conf.d directory
Gentoo provides an easy way to configure such a service: every init script that can be configured has a file in. For instance, the initscript (called ) has a configuration file called, which can contain the options to give to the Apache 2 server when it is started:

Such a configuration file contains only variables (just like does), making it very easy to configure services. It also allows us to provide more information about the variables (as comments).

Is it necessary?
No, writing an init script is usually not necessary as Gentoo provides ready-to-use init scripts for all provided services. However, some users might have installed a service without using Portage, in which case they will most likely have to create an init script.

Do not use the init script provided by the service if it isn't explicitly written for Gentoo: Gentoo's init scripts are not compatible with the init scripts used by other distributions! That is, unless the other distribution is using OpenRC!

Layout
The basic layout of an init script is shown below.

Every init script requires the  function to be defined. All other sections are optional.

Dependencies
There are two dependency-alike settings that can be defined which influence the start-up or sequencing of init scripts:  and. Next to these two, there are also two order-influencing methods called  and. These last two are no dependencies per se - they do not make the original init script fail if the selected one isn't scheduled to start (or fails to start).


 * The  settings informs the init system that this script uses functionality offered by the selected script, but does not directly depend on it. A good example would be   or  . If those services are available, they will be put in good use, but if the system does not have a logger or DNS server the services will still work. If the services exist, then they are started before the script that uses them.
 * The  setting is a hard dependency. It means that the script that is needing another script will not start before the other script is launched successfully. Also, if that other script is restarted, then this one will be restarted as well.
 * When using, then the given script is launched before the selected one if the selected one is part of the init level. So an init script xdm that defines   will start before the alsasound script, but only if alsasound is scheduled to start as well in the same init level. If alsasound is not scheduled to start too, then this particular setting has no effect and xdm will be started when the init system deems it most appropriate.
 * Similarly,  informs the init system that the given script should be launched after the selected one if the selected one is part of the init level. If not, then the setting has no effect and the script will be launched by the init system when it deems it most appropriate.

It should be clear from the above that  is the only "true" dependency setting as it affects if the script will be started or not. All the others are merely pointers towards the init system to clarify in which order scripts can be (or should be) launched.

Now, look at many of Gentoo's available init scripts and notice that some have dependencies on things that are no init scripts. These "things" we call virtuals.

A virtual dependency is a dependency that a service provides, but that is not provided solely by that service. An init script can depend on a system logger, but there are many system loggers available (metalogd, syslog-ng, sysklogd, ...). As the script cannot need every single one of them (no sensible system has all these system loggers installed and running) we made sure that all these services provide a virtual dependency.

For instance, take a look at the postfix dependency information:

As can be seen, the postfix service:


 * Requires the (virtual) net dependency (which is provided by, for instance, ).
 * Uses the (virtual) logger dependency (which is provided by, for instance, ).
 * Uses the (virtual) dns dependency (which is provided by, for instance, ).
 * Provides the (virtual) mta dependency (which is common for all mail servers).

Controlling the order
As described in the previous section, it is possible to tell the init system what order it should use for starting (or stopping) scripts. This ordering is handled both through the dependency settings use and need, but also through the order settings before and after. As we have described these earlier already, let's take a look at the portmap service as an example of such init script.

It is possible to use the "*" glob to catch all services in the same runlevel, although this isn't advisable.

If the service must write to local disks, it should need localmount. If it places anything in such as a pidfile, then it should start after bootmisc:

Standard functions
Next to the  functionality, it is also necessary to define the   function. This one contains all the commands necessary to initialize the service. It is advisable to use the  and   functions to inform the user about what is happening:

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.