In questa seconda parte del tutorial in due parti sulla configurazione dei servizi Linux per l'avvio automatico dopo un riavvio o un arresto anomalo del sistema, discuteremo in dettaglio il sistema init. Puoi fare riferimento alla Parte 1 della serie: Come configurare un servizio Linux per l'avvio automatico dopo un riavvio o un arresto anomalo del sistema: Esempi pratici qui.
Questo tutorial sarà molto teorico. Pertanto, dovresti usarlo come riferimento per acquisire una comprensione più approfondita di come funziona il sistema init in Linux. Nella prima parte di questo tutorial, abbiamo condiviso alcuni frammenti di codice e script di avvio che il sistema init legge all'avvio. Abbiamo anche utilizzato MySQL come esempio per imparare come abilitare e disabilitare un servizio Linux per l'avvio automatico dopo un arresto anomalo o un riavvio. Come hai appreso nella prima parte di questo tutorial in due parti, ci sono tre sistemi init utilizzati in diverse distribuzioni di Linux: System V, Upstart e Systemd. Puoi fare riferimento alla prima parte di questo tutorial per capire la distribuzione e la versione configurate per utilizzare un particolare sistema init.
In questo tutorial, spiegheremo il codice che abbiamo usato nella prima parte del tutorial. Approfondiremo i comandi e i file di configurazione utilizzati dal sistema init. Cominciamo!
Prerequisiti
Nella conclusione della prima parte di questo tutorial in due parti, abbiamo menzionato che dovresti mantenere in esecuzione i tre server di test. Se li avessi eliminati, puoi tornare indietro e ricrearli. Questo ti aiuterà a seguire il tutorial. I tre server di test che dovresti avere sono:
- Ubuntu 9.04 e versioni precedenti, o Debian 6 x64 (lo useremo per dimostrare il sistema init System V)
- Ubuntu 14.04 x64 (lo useremo per dimostrare Upstart). Ecco un tutorial su come configurare facilmente il tuo server Ubuntu.
- CentOS 7 x64 (lo useremo per dimostrare Systemd).
Dovresti avere un utente con privilegi sudo su ciascuno dei server che utilizzerai per eseguire i comandi. Questo tutorial sulla configurazione del file sudoers di Linux può guidarti.
Nota: I comandi nel tutorial interferiranno con i servizi di sistema. Pertanto, non dovresti applicarli su un server di produzione attivo.
Runlevel
Un runlevel è un livello operativo che descrive lo stato corrente di un sistema Linux in relazione ai servizi disponibili. Il concetto ha origine in System V init. Quando il sistema Linux si avvia, inizializza il kernel, entra in un runlevel ed esegue lo script di avvio associato a quel runlevel. È possibile eseguire un solo runlevel all'avvio.
Altri esempi di runlevel includono lo stato di arresto, la modalità di riavvio, una modalità a utente singolo, ecc. Ciascun livello determina quali servizi eseguire in quello stato. Alcuni servizi possono essere eseguiti su più di un livello, mentre altri no.
Ci sono sette runlevel: da 0 a 6. Di seguito è riportata una definizione dei sette runlevel:
- Runlevel 0: Arresto del sistema
- Runlevel 1: Modalità utente singolo e ripristino
- Runlevel 2, 3, 4: Modalità multi-utente e testuale con rete abilitata
- Runlevel 5: Modalità multi-utente, con rete abilitata e grafica
- Runlevel 6: Riavvio del sistema
I runlevel non vengono necessariamente eseguiti in sequenza. I runlevel 2, 3 e 4 variano a seconda della distribuzione Linux in esecuzione. È possibile implementare il runlevel 4 in alcune distribuzioni e non in altre. Quando hai abilitato un servizio per l'avvio automatico, come spiegato nella prima parte, lo hai effettivamente aggiunto a un runlevel. In System V, il sistema operativo si avvia con un particolare runlevel e, durante l'avvio, tenta di avviare tutti i servizi associati a quel runlevel. I runlevel sono target in Systemd, di cui parleremo nella sezione dedicata a Systemd.
Init e PID 1
Il sistema init è il primissimo processo che viene eseguito all'avvio di un sistema Linux e al caricamento del kernel in memoria. Svolge vari compiti, tra cui determinare come verrà caricato un processo utente o un servizio di sistema, in quale ordine e se debba avviarsi automaticamente. In ogni distribuzione Linux, ogni processo è identificato da un ID di processo (PID) e init ha un PID pari a 1. È il genitore di tutti gli altri processi che si avviano successivamente all'avvio del sistema.
Storia di init
Il sistema init presente nelle recenti distribuzioni Linux è un miglioramento rispetto all'originale. Le prime versioni delle distribuzioni Linux utilizzavano System V init, che era analogamente utilizzato nei sistemi Unix. Con l'evoluzione di Linux, è stato implementato il demone init Upstart, creato da Ubuntu. Ora (al momento della stesura di questo tutorial, nel 2021) abbiamo il demone init Systemd, che è stato implementato per la prima volta da Fedora. Poiché i sistemi Linux continuano a evolversi, potrebbe esserci un sistema init più recente. In questo tutorial parleremo di questi tre: System V, Upstart e Systemd.
Le versioni recenti di Linux includono il sistema init Systemd per impostazione predefinita. Tuttavia, hanno mantenuto gli altri sistemi init più vecchi per compatibilità con le versioni precedenti. Esistono diverse implementazioni di System V che è possibile utilizzare in altre varianti di Linux. Ad esempio, FreeBSD, una variante di UNIX, utilizza BSD init. Le versioni precedenti di Debian utilizzano SysVinit. Entrambi derivano da System V.
Il modo in cui ogni versione del demone init gestisce i servizi è diverso. I miglioramenti aggiunti in ogni versione erano orientati a uno strumento di gestione dei servizi robusto in grado di gestire tutto ciò di cui un sistema Linux ha bisogno tra servizi, dispositivi, porte e altre risorse. C'era la necessità di un sistema potente in grado di caricare le risorse in parallelo e di riprendersi elegantemente da un crash di sistema.
Sequenza di System V Init
System V utilizza un file inittab per contenere le istruzioni di inizializzazione. Upstart conserva il file inittab per compatibilità con le versioni precedenti. Ecco il flusso di avvio di System V:
- Il sistema init proviene dal file binario /sbin/init.
- Una volta caricato in memoria, il sistema init legge il suo primo file in /etc/inittab.
- Una delle voci in questo file determina il runlevel con cui la macchina dovrebbe avviarsi. Ad esempio, se il valore del runlevel è specificato come 5, Linux si avvierà in modalità grafica multi-utente con rete abilitata (comune nelle distribuzioni progettate per l'uso desktop). Il runlevel specificato qui è noto come runlevel predefinito perché è quello che verrà sempre utilizzato.
- Successivamente, il sistema init esamina ulteriormente il file /etc/inittab e legge quali script di init deve eseguire per quel runlevel.
Trovando quali script eseguire per un determinato runlevel, il sistema init troverà quali servizi deve avviare. Questi script di init sono il luogo in cui di solito si configura il comportamento di avvio per i singoli servizi, allo stesso modo in cui configuriamo il servizio MySQL nella prima parte di questo tutorial.
Struttura degli script di System V Init
In questa sezione esamineremo in dettaglio gli script di init. I file di configurazione di System V o script di init sono ciò che controlla i servizi. Gli script di init inizializzano un servizio, da cui il nome script di init.
Ogni servizio ha il proprio script di init. Ad esempio, lo script di init di MySQL controlla il server MySQL. I fornitori di applicazioni forniscono gli script di init per la loro specifica applicazione, mentre dei servizi nativi di Linux vengono forniti con l'installazione del sistema operativo. Quando crei un'applicazione personalizzata, puoi anche creare i tuoi script di init personalizzati per essa.
Per avviare un servizio come il server MySQL, il suo programma binario viene prima caricato in memoria. A seconda della sua configurazione, il programma può continuare a essere eseguito in background per continuare ad accettare le connessioni dei client. Lo script di init del servizio gestisce il compito di avviare, arrestare o ricaricare l'applicazione binaria. Gli script di init in System V sono script di shell. Un altro nome per essi è script rc (run command).
Struttura delle directory di System V
La directory principale per gli script di init è la directory /etc. La directory /etc/init.d è la directory effettiva per gli script di shell di init. Gli script sono collegati tramite link simbolico alle directory rc.
Ci sono diverse directory rc all'interno della directory /etc, ognuna con un numero nel nome. I numeri rappresentano diversi runlevel. Se elenchi il contenuto della directory, vedrai nomi come /etc/rc0.d, /etc/rc1.d, /etc/rc2.d, ecc.
Se visualizzi il contenuto di ciascuna delle directory rc, vedrai file che iniziano con K o S nel loro nome file, seguiti da due cifre. Questi file contengono collegamenti simbolici che rimandano agli script di shell init effettivi del programma reale. Le lettere K e S sono abbreviazioni: K significa Kill o Stop, mentre S sta per Start. Le due cifre nei nomi dei file rappresentano l'ordine di esecuzione. Se vedi un file chiamato K05script_name, verrà eseguito prima di un file chiamato K09script_name.
Avvio
Proseguendo con la sequenza di avvio, vediamo come vengono chiamati gli script di init.
Gli script S e K non vengono chiamati direttamente dal sistema init. Piuttosto, vengono chiamati da un altro script: lo /etc/init.d/rc script. Il file /etc/inittab indica al demone init in quale runlevel il sistema dovrebbe avviarsi per impostazione predefinita. A seconda del runlevel specificato, una riga nel file /etc/inittab chiama lo script /etc/init.d/rc, passando il runlevel predefinito come parametro. Utilizzando questo parametro, lo script chiamerà i file sotto la corrispondente directory /etc/rcN.d, dove N indica il runlevel. Ad esempio, se il server si avvia con il runlevel 5, verranno chiamati i file corrispondenti sotto la directory /etc/rc5.d.
All'interno della directory rc, tutti gli script K vengono eseguiti numericamente con un argomento di stop, mentre tutti gli script S vengono eseguiti in modo simile con un argomento di start. I corrispondenti script di shell init effettivi per il programma a cui puntano i collegamenti simbolici sotto /etc/rcN.d verranno chiamati con i parametri stop e start rispettivamente.
In parole povere, ciò che accade ogni volta che un sistema Linux entra o passa a un determinato runlevel è che verranno eseguiti determinati script per arrestare alcuni servizi, mentre altri verranno eseguiti per avviare altri servizi. Questo processo garantisce che qualsiasi processo che non dovrebbe essere eseguito in un determinato stato di Linux venga arrestato e che qualsiasi processo che dovrebbe essere eseguito venga avviato automaticamente.
Avvio automatico di System V
Quando si abilita un servizio per l'avvio automatico all'avvio, si modifica direttamente il comportamento di init. Ad esempio, se si configura un servizio per l'avvio automatico al runlevel 2, il processo init crea i collegamenti simbolici appropriati nella directory /etc/rc2.d. Per aiutarti a capire, lo spiegheremo con un esempio.
Esempio di System V
Per fornirti un esempio pratico, utilizzeremo la configurazione del servizio MySQL della parte 1. Pertanto, accedi al VPS Debian 6 con il tuo utente sudo/root tramite ssh (o putty se sei su Windows) e procedi con i seguenti passaggi.
Passaggio 1: Aprire ed esaminare il file inittab
Innanzitutto, inserisci il seguente comando per visualizzare il contenuto del file inittab sul terminale:
|
1 |
cat /etc/inittab | grep initdefault |
Il contenuto del file dovrebbe essere simile a questo:
|
1 |
id:2:initdefault: |
Il numero 2 indica il runlevel con cui si avvia il sistema. In questo caso, il runlevel 2 è quello predefinito, quindi questo sistema Debian si avvierà nel runlevel 2 come multi-utente, in modalità testo. È possibile eseguire il seguente comando per confermare:
|
1 |
cat /etc/inittab | grep Runlevel |
Mostrerà un output simile a:
|
1 2 3 4 |
# Runlevel 0 is halt. # Runlevel 1 is single-user. # Runlevels 2-5 are multi-user. # Runlevel 6 is reboot. |
Passaggio 2: Esaminare le directory rc
Successivamente, per elencare le directory rc, esegui il seguente comando:
|
1 |
ls -ld /etc/rc*.d |
Ecco uno screenshot dell'output:

Come abbiamo visto in precedenza nel file inittab, il sistema è configurato per avviarsi nel runlevel 2, quindi gli script sotto /etc/rc2.d verranno eseguiti all'avvio del sistema. È possibile elencare il contenuto di questa directory utilizzando il comando:
|
1 |
ls -l /etc/rc2.d |
Come puoi vedere dall'output, i file sono solo collegamenti simbolici che puntano ai file di script effettivi sotto /etc/init.d. Ecco un frammento dell'output:

Non ci sono script K in questa directory, solo script S (start). Gli script avvieranno i servizi qui collegati, come rsync. Puoi anche notare il servizio mysql elencato, di cui parleremo nel prossimo sottoargomento.
Passaggio 3: Esaminare lo script di init
Quando viene installato un servizio conforme a System V, questo crea uno script di shell nella directory /etc/init.d. È possibile verificare la disponibilità dello script di shell di MySQL inserendo il seguente comando:
|
1 |
ls -l /etc/init.d/my* |
Mostra il seguente output:

Il file è piuttosto grande. È possibile inserire il seguente comando per visualizzarne il contenuto:
|
1 |
cat /etc/init.d/mysql | less |
Passo 4: Utilizzo di chkconfig o sysv-rc-conf
Chkconfig è un comando che puoi utilizzare nelle distribuzioni basate su RHEL come CentOS per abilitare o disabilitare i servizi compatibili con System V. Puoi anche usarlo per elencare i servizi installati e i rispettivi runlevel. Ecco il comando per farlo (funziona su CentOS):
|
1 |
chkconfig --list | grep service_name |
Nelle distribuzioni Debian, tale utilità non esiste nativamente. Il comando update-rc.d nei sistemi Debian installa e rimuove solo i servizi dai runlevel. È disponibile uno strumento personalizzato che puoi utilizzare per portare la funzionalità chkconfig sui sistemi Debian. Inserisci il seguente comando per installarlo:
|
1 |
sudo apt-get install sysv-rc-conf –y |
Una volta installato, puoi eseguire il seguente comando per visualizzare i comportamenti dei runlevel per i vari servizi:
|
1 |
sudo sysv-rc-conf |
L'output di questo comando è formattato in una tabella che mostra il nome del servizio a sinistra e il runlevel in cui il servizio viene eseguito:

La X indica il runlevel in cui il servizio verrà eseguito. Questo strumento consente di disabilitare o abilitare un servizio per un runlevel utilizzando i tasti freccia e la barra spaziatrice. Per uscire dallo strumento, premi Q.
Passo 5: Testare il comportamento di avvio di MySQL durante il boot del sistema
Dallo screenshot sopra, puoi vedere che il servizio mysql è abilitato sui runlevel 2,3,4,5. Puoi disabilitare MySQL utilizzando il seguente comando:
|
1 |
sudo update-rc.d mysql disable |
L'output si presenta così. Nota che il servizio si è arrestato per tutti i runlevel:

Esegui il comando seguente per vedere il contenuto della directory:
|
1 |
ls -l /etc/rc2.d |
Guarda la riga relativa a mysql nell'output qui sotto:
|
1 |
lrwxrwxrwx 1 root root 15 Dic 11 05:28 K01mysql -> ../init.d/mysql |
L'output mostra che il symlink è cambiato in K, che significa Kill (arresto). Di conseguenza, MySQL non si avvierà automaticamente per impostazione predefinita al runlevel 2. Ogni volta che si abilita o disabilita un servizio in System V, questo è ciò che accade. Finché esiste uno script S (start) nella directory del runlevel predefinito per un servizio, il demone init avvierà quel servizio durante l'avvio del sistema.
Per abilitare nuovamente il servizio, inserisci il seguente comando:
|
1 |
sudo update-rc.d mysql enable |
Passo 6: Testare il comportamento di avvio di MySQL dopo un crash del sistema
In questa sezione, vedremo come System V gestisce i crash dei servizi. Puoi utilizzare queste informazioni per configurare il comportamento dei tuoi servizi personalizzati dopo un crash.
Nella prima parte di questo tutorial, avevamo apportato una modifica al file /etc/inittab per consentire a MySQL di avviarsi automaticamente dopo un crash. Abbiamo aggiunto la riga seguente per abilitare questo comportamento:
|
1 |
ms:2345:respawn:/bin/sh /usr/bin/mysqld_safe |
Possiamo verificare questo comportamento effettuando alcuni test. Innanzitutto, riavvia il tuo VPS inserendo il seguente comando:
|
1 |
sudo reboot |
Dopo il riavvio, verifica con quali ID di processo sono in esecuzione mysql_safe e mysqld, inserisci il seguente comando per ottenere gli ID di processo:
|
1 |
ps -ef | grep mysql |
L'output che abbiamo ottenuto è stato:
|
1 2 |
hackins 1836 1 0 07:30 ? 00:00:00 /bin/sh /usr/bin/mysqld_safe mysql 186338 907 0 07:30 ? 00:00:00 /usr/sbin/mysqld --basedir=/usr --datadir=/var/lib/mysql --user=mysql --pid-file=/var/run/mysqld/mysqld.pid --socket=/var/run/mysqld/mysqld.sock --port=3306 |
Prendi nota degli ID dei processi. Nel nostro caso, erano 1836 e 186338. Ora, simula un crash terminando il processo con l'opzione -9 inserendo il seguente comando. Ricorda di sostituirli con i tuoi ID di processo:
|
1 2 |
sudo kill -9 1836 sudo kill -9 186338 |
Dopo qualche minuto, verifica lo stato di MySQL eseguendo il seguente comando:
|
1 |
sudo service mysql status |
L'output indica che MySQL è in esecuzione, il che significa che è stato riavviato dopo il crash simulato. Se esegui nuovamente il comando ps -ef | grep mysql, scoprirai che entrambi i processi mysqld_safe e mysqld sono in esecuzione, sebbene con nuovi ID.
Puoi provare a terminare i processi più volte e questi si riavvieranno dopo pochi minuti. Questo comportamento è reso possibile dalla riga che abbiamo aggiunto al file /etc/inittab. Questo è il modo in cui si configurano i servizi per il riavvio automatico dopo un crash in System V. Per vedere nuovamente la sintassi, dai un'occhiata alla Parte 1 di questo tutorial.
Alcuni servizi personalizzati potrebbero presentare bug e non riuscire a riavviarsi dopo molteplici tentativi. Il demone init proverà a riavviare un servizio, ma se fallisce più di dieci volte entro due minuti, il sistema Linux disabilita il servizio per un massimo di 5 minuti. Questo aiuta a mantenere il sistema stabile e garantisce che le risorse di sistema non vengano sprecate in servizi che vanno in crash. È una buona idea controllare i log di sistema per identificare i problemi con le applicazioni personalizzate che devono essere risolti.
Introduzione a Upstart
Il sistema init System V è stato fondamentale per le distribuzioni Linux per molto tempo. Tuttavia, come accade con la tecnologia, continua ad evolversi. L'ecosistema Linux è cresciuto enormemente grazie al supporto della comunità open-source. System V carica i job e i servizi in modo serializzato, il che comporta complessità e richiede tempo. Inoltre, l'introduzione di moderni supporti di memorizzazione rimovibili, per i quali System V non era stato progettato, ha spinto la necessità di un sistema init diverso.
Gli sviluppatori di Ubuntu hanno iniziato a lavorare su un altro sistema di inizializzazione. Questo sistema init è stato progettato per gestire un caricamento più rapido del sistema operativo, garantire una pulizia corretta dei servizi andati in crash, mantenere prevedibili le dipendenze tra i servizi di sistema e tenere conto dei supporti di memorizzazione rimovibili. È nato così il demone Upstart.
L'init Upstart presenta diversi vantaggi rispetto all'init System V nei seguenti modi:
- Upstart non carica i servizi in modo seriale come System V, riducendo così il tempo di avvio del sistema.
- È progettato per gestire meglio i servizi andati in crash con una pulizia corretta e il riavvio del servizio.
- Upstart utilizza un sistema di eventi flessibile per personalizzare la gestione dei servizi in vari stati.
- L'init evita i complessi script di shell per il caricamento e la gestione dei servizi come in System V. Upstart utilizza file di configurazione semplici, facili da capire e modificare.
- Upstart è stato creato pensando alla retrocompatibilità. Lo script /etc/init.d/rc viene ancora eseguito per gestire i servizi nativi di System V.
- Evita di mantenere collegamenti simbolici ridondanti, tutti puntanti allo stesso script.
Eventi Upstart
Upstart è basato su eventi, consentendo di associare più eventi allo stesso servizio. Questa architettura basata su eventi garantisce una gestione flessibile dei servizi. Ogni evento può chiamare uno script di shell specifico per l'evento.
Gli eventi Upstart includono:
- Starting
- Started
- Stopping
- Stopped
Tra un evento e l'altro, un servizio può trovarsi in vari stati, inclusi ma non limitati a:
- Waiting
- Pre-start
- Starting
- Post-start
- Running
- Pre-stop
- Stopping
- Post-stop
L'init Upstart può essere configurato per intraprendere azioni per ciascuno di questi stati, da cui il suo design flessibile.
Sequenza di avvio dell'init Upstart
L'init Upstart esegue lo script /etc/init.d/rc all'avvio, proprio come System V. Questo script esegue normalmente qualsiasi script init di System V per garantire la retrocompatibilità.
I file di configurazione di Upstart si trovano nella directory /etc/init, quindi vi guarda per impostazione predefinita ed esegue i comandi di shell presenti nei file di configurazione in questa directory.
File di configurazione di Upstart
L'init Upstart utilizza file di configurazione del servizio per controllare i servizi, a differenza degli script bash utilizzati in System V. Lo standard di denominazione per questi file di configurazione del servizio è service_name.conf.
I file contengono testo normale suddiviso in varie sezioni chiamate stanze. Ogni stanza descrive uno stato diverso di un servizio e il suo comportamento. Diverse stanze controllano diversi eventi di un servizio. Ad esempio, waiting, pre-start, start, pre-stop, stopping, ecc.
Una stanza contiene comandi shell, rendendo possibile avviare diverse azioni per ogni evento per ciascun servizio. Inoltre, ogni file di configurazione del servizio specifica le seguenti due cose:
- Su quali runlevel il servizio deve essere avviato e interrotto.
- Se il servizio deve essere riavviato (respawn) in caso di arresto anomalo.
Struttura delle directory di Upstart
I file di configurazione del servizio Upstart si trovano nella directory /etc/init. Non confonderla con /etc/init.d.
Esempio di Upstart
In questo esempio, vedremo come Upstart gestisce un servizio durante l'avvio del sistema e in caso di arresto anomalo. Entreremo più nei dettagli spiegando gli esempi pratici mostrati nella prima parte di questo tutorial.
Passo 1: Accedere al server Ubuntu 14.0.4
Innanzitutto, per testare Upstart, useremo il secondo VPS, quello con Ubuntu 14.0.4. Questo perché questa distribuzione Linux implementa Upstart nativamente. Usa ssh o putty se sei su Windows. Devi accedere con un utente con privilegi root o sudo. Ho un utente chiamato hackins, quindi ecco come accedere:
|
1 |
ssh hackins@my_server_ip |
Sostituisci con il tuo utente root/sudo e l'indirizzo IP pubblico del server. Quindi, premi invio e fornisci una password o una passphrase.
Passo 2: Esaminare le directory init e rc
I file di configurazione di Upstart sono memorizzati nella directory /etc/init. È la directory che utilizzerai quando crei nuovi file di configurazione del servizio.
Per elencare i nomi dei file di configurazione nella directory /etc/init, esegui il seguente comando:
|
1 |
sudo ls -l /etc/init/ | less |
Come vedrai dall'output del comando precedente, molti servizi sono in esecuzione sotto Upstart. Premi Q per uscire da less.
Se esegui il seguente comando per elencare i file di configurazione del servizio per System V nella directory rc, ne vedrai solo alcuni:
|
1 |
sudo ls -l /etc/rc3.d/* | less |
Passo 3: Esaminare un file Upstart
Nella prima parte di questo tutorial, avevamo utilizzato un file mysql.conf per conoscere la configurazione del server. Per ampliare le nostre conoscenze, utilizziamo una configurazione diversa. Il file di configurazione di cron è un buon candidato. Inserisci il seguente comando per aprire il file:
|
1 |
sudo nano /etc/init/cron.conf |
Dovresti ottenere un output simile allo screenshot qui sotto:

Lo script è piuttosto semplice. Prendi nota dei seguenti campi importanti: start on, stop on, fork, e respawn. Definiamo cosa fanno queste direttive:
- start on indica a Ubuntu di avviare il daemon cron quando il sistema entra nei runlevel 2, 3, 4 o 5. Non verrà eseguito negli altri runlevel non specificati qui, ovvero 0, 1 o 6.
- stop on indica a Ubuntu di arrestare un daemon in esecuzione. Tuttavia, in questo caso, c'è un punto esclamativo (!) che è un segno di negazione. Lo script non deve essere interrotto nei runlevel successivi al punto esclamativo: 2,3,4,5.
- fork indica a Upstart di scollegare il processo dalla console e mantenerlo in esecuzione in background.
- respawn indica al sistema di avviare cron automaticamente in caso di arresto anomalo per qualsiasi motivo.
Premi Ctrl X per uscire dall'editor senza digitare nulla.
Altri file di configurazione di Upstart seguono la stessa struttura, con stanze per start, stop e respawn. Alcuni file di configurazione possono avere blocchi di script aggiuntivi per pre-start, pre-stop, post-start e altro. Questi blocchi di codice dicono al sistema cosa eseguire quando un processo si trova in uno degli stati definiti.
Passo 4: Testare il comportamento di avvio del servizio MySQL dopo l'avvio del sistema
Per impostazione predefinita, MySQL è impostato per l'avvio automatico dopo l'avvio del sistema. Proveremo a disabilitarlo e a vederne il comportamento. In Upstart, un servizio può essere disabilitato creando un file chiamato service_name.override sotto la /etc/init/ directory. Il contenuto del file è solo una parola: manual.
Vediamo come possiamo usare questo comando per disabilitare il servizio MySQL. Inserisci il seguente comando per aprire il file con l'editor nano:
|
1 |
sudo nano /etc/init/mysql.override |
Nel file aperto aggiungi la seguente riga:
|
1 |
Manual |
Salva le modifiche premendo Ctrl + O, quindi invio. Esci dall'editor premendo Ctrl + X. Esegui il seguente comando per riavviare il server:
|
1 |
sudo reboot |
Attendi qualche minuto, quindi accedi nuovamente. Una volta effettuato l'accesso, verifica lo stato del servizio MySQL inserendo il seguente comando:
|
1 |
sudo initctl status mysql |
L'output indicherà che il servizio non è in esecuzione:
|
1 |
mysql stop/waiting |
Questo indica che MySQL non si è avviato automaticamente dopo l'avvio del sistema. Successivamente, apri il file di configurazione di MySQL e controlla se la direttiva start è cambiata:
|
1 |
sudo cat /etc/init/mysql.conf | grep start\ on |
L'output indicherà che nulla è stato modificato:
|
1 |
start on runlevel [2345] |
Questo significa che se il tuo servizio non si avvia automaticamente e controlli solo il file di configurazione del servizio (service_name.conf), potresti non trovare l'errore. Dovresti anche verificare l'esistenza del file service_name.override nella directory.
Inserisci il seguente comando per eliminare il file override e riabilitare il servizio MySQL. Quindi, riavvia il server:
|
1 2 |
sudo rm -f /etc/init/mysql.override sudo reboot |
Una volta avviato il server, verifica nuovamente lo stato del servizio MySQL:
|
1 |
sudo initctl status mysql |
Dovrebbe mostrare che il servizio MySQL si è avviato automaticamente.
Passo 5: Testare il comportamento di avvio del servizio MySQL dopo un arresto anomalo del sistema
Per impostazione predefinita, il servizio MySQL si riavvia automaticamente in caso di arresto anomalo. Per interrompere questo comportamento, modificheremo il file mysql.conf . Inserisci il seguente comando per aprire il file con l'editor nano:
|
1 |
sudo nano /etc/init/mysql.conf |
Trova le righe della direttiva respawn e commentale come mostrato di seguito con #:
|
1 2 |
# respawn # respawn limit 2 5 |
Esegui i seguenti comandi per riavviare il servizio:
|
1 2 |
sudo initctl stop mysql sudo initctl start mysql |
Abbiamo usato i comandi sopra indicati per arrestare e avviare il servizio perché l'uso di initctl restart o initctl reload non funzionerebbe in questo caso. Quando esegui il comando per avviare il servizio MySQL, l'output mostrerà un PID per MySQL come:
|
1 |
mysql start/running, process 1439 |
Il nostro PID era 1439. Successivamente, annota ciò che hai ottenuto quando hai eseguito il comando, lo useremo nel passaggio successivo. Per simulare un arresto anomalo, termina il processo MySQL utilizzando il seguente comando, ricordandoti di sostituire il tuo PID come spiegato sopra:
|
1 |
sudo kill -9 1439 |
Per verificare se MySQL si è riavviato dopo l'arresto anomalo, attendi qualche minuto, quindi inserisci il seguente comando:
|
1 |
sudo initctl status mysql |
L'output indicherà che MySQL è arrestato:
|
1 |
mysql stop/waiting |
Prova a controllare lo stato ancora qualche volta per vedere se ci sono cambiamenti. Noterai che MySQL rimane arrestato. Questo perché il file di configurazione del servizio non ha le direttive respawn (quelle che abbiamo commentato). Consulta la parte 1 di questo tutorial per ulteriori spiegazioni sulla direttiva respawn.
Perché ti abbiamo mostrato come disabilitare il riavvio automatico dei servizi dopo l'avvio o il crash del sistema? Questo serve principalmente a scopo di risoluzione dei problemi. Se ad esempio il tuo servizio si avvia e continua a bloccarsi, potresti volerlo disabilitare per poter risolvere il problema e mantenere stabile il sistema. Puoi anche impedire il riavvio automatico di alcune vecchie configurazioni di servizi se ti capita di aggiornare a una nuova distribuzione Linux che include nativamente systemd, trattato nella sezione successiva.
Introduzione a Systemd
Systemd è il sistema di init più recente, presente nelle distribuzioni Linux più recenti. Include molti componenti che costituiscono un moderno sistema Linux.
Systemd gestisce non solo i servizi ma anche l'intero sistema Linux. In questa sezione ci concentreremo su come systemd controlla il comportamento dei servizi dopo l'avvio o il crash del sistema.
Systemd è retrocompatibile con gli script e i comandi di init di System V. Di conseguenza, se hai servizi configurati con System V, questi verranno eseguiti anche sotto Systemd. La maggior parte dei comandi amministrativi di Upstart e System V è stata modificata per funzionare con Systemd. Systemd si rinomina in init al momento dell'avvio. Esiste un file /sbin/init che funge da collegamento simbolico a /bin/systemd.
File di configurazione di Systemd: Unit Files
La configurazione di Systemd consiste in file di unità (unit files). Ogni file di unità rappresenta una risorsa di sistema. Mentre gli altri due sistemi di init (ovvero System V e Upstart) erano responsabili della gestione dei servizi di un sistema Linux, Systemd non solo gestisce i daemon dei servizi, ma anche altri tipi di risorse di sistema come percorsi del sistema operativo dei dispositivi, socket, punti di montaggio, ecc. I file di unità memorizzano informazioni sulla risorsa.
Ogni file di unità rappresenta una particolare risorsa di sistema con uno stile di denominazione del tipo service_name.unit_type. Ciò significa che troverai file come home.mount, dbus.service, sshd.socket, ecc. I file di unità sono semplici file di testo con una sintassi dichiarativa facile da capire e modificare.
Struttura delle directory
La posizione principale dei file di unità nativi è la directory /lib/systemd/system/. I file di unità creati da te o quelli personalizzati dagli amministratori di sistema, e altri file di unità nativi modificati, sono memorizzati nella directory /etc/systemd/system directory.
Se un file di unità con lo stesso nome esiste sia nella directory /lib/systemd/system/ che in /etc/systemd/system, systemd utilizzerà quello presente nella directory /etc.
Quando si abilita un servizio per l'avvio all'avvio del sistema o in qualsiasi altro target/runlevel, viene creato un collegamento simbolico per quel file di unità di servizio nelle directory appropriate in /etc/systemd/system. I file di unità nella directory /etc/systemd/system sono solo collegamenti simbolici ai file con nome simile nella directory /lib/systemd/system.
Sequenza di avvio di Systemd: Target Units
Le unità target sono tipi unici di file di unità solitamente con suffisso .target. Le unità target differiscono da altri tipi di file di unità perché non rappresentano una risorsa particolare. Rappresentano invece lo stato dell'intero sistema in un dato momento.
Per ottenere questo risultato, le unità target raggruppano e avviano più file di unità che fanno parte di un particolare stato. Sebbene i target di Systemd e i runlevel di System V possano essere vagamente paragonati, non sono la stessa cosa. Un file di unità target ha un nome invece di un numero. Ad esempio, troverai qualcosa come multi-user.target invece di runlevel 3 o reboot.target invece di runlevel 6. Un sistema Linux può avviarsi con multi-user.target. In questo caso, sta fondamentalmente portando il server al runlevel 2, 3 o 4, che avvia il sistema in modalità testo multi-utente con rete abilitata.
La differenza sta nel modo in cui porta il server a quel livello. System V avvia i servizi in modo sequenziale. D'altra parte, all'avvio del sistema, systemd verifica se esistono altri servizi o risorse e determina il loro ordine di caricamento.
Un'altra differenza tra le unità target di systemd e i runlevel di System V è che una distribuzione Linux che utilizza System V esisterà in un solo runlevel. Se si modifica il runlevel, passerà semplicemente a quel nuovo runlevel ed esisterà in esso. D'altra parte, i file delle unità target possono essere inclusivi. Inoltre, l'attivazione di un'unità target garantisce che altre unità target vengano caricate come parte di essa. Ad esempio, se si avvia un sistema Linux con un'interfaccia grafica, avrà il graphical.target attivato. Questo a sua volta garantisce automaticamente che multi-user.target sia caricato e attivato a sua volta.
Ecco una tabella che confronta i runlevel e i target.
| Runlevel (System V) | Unità Target (systemd) |
| runlevel 0 | poweroff.target |
| runlevel 1 | rescue.target |
| runlevel 2,3,4 | multi-user.target |
| runlevel 5 | graphical.target |
| runlevel 6 | reboot.target |
default.target di Systemd
In systemd, default.target è l'equivalente del runlevel predefinito in System V. Abbiamo visto che il runlevel predefinito in System V era definito nel file inittab. In systemd, abbiamo il file default.target. Il file target predefinito è memorizzato nella directory /etc/systemd/system. Crea un collegamento simbolico (symlink) a uno dei file delle unità target in /lib/systemd/system. Modificare il target predefinito significa semplicemente ricreare un collegamento simbolico e modificare il runlevel del sistema.
In System V, l'inittab specificava in quale directory Linux avrebbe trovato gli script di init. Questa poteva essere una qualsiasi delle directory rc come spiegato in precedenza. D'altra parte, il target predefinito di systemd determina le unità di risorsa da caricare all'avvio. Tutte le unità definite vengono caricate. Tuttavia, non tutte vengono caricate in parallelo e non tutte vengono caricate in sequenza. Il caricamento dell'unità di risorsa dipende dalle altre risorse che essa wants o requires.
Dipendenze di Systemd: Wants e Requires
In questa sezione vedremo come Systemd gestisce le dipendenze. Abbiamo visto che con Upstart è possibile il caricamento parallelo dei servizi quando si utilizzano i file di configurazione. Abbiamo anche discusso di come System V utilizzi i runlevel per determinare quale servizio avviare automaticamente o attendere fino a quando un altro servizio o risorsa non si avvia. Allo stesso modo, i servizi di Systemd possono essere configurati per essere caricati in uno o più target, o attendere fino a quando un altro servizio o risorsa non si avvia.
In Systemd, un file di unità che richiede un'altra unità non si avvierà finché l'unità richiesta non viene caricata e diventa attiva. Se l'unità richiesta non riesce a caricarsi mentre la prima unità è attiva, la prima unità si arresterà.
Questo comportamento garantisce la stabilità del sistema. Un servizio che richiede una risorsa specifica (ad esempio, una porta) per essere disponibile e attivo può quindi essere messo in attesa fino a quando la risorsa non è disponibile (ovvero la porta è aperta).
Al contrario, un'unità che desidera un'altra unità non impone tali restrizioni. Non si arresterà se l'unità desiderata si arresta mentre l'unità chiamante è ancora attiva. Ad esempio, alcuni servizi non essenziali nella modalità graphical-target.
Esempio di Systemd
Vediamo come configurare il comportamento di un servizio sotto systemd.
Passo 1: Accedi alla tua istanza VPS
Utilizzeremo MySQL come servizio reale e CentOS 7 como server. Per seguire i passaggi praticamente e comprendere i concetti, accedi al tuo VPS CentOS 7 o creane uno su CloudSigma. Un VPS con distribuzione CentOS 7, Debian 7 o 8, o Ubuntu 15 o più recente è appropriato per questa sezione poiché sono tutti dotati di systemd. Accedi utilizzando il comando ssh o, se sei su Windows, usa PuTTY:
|
1 |
ssh hackins@your_server_ip |
Passo 2: Esamina il file default.target e le dipendenze
La sequenza di avvio di Systemd segue una lunga catena di dipendenze che discuteremo in dettaglio in questa sezione.
- default.target
Il file default.target controlla i servizi che si avviano durante un normale avvio. Puoi elencare il file dell'unità target predefinito utilizzando il seguente comando:
|
1 |
sudo ls -l /etc/systemd/system/default.target |
L'output mostra qualcosa di simile allo screenshot qui sotto:
![]()
Lo screenshot mostra che il target predefinito rimanda tramite symlink al file multi-user.target nella directory /lib/systemd/system/ directory. Questo significa che, per impostazione predefinita, il sistema si avvierà sotto multi-user.target, equivalente a runlevel 3.
- multi-user.target.wants
Per vedere tutti i servizi richiesti dal file multi-user.target, inserisci il seguente comando:
|
1 |
sudo ls -l /etc/systemd/system/multi-user.target.wants/*.service |
L'output contiene molte righe, ecco un estratto:
|
1 2 3 4 5 6 7 8 |
lrwxrwxrwx. 1 root root 38 Dec 25 10:32 /etc/systemd/system/multi-user.target.wants/mysqld.service -> /usr/lib/systemd/system/mysqld.service lrwxrwxrwx. 1 root root 36 Dec 16 19:10 /etc/systemd/system/multi-user.target.wants/ntpd.service -> /usr/lib/systemd/system/ntpd.service lrwxrwxrwx. 1 root root 39 Dec 16 19:08 /etc/systemd/system/multi-user.target.wants/postfix.service -> /usr/lib/systemd/system/postfix.service lrwxrwxrwx. 1 root root 46 Dec 16 19:08 /etc/systemd/system/multi-user.target.wants/rhel-configure.service -> /usr/lib/systemd/system/rhel-configure.service lrwxrwxrwx. 1 root root 39 Dec 16 19:08 /etc/systemd/system/multi-user.target.wants/rsyslog.service -> /usr/lib/systemd/system/rsyslog.service lrwxrwxrwx. 1 root root 36 Dec 16 19:08 /etc/systemd/system/multi-user.target.wants/sshd.service -> /usr/lib/systemd/system/sshd.service lrwxrwxrwx. 1 root root 37 Dec 16 19:08 /etc/systemd/system/multi-user.target.wants/tuned.service -> /usr/lib/systemd/system/tuned.service lrwxrwxrwx. 1 root root 40 Dec 16 19:14 /etc/systemd/system/multi-user.target.wants/yum-cron.service -> /usr/lib/systemd/system/yum-cron.service |
Come mostra l'output, si tratta di collegamenti simbolici che puntano ai file di unità effettivi nella /lib/systemd/system/ directory. Abbiamo evidenziato mysqld.service per farti notare che fa anche parte di multi-user.target. Se desideri confermare se un determinato servizio è configurato per l'avvio, puoi modificare il comando per quel file. Ad esempio, possiamo filtrare gli output per trovare il demone mysql o cron utilizzando i seguenti comandi:
|
1 |
sudo systemctl show --property "Wants" multi-user.target | fmt -10 | grep mysql |
L'output mostrerà:
|
1 |
mysqld.service |
Per filtrare il risultato per il demone cron, inserisci il seguente comando:
|
1 |
sudo systemctl show --property "Wants" multi-user.target | fmt -10 | grep cron |
L'output mostrerà:
|
1 |
crond.service |
Oltre a multi-user.target, esistono altri tipi diversi di target, ad esempio system-update.target o basic.target.
Inserisci il seguente comando per vedere da quali target dipende il target multi-user:
|
1 |
sudo systemctl show --property "Requires" multi-user.target | fmt -10 |
L'output mostra:
|
1 |
Requires=basic.target |
Questo significa che basic-target deve essere caricato per primo affinché il sistema si avvii in modalità multi-user.target.
- basic-target
Inserisci il seguente comando per vedere quali altri target sono richiesti da basic.target:
|
1 |
sudo systemctl show --property "Requires" basic.target | fmt -10 |
L'output mostrerà:
|
1 |
Requires=sysinit.target |
- sysinit.target
È possibile eseguire il comando seguente per vedere se ci sono target richiesti per sysinit.target. La sintassi del comando è la stessa. È possibile continuare a modificarlo per vedere quali unità target sono richieste da un'altra unità target man mano che si procede. Ecco il comando:
|
1 |
sudo systemctl show --property "Requires" sysinit.target | fmt -10 |
L'output mostrerà che non ci sono unità richieste per sysinit.target. Possiamo verificare se ci sono altri servizi e target richiesti da sysinit.target utilizzando il comando seguente:
|
1 |
sudo systemctl show --property "Wants" sysinit.target | fmt -10 |
L'output mostra un lungo elenco di servizi e target richiesti da sysinit.target. Di seguito è possibile vedere una parte dell'output:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
Wants=systemd-tmpfiles-setup-dev.service systemd-binfmt.service systemd-journald.service rhel-loadmodules.service dev-hugepages.mount systemd-modules-load.service rhel-autorelabel-mark.service plymouth-read-write.service sys-fs-fuse-connections.mount systemd-machine-id-commit.service systemd-random-seed.service systemd-udevd.service systemd-sysctl.service plymouth-start.service rhel-autorelabel.service proc-sys-fs-binfmt_misc.automount local-fs.target rhel-import-state.service sys-kernel-config.mount dev-mqueue.mount kmod-static-nodes.service systemd-update-utmp.service |
Durante l'inizializzazione del sistema con system4, il sistema non rimane in un solo target. Al contrario, carica i servizi in modo dipendente mentre passa da un target all'altro.
Passo 3: Esaminare un file Unit
Vediamo come si presenta un file unit. Nella prima parte di questo tutorial abbiamo usato il file unit del servizio MySQL, e lo useremo di nuovo. Tuttavia, possiamo anche esaminare un altro file unit di servizio: il file unit sshd. Inserire il comando seguente per aprire il file di configurazione di sshd:
|
1 |
sudo nano /etc/systemd/system/multi-user.target.wants/sshd.service |
Di seguito è riportato uno screenshot che mostra le righe del file:

Come si può notare, i blocchi di codice delineati nel file lo rendono facile da capire e da modificare ogni volta che è necessario. Di seguito sono riportate alcune direttive importanti da comprendere:
- After – la clausola After indica al sistema di caricare il servizio solo dopo il caricamento dei target e dei servizi specificati. In questo caso, il servizio SSHD verrà caricato dopo il caricamento del target di rete e del servizio keygen.
- Wants – la clausola Wants mostra quali target richiedono questo servizio. In questo caso il ssh-keygen.service richiede il sshd.service. Tuttavia, se sshd fallisce o si arresta in modo anomalo, non spegnerà il ssh-keygen.service.
Premere Ctrl + X per chiudere l'editor.
Passo 4: Testare il comportamento di avvio del servizio MySQL all'avvio del sistema
In questa sezione, mostreremo come modificare e testare il comportamento del servizio MySQL all'avvio del sistema. Nella sezione precedente, abbiamo visto che il mysqld.service è richiesto da multi-user.target. Pertanto, si avvierà automaticamente all'avvio.
È possibile disabilitare il servizio eseguendo il comando seguente:
|
1 |
sudo systemctl disable mysqld.service |
L'esecuzione del comando mostra che il symlink di mysql viene rimosso dalla directory /etc/systemd/system/multi-user.target.wants/. Per testare questo comportamento, eseguire il comando seguente per verificare se MySQL è ancora richiesto da multi-user.target:
|
1 |
sudo systemctl show --proprietà "Wants" multi-user.target | fmt -10 | grep mysql |
Il comando non restituisce nulla. Se provi a riavviare il server e a controllare lo stato di MySQL, non sarà in esecuzione, il che significa che non si è avviato automaticamente all'avvio.
Ora riabilita il servizio usando il comando:
|
1 |
sudo systemctl enable mysqld.service |
L'output mostrerà un symlink. Se riavvii il server, MySQL dovrebbe avviarsi automaticamente. L'abilitazione di un servizio Systemd crea un collegamento simbolico nella directory wants del target predefinito. La disabilitazione di un servizio Systemd rimuove il collegamento simbolico dalla wants directory.
Passo 5: Testare il comportamento di avvio del servizio MySQL dopo un arresto anomalo del servizio
Per impostazione predefinita, il servizio MySQL si avvierà automaticamente in caso di arresto anomalo. Possiamo disabilitare questo comportamento nel file di configurazione di Systemd per MySQL. Per prima cosa, diamo un'occhiata al file. Inserisci il seguente comando per aprire il file:
|
1 |
sudo nano /etc/systemd/system/multi-user.target.wants/mysqld.service |
La schermata qui sotto mostra l'output:

Il valore della direttiva Restart è impostato su on-failure. Ciò significa che il servizio MySQL si riavvierà dopo codici di uscita non puliti, timeout o segnali non puliti. Di seguito è riportata una tabella che mostra alcuni dei parametri di riavvio tratti da la pagina man.
| Impostazioni di riavvio/Cause di uscita | no | always | on-success | on-failure | on-abnormal | on-abort | on-watchdog |
| codice di uscita pulito o segnale | X | X | |||||
| Codice di uscita non pulito | X | X | |||||
| Segnale non pulito | X | X | X | X | |||
| Timeout | X | X | X | ||||
| Watchdog | X | X | X | X |
Le due direttive importanti in un file unit di Systemd sono Restart e RestartSec. Controllano il comportamento del servizio in caso di arresto anomalo. Restart specifica quando il servizio deve riavviarsi, e RestartSec specifica quanto tempo deve attendere prima di riavviarsi dopo un arresto anomalo. Per disabilitare il comportamento di riavvio, commenta la direttiva Restart aggiungendo un # all'inizio della riga come mostrato:
|
1 |
# Restart=always |
Ora, ricarica il demone di sistema, quindi ricarica il servizio mysqld utilizzando i seguenti comandi:
|
1 2 |
sudo systemctl daemon-reload sudo systemctl restart mysqld.service |
Successivamente, esegui il seguente comando per trovare il PID principale del servizio MySQL:
|
1 |
sudo systemctl status mysqld.service |

Il PID principale per il nostro test era 23809. Prendi nota del tuo per usarlo nel comando successivo. Usando il comando kill -9, simula un arresto anomalo terminando il processo. Inoltre, ricorda di sostituirlo con il numero di processo ottenuto nel tuo test:
|
1 |
sudo kill -9 23809 |
Se esegui il comando che controlla lo stato di MySQL, scoprirai che non è attivo e non è riuscito a riavviarsi:
|
1 |
sudo systemctl status mysqld.service |

Rimarrà nello stato di errore finché la direttiva Restart è commentata nel file di configurazione mysqld.service. Questo emula un arresto anomalo in cui un servizio si interrompe e non si riavvia.
Per riabilitare il servizio, puoi modificare il file di configurazione mysqld.service, decommentare la direttiva Restart, quindi salvare e chiudere. Come hai fatto in precedenza, ricarica il demone e riavvia il servizio. Questo riporta il servizio alla sua configurazione iniziale, e ora può avviarsi automaticamente dopo un arresto anomalo. Infine, questo è tutto per configurare un servizio per l'avvio automatico dopo un arresto anomalo. Se desideri configurare i servizi per l'avvio automatico dopo un arresto anomalo, devi semplicemente aggiungere la direttiva Restart, (e se lo desideri, puoi anche aggiungere la direttiva RestartSec), sotto la sezione [Service] del file unit del servizio.
Conclusione
In questo tutorial, abbiamo discusso di come Linux gestisce i servizi durante l'avvio o dopo un arresto anomalo. Per comprendere il processo di inizializzazione del sistema Linux, abbiamo discusso i tre sistemi init utilizzati da Linux: System V, Upstart e Systemd. Abbiamo discusso la loro evoluzione e come funziona ciascun processo init in relazione all'avvio automatico di un servizio dopo un riavvio del sistema o un arresto anomalo.
Poiché sia i daemon di init che le distribuzioni Linux si sono evoluti nel tempo, ricordati di verificare la versione della distribuzione Linux che stai eseguendo, in modo da sapere quale daemon di init il tuo sistema supporta nativamente.
Le applicazioni native di Linux e la maggior parte delle applicazioni di terze parti si avviano già automaticamente dopo l'avvio o il crash del sistema, quindi non dovrai fare nulla. Le conoscenze di questo tutorial sono fondamentali quando configuri il comportamento di avvio e riavvio dei tuoi servizi personalizzati, o quando risolvi i problemi di servizi che si arrestano continuamente in modo anomalo.
Buon computing!
Commenti
Ancora nessun commento. Scrivi il primo.