El sábado pasado recibo un mail de un chango del laburo con subject «ayuuuudaaa urgenteeeeee»[sic]. Me dice que estaba boludeando el viernes a la noche cuando la máquina se quedó primero sin sonido y luego se tildaba. Cuando la quizo reiniciar no arrancó más. «dice algo de disco no booteable...».
El lunes caigo como siempre y me voy a verla. Efectivamente, decía algo de disco no booteable. Booteo con un GRML que tengo en un pendrive y descubro que el disco no tiene particiones.
Pánico.
El tipo está acá haciendo un posdoc en algo astronómico (literalmente) y todo su laburo está ahí dentro. No hay backups, como corresponde, así que me preparo a hacer un rescate de particiones.
En el mismo pendrive tengo un sistema con parted. Booteo con eso y trato de usar el rescue del parted. Naranja. Le pregunto cómo eran las particiones, etc. Me responde que él sólo instaló un Kubuntu por defecto. Por defecto Kubuntu crea una partición swap y una ext3 para / y eso es todo, lo cual hacía mas fácil lo que estaba por venir.
Reninicio en el GRML y con hexdump -C /dev/sda |
more me pongo a ver el contenido del diso a pelo. No es la
primera vez que hago malabares con particiones y MBRs, pero antes
lo hacía con una herramienta que creo que a esta ahora está
discontinuada (El programa se llamaba adecuadamente DiskEdit, de
una empresa que lleva el mismo nobre que un vino y que el apellido
del dueño, cuyo nombre es el mismo que el padre en Family Guy, y
que vienen haciendo Utilities para Windows desde que las hacían
para DOS) y que tenía visores especiales para estos sectores y
también editar FATs y un montón cosas útiles... en el universo
M$.
Primero confirmo que, efectivamente, el primer sector es un MBR
(al menos tiene el signature 0x55aa en los últimos dos
bytes), y toda la tabla
de particiones está vacía, pero que en el segundo sector parece
haber una copia. Agarro papel y lápiz, transcribo lo que parece
haber, pero al final resulta que no sólo tengo la mitad de los
datos, sino que es una partición muy chica.
Entonces me propongo buscar la partición ext3 a mano. Para ello tuve que averiguar cómo es que hace un ext3 para saber que la partición realmente es una ext3 y no cualquier verdura. Sabía que que sería con un magic, pero no tenía ni idea. Instalé las fuentes del 2.6.29 en mi laptop y me puse a mirar el código de ext3. Después de dar bastante vueltas, incluyendo seguir el código que se ejecuta cuando montás un filesystem ext3, donde podemos ver que usa un magic[3] y también la estructura del superblock del ext3, donde vemos que el offset del magic es 0x38.
Entonces el problema de encontrar un ext3 en un disco se reduce
a buscar un 0x53ef (fucking little endian) en la posición 0x38 de
un sector en el disco. Por suerte more tiene para
buscar, así que me siento a buscar toooodas las ocurrencias de
53 ef esperando que la dirección a la derecha termine
con 30 y que sean el 9no y el 10mo byte de la línea
(maldito 0 based).
Unos cuantos next después, tengo mi primer candidato. Pinta muy
bien, porque además lo estaba comparando con el mismo dump pero del
pendrive (que tengo formateado en ext2, y por suerte ext2 y ext3
comparten todas estas estructuras), y además pude ver algo que
tenía toda la pinta de ser un
uuid.
Saco que la dirección del magic es 0x80731038. A
eso le resto los 0x38 y me da que el superblock
empieza en 0x80731000, un lindo número redondito.
Pasado a decimal me dá el byte 2.155.024.384, unos
2GiB desde del comienzo del disco. ¡Pinta muy bien! El swap podría
estar primero, y ser de unos 2GiB.
Arranco un fdisk /dev/sda y al mostrar la tabla
(aún vacía) de particiones me dice que hay 16.065
sectores por cilindro*512 bytes por sector=
8.225.280 bytes por cilindro. Casi todas las distros
(en realidad creo que todas) particionan los discos por
cilindros[1], por lo que si el sector éste está justo al principio
de un cilindro...
Divido 2.155.024.384/8.225.280=...
(suspenso)[2]
262.000124494...
¡Damn! Casi lo tenía... Hmm, ¿y cuánto es lo que sobra?
(262.000124494-262)*8.225.280=... ¡1024!
¿Será que...?
Arranco un strace debugfs -R show_super_stats
/dev/sdb1 (la partición en mi pendrive) y veo que
¡efectivamente hace un seek de 1024 bytes dentro de la
partición para leer el superblock!
This is it. Con el 262 en la cabeza arranco fdisk
/dev/sda y creo dos particiones: un swap en los cilindros
1-261 y una linux del cilindro 262 en adelante. Guardo, salgo,
cruzo los dedos y corro un debugfs -R show_super_stats
/dev/sda1. ¡Fail! ¿Qué pasa? Reinicio y pruebo de nuevo, no
vaya a ser que el kernel no haya leído bien la nueva tabla de
particiones. Tampoco. ¿WTF?
Ah, duh, es sda2. Ok, debugfs -R
show_super_stats /dev/sda2... ¡Anda, el muy HDP anda! No lo
puedo creer. Me la juego: fsck -n /dev/sda2.
«Filesystem is clean» Damn, vamos de nuevo: fsck -n -f
/dev/sda2...
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/dev/sda2 sarasa sarasa...
¡Intacto! Pero el MBR no tiene un grub, así que hago el habitual proceso de reinstalar Grub, reinicio...
Bootea perfecto, y termina en un hermoso login. Satisfecho, me doy unas palmaditas en la espalda, cargo mis cosas y comienzo el fin de semana.
sysadmin rescue
[1] ... desperdiciando unos 8MiB entre el MBR y la primera partición
[2] Los perspicaces se darán cuenta al toque que eso no puede ni a ganchos dar entero.
[3] Son muy graciosos los magics de Reiser. Parece haber iniciado una moda que ahora usan los AdOlEsCeNtEs.