Raid0 Recovery Scenario - Part 1

Situation

Well, just got 2 harddisks in for recovery. The PC manufacturer apparently decided to have 2 harddisks in a RAID0, but now since one of the harddisks failed, there was no way to simply get the data back. As you might know, RAID0 sucks! If you only have one drive working, you might be able to find some headers of a JPG for example, but when you try to view it, you'll notice that only parts of the image are intact. This is because of the striping, which stores a block (usually sth like 64K, 128K) on disk0 and the next block is on disk1. So one disk is useless for sure!

fixing the harddrives

First of all I wanted to get an image (using ddrescue) of both disks. Disk0 went through smoothly, so I had the image within a blink of an eye.. Disk1 was a bit more of a hassle, it initially didn't want to initialize properly (clickin').. Since I've had two identical harddrives (in terms of firmware, model etc.) I've simply swapped the ECB among them, and voila, disk1 was also spinning up and spitting out the data! :-D nice! So let's proceed with the 2 disk-images.

rebuilding the raid0

Now that I've got the disks imaged, I can start to first rebuild the RAID0 part. My plan was to get rid of the RAID0, which was 2x 500GB, and rebuild it to a single drive with 1TB.
First looking for something pre-built software to do this part, I started using 'pyraid', which is able to recover RAID0 and RAID5. Soon after, I've noted that the performance is not what I expected, so according to my calculations, it would have taken several days to 'rebuild' the drive.
Bash is my friend, it was up to me to quickly put a few lines together to get this job done.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
#!/bin/bash
OUTPUT=/dev/sdc ## the target device
BLOCKSIZE=128k ## or stripesize, however you call it
echo -n >mass-dd.sh
for i in $(seq 0 3815553); do

    INPUT=/dev/loop0 ## raid0 disk1
    INPUTsector=$i
    OUTPUTsector=$(($INPUTsector*2))
    echo "sudo dd if=$INPUT bs=$BLOCKSIZE skip=$i seek=$OUTPUTsector count=1 of=$OUTPUT conv=notrunc 2>/dev/null" >>mass-dd.sh

    INPUT=/dev/loop1 ## raid0 disk2
    INPUTsector=$i
    OUTPUTsector=$(($INPUTsector*2+1))
    echo "sudo dd if=$INPUT bs=$BLOCKSIZE skip=$i seek=$OUTPUTsector count=1 of=$OUTPUT conv=notrunc 2>/dev/null" >>mass-dd.sh

done

This script is just a quick helper, which will write to a file called 'mass-dd.sh', which then contains all the dd calls to rebuild the raid. Afterwards use one of these lines to start rebuilding:

## start rebuilding
$ cat mass-dd.sh | sh
## resume rebuilding at a known point
$ grep -A 500000000 'skip=3751208' mass-dd.sh | sh

## start rebuilding with several threads, might give a performance improvement, can't say.. Needs GNU Parallel installed
$ cat mass-dd.sh | parallel -k -j 4 sh {}
$ grep -A 500000000 'skip=3751208' mass-dd.sh | parallel -k -j 4 sh {}

## only read from one input-file at a time, might increase the performance (can also be run using GNU Parallel)
$ grep /dev/loop0 mass.sh | sh
$ grep /dev/loop1 mass.sh | sh

So, that's it for part one, haven't finished part two yet. Next one will have the details about fixing the logical part with the partition-table and filesystem.

Cheers,
Raphi