Hard Disk Recover 2

From Freehackers
Revision as of 09:06, 1 August 2007 by Orzel (talk | contribs) (New page: Following the previous article, here is yet another hard disk recovery. The problem here, was '''not''' the bad sectors (there were few, luckily), but the tools. C...)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Following the previous article, here is yet another hard disk recovery.

The problem here, was not the bad sectors (there were few, luckily), but the tools. Contrary to what people usually thinks, some unix tools are very bad. Let me show you.

So, for some reason (electrical shock) i have a hard disk which starts to have bad blocks. The server is almost freezing each time linux tries to access this hard disk. I remove it, and install it on a dedicated computer with its own system disk, a brand new hard disk for the rescued data, and the bad disk. I put the bad disk on its very own ide cable, alone.

fdisk sucks

First thing i do is

 #fdisk  /dev/hdc -l
 
 Disk /dev/hdc: 163.9 GB, 163928604672 bytes
 255 heads, 63 sectors/track, 19929 cylinders
 Units = cylinders of 16065 * 512 = 8225280 bytes
 
    Device Boot      Start         End      Blocks   Id  System
 /dev/hdc1   *           1        1217     9775521   fd  Linux raid autodetect
 /dev/hdc2            1218        3650    19543072+  fd  Linux raid autodetect
 /dev/hdc3            3651        3687      297202+  82  Linux swap / Solaris
 /dev/hdc4            3688       19929   130463865    5  Extended
 /dev/hdc5            3688        9767    48837568+  fd  Linux raid autodetect
 /dev/hdc6            9768       19929    81626233+  83  Linux

I dont care about the swap/raid partition. The only one i'm interested in is hdc6. Funnily, the kernel can't find it:

 # ls /dev/hdc*
 /dev/hdc  /dev/hdc1  /dev/hdc2  /dev/hdc3  /dev/hdc4  /dev/hdc5

You can ask the kernel to re-read the partition table. Several tools (partprobe, hdparm) allow to do that, for example:

 blockdev --rereadpt /dev/hdc

But in this case, this doesn't work.

Ok, so now the problem is to know where in the hard disk the partition starts. Byte-wise, that is. The problem is that tools do not agree on that. The previous fdisk for example, says hdc6 starts on cylinder 9768, the size of a cylinder being 8225280, which would mean 9768*8225280 = 80344535040.

sfdisk -uC /dev/hdc (the -uC displays cylinder number) says:

 /dev/hdc6       9767+  19928   10162-  81626233+  83  Linux

They dont agree on the number of cylinder! (but they do agree on the size of cylinder..)

So this one gives the start of hdc6 on : 9767 * 8225280 = 80336309760.

sfdisk can also output in sectors

 /dev/hdc6     156906918 320159384  163252467  83  Linux

or blocks :

 /dev/hdc6     78453459  160079692-  81626233+  83  Linux

The size of a block is 512, the size of a block is 1024, which gives the same start for hdc6 : 78453459 * 1024 = 80336342016 = 156906918 * 512. This is the one I will use.


dd_rescueing

Based on Hard disk recovery tools, i decided (this time) to use dd_rescue.

 dd_rescue -v  -s 80336342016 /dev/hdc  /mnt/store/rescue -l ~/rescue.errors -o ~/rescue.badblock

After few hours (i went to sleep meanwhile), it finishes. The result is not that bad:

 dd_rescue: (info): /dev/hdc (160086528.0k): EOF
 Summary for /dev/hdc -> /mnt/store/rescue_music:
 dd_rescue: (info): ipos: 160086528.0k, opos: 160086528.0k, xferd:  81633069.0k
                    errs:    650, errxfer:       325.0k, succxfer:  81632744.0k
              +curr.rate:     6646kB/s, avg.rate:     2781kB/s, avg.load: -6.9%

Only 325k of bad block, which is roughly 0.0004 % :-).

Reiserfs'ing

As i didn't specify anything for the output file, dd_rescue did a copy of /dev/hdc6, of the same size:

 #ls -l 
 -rw-r----- 1 root root 163928604672 Aug  1 06:12 rescue

The whole beginning was not copied though. The actual size on the hard disk is only half of this :

 du -shx rescue
 79G     rescue

Now i need to use reiserfsck. For this, i would like to 1) check the exact start address for the hdc6 partion, 2) copy the relevant data to another file.

I first tried to use hexdump.

 hexdump  -s 80336342016  rescue_music
 7fffffff 0000 0000 0000 0000 0000 0000 0000 0000
 *

AHA, you see ? hexdump can't handle index more than 7fffffff. What a shame. After a while a figured out there's another tool, called 'od'. od is great : it can handle such long index. But in mostly knows about octal. How odd. For example i never managed to make it output the index number in anything else than octal.

The partition on hdc6 was using the reiserfs filesystem. The very beginning of a reiserfs filesystem is made of 64k of "nothing" and then a header. Here is an example on a real, working, partition.

 od  -x /dev/sdb1 |less
 0000000 0000 0000 0000 0000 0000 0000 0000 0000
 *
 0200000 1470 02e9 ee8a 02e8 2013 0000 0012 0000
 0200020 0000 0000 2000 0000 0400 0000 39a4 13fb
 0200040 0384 0000 001e 0000 0000 0000 1000 03cc
 0200060 0002 0002 6552 7349 7245 4632 0073 0000

(the -x is for hex output, but only display the content in hex, not the index) The "6552 7349 7245 4632" stands for "ReIsEr2F", the start of the magic signature of the header, in ascii little endian.

Doing the same on my rescue file, i find the beginning of the partition. I search (using less) for the string "6552 7349 7245 4632" and finds this :

 od -x -j 80336342016  rescue |less
 ...
 1126433176000 6110 0137 e0df 00ba 1b56 00a5 0012 0000
 1126433176020 0000 0000 2000 0000 0400 0000 e490 2559
 1126433176040 0384 0000 001e 0000 0000 0000 1000 03cc
 1126433176060 0002 0002 6552 7349 7245 4632 0073 0000

This gives the start of the header on (dec)80336452608 = (octal)1126433176000, and hence, the start of the partition on : (octal) 01126433176000 - 0200000 = 01126432776000 In decimal : 80336387072. This is not what we had previously estimated : we did an error of80336387072 - 80336342016 = 45056 = 0xB000. Strange....

So now, i extract the data for the partition on another file :

 dd_rescue  -v -s 80336387072 -S 0 rescue  rescue.partition6

It takes some time.