Lo hice y lo entendí

El blog de Vicente Navarro
25 jul

Recuperación de particiones perdidas con gpart

Muchos de nosotros que nos dedicamos con cierta frecuencia a borrar particiones de aquí, crear por allá y ampliar por más allá, nos hemos encontrado alguna vez en el fatídico momento en el que te das cuenta que te has cargado esa partición repleta de ficheros que tanta falta te hacen. ¿Qué podemos hacer en esos casos? ¿Es reversible?

Como ya vimos en Montar una imagen raw de Qemu. Los primeros 32 Kbytes de un disco., las particiones son apenas 64 bytes en el primer sector (512 bytes) del disco duro, el que llamamos MBR (Master Boot Record). Bueno, para ser exactos, en el MBR sólo se pueden guardar las 4 particiones (apenas 16 bytes para cada partición) primarias que podemos tener en el sistema de particiones de los PC, o 3 primarias más 1 extendida que puede almacenar un número indefinido de particiones lógicas en el EBR (Extended Boot Record).

Pues bien, un cambio que podamos hacer en esa tabla de particiones por ejemplo con el fdisk de Linux en principio sólo nos estará modificando la información del MBR y/o del EBR, pero en principio no la del sitio donde está la partición, a menos que el programa de gestión de particiones haga cosas más agresivas, algo que suele hacer, por ejemplo, el administrador de discos de windows. Además, si el gestor de particiones que usemos también tiene la capacidad de formatear particiones recién creadas, y es eso lo que seleccionamos, también es altamente probable que perdamos irremediablemente nuestros datos.

Me acuerdo de una vez, hace muchos años, que me cargué la tabla de particiones, ya no recuerdo cómo. Como en aquella ocasión no conocía ninguna herramienta de recuperación de particiones, me tocó armarme de paciencia, recordar de cuánto tamaño era más o menos cada partición e ir probando durante varias horas a crear particiones con el fdisk de Linux empezando un poco más aquí y empezando un poco más allá hasta que conseguí dar con un conjunto de particiones que se montaban sin errores y conseguí no perder mis datos. Hice una recuperación de particiones manual. No fui difícil pero sí muy pesado.

Más recientemente también me ha pasado alguna vez tocar la partición que no era pero, esta vez sí, ya conocía el genial gpart y pude recuperarlas sin apenas despeinarme. Aunque el nombre sea muy parecido, no debemos confundir el gpart (Guess PC-type hard disk partitions), una herramienta de recuperación de particiones, con el GParted (Gnome Partition Editor), un gestor de particiones que nos permite crearlas, eliminarlas, moverlas, copiarlas e incluso cambiarles el tamaño, llegando a igualar y superar al antiguo rey en este campo: el famoso Partition Magic.

Así, si tenemos una tabla de particiones como esta:

# sfdisk -l /dev/hdb

Disk /dev/hdb: 4161 cylinders, 16 heads, 63 sectors/track
Units = cylinders of 516096 bytes, blocks of 1024 bytes, counting from 0

   Device Boot Start     End   #cyls    #blocks   Id  System
/dev/hdb1   *      0+   1999-   2000-   1007968   83  Linux
/dev/hdb2       2000    2499-    500-    251996    7  HPFS/NTFS
/dev/hdb3       2500    4160    1661     837144    5  Extended
/dev/hdb4          0       -       0          0    0  Empty
/dev/hdb5       2500+   2999     500-    251968+  82  Linux swap / Solaris
/dev/hdb6       3000+   3499     500-    251968+   b  W95 FAT32
/dev/hdb7       3500+   4160     661-    333112+  83  Linux

y las borramos todas con el comando fdisk de Linux o incluso más agresivamente, eliminando todo el MBR:

# dd if=/dev/zero of=/dev/hdb count=1 bs=512
1+0 records in
1+0 records out
512 bytes (512 B) copied, 0.00656895 s, 77.9 kB/s
# sfdisk -l /dev/hdb

Disk /dev/hdb: 4161 cylinders, 16 heads, 63 sectors/track

sfdisk: ERROR: sector 0 does not have an msdos signature
 /dev/hdb: unrecognized partition table type
No partitions found

una primera ejecución de gpart (paquete que viene en Debian y Ubuntu) nos encontrará todas las particiones sin fallos, pero de momento aún no las escribe:

# gpart /dev/hdb

