Note: this is a translation of an old post. I decided to translate it because now I'm looking for a SysAdmin position (tell your friends!) and I would like this post to show how I work.

Last Saturday I received an email from one of the guys from work with the subject «urgennnnnnnnt: heeeeeeeeeelp»[sic]. He says he was idling on Friday night when his machine stopped emiting sound via the soundcard and then it behaved erratically. When he tried rebooting it, it didn't boot anymore. «It says something about disk not bootable...».

Monday morning I go to work and go to see the machine. Precisely, it said something about «disk not bootable». I boot with a USB key with GRML and I find that the disk has no partitions.

Panic.

The guy is doing a PostDoc in something astronomical (literally) and all his work is in that machine. No backups, as usual, so I prepare myself to rescue the partitions.

In that same USB key I have a system with parted. I boot with it and I try using parted's rescue tool. Nothing. I ask the guy how the disk was partitioned, etc. He tells me that he only installed Kubuntu clicking 'Next'. Kubuntu by default creates a swap partition and an ext3 partition for / and that's it, which made what was coming relatively easy.

I reboot in GRML and I use hexdump -C /dev/sda | more to see the disk's content. This is not the first time that I juggle with partitions and MBRs, but last time I did it, I used a tool that is now discontinued (the tool was called DiskEdit, included in The Norton Utilities), which had special edit modes for MBRs, FATs, and a lot of useful things... in MS universe.

First I confirm that, yes, the first sector is a MBR (at least it has the 0x55aa signature at the end), and that the whole partition table is empty, but in the second sector of the disk there seems to be a copy. I take pen and paper, write down what I found, but it turns out not only I have half the data, the partition I thought I found was too small.

So I decide to look for the partition by hand. To do that I needed to find out first how does the ext3 kernel code know wether a partition is ext3 or not. I knew it would be some kind of magic signature, but I had no idea which. So I installed the sources for 2.6.29 in my laptop and started to look at ext3's code. After going around a lot, including reading the code that is excuted when you mount a filesystem of type ext3, where we can see that it uses a magic signature[3] and the structure of the ext3 superblock, where we can see the magic's offset is 0x38.

So the problem of finding an ext3 partition is reduced to the problem of finding 0x53ef (damn little endian) at a sector's offset 0x38 in the disk. Luckily more has a find tool, so I sit down to search every occurrence of 53 ef, hoping that the address at the left ends in 30 and that they would be the 9th and 10th bytes in the line (damn 0 based offsets).

A few 'next' after, I get my first candidate. It looks good, because I was also comparing my findings with a similar dump from my USB key (which I have formatted as ext2, and luckily ext2 and ext3 share those structures), and also I spot something that looks like a uuid.

This candidate's address is 0x80731038. I substract 0x38 and I get the address 0x80731000, a nice round number for a superblock. Converted to decimal that's 2.155.024.384, some 2GiB from the disk's begginning. Looks really good! The swap partition could be before the root one, and could have that size.

I use fdisk /dev/sda to see the (still empty) partition table. It says there's 16.065 sectors per cylinder, times 512 bytes per sector, equals 8.225.280 bytes per cylinder. Almost all distros (actually I think all of them) partition disks at cylinder boundaries[1], so if the sector I found is right at the beginning of a cylinder...

I divide 2.155.024.384/8.225.280=...

(suspense pause)[2]

262.000124494...

¡Damn! I almost had it... Hmm, how much is the factional part? (262.000124494-262)*8.225.280=... ¡1024! ¿Is it that...?

I run strace debugfs -R show_super_stats /dev/sdb1 (the partition in my USB key) and I see that it actually seeks 1024 bytes within the partition for reading the superblock!

This is it. With 262 in my head, I fire fdisk /dev/sda and I create two partitions: swap in cylinders 1-261 and root from cylinder 262 till the end. I save, cross my fingers and I run debugfs -R show_super_stats /dev/sda1. It fails! What's wrong? I reboot and I try again, just in case the kernel did not re-read correctly the partition table. It fails again. WTF?

Ah, duh, it's sda2, where do I have my head... Ok, debugfs -R show_super_stats /dev/sda2... it works, the sonofabitch works! I can't believe it. I risk it: fsck -n /dev/sda2. «Filesystem is clean». Damn, I try harder: 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 etc etc...

It's fine! But the MBR doesn't have GURB installed, so I do the usual GRUB reinstall process, I reboot...

It boots like nothing has happened, and it finishes in a beautiful login. Satisifed, I pat myself in the back, pack my things and I start my weekend.

sysadmin rescue


[1] ... wasting some 8MiB between the MBR and the first partition.

[2] The sharp ones reading this will notice that this can not give an integer by no means.

[3] Reiser magics are funny. Looks like he started the fad that now AdOlEsCeNtS use.

Posted Thu 07 Apr 2011 11:46:15 PM CEST Tags: rescue

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.

Posted Wed 27 Jan 2010 11:55:55 PM CET Tags: rescue