From 7414f8daec56ec91d756ca07d354db8ed34b94b5 Mon Sep 17 00:00:00 2001 From: Andrea Mazzoleni Date: Sun, 27 Oct 2013 17:31:10 +0100 Subject: [PATCH] Adds a basic memory test on the used memory buffers. --- HISTORY | 2 ++ check.c | 2 ++ scrub.c | 2 ++ selftest.c | 2 ++ speed.c | 1 + sync.c | 2 ++ util.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ util.h | 6 ++++++ 8 files changed, 67 insertions(+) diff --git a/HISTORY b/HISTORY index 6fe1b56b..afee144e 100644 --- a/HISTORY +++ b/HISTORY @@ -23,6 +23,8 @@ SnapRAID HISTORY * Changed the output format of some commands to make it similar at the new "list" one. * Reduced memory usage removing some unnecessary allocations. + * Added a memory test on the memory buffers used in sync/scrub/check/fix + before using them. 4.4 2013/10 =========== diff --git a/check.c b/check.c index c404ad01..a6696370 100644 --- a/check.c +++ b/check.c @@ -482,6 +482,8 @@ static int state_check_process(struct snapraid_state* state, int check, int fix, buffermax = diskmax + state->level * 2 + 1; buffer = malloc_nofail_vector_align(buffermax, state->block_size, &buffer_alloc); + if (!state->opt.skip_self) + mtest_vector(buffer, buffermax, state->block_size); /* fill up the zero buffer */ memset(buffer[buffermax-1], 0, state->block_size); diff --git a/scrub.c b/scrub.c index 8006dcff..3e0b81a5 100644 --- a/scrub.c +++ b/scrub.c @@ -68,6 +68,8 @@ static int state_scrub_process(struct snapraid_state* state, struct snapraid_par buffermax = diskmax + state->level * 2; buffer = malloc_nofail_vector_align(buffermax, state->block_size, &buffer_alloc); + if (!state->opt.skip_self) + mtest_vector(buffer, buffermax, state->block_size); error = 0; silent_error = 0; diff --git a/selftest.c b/selftest.c index 0a54db04..19b19acd 100644 --- a/selftest.c +++ b/selftest.c @@ -66,6 +66,7 @@ static void recovtest(int diskmax, unsigned block_size) buffermax = diskmax + LEV_MAX * 2 + 2; buffer = malloc_nofail_vector_align(buffermax, block_size, &buffer_alloc); + mtest_vector(buffer, buffermax, block_size); data = buffer; parity = buffer + diskmax; @@ -336,6 +337,7 @@ static void gentest(unsigned diskmax, unsigned block_size) buffermax = diskmax + LEV_MAX * 2; buffer = malloc_nofail_vector_align(buffermax, block_size, &buffer_alloc); + mtest_vector(buffer, buffermax, block_size); /* fill with random */ for(i=0;ilevel; buffer = malloc_nofail_vector_align(buffermax, state->block_size, &buffer_alloc); + if (!state->opt.skip_self) + mtest_vector(buffer, buffermax, state->block_size); error = 0; silent_error = 0; diff --git a/util.c b/util.c index 0177b4d3..27c13667 100644 --- a/util.c +++ b/util.c @@ -1388,6 +1388,56 @@ unsigned char** malloc_nofail_vector_align(size_t count, size_t size, void** fre return buffer; } +void mtest_vector(unsigned char** buf, size_t count, size_t size) +{ + size_t i; + size_t j; + unsigned k; + unsigned char d; + unsigned char p; + + /* fill with 0 */ + d = 0; + for(i=0;i0;--j) { + if (buf[i][j-1] != p) + goto fail; + buf[i][j-1] = d; + } + } + } + + return; + +fail: + fprintf(stderr, "DANGER! Your RAM memory is broken! DO NOT PROCEED UNTIL FIXED!\n"); + fprintf(stderr, "Try running some memory test like http://www.memtest86.com/\n"); + exit(EXIT_FAILURE); +} + char* strdup_nofail(const char* str) { size_t size; diff --git a/util.h b/util.h index 1782c399..d39885c0 100644 --- a/util.h +++ b/util.h @@ -464,6 +464,12 @@ void* malloc_nofail_align(size_t size, void** freeptr); */ unsigned char** malloc_nofail_vector_align(size_t count, size_t size, void** freeptr); +/** + * Test the memory vector for RAM problems. + * If a problem is found, it crashes. + */ +void mtest_vector(unsigned char** buf, size_t count, size_t size); + /** * Safe strdup. * If no memory is available, it aborts.