Adds a basic memory test on the used memory buffers.

This commit is contained in:
Andrea Mazzoleni 2013-10-27 17:31:10 +01:00
parent e7804a5f8f
commit 7414f8daec
8 changed files with 67 additions and 0 deletions

View file

@ -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
===========

View file

@ -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);

View file

@ -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;

View file

@ -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;i<diskmax;++i) {

View file

@ -70,6 +70,7 @@ void speed(void)
unsigned char* zero;
buffer = malloc_nofail_vector_align(diskmax + LEV_MAX + 1, block_size, &buffer_alloc);
mtest_vector(buffer, diskmax + LEV_MAX + 1, block_size);
/* initialize with fixed data */
for(i=0;i<diskmax+LEV_MAX;++i) {

2
sync.c
View file

@ -75,6 +75,8 @@ static int state_sync_process(struct snapraid_state* state, struct snapraid_pari
buffermax = diskmax + state->level;
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;

50
util.c
View file

@ -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;i<count;++i) {
for(j=0;j<size;++j) {
buf[i][j] = d;
}
}
/* test with all the byte patterns */
for(k=1;k<256;++k) {
p = d;
d = k;
/* forward fill */
for(i=0;i<count;++i) {
for(j=0;j<size;++j) {
if (buf[i][j] != p)
goto fail;
buf[i][j] = d;
}
}
p = d;
d = ~p;
/* backward fill with complement */
for(i=0;i<count;++i) {
for(j=size;j>0;--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;

6
util.h
View file

@ -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.