Salta al contenuto principale

Orvieto Linux User Group | Promozione software libero a Orvieto

systemd-analyze: guida per analizzare il boot di Linux

Quando un computer Linux impiega molto tempo ad avviarsi, la prima domanda è quasi sempre la stessa:

Che cosa sta rallentando il boot?

Individuare la causa, però, non è sempre immediato. Il sistema operativo deve inizializzare il kernel, eventualmente l’initrd e una lunga serie di Unit e servizi, molti dei quali vengono avviati contemporaneamente.

Nel caso di systemd, abbiamo a disposizione uno strumento specifico per analizzare questo processo: systemd-analyze.

Il comando permette di ottenere informazioni sui tempi di avvio, individuare le Unit che hanno richiesto più tempo per essere inizializzate e analizzare la catena critica, cioè la sequenza di dipendenze che ha maggiormente influenzato il raggiungimento di un determinato Target.

Non si tratta quindi semplicemente di trovare “il servizio più lento”: systemd-analyze ci aiuta a capire come le diverse Unit interagiscono durante il boot.


Cosa imparerai

Al termine della guida saprai:

  • utilizzare systemd-analyze per ottenere un riepilogo del boot;
  • individuare le Unit che richiedono più tempo;
  • interpretare systemd-analyze blame;
  • utilizzare critical-chain;
  • generare un grafico temporale del boot;
  • capire perché il servizio più lento non è necessariamente il principale responsabile del ritardo;
  • costruire un semplice metodo di analisi del boot.

Che cos’è systemd-analyze?

systemd-analyze è uno strumento della suite systemd dedicato all’analisi e al debugging del system manager.

Tra le sue funzioni troviamo l’analisi delle prestazioni del boot, la visualizzazione delle dipendenze e la verifica delle Unit.

La forma più semplice del comando è:

systemd-analyze

oppure:

systemd-analyze time

Il risultato può essere simile a:

Startup finished in 2.584s (kernel)
                    + 19.176s (initrd)
                    + 47.847s (userspace)
                    = 1min 9.608s

multi-user.target reached after 47.820s in userspace

Le cifre cambieranno naturalmente da sistema a sistema.

È importante però capire che questi tempi non rappresentano necessariamente il momento in cui ogni servizio ha terminato completamente tutte le proprie attività: il comando misura specifici punti del processo di avvio e, per il tempo userspace, arriva al momento in cui i servizi sono stati avviati, non necessariamente quando ogni processo ha terminato ogni fase di inizializzazione.


Il primo comando: systemd-analyze time

Cominciamo quindi da:

systemd-analyze time

È il punto di partenza della nostra analisi.

Possiamo immaginare il boot come una serie di fasi:

Firmware
   │
   ▼
Kernel
   │
   ▼
Initrd
   │
   ▼
Userspace / systemd
   │
   ▼
Target

systemd-analyze time ci aiuta a capire quanto tempo viene impiegato nelle diverse fasi che systemd può misurare.

Se il tempo è particolarmente elevato nella fase userspace, possiamo procedere con un’analisi più dettagliata.


Quali Unit stanno rallentando l’avvio?

Il comando probabilmente più conosciuto di systemd-analyze è:

systemd-analyze blame

L’output è una lista delle Unit ordinate in base al tempo impiegato per la loro inizializzazione.

Un esempio semplificato:

12.345s NetworkManager-wait-online.service
 7.812s docker.service
 4.215s plymouth-quit-wait.service
 3.102s systemd-journald.service
 2.341s cron.service

A prima vista potremmo essere tentati di concludere:

“NetworkManager-wait-online è il problema.”

Non necessariamente.

Ed è qui che bisogna prestare attenzione.


blame non racconta tutta la storia

Il tempo mostrato da systemd-analyze blame è utile, ma non deve essere interpretato come una classifica assoluta dei “colpevoli” del boot.

Una Unit può risultare lenta perché sta aspettando un’altra Unit.

Inoltre, systemd avvia molte Unit in parallelo.

Immaginiamo:

           ┌── service A ── 10s
Boot ──────┼── service B ──  2s
           └── service C ──  1s

Il fatto che service A richieda 10 secondi non significa automaticamente che il boot complessivo sia stato ritardato di 10 secondi.

Potrebbe infatti essere stato avviato parallelamente ad altre Unit e non trovarsi lungo il percorso che determina il raggiungimento del Target.

Per questo, dopo blame, è fondamentale utilizzare un altro comando.


