venerdì 9 gennaio 2009

Recupero di dati da un volume FAT32 corrotto

Racconto di un'esperienza di recupero di dati da una partizione FAT32 con l'intestazione danneggiata
Inizio il nuovo anno con un bel problema. Il "vecchio" pc fisso (un Olidata con processore AMD da 1.8GHz ) non ne vuole più sapere di ripartire: è vero lo stavo usando molto poco negli ultimi mesi, siccome il portatile è molto più comodo, ma non pensavo mi abbandonasse così!
I sintomi sono questi: all'accensione parte il boot loader (uso grub perché ho windows 98, windows XP e Ubuntu linux in multi boot: pessima scelta, ma è un altro discorso), si blocca con "error 17" ancora prima di presentare la lista delle opzioni. Quasi sicuramente il problema è (solo?!) l'hard disk. L'occasione è buona per un esperimento di recupero dei dati.
Occorrente:
  • Un PC con hard disk danneggiato
  • Una chiavetta USB da almeno 1Gb
  • Un hard disk esterno USB con abbastanza spazio libero da contenere i dati da recuperare.
  • Un altro PC funzionante con connessione a internet.

Avvio del sistema

Il primo passo è accedere al PC senza sfruttare l'hard disk: scarico l'immagine ISO dell'ultima versione di Ubuntu (la 8.10, versione desktop), la masterizzo e tento il boot da CD. Purtroppo i guai non vengono mai da soli: il lettore CD aveva già dato segni di cedimento in passato (questo PC è proprio da buttare!) ma questa volta non ne vuole proprio sapere di partire; emette strani suoni e dopo alcuni tentativi falliti decido di tentare un altra strada. Il secondo tentativo ha esiti migliori. Scarico UNetbootin, un software che permette di creare una installazione di una distribuzione linux avviabile da chiavetta USB. L'interfaccia grafica è chiarissima: infilo la chiavetta USB da 1G, seleziono l'immagine ISO appena scaricata e in pochi minuti la mia chiavetta è pronta. Dal BIOS del PC danneggiato imposto la sequenza di avvio in modo che tenti, come prima cosa, l'avvio da chiavetta, resetto ed ecco finalmente Ubuntu Linux. La versione che parte è "live", cioè viene eseguita senza essere installata sull'hard disk, ma le funzionalità presenti dovrebbero essere sufficienti per una verifica dei problemi del disco e per un eventuale recupero dei dati. Il caricamento è piuttosto lento, probabilmente a causa delle porte USB versione 1.1, ma non è la velocità che mi interessa. Durante l'avvio il sistema cerca di montare le partizioni presenti sul disco rigido e infatti vedo scorrere diversi errori: è la conferma che il problema è proprio l'hard disk.

Verifica dei problemi

