#!/usr/bin/env python # Destripe 0.1 # Copyright 2009 Vasili Revelas - vasili (at the domain) techcollective (dot) com # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . import sys import signal class Destriper(object): def __init__(self, chunk_size, device1, device2, outfile): self.bytes_copied = 0L self.chunk_size = chunk_size self.device1 = device1 self.device2 = device2 self.outfile = outfile def destripe(self): file1 = open(self.device1, 'rb') file2 = open(self.device2, 'rb') output_file = open(self.outfile, 'wb') amount_written = self.chunk_size * 2 while True: chunk1 = file1.read(chunk_size) if not chunk1: break chunk2 = file2.read(chunk_size) output_file.write(chunk1) output_file.write(chunk2) self.bytes_copied += amount_written file1.close() file2.close() output_file.close() def print_progress(self, *args): print str(self.bytes_copied / (1024*1024)) + "MB copied to " + self.outfile def usage(): print "Usage: %s chunk_size disk1 disk2 output_file" % sys.argv[0] print "Use -h or --help for help." def help(): print "chunk_size : The RAID 0 stripe size in bytes. Can be used with a k suffix for kilobytes (1024 bytes)" print "disk1 : The first disk in the array." print "disk2 : The second disk in the array." print "output_file : The file to write the reassembled image to. Can also be a block device." print "" print "A progress message is printed when the program receives a USR1 signal." if __name__ == '__main__': if ("-h" in sys.argv) or ("--help" in sys.argv): usage() help() sys.exit(0) if len(sys.argv) > 5: print "Error: Too many arguments." usage() sys.exit(1) try: chunk_size = sys.argv[1] device1 = sys.argv[2] device2 = sys.argv[3] outfile = sys.argv[4] except IndexError: print "Error: Not enough arguments." usage() sys.exit(1) multiplier = 1 if chunk_size[-1].lower() == "k": multiplier = 1024 chunk_size = chunk_size[:-1] try: chunk_size = int(chunk_size) * multiplier except ValueError: print "Error: chunk_size must be an integer with an optional 'k' suffix. Use -h or --help for help." usage() sys.exit(1) destriper = Destriper(chunk_size, device1, device2, outfile) signal.signal(signal.SIGUSR1, destriper.print_progress) try: destriper.destripe() except KeyboardInterrupt: print "\rGoodbye." sys.exit(1)