Begin scan...
Possible partition(Linux ext2), size(984mb), offset(0mb)
Possible partition(Windows NT/W2K FS), size(246mb), offset(984mb)
Possible extended partition at offset(1230mb)
   Possible partition(Linux swap), size(246mb), offset(1230mb)
   Possible partition(DOS FAT), size(246mb), offset(1476mb)
   Possible partition(Linux ext2), size(325mb), offset(1722mb)
End scan.

Checking partitions...
Partition(Linux ext2 filesystem): primary 
Partition(OS/2 HPFS, NTFS, QNX or Advanced UNIX): primary 
   Partition(Linux swap or Solaris/x86): logical 
   Partition(DOS or Windows 95 with 32 bit FAT): logical 
   Partition(Linux ext2 filesystem): logical 
Ok.

Guessed primary partition table:
Primary partition(1)
   type: 131(0x83)(Linux ext2 filesystem)
   size: 984mb #s(2015936) s(63-2015998)
   chs:  (0/1/1)-(1023/15/63)d (0/1/1)-(1999/15/62)r

Primary partition(2)
   type: 007(0x07)(OS/2 HPFS, NTFS, QNX or Advanced UNIX)
   size: 246mb #s(503992) s(2016000-2519991)
   chs:  (1023/15/63)-(1023/15/63)d (2000/0/1)-(2499/15/55)r

Primary partition(3)
   type: 005(0x05)(Extended DOS)
   size: 817mb #s(1674288) s(2520000-4194287)
   chs:  (1023/15/63)-(1023/15/63)d (2500/0/1)-(4160/15/63)r

Primary partition(4)
   type: 000(0x00)(unused)
   size: 0mb #s(0) s(0-0)
   chs:  (0/0/0)-(0/0/0)d (0/0/0)-(0/0/0)r

Si convenimos que el gpart ha hecho un buen trabajo, podemos decirle con la opción -W que escriba el MBR completo con la tabla de particiones que ha conseguido averiguar en un fichero normal o en un fichero de dispositivo. Por ejemplo, si lo hiciéramos en un fichero, el comando sería algo así (nos hace unas preguntas adicionales al final sobre si queremos editar las particiones o cuál queremos que sea la partición activa):

# gpart -W mbr_del_sistema /dev/hdb

Begin scan...
Possible partition(Linux ext2), size(984mb), offset(0mb)
Possible partition(Windows NT/W2K FS), size(246mb), offset(984mb)
Possible extended partition at offset(1230mb)
   Possible partition(Linux swap), size(246mb), offset(1230mb)
   Possible partition(DOS FAT), size(246mb), offset(1476mb)
   Possible partition(Linux ext2), size(325mb), offset(1722mb)
End scan.

Checking partitions...
Partition(Linux ext2 filesystem): primary 
Partition(OS/2 HPFS, NTFS, QNX or Advanced UNIX): primary 
   Partition(Linux swap or Solaris/x86): logical 
   Partition(DOS or Windows 95 with 32 bit FAT): logical 
   Partition(Linux ext2 filesystem): logical 
Ok.

Guessed primary partition table:
Primary partition(1)
   type: 131(0x83)(Linux ext2 filesystem)
   size: 984mb #s(2015936) s(63-2015998)
   chs:  (0/1/1)-(1023/15/63)d (0/1/1)-(1999/15/62)r

Primary partition(2)
   type: 007(0x07)(OS/2 HPFS, NTFS, QNX or Advanced UNIX)
   size: 246mb #s(503992) s(2016000-2519991)
   chs:  (1023/15/63)-(1023/15/63)d (2000/0/1)-(2499/15/55)r

Primary partition(3)
   type: 005(0x05)(Extended DOS)
   size: 817mb #s(1674288) s(2520000-4194287)
   chs:  (1023/15/63)-(1023/15/63)d (2500/0/1)-(4160/15/63)r

Primary partition(4)
   type: 000(0x00)(unused)
   size: 0mb #s(0) s(0-0)
   chs:  (0/0/0)-(0/0/0)d (0/0/0)-(0/0/0)r

Edit this table (y,n) : n

Activate which partition (1..4, q to quit) : 1
Write this partition table (y,n) : y

y la escritura final del MBR al disco la haríamos con un dd:

# dd if=mbr_del_sistema of=/dev/hdb
1+0 records in
1+0 records out
512 bytes (512 B) copied, 0.00676343 s, 75.7 kB/s

Aunque también podemos querer escribir el MBR con la tabla de particiones recuperada directamente en el disco, algo que podríamos hacer con un comando como este:

# gpart -W /dev/hdb /dev/hdb

Ambos caminos nos devolverían nuestra preciada tabla de particiones.