La catena critica: critical-chain

Eccoci al cuore dell’analisi.

systemd-analyze critical-chain

Questo comando mostra la catena critica del boot, evidenziando la sequenza di Unit che ha maggiormente condizionato il raggiungimento del Target analizzato.

Un output semplificato potrebbe essere:

graphical.target
└─multi-user.target
  └─docker.service
    └─network-online.target
      └─NetworkManager-wait-online.service

La cosa interessante non è soltanto sapere quale servizio è lento.

Vogliamo capire:

Quale sequenza di dipendenze sta impedendo al sistema di arrivare prima al Target?

È una domanda molto diversa.


critical-chain e blame insieme

A questo punto possiamo stabilire una procedura molto semplice.

1. Misuriamo il boot

systemd-analyze time

2. Cerchiamo le Unit più lente

systemd-analyze blame

3. Analizziamo la catena critica

systemd-analyze critical-chain

Il flusso diventa:

          Quanto dura il boot?
                  │
                  ▼
       systemd-analyze time
                  │
                  ▼
       Quali Unit sono lente?
                  │
                  ▼
       systemd-analyze blame
                  │
                  ▼
      Qual è la catena critica?
                  │
                  ▼
   systemd-analyze critical-chain

Questa sequenza è già sufficiente per effettuare una prima analisi su moltissimi sistemi.


Analizzare una Unit specifica

Possiamo anche chiedere a critical-chain di concentrarsi su una determinata Unit:

systemd-analyze critical-chain docker.service

Questo può essere utile quando abbiamo già individuato un servizio interessante e vogliamo capire quali dipendenze si trovano prima di esso.


Creare un grafico del boot

Per un’analisi ancora più intuitiva possiamo utilizzare:

systemd-analyze plot > boot.svg

Viene generato un file SVG contenente una rappresentazione temporale dell’avvio.

Possiamo quindi aprirlo con il browser:

 
xdg-open boot.svg

oppure semplicemente aprire il file con il proprio visualizzatore preferito.

Il grafico permette di visualizzare quando le diverse Unit vengono attivate e quanto tempo richiedono, rendendo più semplice individuare sovrapposizioni, attese e colli di bottiglia.


Un esempio pratico

Immaginiamo che il nostro sistema sembri lento ad avviarsi.

Cominciamo:

systemd-analyze time

Otteniamo:

Startup finished in 8.4s

Non sappiamo ancora cosa stia causando il ritardo.

Passiamo quindi a:

systemd-analyze blame

e troviamo:

7.2s NetworkManager-wait-online.service
3.1s docker.service
2.8s snapd.service

Potremmo essere tentati di disabilitare immediatamente NetworkManager-wait-online.service.

Non facciamolo.

Prima analizziamo:

systemd-analyze critical-chain

Se scopriamo che il servizio di attesa della rete si trova effettivamente nella catena critica, allora abbiamo trovato un elemento che merita un’indagine.

A quel punto possiamo chiederci:

  • il sistema ha davvero bisogno di aspettare la rete durante il boot?
  • quali servizi richiedono network-online.target?
  • il servizio sta aspettando una rete che non sarà disponibile?
  • la configurazione di rete è corretta?

Il comando non ci dice semplicemente “disabilita questo servizio”.

Ci fornisce gli elementi per capire perché sta accadendo qualcosa.

Ed è questa la differenza tra ottimizzazione e semplice eliminazione di servizi.


Visualizzare le dipendenze

systemd-analyze permette anche di generare grafi delle dipendenze utilizzando il comando:

systemd-analyze dot

L’output è in formato Graphviz DOT.

Possiamo quindi generare un SVG, ad esempio:

systemd-analyze dot | dot -Tsvg > systemd.svg

Questo tipo di visualizzazione è particolarmente interessante quando stiamo studiando sistemi complessi con molte dipendenze tra Unit.

Per un’amministrazione quotidiana, tuttavia, critical-chain rimane generalmente più immediato.


Un metodo pratico per ottimizzare il boot

A questo punto possiamo trasformare i comandi che abbiamo visto in un vero metodo di lavoro.

1. Misura

systemd-analyze time

Prima di modificare qualsiasi cosa, dobbiamo sapere da dove partiamo.

2. Individua

systemd-analyze blame

Cerchiamo le Unit che richiedono più tempo.

3. Correla le Unit

systemd-analyze critical-chain

Verifichiamo se quelle Unit si trovano realmente lungo la catena critica.

