/*
* Copyright (C) 2011 Andrea Mazzoleni
*
* 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 .
*/
#include "portable.h"
#include "snapraid.h"
#include "util.h"
#include "raid.h"
#include "cpu.h"
#include "elem.h"
#include "state.h"
#include "combos.h"
struct hash_test_vector {
const char* data;
int len;
unsigned char digest[HASH_SIZE];
};
/**
* Test vectors for MurmorHash3_x86_128
*/
static struct hash_test_vector TEST_MURMUR3[] = {
#include "murmur3test.c"
{ 0, 0, { 0 } }
};
/**
* Test vectors for SpookyHash_128
*/
static struct hash_test_vector TEST_SPOOKY2[] = {
#include "spooky2test.c"
{ 0, 0, { 0 } }
};
static void recovtest(int diskmax, unsigned block_size)
{
void* buffer_alloc;
unsigned char** buffer;
unsigned char** data;
unsigned char** parity;
unsigned char** test;
unsigned char* data_save[LEV_MAX];
unsigned char* parity_save[LEV_MAX];
unsigned char* zero;
unsigned char* waste;
unsigned buffermax;
int d[LEV_MAX];
int i;
unsigned j;
buffermax = diskmax + LEV_MAX * 2 + 2;
buffer = malloc_nofail_vector_align(buffermax, block_size, &buffer_alloc);
data = buffer;
parity = buffer + diskmax;
test = buffer + diskmax + LEV_MAX;
for(i=0;i=0;++i) {
/* set */
for(j=0;j<6;++j) {
/* remove the missing data */
data_save[j] = data[d[j]];
data[d[j]] = test[j];
/* set the parity to use */
parity[combo[5][i][j]] = parity_save[combo[5][i][j]];
}
/* recover */
raid_recov(6, d, combo[5][i], buffer, diskmax, zero, block_size);
/* check */
for(j=0;j<6;++j) {
if (memcmp(test[j], data_save[j], block_size) != 0) {
fprintf(stderr, "Failed RAID test\n");
exit(EXIT_FAILURE);
}
}
/* restore */
for(j=0;j<6;++j) {
/* restore the data */
data[d[j]] = data_save[j];
/* restore the parity */
parity[combo[5][i][j]] = waste;
}
}
}
}
}
}
}
}
/* check 5data */
for(d[0]=0;d[0]=0;++i) {
/* set */
for(j=0;j<5;++j) {
/* remove the missing data */
data_save[j] = data[d[j]];
data[d[j]] = test[j];
/* set the parity to use */
parity[combo[4][i][j]] = parity_save[combo[4][i][j]];
}
/* recover */
raid_recov(5, d, combo[4][i], buffer, diskmax, zero, block_size);
/* check */
for(j=0;j<5;++j) {
if (memcmp(test[j], data_save[j], block_size) != 0) {
fprintf(stderr, "Failed RAID test\n");
exit(EXIT_FAILURE);
}
}
/* restore */
for(j=0;j<5;++j) {
/* restore the data */
data[d[j]] = data_save[j];
/* restore the parity */
parity[combo[4][i][j]] = waste;
}
}
}
}
}
}
}
/* check 4data */
for(d[0]=0;d[0]=0;++i) {
/* set */
for(j=0;j<4;++j) {
/* remove the missing data */
data_save[j] = data[d[j]];
data[d[j]] = test[j];
/* set the parity to use */
parity[combo[3][i][j]] = parity_save[combo[3][i][j]];
}
/* recover */
raid_recov(4, d, combo[3][i], buffer, diskmax, zero, block_size);
/* check */
for(j=0;j<4;++j) {
if (memcmp(test[j], data_save[j], block_size) != 0) {
fprintf(stderr, "Failed RAID test\n");
exit(EXIT_FAILURE);
}
}
/* restore */
for(j=0;j<4;++j) {
/* restore the data */
data[d[j]] = data_save[j];
/* restore the parity */
parity[combo[3][i][j]] = waste;
}
}
}
}
}
}
/* check 3data */
for(d[0]=0;d[0]=0;++i) {
/* set */
for(j=0;j<3;++j) {
/* remove the missing data */
data_save[j] = data[d[j]];
data[d[j]] = test[j];
/* set the parity to use */
parity[combo[2][i][j]] = parity_save[combo[2][i][j]];
}
/* recover */
raid_recov(3, d, combo[2][i], buffer, diskmax, zero, block_size);
/* check */
for(j=0;j<3;++j) {
if (memcmp(test[j], data_save[j], block_size) != 0) {
fprintf(stderr, "Failed RAID test\n");
exit(EXIT_FAILURE);
}
}
/* restore */
for(j=0;j<3;++j) {
/* restore the data */
data[d[j]] = data_save[j];
/* restore the parity */
parity[combo[2][i][j]] = waste;
}
}
}
}
}
/* check 2data */
for(d[0]=0;d[0]=0;++i) {
/* set */
for(j=0;j<2;++j) {
/* remove the missing data */
data_save[j] = data[d[j]];
data[d[j]] = test[j];
/* set the parity to use */
parity[combo[1][i][j]] = parity_save[combo[1][i][j]];
}
/* recover */
raid_recov(2, d, combo[1][i], buffer, diskmax, zero, block_size);
/* check */
for(j=0;j<2;++j) {
if (memcmp(test[j], data_save[j], block_size) != 0) {
fprintf(stderr, "Failed RAID test\n");
exit(EXIT_FAILURE);
}
}
/* restore */
for(j=0;j<2;++j) {
/* restore the data */
data[d[j]] = data_save[j];
/* restore the parity */
parity[combo[1][i][j]] = waste;
}
}
}
}
/* check 1data */
for(d[0]=0;d[0]=0;++i) {
/* set */
for(j=0;j<1;++j) {
/* remove the missing data */
data_save[j] = data[d[j]];
data[d[j]] = test[j];
/* set the parity to use */
parity[combo[0][i][j]] = parity_save[combo[0][i][j]];
}
/* recover */
raid_recov(1, d, combo[0][i], buffer, diskmax, zero, block_size);
/* check */
for(j=0;j<1;++j) {
if (memcmp(test[j], data_save[j], block_size) != 0) {
fprintf(stderr, "Failed RAID test\n");
exit(EXIT_FAILURE);
}
}
/* restore */
for(j=0;j<1;++j) {
/* restore the data */
data[d[j]] = data_save[j];
/* restore the parity */
parity[combo[0][i][j]] = waste;
}
}
}
free(buffer_alloc);
free(buffer);
}
static void gentest(unsigned diskmax, unsigned block_size)
{
void* buffer_alloc;
unsigned char** buffer;
unsigned buffermax;
unsigned i, j;
void (*map[64])(unsigned char** buffer, unsigned diskmax, unsigned size);
unsigned mac;
buffermax = diskmax + LEV_MAX * 2;
buffer = malloc_nofail_vector_align(buffermax, block_size, &buffer_alloc);
/* fill with random */
for(i=0;i