/* * 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