2005-04-17 02:20:36 +04:00
/* -*- linux-c -*- ------------------------------------------------------- *
*
2008-02-06 12:39:48 +03:00
* Copyright 2002 - 2007 H . Peter Anvin - All Rights Reserved
2005-04-17 02:20:36 +04:00
*
2008-02-06 12:39:48 +03:00
* This file is part of the Linux kernel , and is made available under
* the terms of the GNU General Public License version 2 or ( at your
* option ) any later version ; incorporated herein by reference .
2005-04-17 02:20:36 +04:00
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/*
* raid6test . c
*
* Test RAID - 6 recovery with various algorithms
*/
# include <stdlib.h>
# include <stdio.h>
# include <string.h>
# include "raid6.h"
# define NDISKS 16 /* Including P and Q */
const char raid6_empty_zero_page [ PAGE_SIZE ] __attribute__ ( ( aligned ( 256 ) ) ) ;
struct raid6_calls raid6_call ;
char * dataptrs [ NDISKS ] ;
char data [ NDISKS ] [ PAGE_SIZE ] ;
char recovi [ PAGE_SIZE ] , recovj [ PAGE_SIZE ] ;
2008-02-06 12:39:48 +03:00
static void makedata ( void )
2005-04-17 02:20:36 +04:00
{
int i , j ;
2008-02-06 12:39:48 +03:00
for ( i = 0 ; i < NDISKS ; i + + ) {
for ( j = 0 ; j < PAGE_SIZE ; j + + )
2005-04-17 02:20:36 +04:00
data [ i ] [ j ] = rand ( ) ;
2008-02-06 12:39:48 +03:00
2005-04-17 02:20:36 +04:00
dataptrs [ i ] = data [ i ] ;
}
}
2008-02-06 12:39:48 +03:00
static char disk_type ( int d )
{
switch ( d ) {
case NDISKS - 2 :
return ' P ' ;
case NDISKS - 1 :
return ' Q ' ;
default :
return ' D ' ;
}
}
static int test_disks ( int i , int j )
{
int erra , errb ;
memset ( recovi , 0xf0 , PAGE_SIZE ) ;
memset ( recovj , 0xba , PAGE_SIZE ) ;
dataptrs [ i ] = recovi ;
dataptrs [ j ] = recovj ;
raid6_dual_recov ( NDISKS , PAGE_SIZE , i , j , ( void * * ) & dataptrs ) ;
erra = memcmp ( data [ i ] , recovi , PAGE_SIZE ) ;
errb = memcmp ( data [ j ] , recovj , PAGE_SIZE ) ;
if ( i < NDISKS - 2 & & j = = NDISKS - 1 ) {
/* We don't implement the DQ failure scenario, since it's
equivalent to a RAID - 5 failure ( XOR , then recompute Q ) */
erra = errb = 0 ;
} else {
printf ( " algo=%-8s faila=%3d(%c) failb=%3d(%c) %s \n " ,
raid6_call . name ,
i , disk_type ( i ) ,
j , disk_type ( j ) ,
( ! erra & & ! errb ) ? " OK " :
! erra ? " ERRB " :
! errb ? " ERRA " : " ERRAB " ) ;
}
dataptrs [ i ] = data [ i ] ;
dataptrs [ j ] = data [ j ] ;
return erra | | errb ;
}
2005-04-17 02:20:36 +04:00
int main ( int argc , char * argv [ ] )
{
2008-02-06 12:39:48 +03:00
const struct raid6_calls * const * algo ;
2005-04-17 02:20:36 +04:00
int i , j ;
2008-02-06 12:39:48 +03:00
int err = 0 ;
2005-04-17 02:20:36 +04:00
makedata ( ) ;
2008-02-06 12:39:48 +03:00
for ( algo = raid6_algos ; * algo ; algo + + ) {
if ( ! ( * algo ) - > valid | | ( * algo ) - > valid ( ) ) {
2005-04-17 02:20:36 +04:00
raid6_call = * * algo ;
/* Nuke syndromes */
memset ( data [ NDISKS - 2 ] , 0xee , 2 * PAGE_SIZE ) ;
/* Generate assumed good syndrome */
2008-02-06 12:39:48 +03:00
raid6_call . gen_syndrome ( NDISKS , PAGE_SIZE ,
( void * * ) & dataptrs ) ;
for ( i = 0 ; i < NDISKS - 1 ; i + + )
for ( j = i + 1 ; j < NDISKS ; j + + )
err + = test_disks ( i , j ) ;
2005-04-17 02:20:36 +04:00
}
printf ( " \n " ) ;
}
printf ( " \n " ) ;
/* Pick the best algorithm test */
raid6_select_algo ( ) ;
2008-02-06 12:39:48 +03:00
if ( err )
printf ( " \n *** ERRORS FOUND *** \n " ) ;
return err ;
2005-04-17 02:20:36 +04:00
}