Risoluzione dei problemi di avvio di Systemd: problemi comuni e soluzioni

Incontrare problemi di avvio di Linux può essere scoraggiante. Questa guida completa fornisce soluzioni pratiche per i fallimenti di avvio relativi a systemd, una causa comune nei moderni sistemi Linux. Impara a diagnosticare efficacemente i problemi accedendo e interpretando i log di avvio con `journalctl` e `dmesg`. Copriamo la risoluzione dei problemi di scenari comuni come servizi falliti, corruzione del filesystem e conflitti di dipendenza delle unità, offrendo istruzioni passo passo ed esempi di comandi. Scopri tecniche avanzate come la modalità di ripristino e `rd.break` per un debug più approfondito, assicurandoti di poter risolvere sistematicamente i problemi di avvio e ripristinare la funzionalità del sistema.

36 visualizzazioni

Risoluzione dei problemi di avvio di Systemd: problemi comuni e soluzioni

I problemi di avvio di Linux possono essere tra le problematiche più frustranti per qualsiasi amministratore di sistema o utente esperto. Quando il tuo sistema non si avvia correttamente, il primo passo è spesso quello di identificare cosa sta impedendo al processo di avvio di completarsi con successo. Poiché systemd è il gestore principale del sistema e dei servizi per le moderne distribuzioni Linux, svolge un ruolo fondamentale nell'orchestrare la sequenza di avvio, dal passaggio iniziale del kernel all'avvio di tutti i servizi necessari.

Questo articolo serve come guida completa per comprendere e risolvere i comuni errori di avvio correlati a systemd. Approfondiremo metodi pratici per analizzare i log di avvio, identificare i servizi problematici e risolvere conflitti complessi nell'ordinamento delle unità. Al termine di questa guida, avrai un approccio sistematico per diagnosticare e risolvere i problemi di avvio, garantendo che i tuoi sistemi Linux tornino a uno stato sano con fiducia.

Comprensione del processo di avvio di Systemd

Systemd gestisce il processo di avvio di Linux attraverso un sistema di "unità". Queste unità descrivono varie risorse e servizi di sistema, come servizi (.service), punti di mount (.mount), dispositivi (.device) e target (.target). I target sono unità speciali che raggruppano altre unità e rappresentano specifici punti di sincronizzazione o stati durante il processo di avvio, come multi-user.target (il tradizionale runlevel 3) o graphical.target (runlevel 5).

Il processo di avvio coinvolge tipicamente:
1. Inizializzazione del Kernel: Il kernel carica e inizializza l'hardware.
2. Fase Initramfs: Viene caricato un filesystem iniziale in RAM, che include driver e strumenti essenziali per montare il filesystem root.
3. Avvio di Systemd: Systemd subentra come PID 1, avviando il default.target (che spesso è un symlink a multi-user.target o graphical.target).
4. Attivazione delle Unità: Systemd legge i file delle unità, risolve le dipendenze e avvia i servizi e i mount in modo altamente parallelo.

I problemi di avvio possono verificarsi in una qualsiasi di queste fasi, ma questa guida si concentra principalmente sui problemi che si manifestano una volta che systemd è stato avviato.

Triagggio iniziale: accesso ai log di avvio

Quando il tuo sistema non si avvia correttamente, il primo e più critico passo è accedere ai log di avvio. Questi log forniscono indizi su cosa è andato storto. Se il tuo sistema non si avvia in un ambiente grafico o nemmeno in una TTY standard, dovrai utilizzare metodi alternativi.

1. Utilizzo di journalctl (dalla modalità di soccorso/emergenza o da un supporto live)

journalctl è l'utility per interrogare il journal di systemd. Se il tuo sistema può avviarsi in modalità di soccorso (rescue mode) o modalità di emergenza (emergency mode), o se stai utilizzando una USB/CD live per accedere al tuo disco, journalctl è il tuo strumento principale.

Per visualizzare i log dell'avvio precedente:

journalctl -b -1

Per visualizzare tutti i messaggi dall'avvio del sistema:

journalctl -b

Per visualizzare i log relativi alle unità fallite:

journalctl -b -p err..emerg # Mostra messaggi di errore, critici, di avviso, di emergenza
journalctl -b --since "-5min" # Mostra i log degli ultimi 5 minuti dell'avvio corrente

Se stai utilizzando un ambiente live, dovrai prima eseguire chroot nella partizione root del tuo sistema per accedere ai suoi file di journal.

2. Utilizzo di dmesg

