Un disco che comincia a dare errori di lettura, una chiavetta usata da anni o un disco usato appena comprato: prima di fidarsi dei propri dati può essere utile verificare che ogni settore risponda. Il comando classico per farlo, su Linux, è badblocks.
Cos'è
badblocks fa parte di e2fsprogs, lo stesso pacchetto di mkfs.ext4, e2fsck e tune2fs, ma non dipende dal tipo di file system: lavora direttamente sul dispositivo, e quindi funziona su una partizione, su un disco intero o su un file immagine. Non ripara nulla: il suo unico compito è scoprire quali blocchi non si leggono (o non mantengono ciò che vi si scrive) e riferirlo.
Cosa fa
Legge, o legge e scrive, tutti i blocchi del dispositivo uno dopo l'altro e stampa il numero di ogni blocco che dà errore. Ha tre modalità: una di sola lettura (la predefinita), una di lettura e scrittura non distruttiva (-n) e una di scrittura distruttiva (-w). L'elenco dei blocchi difettosi può essere salvato in un file e passato a mkfs o e2fsck, che lo usano per non assegnare mai quei blocchi ai file.
Come si usa
$ sudo badblocks [opzioni] DISPOSITIVO [ULTIMO [PRIMO]]Gli ultimi due argomenti, facoltativi, limitano il controllo a un intervallo di blocchi, e vanno nell'ordine "ultimo, poi primo" (un'inversione rispetto a quello che ci si aspetta). Come negli articoli precedenti, negli esempi lavoro su un'immagine (d.img, 16 MB) per non toccare dischi veri; sul tuo sistema usa il dispositivo reale, ad esempio /dev/sdb. Un limite importante del mio banco di prova: un'immagine su un disco sano non ha blocchi difettosi, quindi tutti i test hanno trovato 0 errori. I messaggi che mostrano blocchi difettosi veri li descrivo ma non li ho potuti ottenere.
Esempio 1: il controllo base, in sola lettura
$ sudo badblocks -sv d.img
Checking blocks 0 to 16383
Checking for bad blocks (read-only test): done
Pass completed, 0 bad blocks found. (0/0/0 errors)-s mostra l'avanzamento e -v i messaggi di stato. Senza -v il comando non stampa niente se non trova errori, e termina con codice 0: per questo conviene quasi sempre usarlo. Il numero di blocchi dipende dalla loro dimensione: con la dimensione predefinita (1024 byte) un'immagine da 16 MB ha 16384 blocchi, numerati da 0 a 16383. Nell'originale la riga di avanzamento viene riscritta sul posto, per cui nel terminale vedi una percentuale che sale; qui ho riportato solo il risultato finale.
Esempio 2: la dimensione del blocco
$ sudo badblocks -b 4096 -sv d.img
Checking blocks 0 to 4095
Checking for bad blocks (read-only test): done
Pass completed, 0 bad blocks found. (0/0/0 errors)-b indica la dimensione del blocco in byte. I numeri stampati si riferiscono a quella dimensione: se poi vuoi usare l'elenco con mkfs.ext4 o e2fsck, devi usare lo stesso valore del file system (di solito 4096; lo trovi con tune2fs -l DEV | grep "Block size").
Esempio 3: controllare solo un intervallo
$ sudo badblocks -v d.img 100 50
Checking blocks 50 to 100
Checking for bad blocks (read-only test): done
Pass completed, 0 bad blocks found. (0/0/0 errors)L'intervallo si scrive come "ultimo primo": qui 100 è l'ultimo e 50 il primo. Utile per riprovare una zona sospetta dopo un errore che il kernel ha segnalato (vedi dmesg).
Esempio 4: salvare l'elenco dei blocchi difettosi
$ sudo badblocks -b 4096 -o lista.txt d.img-o scrive i numeri dei blocchi difettosi in un file, uno per riga. Su un disco sano il file resta vuoto (nel mio test pesava 0 byte). Il formato è semplicemente un numero per riga; non avendo blocchi difettosi veri, l'ho scritto a mano e verificato che mkfs.ext4 lo accetti:
$ cat lista.txt
100
101
2000Esempio 5: usare l'elenco con mkfs.ext4
$ sudo mkfs.ext4 -b 4096 -l lista.txt d.img
$ sudo dumpe2fs -b d.img
dumpe2fs 1.47.0 (5-Feb-2023)
100
101
2000L'opzione -l di mkfs.ext4 legge l'elenco e riserva quei blocchi, così nessun file li userà. dumpe2fs -b mostra l'elenco memorizzato nel file system. Qui l'ho provato con un elenco inventato su un'immagine, e ha funzionato; con blocchi realmente difettosi il discorso cambia (vedi in fondo). Per un file system esistente si usa e2fsck -l lista.txt DEV, che aggiunge i blocchi all'elenco ("Updating bad block inode"). In alternativa mkfs.ext4 -c esegue direttamente badblocks e usa il risultato.
Esempio 6: test non distruttivo
$ sudo badblocks -nsv -b 4096 n.img
Checking for bad blocks (non-destructive read-write test)
Testing with random pattern: done
Pass completed, 0 bad blocks found. (0/0/0 errors)-n legge un blocco, ci scrive sopra dei dati di prova, li rilegge e poi rimette il contenuto originale. Il test è più accurato di quello di sola lettura e, in teoria, non perde dati. Nel mio test il checksum dell'immagine (md5sum) era identico prima e dopo, e il file system risultava ancora riconoscibile con blkid. Resta comunque rischioso su un disco malato: se il computer si spegne a metà, i dati di un blocco possono andare perduti. Il dispositivo non deve essere montato.
Esempio 7: test distruttivo di scrittura
$ sudo badblocks -wsv -b 4096 d.img
Checking for bad blocks in read-write mode
From block 0 to 4095
...
Pass completed, 0 bad blocks found. (0/0/0 errors)
$ blkid d.img
$ echo $?
2-w scrive sul dispositivo una serie di schemi di prova e li rilegge. È il test più completo ma cancella tutto: nel mio test, dopo il comando blkid non riconosceva più nessun file system (nessun output e codice 2). Si usa su dischi nuovi o da riformattare, mai su dischi con dati. Con -t scegli lo schema (-t 0xaa, -t random) e con -p quante passate fare. Senza -t, da documentazione, il test usa quattro schemi in sequenza e richiede ore su un disco grande (non l'ho potuto cronometrare su un disco vero).
Esempio 8: uso negli script
#!/bin/bash
DEV="$1"
OUT=$(mktemp)
badblocks -b 4096 -o "$OUT" "$DEV" 2>/dev/null || {
echo "test fallito su $DEV" >&2
rm -f "$OUT"
exit 2
}
n=$(wc -l < "$OUT")
rm -f "$OUT"
if [ "$n" -gt 0 ]; then
echo "$DEV: $n blocchi difettosi" >&2
exit 1
fi
echo "$DEV: nessun blocco difettoso"Lo script fa un test in sola lettura e conta le righe del file di output: se ce ne sono, i blocchi difettosi sono tanti quante le righe. Sull'immagine sana stampa "nessun blocco difettoso" (codice 0); su un file inesistente dice "test fallito" (codice 2). Per provare il ramo dei blocchi difettosi ho messo nel PATH un finto badblocks che scrive due righe: lo script ha risposto "2 blocchi difettosi" con codice 1. Non fidarti del solo codice di uscita di badblocks: nel test su dischi sani è sempre 0 e non l'ho potuto verificare su dischi difettosi, per questo lo script conta le righe.
Opzioni utili
-v: messaggi dettagliati;-s: mostra l'avanzamento.-b DIMENSIONE: dimensione del blocco in byte (usa quella del file system).-o FILE: salva i blocchi difettosi in un file.-i FILE: legge un elenco di blocchi già noti da saltare.-n: test di lettura e scrittura non distruttivo.-w: test di scrittura distruttivo.-t SCHEMA: schema di prova (0xaa,random...);-p NUMERO: numero di passate.-c BLOCCHI: quanti blocchi leggere alla volta;-e NUMERO: ferma il test dopo quel numero di errori.-f: forza il test anche su un dispositivo che risulta montato (sconsigliato).
Attenzione a
-wcancella tutto: controlla due volte il nome del dispositivo conlsblk. Un errore di lettera distrugge il disco sbagliato.- Dispositivo smontato: i test di scrittura vanno fatti solo con il disco smontato.
- Tempi lunghi: su un disco da qualche terabyte il test completo può richiedere ore o giorni. Lancialo in
tmuxo connohup, così non si ferma se chiudi il terminale. - I dischi moderni si autoripristinano: hard disk e SSD rimappano da soli i settori difettosi, per cui un blocco difettoso che
badblocksvede è già un segnale d'allarme. Prima di tutto guarda i dati SMART consmartctl. - Un blocco difettoso non si "ripara": sostituire il disco è quasi sempre la scelta giusta; l'elenco di
mkfs -lserve a tamponare, non a risolvere. - Dimensione del blocco coerente: i numeri dell'elenco valgono solo con la dimensione usata da
badblocks -b; se differisce da quella del file system, i blocchi esclusi sono quelli sbagliati. - Non è un controllo del file system:
badblocksguarda l'hardware, non la coerenza dei file. Per quella servefsck.
Riepilogo
| Comando | Cosa fa |
|---|---|
badblocks -sv DEV | Test in sola lettura con messaggi |
badblocks -b 4096 -sv DEV | Test con blocchi da 4 KiB |
badblocks -v DEV 100 50 | Controlla solo i blocchi da 50 a 100 |
badblocks -o FILE DEV | Salva l'elenco dei blocchi difettosi |
badblocks -nsv DEV | Test di lettura e scrittura non distruttivo |
badblocks -wsv DEV | Test di scrittura distruttivo |
mkfs.ext4 -l FILE DEV | Crea ext4 escludendo i blocchi elencati |
e2fsck -l FILE DEV | Aggiunge blocchi difettosi a un file system |
dumpe2fs -b DEV | Mostra i blocchi difettosi registrati |