Recovering a RAID 0 array with Linux and Python!

Background of my problem

A few days ago my Dell XPS 720 decided to die on me. When I push the power button it turns on for about 12 second and then turns off. After much debate, I bought a new power supply for it (non-standard of course [24pin AND 20pin power connectors]). Today I received the power supply and low-and-behold that wasn’t the problem. Now I need to buy either a motherboard or a new CPU (the existing one is a Core 2 Quad Extreme 3.0). I decided that buying from Dell was a bad choice and I’ll just build myself a Phenom II system. Meanwhile, the XPS 720 shipped with 2x 120GB 10k Raptors in a RAID-0 using the sub-par onboard SATA RAID controller. I would just love to get my data off the system, but I can’t get it up and running and I’m not going to sink anymore money into it. I decided to figure out exactly how the data was stored on the array members and try to de-interlace it directly into a raw image that I could then mount via loopback device in Linux and copy all my data back out :) It sounds easy, huh? I found this GREAT little python code snippet that does the heavy lifting for me - thanks Sim

Here’s my lightly-altered version of the deinterlacer which includes a progress indicator:

#!/usr/bin/python
#
# raid0_deinterlace.py
#
# INTENT = This is a script for deinterlacing two raw dd images
#	 or drives from a RAID-0 and combine them into a single
#	 image file
#
#		  This is strictly experimental.
#
#	Original Script By: Simon A. Ruiz; Thursday, May 1, 2008
#
#	Modified By: Steve Kamerman; Thursday, May 28, 2009
#		Changes: Added status indicator so you can estimate ETA

import datetime

inputFiles = [open("/dev/sdb","rb"),open("/dev/sdc","rb")]
outputFile = open("output","wb")
chunkSize = 65536

# And, so as not to have to figure this out every time through the loop...
numFiles = len(inputFiles)

i = 0
a = 0
gb = 0
while True:
	if a == 16384:
		gb += 1
		print 'Copied', gb, 'GB of data', datetime.datetime.now()
		a = 0
	nextChunk = inputFiles[i%numFiles].read(chunkSize)
	if not nextChunk:
		print 'Done! No more data.'
		break
	outputFile.write(nextChunk)
	i += 1
	a += 1

outputFile.close()
for file in inputFiles:
	file.close()

stevekamerman

COO @scientiamobile