dmesg visualizza il buffer ad anello del kernel, che contiene messaggi dal kernel durante l'avvio. Questo è particolarmente utile per problemi che si verificano molto presto nel processo di avvio, prima che systemd abbia preso il pieno controllo.

dmesg

3. Esame dello stato delle unità

Una volta in una shell utilizzabile (modalità di soccorso, modalità di emergenza o ambiente live con chroot), puoi controllare lo stato di tutte le unità di systemd.

systemctl --failed

Questo comando elenca tutte le unità che non sono riuscite ad avviarsi. Per informazioni dettagliate su una specifica unità fallita, usa:

systemctl status <unit_name>.service

E per visualizzare le sue specifiche voci di journal:

journalctl -u <unit_name>.service -b

Problemi comuni di avvio di Systemd e Soluzioni

1. Servizi falliti e guasti delle unità

Problema: Un servizio critico non riesce ad avviarsi, impedendo al sistema di raggiungere il target desiderato (ad es. multi-user.target). Questo si manifesta spesso con il sistema che entra in modalità di emergenza.

Sintomi: systemctl --failed mostra una o più unità con stato "fallito". journalctl -u <unit_name>.service rivela messaggi di errore che spiegano perché il servizio non è potuto partire.

Cause Comuni:
* Configurazione errata: Errore di battitura in un file di configurazione, percorsi errati, dipendenze mancanti.
* File/Dipendenze mancanti: Un servizio tenta di accedere a un file o una directory che non esiste o è inaccessibile.
* Esaurimento delle risorse: Il servizio tenta di allocare troppa memoria o altre risorse.
* Problemi di permessi: Il servizio non dispone dei permessi necessari per leggere/scrivere file o eseguire comandi.

Soluzioni:
1. Identifica l'unità fallita: Usa systemctl --failed.
2. Ispeziona i log: Esegui journalctl -u <unit_name>.service -b per messaggi di errore dettagliati.
3. Correggi la configurazione: Modifica il file di configurazione del servizio (ad es. /etc/systemd/system/<unit_name>.service o file in /etc/). Presta attenzione alle direttive ExecStart, WorkingDirectory, User, Group, Environment.
4. Verifica le dipendenze: Assicurati che tutte le direttive Wants=, Requires=, After=, Before= siano specificate correttamente e che i servizi richiesti siano abilitati.
5. Riavvia e Riabilita: Dopo aver apportato modifiche, esegui systemctl daemon-reload, quindi prova systemctl start <unit_name>.service e systemctl enable <unit_name>.service.

Esempio: Un servizio web personalizzato mywebapp.service fallisce perché il suo database non è disponibile.

# Controlla lo stato
systemctl status mywebapp.service

# Controlla i log per indizi
journalctl -u mywebapp.service -b

# Modifica il file dell'unità (ad es. in /etc/systemd/system/mywebapp.service)
# Aggiungi/modifica la direttiva After= per assicurarti che il database si avvii prima
# es. After=postgresql.service mysql.service

# Ricarica systemd e riprova
systemctl daemon-reload
systemctl start mywebapp.service
systemctl enable mywebapp.service # Assicurati che si avvii al prossimo riavvio

2. Problemi del filesystem

Problema: Filesystem corrotti o voci errate in /etc/fstab possono impedire al sistema di montare partizioni critiche, portando alla modalità di emergenza.

Sintomi: Messaggi di errore relativi a fallimenti di fsck, errori di mount, o il sistema che entra in modalità di emergenza con un messaggio simile a "Dai la password di root per la manutenzione (o digita Control-D per continuare)".

Cause Comuni:
* Filesystem sporco: Spegnimento improprio, perdita di alimentazione.
* /etc/fstab errato: Errore di battitura nell'UUID/percorso del dispositivo, tipo di filesystem errato, noauto mancante per mount non critici.
* Guasto hardware: Corruzione del disco.

Soluzioni:
1. Accedi alla modalità di emergenza: Se richiesto, inserisci la password di root.
2. Controlla /etc/fstab: Rivedi attentamente /etc/fstab per eventuali errori. Commenta temporaneamente le righe sospette con #.
3. Esegui fsck: Controlla e ripara manualmente i filesystem. Ad esempio, se /dev/sda1 è la partizione root:
bash # Smonta se possibile (per partizioni non root), o riavvia con parametro fsck umount /dev/sda1 fsck -y /dev/sda1
Suggerimento: Se non riesci a smontare la partizione root, potrebbe essere necessario avviare da una USB live ed eseguire fsck da lì.
4. Riavvia: Dopo aver apportato modifiche o eseguito fsck, prova a riavviare.

