Recuperare un /boot pieno durante l'upgrade senza reinstallare
C'è una classe di guasti che non nasce da un errore ma da un'aritmetica: una partizione /boot da 256 MB, dimensionata da un installer di anni fa, contro kernel che oggi pesano 10-15 MB di immagine e 60-80 MB di initrd l'uno. Tre kernel installati, e la matematica non torna più. Il momento in cui te ne accorgi è sempre lo stesso, a metà di un apt upgrade che scarica un kernel nuovo: update-initramfs fallisce con No space left on device, dpkg lascia il pacchetto a metà configurazione, e da quel momento ogni comando apt della macchina risponde con lo stesso muro di errori. Qualche mese fa, in un subentro su un VPS che nessuno manuteneva da tempo, ho trovato esattamente questa scena: quattro kernel accumulati, /boot al 100%, e nel cronologia dei comandi il tentativo che peggiora sempre le cose, un rm frettoloso dentro /boot che aveva cancellato l'initrd del kernel in esecuzione. Il sistema girava, ma un riavvio l'avrebbe lasciato al prompt di GRUB. In questo articolo smonto il guasto pezzo per pezzo: perché /boot si riempie proprio durante gli upgrade, come si esce dallo stallo di dpkg senza reinstallare niente, qual è l'ordine esatto delle operazioni (e perché l'ordine è la parte che conta), e come si dimensiona e si manutiene la partizione per non tornarci mai più.
TL;DR
- Sintomo:
update-initramfs: failedoNo space left on devicesu/bootdurante un aggiornamento kernel; dpkg in stato incoerente, apt bloccato.- Prima mossa: identifica il kernel in esecuzione con
uname -r: quello non si tocca, mai.- Fix rapido: libera spazio SENZA dpkg: sposta (non cancellare) l'initrd di un kernel vecchio non in esecuzione in una directory di parcheggio, poi
dpkg --configure -aeapt -f install.- Fix corretto: a sistema coerente, rimuovi i kernel vecchi con
apt purge/apt autoremove --purge, poiupdate-grube verifica che ogni kernel residuo abbia la sua coppia vmlinuz + initrd.- Prevenzione:
apt autoremovecome rito post-aggiornamento, l'opzione di unattended-upgrades che rimuove i kernel inutilizzati, e su installazioni nuove una /boot da almeno 1 GB.
Perché /boot si riempie proprio durante l'upgrade?
La risposta breve: perché l'aggiornamento di un kernel è l'unico momento in cui su quella partizione devono coesistere il vecchio, il nuovo e lo spazio di lavoro per costruire il nuovo. Quando apt installa un kernel, non sostituisce quello in esecuzione: affianca. È un comportamento corretto e voluto, la tua rete di sicurezza per riavviare sul kernel precedente se il nuovo dà problemi. Ma significa che il picco di occupazione di /boot non è la somma dei kernel installati: è quella somma più l'initrd nuovo che update-initramfs sta generando, tipicamente scrivendo un file temporaneo prima di metterlo al suo posto. Una partizione che a riposo sta al 70% esplode esattamente lì, a metà della generazione, ed è per questo che il guasto si presenta sempre durante un upgrade e mai in un momento qualunque.
Il secondo fattore è la crescita silenziosa degli initrd. L'immagine del kernel è relativamente stabile, ma l'initramfs incorpora moduli, firmware e microcode, e negli anni è ingrassato: le note di rilascio di Debian raccomandano di verificare lo spazio disponibile prima dell'upgrade non per scrupolo burocratico, ma perché un major upgrade rigenera gli initrd di tutti i kernel presenti, ed è il momento in cui una /boot risicata mostra il conto. Il terzo fattore è umano: apt autoremove mai eseguito. Debian mantiene per design il kernel corrente e l'ultimo precedente, ma i kernel più vecchi diventano semplicemente "auto-rimovibili", e se nessuno lancia mai la rimozione restano lì, un centinaio di megabyte alla volta, finché la partizione dice basta.
La diagnosi si fa in trenta secondi e conviene farla adesso, non durante il prossimo upgrade:
df -h /boot
# se Use% è sopra l'80%, sei un candidato al guasto
ls -lh /boot/vmlinuz-* /boot/initrd.img-*
dpkg -l 'linux-image-*' | grep ^ii
uname -r
# il kernel di uname -r NON si tocca in nessuna fase del recuperoSe df non mostra una partizione separata per /boot, il tuo problema è un altro, il filesystem di root pieno, e la diagnosi giusta è quella che ho descritto nella guida ai problemi di spazio disco su VPS: sintomi simili, cause e rimedi diversi. Questo pezzo riguarda il caso della partizione dedicata, e vale la pena dire perché esiste: il bootloader deve poter leggere kernel e initrd prima che il sistema sia in piedi, quindi ogni configurazione in cui la root non è leggibile direttamente, dischi cifrati con LUKS, volumi LVM su installer datati, filesystem esotici, impone una /boot separata e in chiaro. È il motivo per cui la trovi spessissimo proprio sui VPS irrobustiti anni fa con la cifratura del disco: una scelta di sicurezza corretta che si porta dietro, in dote, questa manutenzione in più.
Una parentesi per il parente stretto di questo guasto: sui sistemi UEFI esiste anche la ESP montata su /boot/efi, ed è una partizione diversa con un problema diverso. Se a riempirsi è quella, i sospettati non sono i kernel ma i bootloader accumulati e, su alcune configurazioni, i dump di firmware: la diagnosi parte sempre da df -h /boot/efi e da un du -sh del contenuto, ma la procedura di bonifica non è quella di questo articolo. Riconoscere quale delle due partizioni è piena è il primo bivio della diagnosi.
Questa attenzione all'ordine delle operazioni nei recuperi è il cuore del lavoro che faccio sui VPS in produzione delle PMI, dove l'errore da evitare non è il guasto ma il peggioramento del guasto: nel mio profilo professionale trovi come lavoro su manutenzioni, subentri e situazioni compromesse.
Lo stallo: perché apt non può più aiutarti
Vale la pena capire la forma della trappola, perché spiega la via d'uscita. Quando update-initramfs fallisce per spazio, dpkg marca il pacchetto kernel come non configurato e si ferma. Da quel momento qualunque operazione apt, inclusa la rimozione di un kernel vecchio che libererebbe lo spazio, pretende prima di completare la configurazione interrotta: apt purge linux-image-vecchio risponde proponendo di sistemare prima lo stato, la sistemazione richiede di rigenerare l'initrd, la rigenerazione richiede lo spazio che non c'è. È un abbraccio circolare: lo strumento che dovrebbe liberare spazio ha bisogno dello spazio per funzionare. E attenzione a un riflesso condizionato che qui non serve a niente: apt clean svuota la cache dei pacchetti scaricati, che vive in /var, non in /boot; sulla partizione piena non libera un byte, e il tempo speso a stupirsi del perché è tempo tolto al recupero vero.
La regola dei recuperi su dpkg è una sola: non si combatte il gestore di pacchetti, lo si sblocca. Prima gli si restituisce la precondizione che gli manca (lo spazio), poi gli si lascia completare il suo stato, e solo alla fine gli si chiede di rimuovere qualcosa. Ogni scorciatoia che inverte quest'ordine allunga il recupero.
Da qui la sequenza corretta, in tre tempi. Tempo uno: liberare spazio senza toccare dpkg. Il modo sicuro è spostare, non cancellare, l'initrd di un kernel vecchio e non in esecuzione in una directory di parcheggio sul filesystem di root:
mkdir -p /root/boot-parcheggio
# scegli una versione che NON sia quella di uname -r
mv /boot/initrd.img-6.1.0-37-amd64 /root/boot-parcheggio/
df -h /boot # verifica di aver liberato decine di MBLo spostamento è reversibile per definizione, e se hai scelto il file giusto non hai degradato nulla di ciò che serve al prossimo riavvio. Tempo due: lasciare che dpkg completi. dpkg --configure -a riprende la configurazione interrotta, update-initramfs stavolta trova lo spazio e finisce il lavoro, e un apt -f install di controllo deve chiudersi senza proporre nulla. Tempo tre: la rimozione pulita. Ora che apt è tornato funzionante, i kernel vecchi si rimuovono nel modo giusto, dal gestore di pacchetti, che si porta via immagini, initrd e voci di menu in modo coerente:
apt purge linux-image-6.1.0-37-amd64 # esplicito, versione per versione
apt autoremove --purge # oppure: lascia decidere ad apt
update-grubA quel punto la directory di parcheggio si svuota (il file spostato apparteneva a un pacchetto ormai rimosso), e resta l'ultima verifica, quella che separa un recupero completo da uno lasciato a metà: per ogni kernel ancora installato devono esistere in /boot la coppia vmlinuz-* e initrd.img-* con la stessa versione, e la voce corrispondente nel menu di GRUB. Se un initrd manca o ha dimensione sospetta (un file da pochi megabyte dove i fratelli ne pesano sessanta è un initrd troncato dal fallimento), si rigenera esplicitamente con update-initramfs -u -k <versione>, come documentato nella manpage di update-initramfs. E il collaudo finale è un riavvio pianificato: un sistema che non è mai stato riavviato dopo un incidente su /boot è un sistema di cui non sai se si riavvia.
Gli errori che trasformano un intoppo in un'emergenza
Il guasto in sé è banale; le versioni gravi che ho incontrato erano tutte auto-inflitte nel tentativo di risolverlo. Il primo errore, il classico: rm a mano dentro /boot scegliendo il file sbagliato. Cancellare l'initrd del kernel in esecuzione non produce alcun sintomo immediato, il sistema gira tranquillo, ed è proprio questo il veleno: il problema si manifesta al riavvio successivo, magari settimane dopo, quando il collegamento mentale con la causa è svanito. Per questo la sequenza sopra usa mv e non rm, e per questo uname -r si esegue prima di toccare qualunque cosa. Il secondo errore: riavviare per "sbloccare". Con dpkg a metà configurazione e un initrd potenzialmente troncato, il riavvio è l'unica mossa che può trasformare uno stallo amministrativo in una macchina che non parte; il riavvio arriva alla fine del recupero, mai durante. Il terzo: allargare la partizione come prima risposta. Su un VPS con LVM può perfino essere fattibile a caldo, ma farlo mentre dpkg è incoerente e il filesystem è pieno significa fare un'operazione delicata nel momento peggiore; prima si esce dallo stallo con la procedura sopra, poi, con calma e con uno snapshot del provider alle spalle, si ragiona sul ridimensionamento. Se poi il riavvio serve comunque e la macchina è remota, valgono le precauzioni che ho messo in fila nella sequenza per lavorare via SSH senza restare chiusi fuori: console del provider verificata prima, non dopo.
La prevenzione, che costa cinque minuti l'anno
La versione lunga della prevenzione è dimensionale: su ogni installazione nuova, /boot da almeno 1 GB. Lo spazio su disco costa centesimi, un recupero costa una serata, e gli initrd non torneranno a dimagrire. Ma sul parco esistente, dove ridimensionare non è gratis, la prevenzione vera è comportamentale e sta in tre abitudini. Primo: apt autoremove come parte del rito di aggiornamento, non come comando esotico; il momento giusto è subito dopo ogni aggiornamento kernel andato a buon fine, quando sai con certezza quale kernel è buono. Secondo: se usi unattended-upgrades, verifica che la rimozione automatica dei kernel inutilizzati sia attiva (Unattended-Upgrade::Remove-Unused-Kernel-Packages "true" nella configurazione): è il singolo interruttore che disinnesca l'accumulo alla radice sui sistemi che si aggiornano da soli. Terzo: una soglia di monitoraggio dedicata su /boot, perché è la partizione che tutti i template di monitoring dimenticano; un alert all'80% ti fa gestire il tema in un martedì qualunque invece che a metà di un upgrade. Vale anche la pena sapere quanti kernel apt intende conservare: la logica vive nei file 01autoremove sotto /etc/apt/apt.conf.d/, e il default, kernel corrente più l'ultimo installato, è quello giusto per la quasi totalità dei server; alzarlo su una partizione piccola significa programmare il prossimo guasto. Nota a margine per chi sta pianificando il salto a Debian 13: il major upgrade rigenera tutti gli initrd, quindi il controllo di df -h /boot merita un posto fisso nei preliminari, accanto ai backup e alle verifiche che la guida completa da bookworm a trixie mette in cima alla procedura.
La morale di questo guasto è la stessa di quasi tutti i guasti da manutenzione: non è un imprevisto, è un appuntamento. La partizione piccola, i kernel che si accumulano e l'initrd che cresce convergono verso una data certa con la puntualità di una cambiale, e l'unica variabile è se quel giorno troveranno un sistema monitorato con margine o un upgrade in corso. Se hai un parco macchine ereditato di cui non conosci lo stato, o un VPS che non vede un apt autoremove da anni e preferisci che il censimento e la bonifica li faccia qualcuno che questi recuperi li ha già fatti, contattami per una consulenza: mezz'ora di verifica preventiva su /boot, kernel e monitoraggio vale più di qualunque procedura di emergenza eseguita alle due di notte.