/* * 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" 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(unsigned diskmax, unsigned block_size) { void* buffer_alloc; unsigned char** buffer; unsigned char* buffer_test0; unsigned char* buffer_test1; unsigned char* buffer_test2; unsigned char* buffer_test3; unsigned char* buffer_zero; unsigned char* buffer_bad; unsigned buffermax; unsigned i, j, k, l; unsigned n; struct combo1 { int ignore[3]; int use; } COMBO1[] = { { { 1, 2, 3 }, 0 }, { { 0, 2, 3 }, 1 }, { { 0, 1, 3 }, 2 }, { { 0, 1, 2 }, 3 } }; struct combo2 { int ignore[2]; int use[2]; } COMBO2[] = { { { 0, 1 }, { 2, 3 } }, { { 0, 2 }, { 1, 3 } }, { { 0, 3 }, { 1, 2 } }, { { 1, 2 }, { 0, 3 } }, { { 1, 3 }, { 0, 2 } }, { { 2, 3 }, { 0, 1 } } }; struct combo3 { int ignore; int use[3]; } COMBO3[] = { { 0, { 1, 2, 3 } }, { 1, { 0, 2, 3 } }, { 2, { 0, 1, 3 } }, { 3, { 0, 1, 2 } } }; buffermax = diskmax + LEV_MAX * 2 + 1 + 1; buffer = malloc_nofail_vector_align(buffermax, block_size, &buffer_alloc); buffer_test0 = buffer[buffermax-6]; buffer_test1 = buffer[buffermax-5]; buffer_test2 = buffer[buffermax-4]; buffer_test3 = buffer[buffermax-3]; buffer_zero = buffer[buffermax-2]; buffer_bad = buffer[buffermax-1]; memset(buffer_zero, 0, block_size); memset(buffer_bad, 0xA5, block_size); /* fill with random */ for(i=0;i RAIDQP_DATA_LIMIT && COMBO3[n].use[2] >= 3) continue; /* save */ a = buffer[i]; b = buffer[j]; c = buffer[k]; /* damage */ buffer[i] = buffer_test0; buffer[j] = buffer_test1; buffer[k] = buffer_test2; /* ignore parity */ l = diskmax + COMBO3[n].ignore; p = buffer[l]; buffer[l] = buffer_bad; /* recover ignoring p */ raid_recov_3data(i, j, k, COMBO3[n].use[0], COMBO3[n].use[1], COMBO3[n].use[2], buffer, diskmax, buffer_zero, block_size); /* check */ if (memcmp(buffer_test0, a, block_size) != 0 || memcmp(buffer_test1, b, block_size) != 0 || memcmp(buffer_test2, c, block_size) != 0 ) { fprintf(stderr, "Failed RAID test\n"); exit(EXIT_FAILURE); } /* restore parity */ buffer[l] = p; /* restore */ buffer[i] = a; buffer[j] = b; buffer[k] = c; } } } } /* check 2data */ for(i=0;i