RAID5重组C代码

/****************************************************************************\
*                                                                            *
*  raidrec v0.6 - Manually try to put a RAID5 array back together.           *
*                                                                            *
*  I wrote this program when, after a few disk failures, md refused to put   *
*  my damaged RAID array back together itself, or tried to resync it incor-  *
*  rectly, further damaging my partitions.                                   *
*                                                                            *
*  Instead of figuring out how to do this, I decided to just write a small   *
*  program that does all the required XOR-ing.                               *
*                                                                            *
*  Note that I wrote this tool to scratch *my* specific itch, it's possible  *
*  that your RAID5 array was built differently. Mine had a stripe size of    *
*  64K. If yours is different, try changing the #define down here. Also, my  *
*  array is left-symmetric so if yours isn't, this tool is going to expect   *
*  the checksum at the wrong place. I haven't made this configurable. But    *
*  since AFAIK left-symmetric is the default setup, you may be lucky. It     *
*  may also work with some hardware RAID disks, depending on the setup.      *
*                                                                            *
*  Usage is very simple: Run the tool, pass it the partitions/images you're  *
*  trying to recover, and the reconstructed image will be written to std-    *
*  out. If one of the images is missing or corrupted, pass an empty string   *
*  instead. Its data will then be reconstructed.                             *
*                                                                            *
*  Example:                                                                  *
*  root@txt:/mnt/toscadisks# /root/raidrec sda2 '' sdc2 > md2                *
*                                                                            *
*  If you're impatient and want some kind of progress indicator, you can     *
*  pipe stuff through pv: http://www.ivarch.com/programs/pv.shtml            *
*                                                                            *
*  Use this tool at your own risk. I can't guarantee that it will work, but  *
*  definitely did for me. Obviously, don't use it on your partitions direc-  *
*  tly, but on block-by-block copies of them. If you have any questions,     *
*  feel free to e-mail me, but I can't guarantee a quick response, sorry.    *
*  If the program actually helped you, I'd also love to hear about it!       *
*                                                                            *
*  But please, no questions like "how do I compile this" or anything like    *
*  that. If you have to ask that, you'll be better off sending your disks    *
*  to a professional recovery company as soon as possible. Doing something   *
*  wrong here could only get you in more trouble.                            *
*                                                                            *
*  Good luck!                                                                *
*                                                                            *
*  Copyright 2009 Wilmer van der Gaast. <wilmer@gaast.net>                   *
*  Licensed under the GPLv2.                                                 *
*                                                                            *
\****************************************************************************/

#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAXCOLS 5
#define STRIPESIZE 0x10000

char *getblocks( int ncols, char **istr, int xor_col );

int main( int argc, char *argv[] )
{
        int ifd[MAXCOLS];
        char **istr;
        int i, n, ncols;
        
        ncols = argc - 1;
        if( ncols > MAXCOLS || ncols < 3 )
        {
                fprintf( stderr, "Invalid number of columns.\n" );
                return 1;
        }
        
        n = 0;
        istr = malloc( sizeof( char* ) * ncols );
        for( i = 0; i < ncols; i ++ )
        {
                if( strcmp( argv[i+1], "" ) != 0 )
                {
                        ifd[i] = open( argv[i+1], O_RDONLY );
                        if( ifd[i] == -1 )
                        {
                                perror( "open" );
                                return 1;
                        }
                        istr[i] = malloc( STRIPESIZE );
                }
                else
                {
                        if( ( n ++ ) > 0 )
                        {
                                fprintf( stderr, "More than one missing image.\n" );
                                return 1;
                        }
                        
                        ifd[i] = -1;
                        istr[i] = NULL;
                }
        }
        
        while( 1 )
        {
                static int xor_col = 0;
                
                xor_col = ( xor_col + ncols - 1 ) % ncols;
                
                for( i = 0; i < ncols; i ++ )
                {
                        if( istr[i] == NULL )
                                continue;
                        
                        if( ( n = read( ifd[i], istr[i], STRIPESIZE ) ) != STRIPESIZE )
                        {
                                if( n == 0 )
                                {
                                        return 0;
                                }
                                else
                                {
                                        perror( "read" );
                                        return 1;
                                }
                        }
                }
                write( 1, getblocks( ncols, istr, xor_col ), ( ncols - 1 ) * STRIPESIZE );
        }
}

char *getblocks( int ncols, char **istr, int xor_col )
{
        static char ret[(MAXCOLS-1)*STRIPESIZE], *s;
        int cur_col;
        int i;
        
        cur_col = ( xor_col + 1 ) % ncols;
        s = ret;
        
        for( i = 0; i < ( ncols - 1 ); i ++ )
        {
                if( istr[cur_col] )
                {
                        memcpy( s, istr[cur_col], STRIPESIZE );
                }
                else
                {
                        int j;
                        
                        memset( s, 0, STRIPESIZE );
                        
                        for( j = 0; j < ( ncols - 1 ); j ++ )
                        {
                                long *ip, *op;
                                
                                cur_col = ( cur_col + 1 ) % ncols;
                                ip = (long*) istr[cur_col];
                                op = (long*) s;
                                
                                while( op < (long*) ( s + STRIPESIZE ) )
                                {
                                        *op ^= *ip;
                                        ip ++;
                                        op ++;
                                }
                        }
                        cur_col = ( cur_col + 1 ) % ncols;
                }
                s += STRIPESIZE;
                cur_col = ( cur_col + 1 ) % ncols;
        }
        
        return ret;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值