Una volta avviato il sistema (interfaccia grafica con diverse applicazioni), imposto nel menù System la tastiera italiana (il default è quella americana) e apro un terminale. Il disco viene visto e riconosciuto dal sistema come /dev/sda e l'MBR è leggibile in quanto il comando
sudo fdisk /dev/sda
(seguito poi dall'istruzione 'p') stampa correttamente la tabella delle partizioni.
È una buona notizia.
L'hard disk è suddiviso in diverse partizioni. Mi interessa recuperare i dati di una partizione formattata con FAT32 che si chiama /dev/sda6. Tento di montarla:
sudo mkdir /media/hd
sudo mount -t vfat /dev/sda6 /media/hd
mi risponde:
mount: /dev/sda6: can't read superblock
questa non è una buona notizia.
Provo a eseguire il programma di verifica e riparazione del filesystem FAT32
sudo fsck.vfat -v -l -r /dev/sda6
Risponde:
Read 512 bytes ad 0: Input/output error
Altra brutta notizia: non è possibile nemmeno leggere i primi 512 bytes del volume, quelli dove si trova l'header del filesystem (vedi specifiche FAT32). Voglio capire esattamente quali parti della partizione sono corrotte, uso badblocks, un programma che generalmente viene utilizzato automaticamente dalle varie versioni di fsck quando richiamate con l'opzione -c; in questo caso lo eseguo manualmente impostando una dimensione arbitraria dei blocchi a 512 bytes:
sudo badblocks -s -v -c1 -b 512 -o badblocks.out /dev/sda6
mi restituisce nel file badblocks.out una lista di 32 blocchi danneggiati, precisamente i primi 32. Questa volta c'è una notizia buona e una cattiva: la buona è che il settore contenente i dati è sicuramente oltre il 32mo blocco, cioè i dati sono tutti leggibili; la cattiva notizia è che è illeggibile tutta l'intestazione del filesystem e probabilmente una parte della prima copia della FAT, inoltre, siccome è essenziale per il funzionamento del filesystem e non può essere allocata altrove, il filesystem non è riparabile nel punto in cui si trova.
Riesco a dedurre (come ho fatto lo spiegherò in un altro post altrimenti mi dilungo troppo) che in realtà la prima copia della FAT inizia al 33mo blocco quindi entrambe le copie sono intatte: devo solo ricostruire l'intestazione.

Recupero dei dati

Una grande possibilità dei sistemi linux è quella di montare un file come se fosse una partizione fisica, sfruttando i "loop device". Ho a disposizione un hd esterno usb, completamente formattato con NTFS, con 30 Gb liberi, a me ne bastano 20 (la dimensione del volume danneggiato). L'hd viene riconosciuto automaticamente da Ubuntu ed è subito disponibile. Prima di tutto travaso tutto il contenuto del volume in un file sostituendo la parte illeggibile con degli zeri:
dd ibs=512 obs=512 skip=32 seek=32 if=/dev/sda6 of=sda6.data
(ci vuole un bel po' di tempo, probabilmente sempre a causa dell'USB1.1)
Poi creo su questo file un filesystem di tipo FAT32:
mkfs.vfat -F 32 -s 32 -S 512 -v sda6.data
una spiegazione dei parametri:
-F 32 indica di creare un fs di tipo FAT32 (esiste anche FAT16 FAT12)
-S 512 indica di considerare settori da 512 byte
-s 32 indica che ogni cluster (unità di allocazione minima di un file) è composto da 32 settori (cioè 512 * 32 = 16Kb). Il fatto che i clusters debbano essere di 16 Kb l'ho ricavato da considerazioni sui dati che spiegherò in un altro post.
-v è solo per avere un output più prolisso
Fatto questo provo a montare il file, solo per vedere se è corretto; non vedrò ancora i miei dati ma solo un filesystem vuoto siccome le FAT sono state sovrascritte da mkfs:
sudo mount -o loop -tvfat sda6.data /media/hd
Bene funziona. Lo smonto di nuovo.
sudo umount /media/hd
Ora che ho in sda6.data un filesystem vuoto con un header corretto provo a sostituire le due copie delle FAT vuote con quelle piene presenti nella partizione originale e, come abbiamo visto, integre.
La dimensione di una FAT del mio volume è di 5118 Kb (come faccio a saperlo lo spiego nell'altro post che farò), le due copie occupano dunque 10236 Kb e partono dopo 16 Kb dall'inizio del volume (32 blocchi da 512 byte di header danneggiati). In realtà oltre a copiare le FAT devo anche copiare i cluster contenenti la root directory che sono stati sovrascritti quando ho generato il filesystem. La root directory è verosimilmente contenuta nei primi clusters dopo le FAT (essendo la prima creata) quindi abbondo un po' e prendo 30000 Kb. Notare che avrei potuto ricopiare nuovamente tutto il volume per maggior sicurezza, ma siccome ci vuole molto tempo evito di farlo.
Le estraggo in un file:
sudo dd bs=1024 count=30000 skip=16 if=/dev/sda6 of=sda6.fat
e inserisco il file nel punto corretto all'interno di sda6.data.
Per fare questo non sono riuscito a trovare un comando unix (se qualcuno lo conosce mi "faccia un fischio"), ma ho usato uno script python di poche righe (la versione live di Ubuntu comprende anche l'interprete python)
f=open('sda6.fat')
fat=f.read()
f.close()
f = open('sda6.data', 'r+')
f.seek(16384) #inizio a scrivere dopo i primi 16 Kb
f.write(fat)
f.close()
ora monto nuovamente il volume
sudo mount -o loop -tvfat sda6.data /media/hd
ls /media/hd
e...
EUREKA!
ecco tutti i miei dati: non mi resta che copiarmeli e sono salvi.

4 commenti:

Anonimo ha detto...

Complimenti!!!
Per la conoscenza di linux, ma soprattutto per la pazienza e costante nel tentativo di recuperare un disco così danneggiato.
Ho capito il 20% delle operazioni che hai fatto, non perchè sono spiegate male, ma perchè non sono così esperto come te.
Ad esempio non ho capito se "sudo" è un comando linux o una descrizione del tuo stato fisico dopo le prime brutte notizie!

Zac ha detto...

Bella questa!

dado ha detto...

Ciao a tutti, ho un problema presso che identico e non riesco a recuperare i dati. Ci sto provando con ubuntu ma finora pochi, inutili risultati; se potete aiutarmi fatemi sapere. Grazie.

Gabriele ha detto...

Molto interessante ! BRAVO !