Sin embargo, puede que no siempre sea tan fácil. Por ejemplo, si esas mismas particiones del principio las borramos con el administrador de discos de Windows y volvemos a Linux a ver si las podemos recuperar, sfdisk no es capaz de hacer un buen trabajo del todo, ya que no consigue colocar correctamente la partición extendida: la partición swap de Linux la pone primaria cuando era lógica, la extendida se sale del disco y la de Linux del final está orphaned. Un pequeño desastre, vamos. De hecho, el Warning que nos devuelve impide que podamos escribir esta tabla de particiones con la opción -W. Sin embargo, las pistas que nos dá son más que buenas para que, con un poco de paciencia, un poco de recordar cómo estaba todo y unas pruebas, consigamos reconstruir la tabla ya más manualmente, eso sí:

# gpart /dev/hdb

Begin scan...
Possible partition(Linux ext2), size(984mb), offset(0mb)
Possible partition(Windows NT/W2K FS), size(246mb), offset(984mb)
Possible partition(Linux swap), size(246mb), offset(1230mb)
Possible extended partition at offset(1476mb)
   Possible partition(DOS FAT), size(246mb), offset(1476mb)
   Possible partition(Linux ext2), size(325mb), offset(1722mb)
End scan.

Checking partitions...
Partition(Linux ext2 filesystem): primary 
Partition(OS/2 HPFS, NTFS, QNX or Advanced UNIX): primary 
Partition(Linux swap or Solaris/x86): primary 
   Partition(DOS or Windows 95 with 32 bit FAT): logical 
   Partition(Linux ext2 filesystem): orphaned logical 

* Warning: partition(Extended DOS) ends beyond disk end.
Number of inconsistencies found: 1.

Guessed primary partition table:
Primary partition(1)
   type: 131(0x83)(Linux ext2 filesystem)
   size: 984mb #s(2015936) s(63-2015998)
   chs:  (0/1/1)-(1023/15/63)d (0/1/1)-(1999/15/62)r

Primary partition(2)
   type: 007(0x07)(OS/2 HPFS, NTFS, QNX or Advanced UNIX)
   size: 246mb #s(503992) s(2016000-2519991)
   chs:  (1023/15/63)-(1023/15/63)d (2000/0/1)-(2499/15/55)r

Primary partition(3)
   type: 130(0x82)(Linux swap or Solaris/x86)
   size: 246mb #s(503936) s(2520063-3023998)
   chs:  (1023/15/63)-(1023/15/63)d (2500/1/1)-(2999/15/62)r

Primary partition(4)
   type: 005(0x05)(Extended DOS)
   size: 817mb #s(1674288) s(3024000-4698287)
   chs:  (1023/15/63)-(1023/15/63)d (3000/0/1)-(4660/15/63)r

La página man de gpart es de lectura y comprensión imprescindible previos a su uso. Su sección de particiones extendidas es especialmente interesante.

Finalmente, no hace falta decir que la mejor forma de recuperar una tabla de particiones perdida es, como siempre, tener un backup. ¿Y como hacemos un backup de la tabla de particiones? No podría ser más sencillo. Con un dd podemos guardar el MBR del disco que nos interese:

dd if=/dev/hda of=backup-hda.mbr count=1 bs=512

El MBR, como hemos dicho, contiene las particiones primarias y la extendida si existe, pero no las lógicas. Para guardarlas también, y además tener un fichero de texto que describa todas las particiones por si queremos recuperarlas por otros medios, podemos usar el sfdisk:

# sfdisk -d /dev/hda > backup-hda.sf

El fichero resultante tiene un aspecto como éste:

# cat backup-hdb.sf 
# partition table of /dev/hdb
unit: sectors

/dev/hdb1 : start=       63, size=  2015937, Id=83
/dev/hdb2 : start=  2016000, size=   504000, Id= 7
/dev/hdb3 : start=  2520000, size=  1674288, Id= 5
/dev/hdb4 : start=        0, size=        0, Id= 0
/dev/hdb5 : start=  2520063, size=   503937, Id=82
/dev/hdb6 : start=  3024063, size=   503937, Id= b
/dev/hdb7 : start=  3528063, size=   666225, Id=83

Para recuperar el MBR del backup:

dd if=backup-hda.mbr of=/dev/hda

Para recuperar las particiones del backup:

sfdisk /dev/hda < backup-hda.sf

(Partimage: Manual backup partition table)

:wq

Entradas relacionadas

13 Comentarios a “Recuperación de particiones perdidas con gpart”

Trackbacks y pingbacks:

Tema LHYLE09, creado por Vicente Navarro