124 lines · 2.6 KB · C
RawDownload
/* -*- linux-c -*- ------------------------------------------------------- * * *   Copyright 2002-2007 H. Peter Anvin - All Rights Reserved * *   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. * * ----------------------------------------------------------------------- */ /* * raid6test.c * * Test RAID-6 recovery with various algorithms */ #include <stdlib.h>#include <stdio.h>#include <string.h>#include <linux/raid/pq.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]; static void makedata(void){	int i, j; 	for (i = 0; i < NDISKS; i++) {		for (j = 0; j < PAGE_SIZE; j++)			data[i][j] = rand(); 		dataptrs[i] = data[i];	}} 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;} int main(int argc, char *argv[]){	const struct raid6_calls *const *algo;	int i, j;	int err = 0; 	makedata(); 	for (algo = raid6_algos; *algo; algo++) {		if (!(*algo)->valid || (*algo)->valid()) {			raid6_call = **algo; 			/* Nuke syndromes */			memset(data[NDISKS-2], 0xee, 2*PAGE_SIZE); 			/* Generate assumed good syndrome */			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);		}		printf("\n");	} 	printf("\n");	/* Pick the best algorithm test */	raid6_select_algo(); 	if (err)		printf("\n*** ERRORS FOUND ***\n"); 	return err;}