4. Approfondisci

Utilizziamo:

systemctl status nome.service

e:

journalctl -u nome.service

per capire cosa sta succedendo.

5. Modifica

Solo a questo punto valutiamo se intervenire sulla configurazione.

6. Misura nuovamente

Dopo la modifica:

systemd-analyze time

e confrontiamo il risultato con quello iniziale.


Attenzione alle ottimizzazioni “facili”

Uno degli errori più comuni è cercare di ridurre il numero di servizi avviati senza sapere cosa fanno.

Ad esempio:

systemctl disable servizio.service

può apparentemente ridurre i tempi di boot.

Ma se quel servizio è necessario a una funzione del sistema, abbiamo semplicemente scambiato qualche secondo di boot con un problema successivo.

Lo stesso vale per la modifica indiscriminata delle dipendenze.

Un boot più veloce non è automaticamente un boot migliore.

L’obiettivo dovrebbe essere eliminare attese inutili, correggere configurazioni problematiche e avviare soltanto ciò che serve davvero.


Un comando interessante: systemd-analyze verify

C’è un’altra funzione di systemd-analyze che vale la pena conoscere:

systemd-analyze verify nome.service

È particolarmente utile quando stiamo sviluppando o modificando una Unit.

Permette di verificare la correttezza della configurazione e può segnalare diversi problemi, come direttive sconosciute o dipendenze mancanti.

È quindi un ottimo complemento al lavoro che abbiamo fatto nell’articolo dedicato alla creazione dei file .service.


I comandi da ricordare

ComandoFunzione
systemd-analyzeRiepilogo dei tempi di boot
systemd-analyze timeAnalizza i tempi di avvio
systemd-analyze blameMostra le Unit ordinate per tempo di inizializzazione
systemd-analyze critical-chainMostra la catena critica
systemd-analyze plotGenera un grafico SVG del boot
systemd-analyze dotGenera un grafo delle dipendenze
systemd-analyze verifyVerifica una Unit
systemd-analyze calendarVerifica espressioni temporali per i Timer

Quest’ultimo comando è particolarmente interessante perché collega questo articolo al precedente: systemd-analyze calendar permette infatti di interpretare e verificare le espressioni utilizzate da OnCalendar= nei Timer.


Errori comuni

Guardare soltanto blame

È probabilmente l’errore più frequente.

blame è utile, ma non racconta da solo la relazione tra tempi e dipendenze.

Disabilitare il servizio più lento

Il servizio più lento potrebbe non trovarsi sulla catena critica.

Ottimizzare senza misurare

Prima:

systemd-analyze time

Dopo:

systemd-analyze time

Altrimenti non sappiamo se la modifica abbia realmente prodotto un miglioramento.

Confondere tempo di attivazione e impatto sul boot

Le Unit possono essere avviate in parallelo. Una Unit lenta non implica necessariamente un ritardo equivalente dell’intero sistema.


Conclusioni

systemd-analyze è uno degli strumenti più utili per comprendere cosa accade durante l’avvio di una distribuzione Linux moderna.

Il suo utilizzo diventa particolarmente efficace quando smettiamo di considerare il boot come una semplice sequenza:

servizio 1
   ↓
servizio 2
   ↓
servizio 3

e iniziamo a considerarlo per quello che è realmente: un insieme di Unit con dipendenze che possono essere attivate anche in parallelo.

Per una prima analisi possiamo ricordare soltanto tre comandi:

systemd-analyze time
systemd-analyze blame
systemd-analyze critical-chain

Il primo ci dice quanto dura il boot, il secondo ci aiuta a capire quali Unit richiedono più tempo, mentre il terzo ci mostra quale catena di dipendenze condiziona maggiormente l’avvio.

Ed è proprio questa combinazione che trasforma systemd-analyze da semplice comando diagnostico in uno strumento concreto di troubleshooting e ottimizzazione.

Nel prossimo articolo della serie systemd arriveremo al troubleshooting vero e proprio: vedremo cosa fare quando un servizio non parte, come leggere systemctl status, come interrogare il journal con journalctl e come procedere dall’errore alla soluzione.

LICENZA E CONDIZIONI D’USO

Questo How-to è rilasciato sotto licenza Creative Commons Attribution-NonCommercial 3.0 Italy

CONTATTI DELL’AUTORE

Marco Ciammella marco@orvietolinux.it

Orvieto Linux User Group info@orvietolinux.it