How to read the in-memory (kernel) partition table of /dev/sda?
Yes, you can do this with the /sys
filesystem.
/sys
is a fake filesystem dynamically generated by the kernel & kernel drivers.
In this specific case you can go to /sys/block/sda
and you will see a directory for each partition on the drive. There are 2 specific files in those folders you need, start
and size
. start
contains the offset from the beginning of the drive, and size
is the size of the partition. Just delete the partitions and recreate them with the exact same starts and sizes as found in /sys
.
For example this is what my drive looks like:
Device Boot Start End Blocks Id System
/dev/sda1 * 2048 133119 65536 83 Linux
/dev/sda2 * 133120 134340607 67103744 7 HPFS/NTFS/exFAT
/dev/sda3 134340608 974675967 420167680 8e Linux LVM
/dev/sda4 974675968 976773167 1048600 82 Linux swap / Solaris
And this is what I have in /sys/block/sda
:
sda1/
start: 2048
size: 131072
sda2/
start: 133120
size: 134207488
sda3/
start: 134340608
size: 840335360
sda4/
start: 974675968
size: 2097200
I have tested this to verify information is accurate after modifying the partition table on a running system
I made a script to help solve this problem, with NO WARRANTY. (but I tested on my virtual machine)
Running the following script, with damaged HD at first parameter, as in:
user@host:~$ ./repart.sh sda
Content of repart.sh
:
#!/bin/bash
echo "unit: sectors"
for i in /sys/block/$1/$1?/; do
printf '/dev/%s : start=%d, size=%d, type=XX\n' "$(basename $i)" "$(<$i/start)" "$(<$i/size)"
done
The output is a sfdisk format. But caution, this file has to be modified to be used. At the extended partition type=5, increase the size, using all logical space plus space between start of extended and start of first logical partition.
unit: sectors
/dev/sda1 : start=63, size=2040192, type=XX
/dev/sda2 : start=2040255, size=20482875, type=XX
/dev/sda3 : start=22523130, size=19197675, type=XX
/dev/sda4 : start=41720805, size=2, type=XX
/dev/sda5 : start=41720868, size=208782, type=XX
You have to change the type, from XX to number of partition type. Put the bootable partition at first line.
unit: sectors
/dev/sda1 : start=63, size=2040192, type=83, bootable
/dev/sda2 : start=2040255, size=20482875, type=83
/dev/sda3 : start=22523130, size=19197675, type=fd
/dev/sda4 : start=41720805, size=208845, type=5
/dev/sda5 : start=41720868, size=208782, type=82
Apply this changes
cat repart.sfdisk | sfdisk -f /dev/sda
Reread partition tables
partprobe
/sbin/blockdev --rereadpt
Reinstall grub
grub-install /dev/sda
Have you tried testdisk? It can scan the disk and recover lost partition tables, even after you've rebooted.
It's available pre-packaged for Debian and presumably for Ubuntu too. Probably other distros.
If you're booting a gparted CD it's probably worth checking to see if it's pre-installed on that.