Restoring a killed partition table

While playing around with my Raspberry PI, I have managed to destroy my partition table of my notebook – ouch!

What happened: I was building a new boot image for my PI on my desktop box as it has much more power than my notebook. To copy the image to the SD card, I want to use my notebook, because my workstation has no SD card slot. As both boxes are using linux, I was going to try nbd – the Network Block Device, which allows to provide a block device over the network.

While I was fighting with the poorly documented configuration syntax, I needed a test device. As it was 4 am in the morning I useded /dev/sda instead of something like /dev/zero – what a bad idea.

After I got the config working and the NBD server running I started to copy the image – without changing the exported device from /dev/sda to the SD card.

Around a trillionth second after I started the copy process, I realized what I have done – I just killed my partition table.
Now I had put my system in a state which will destroy itself on the next reboot. But as long as the system was not shut down it was still usable and I had some time to do backups and try to rescue my system.

The good thing is, my system was still running and nothing had triggered a reload of the partition table. As /proc/partitions shows, the kernel still knew the old partition table. The sys filesystem had some additional details about the loaded partition table:

grep . /sys/block/sda/sda*/{start,size}

That’s all I had needed to restore the partition table. I have used parted as it allows me to enter the complete partition definition at once.
As the command above only showed the start sector and the size, I had to calculate the end sector required by parted:

end = start + size - 1

As I had a extended partition, I had to recalculate the boundaries for that partition, too. The problem with the extended partitions was, the kernel had no clue about these partitions. The solution for this was to use the start of the first and the end of the last logical partition as boundary for the extended one.

After I had calculated all the values needed, I used parted to recreate the partitions:

mkpart primary ${START}s ${END}s

whereas ${START} and ${END} must be replaced with the calculated values. The suffix s tells parted to use sectors as unit.

The last step was to recreate the boot loader – grub in my case:

grub-install /dev/sda

The backup has finished and the partition table was restored (hopefully) correctly – it was time to reboot.

Unexpectedly my system booted without any problems. The filesystem checks completed without any error and any thing worked as expected.

Leave a Reply