From f612f4397d2684a2b6f59e56cdef8265ea4fc8e3 Mon Sep 17 00:00:00 2001 From: zab Date: Mon, 20 Oct 2003 18:05:20 +0000 Subject: [PATCH] - ll_sparseness_verify had problems with certain combinations of file length and the number of offsets to test for. It took me a while to find the problem in the old code -- this cleanup fixes it and gives people less code to debug in the future. --- lustre/tests/ll_sparseness_verify.c | 274 +++++++++--------------------------- 1 file changed, 69 insertions(+), 205 deletions(-) diff --git a/lustre/tests/ll_sparseness_verify.c b/lustre/tests/ll_sparseness_verify.c index 568a1f3..574f064 100644 --- a/lustre/tests/ll_sparseness_verify.c +++ b/lustre/tests/ll_sparseness_verify.c @@ -1,5 +1,10 @@ /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- * vim:expandtab:shiftwidth=8:tabstop=8: + * + * The companion to ll_sparseness_write; walk all the bytes in the file. + * the bytes at the offsets specified on the command line must be '+', as + * previously written by ll_sparseness_write. All other bytes must be + * 0. */ #include #include @@ -10,229 +15,88 @@ #include #include #include +#include #define BUFSIZE (1024*1024) -int compfunc(const void *x, const void *y) -{ - if (*(unsigned int *)x < *(unsigned int *)y) { - return -1; - } else if (*(unsigned int *)x == *(unsigned int *)y) { - return 0; - } else { - return 1; - } -} - -/* sort offsets and delete redundant data in offsets - * no return - */ -void collapse_redundant(unsigned *offsets, int offsetcount) -{ - int i, j; - qsort(offsets, offsetcount, sizeof(unsigned int), compfunc); - - /* collapse the redundant offsets */ - for (i = 0; i < offsetcount - 1; i++) { - if (offsets[i] == offsets[i + 1]) { - for (j = i; j < offsetcount; j++) { - offsets[j] = offsets[j + 1]; - } - offsetcount--; - } - } -} - -/* verify the sparse pwrite from page(0) to page(filesize / BUFSIZE) - * if sucess return last verified page number else return (-1) - */ -int verify_content(int fd, int filesize, unsigned int *offsets, - int O_number) +void error(char *fmt, ...) { - int i , j; - char *filebuf; - int focus = 0; - int p_number; - - filebuf = (char*) malloc(BUFSIZE); - - p_number = filesize / BUFSIZE; - for (j = 0; j < p_number ; j++) { - - i = read(fd, filebuf, BUFSIZE); - - if (i != BUFSIZE) { - fprintf(stderr, - "Reading file fails (%s), returning (%d)\n", - strerror(errno), i); - free(filebuf); - return -1; - } - - /* check the position that should hold '+' - * If correct, change it to 0 in the buffer */ - for (; focus < O_number; focus++) { - if (offsets[focus] < (j + 1) * BUFSIZE - 1) { - if (filebuf[offsets[focus] % BUFSIZE] != '+') { - fprintf(stderr, - "Bad content, should \ - be '+' at %d.\n", - offsets[focus]); - free(filebuf); - return -1; - } else { - /* '+', change it to 0 for comparison */ - filebuf[offsets[focus] % BUFSIZE] = 0; - } - } - } - - /* Hopefully '+' should have been changed to 0 - * Thus, we should not encounter any strange character */ - for (i = 0; i < BUFSIZE; i++) { - if (filebuf[i] != 0) { - fprintf(stderr, - "Bad content, should be 0 at %d.\n", - i + j * BUFSIZE); - free(filebuf); - return -1; - } - } - } - - free(filebuf); - return focus; + va_list ap; + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + exit(1); } -/* verify the sparse pwrite with last page - * if sucess return 0 else return 1 - */ -int verify_tail(int fd, int filesize, unsigned int *offsets, - int O_number, int focus) +int compare_offsets(const void *a, const void *b) { - int i; - char *filebuf; - int p_number; - - filebuf = (char*) malloc(BUFSIZE); - - /* The last page */ - p_number = filesize % BUFSIZE; - i = read(fd, filebuf, p_number); - if (i != p_number) { - fprintf(stderr, "Reading file fails (%s), returning (%d)\n", - strerror(errno), i); - free(filebuf); - return 1; - } - for (; focus < O_number; focus++) { - if (offsets[focus] < filesize) { - if (filebuf[offsets[focus] % BUFSIZE] != '+') { - fprintf(stderr, - "Bad content, should be '+' at %d.\n", - offsets[focus]); - free(filebuf); - return 1; - } else { - /* '+', change it to 0 for later comparison */ - filebuf[offsets[focus]%BUFSIZE] = 0; - } - } else { - fprintf(stderr, - "Error: File size <= offset %d\n", - offsets[focus]); - free(filebuf); - return 1; - } - } - - for (i = 0; i < p_number; i++) { - if (filebuf[i] != 0) { - fprintf(stderr, "Bad content, should be 0 at %d.\n", - filesize - (p_number - i) - 1); - free(filebuf); - return 1; - } - } - - free(filebuf); - return 0; + off_t *A = (off_t *)a; + off_t *B = (off_t *)b; + return *A - *B; } -/* Function: verify the sparse pwrite (bug 1222): the charaters at - * should be '+', and all other characters should be 0 - * Return: 0 success - * 1 failure*/ -int verify(char *filename, unsigned int *offsets, int O_number) +int main(int argc, char **argv) { - int status; - unsigned int size; + unsigned int num_offsets, cur_off = 0, i; + off_t *offsets, pos = 0, end_of_buf = 0; + char *end, *buf; + struct stat st; + ssize_t ret; int fd; - struct stat Fstat; - - status = stat(filename, &Fstat); - if (status == -1) { - fprintf(stderr, "No such file named as %s.\n", filename); - return 1; - } - size = Fstat.st_size; - - /* Because we always have '+' just before EOF, - * qsorted offsets[] should have the (filesize-1) at the end */ - if (size != offsets[O_number - 1] + 1) { - fprintf(stderr, - "Error: the final character not in the offset?\n"); - return 1; - } - - /* now we check the integrity of the file */ - fd = open(filename, O_RDONLY); - if (fd == -1) { - fprintf(stderr, "Openning %s fails (%s)\n", - filename, strerror(errno)); - return 1; - } - if((status = verify_content(fd, size, offsets, O_number)) < 0) { - close(fd); - return status ; - } + if (argc < 3) + error("Usage: %s [ offset ... ]\n", + argv[0]); - return verify_tail(fd, size, offsets, O_number, status); -} + fd = open(argv[1], O_RDONLY); + if (fd < 0) + error("couldn't open %s: %s\n", argv[1], strerror(errno)); -/* verify the sparse pwrite file with the charaters at - * should be '+', and all other characters should be 0 - */ -int main(int argc, char**argv) -{ - int i; - char *filename; - char *end; - int O_number; - unsigned int *offsets; + buf = malloc(BUFSIZE); + if (buf == NULL) + error("can't allocate buffer\n"); - if (argc < 3) { - fprintf(stderr, - "Usage: %s [ offset ... ]\n", - argv[0]); - exit(1); + num_offsets = argc - 2; + offsets = calloc(sizeof(offsets[0]), num_offsets); + for (i = 0; i < num_offsets; i++) { + offsets[i] = strtoul(argv[i + 2], &end, 10); + if (*end) + error("couldn't parse offset '%s'\n", argv[i + 2]); } + qsort(offsets, num_offsets, sizeof(offsets[0]), compare_offsets); + + if (fstat(fd, &st) < 0) + error("stat: %s\n", strerror(errno)); + + for (i = 0; pos < st.st_size; i++, pos++) { + if (pos == end_of_buf) { + ret = read(fd, buf, BUFSIZE); + if (ret < 0) + error("read(): %s\n", strerror(errno)); + end_of_buf = pos + ret; + if (end_of_buf > st.st_size) + error("read %d bytes past file size?\n", + end_of_buf - st.st_size); + i = 0; + } - filename = argv[1]; - O_number = argc - 2; - offsets = (unsigned int *) malloc(sizeof(unsigned int) * O_number); - for (i = 0; i < O_number; i++) { - offsets[i] = strtoul(argv[i + 2], &end, 10); - if (*end) { - fprintf(stderr, - " parameter should be integer\n"); - exit(1); + /* check for 0 when we aren't at a given offset */ + if (cur_off >= num_offsets || pos != offsets[cur_off]) { + if (buf[i] != 0) + error("found char 0x%x at pos %lu instead of " + "0x0\n", buf[i], (long)pos); + continue; } - } - collapse_redundant(offsets, O_number); + /* the command line asks us to check for + at this offset */ + if (buf[i] != '+') + error("found char 0x%x at pos %lu instead of " + "'.'\n", buf[i], (long)pos); - return verify(filename,offsets,O_number); + /* skip over duplicate offset arguments */ + while (cur_off < num_offsets && offsets[cur_off] == pos) + cur_off++; + } + /* don't bother freeing or closing.. */ + return 0; } - -- 1.8.3.1