## Sistema di init

I servizi (o *demoni*) possono essere controllati da script di shell, come in `SysVinit`, o da un programma e dai suoi file di configurazione, come in `systemd`. 

Il sistema di init e' il primo programma lanciato dal kernel, quindi il suo **PID** (*Process Identification Number*) sara' sempre 1.

### SysVinit

Fornisce un set predefinito di stati di sistema, chiamati *runlevel*, numerati da 0 a 6.

- **runlevel 0**: spegnimento del sistema
- **runlevel 1**, s o single: modalita' utente singolo, senza rete (manutenzione)  
- **runlevel 2**,**3** o **4**: modalita' multiutente con accesso tramite console  
- **runlevel 5**: modalita' multiutente grafica
- **runlevel 6**: riavvio del sistema

Il programma responsabile della gestione dei runlevel e dei demoni associati e' `/sbin/init`. Identifica il runlevel richiesto, definito nel file `/etc/inittab` o da un parametro del kernel, e carica gli script associati, definiti nella directory `/etc/init.d/`. Ogni runlevel ha una cartella `/etc/rcX.d/` con all'interno gli script che vengono eseguiti al runlevel corrispondente. Questi sono dei collegamenti simbolici agli script presenti in `/etc/init.d/`. La prima lettera del nome del collegamento indica se il servizio deve essere avviato (S, start), terminato (K, kill), ecc. per il runlevel corrispondente.    

La sintassi del file `/etc/inittab` usa il seguente formato:

```bash
id:runlevels:action:process
```
Le possibili azioni:

- **boot**: il processo sara' eseguito durante l'inizializzazione del sistema
- **bootwait**: il processo sara' eseguito durante l'inizializzazione del sistema e init attendera' fino a termine prima di continuare 
- **sysinit**il processo sara' eseguito dopo l'inizializzazione del sistema
- **wait**: il rpocesso verra' eseguito per il runlevel indicato e init attendera' fino al termine per continuare 
- **respawn**: il processo verra' riavviato, se viene terminato
- **ctrlaltdel**: il processo sara' eseguito quando init riceve il segnale di SIGINT, attivato alla pressione di ctrl+alt+canc 

Il runlevel predefinito e' definito nello stesso file: `id:x:initdefault`. `x` indica il numero del runlevel. 

Ogni volta che il file `/etc/inittab` viene modificato, per ricaricare la configurazione, dare il comando: `telinit q`. IL comando puo' essere usato anche per spostarsi tra i runlevel, senza dover riavviare. Ad esempio, `telinit 1` cambia il sistema al runlevel 1.

Il comando `runlevel` mostra il runlevel corrente. 

### systend

I servizi vengono definiti come *units*. Ogni unita' e' composta da un nome, un tipo e un file di configurazione. 

Esistono sette tipi di unita':

- **service**
- **socker**: puo' essere un socket di rete o un socket del filesystem (utilizzato per la comunicazione tra processi che si trovano sulla stessa macchina). Tutte le unita' socket hanno un unita' di servizio corrispondente, caricata quando il socket riceve una richiesta
- **device**: associata a un dispositivo hardware identificato dal kernel
- **mount**: una definizione del punto di mount nel filesystem, simile alle voci in `/etc/fstab`
- **automount**: e' sempre una definizione del punto di mount nel filesystem, ma viene montata automaticamente. Ogni unita' di automount ha un'unita' di mount corrispondente che viene avviata quando si accede al punto di montaggio
- **target**: un raggruppamento di altre unita'. Emula il concetto di runlevel
- **snapshot**

Il comando principale per il controllo delle unita' systemd e' `systemctl`:

```bash
systemctl start unit.service

systemctl stop unit.service

systemctl restart unit.service

systemctl status unit.service

systemctl is-active unit.service # mostra se unit.service e' in esecuzione

systemctl enable unit.service

systemctl disable unit.service

systemctl is-enable unit.service # verifica se unit.service si avvia col sistema

systemctl isolate multi-user.target # utile per passare tra un target e un altro

systemctl get-default # visualizza il target di avvio predefinito

systemctl set-default multi-user.target # imposta un nuovo target predefinito
```

I file di configurazione di ogni unita' si trovano in `/etc/systemd/system/`L'eseguibile`/sbin/init` e' un collegamento simbolico a `/lib/systemd/systemd`.

```bash
systemctl list-unit-files # elenca tutte le unita' disponibili e mostra se sono abilitate all'avvio

systemctl list-unit-files --type=service

systemctl list-unit-files --type=target

systemctl list-units # mostra le unita' attive
```
## Spegnimento e riavvio

Il comando principale per arrestare o riavviare il sistema e' `shutdown`, che avvisa anche tutti gli utenti che hanno effettuato un accesso con un messaggio di avviso nelle loro sessioni di shell.

```bash
shutdown [option] time [message]
```
E' richiesto solo il parametro *time*, che accetta i seguenti formati:

- **hh:mm**
- **+m**: quanti minuti attendere prima dell'esecuzione
- **now** 

Il comando systemctl puo' anche essere utilizzato per spegnere o riavviare la macchina:

```bash
systemctl reboot

systemctl poweroff

systemctl suspend # manda il sistema nella modalita' di sospensione a basso consumo, mantenendo i dati in memoria

systemctl hibernate # copia tutti i dati su disco e iberna il sistema
```