3. Conflitti di dipendenza e ordinamento delle unità

Problema: I servizi si avviano nell'ordine sbagliato o le unità hanno dipendenze conflittuali, portando a deadlock o fallimenti.

Sintomi: Timeout dei servizi, servizi che falliscono perché le loro dipendenze non sono pronte, systemd-analyze plot che mostra lunghe catene o cicli.

Cause Comuni:
* Direttive Wants=, Requires=, After=, Before= mal configurate nei file delle unità.
* Unità che si aspettano risorse non ancora disponibili.

Soluzioni:
1. Analizza la sequenza di avvio: Usa systemd-analyze per visualizzare il processo di avvio.
* systemd-analyze blame: Mostra i servizi ordinati per tempo di avvio, evidenziando le unità lente.
* systemd-analyze critical-chain: Mostra il percorso critico delle unità che influiscono direttamente sul tempo totale di avvio.
* systemd-analyze plot > boot.svg: Genera un'immagine SVG dell'intero grafo delle dipendenze di avvio, preziosa per problemi complessi.

  1. Ispeziona le dipendenze delle unità: Usa systemctl list-dependencies <unit_name> per vedere cosa richiede un'unità e cosa dipende da essa.

  2. Regola le direttive del file di unità:

    • After=, Before=: Controllano l'ordinamento delle unità. Se A.service ha After=B.service, A si avvierà dopo B (se B viene avviato). Usa After= per la maggior parte delle esigenze di ordinamento.
    • Wants=: Esprime una dipendenza debole. Se A.service Wants=B.service, B verrà avviato quando A si avvia, ma A continuerà anche se B fallisce.
    • Requires=: Esprime una dipendenza forte. Se A.service Requires=B.service, B verrà avviato quando A si avvia, e se B fallisce o viene fermato, anche A verrà fermato.
    • Conflicts=: Assicura che un'unità specifica venga fermata se l'unità corrente viene avviata, e viceversa.
    • PartOf=: Collega il ciclo di vita di un'unità a un'altra (ad es. se uno slice viene fermato, tutte le unità PartOf esso vengono anch'esse fermate).

    Suggerimento: Preferisci sempre After= e Wants= per la maggior parte delle dipendenze per evitare di creare accoppiamenti stretti che potrebbero portare a deadlock o cascate di fallimenti.

4. Kernel Panics / Problemi Initramfs

Problema: Il sistema non si avvia molto presto, spesso prima che systemd prenda completamente il controllo, mostrando messaggi come "Kernel panic - not syncing" o relativi a dracut o initramfs.

Sintomi: Fallimento precoce dell'avvio, spesso con un muro di testo che mostra stack trace o messaggi sulla mancanza del dispositivo root, /dev/root non trovato, ecc.

Cause Comuni:
* Moduli del kernel mancanti: Initramfs non contiene i driver necessari per il filesystem root (ad es. LVM, RAID, controller disco specifici).
* Kernel/Initramfs corrotti: File danneggiati.
* Parametri del kernel errati: Il parametro root= in GRUB punta al dispositivo sbagliato.

Soluzioni:
1. Ricostruisci Initramfs: Questa è una soluzione comune. Avvia da un ambiente live o un altro kernel, esegui chroot nel tuo sistema e ricostruisci l'initramfs.
```bash
# Esempio per Dracut (Fedora/RHEL/CentOS)
dracut -f -v /boot/initramfs-$(uname -r).img $(uname -r)

# Esempio per mkinitcpio (Arch Linux)

mkinitcpio -P

# Esempio per update-initramfs (Debian/Ubuntu)
update-initramfs -u -k all
```
  1. Verifica la configurazione di GRUB: Controlla /boot/grub/grub.cfg (o /etc/default/grub se lo rigeneri) per il parametro root= corretto e il percorso initrd.
  2. Parametri del kernel: Se sospetti che un modulo specifico sia mancante o causi problemi, puoi provare ad aggiungere parametri del kernel in GRUB (ad es. rd.break per entrare in una shell dell'initramfs per il debug).

5. Problemi di GRUB/Bootloader

Problema: Il sistema non raggiunge nemmeno il punto in cui il kernel viene caricato, o si blocca nel menu GRUB.

Sintomi: "Nessun dispositivo di avvio trovato", prompt GRUB rescue, o GRUB che non riesce a caricare il kernel.

Cause Comuni:
* Bootloader corrotto.
* Configurazione GRUB errata che punta a kernel/initramfs inesistenti.
* Impostazioni BIOS/UEFI che impediscono un ordine di avvio corretto.

Soluzioni:
1. Reinstalla GRUB: Avvia da una USB live, esegui chroot nel tuo sistema e reinstalla GRUB sulla partizione MBR/EFI.
```bash
# Esempio
mount /dev/sdaX /mnt # Monta la partizione root

mount /dev/sdaY /mnt/boot/efi # Se partizione EFI separata

for i in /dev /dev/pts /proc /sys /run; do mount --bind $i /mnt$i; done
chroot /mnt

grub-install /dev/sda # Installa sul disco principale

grub-mkconfig -o /boot/grub/grub.cfg # Rigenera la configurazione GRUB

exit
umount -R /mnt
reboot
```
  1. Controlla le impostazioni BIOS/UEFI: Assicurati che l'unità di avvio corretta sia prioritaria.

Tecniche avanzate di risoluzione dei problemi

Avvio in modalità Rescue/Emergency

Queste modalità forniscono un ambiente minimo per la risoluzione dei problemi. Per entrarvi:

  1. Durante GRUB: Premi e per modificare la riga di comando del kernel.
  2. Individua la riga linux: Trova la riga che inizia con linux (o linuxefi).
  3. Aggiungi systemd.unit=rescue.target per la modalità rescue (la maggior parte dei servizi è disattivata, shell mono-utente).
  4. Aggiungi systemd.unit=emergency.target per la modalità di emergenza (servizi minimi, root spesso in sola lettura).
  5. Premi Ctrl+X o F10 per avviare.

Utilizzo di rd.break per il debug dell'Initramfs

Aggiungere rd.break alla riga di comando del kernel in GRUB ti farà entrare in una shell all'interno dell'initramfs prima che il vero filesystem root venga montato. Questo è estremamente utile per il debug dei problemi di initramfs, come driver mancanti o problemi con la configurazione LVM/RAID.

Una volta nella shell dell'initramfs, puoi:
* Ispezionare lsblk, mount.
* Verificare la presenza di file mancanti in /sysroot.
* Tentare di montare manualmente il filesystem root.

Analisi delle prestazioni di avvio

Sebbene non sia strettamente un "fallimento", i tempi di avvio lenti possono indicare problemi sottostanti o configurazioni inefficienti dei servizi.

  • systemd-analyze blame: Identifica i servizi che impiegano più tempo ad avviarsi.
  • systemd-analyze critical-chain: Comprendi il percorso critico delle dipendenze che influiscono sul tempo totale di avvio.

Utilizza questi strumenti per identificare i colli di bottiglia e ottimizzare l'avvio delle unità regolando le direttive After=, Requires=, TimeoutStartSec= o Type=.

Prevenzione e Best Practice

  • Testa le modifiche: Prima di distribuire modifiche ai file delle unità in produzione, testale in un ambiente di staging.
  • Backup della configurazione: Esegui regolarmente il backup di /etc/ o almeno dei file critici in /etc/systemd/system/.
  • Comprendi le direttive delle unità: Una solida comprensione delle pagine man di systemd.service(5) e systemd.unit(5) è inestimabile.
  • Usa file drop-in: Invece di modificare direttamente i file delle unità in /lib/systemd/system/ (che possono essere sovrascritti dagli aggiornamenti), usa file drop-in (/etc/systemd/system/<unit_name>.service.d/*.conf) per configurazioni personalizzate.
  • Mantieni i kernel: Conserva sempre almeno un kernel precedente noto per funzionare sul tuo sistema, in modo da poterlo avviare se un nuovo kernel causa problemi.

Conclusione

Risolvere i problemi di avvio di systemd richiede un approccio sistematico, a partire da un'efficace analisi dei log. Comprendendo l'architettura basata su unità di systemd e sfruttando strumenti come journalctl, systemctl e systemd-analyze, puoi individuare in modo efficiente la causa principale dei fallimenti di avvio, che si tratti di un servizio mal configurato, di un problema del filesystem o di un complesso conflitto di dipendenze. La capacità di avviare in modalità rescue o di emergenza, unita a tecniche di debug avanzate, ti consente di riprendere il controllo del tuo sistema anche quando sembra completamente non responsivo. Con queste strategie e best practice, sarai ben equipaggiato per affrontare la maggior parte delle sfide di avvio di systemd e mantenere operazioni Linux stabili e affidabili.