Whamcloud - gitweb
land v0.9.1 on HEAD, in preparation for a 1.0.x branch
[fs/lustre-release.git] / lustre / tests / ll_sparseness_verify.c
diff --git a/lustre/tests/ll_sparseness_verify.c b/lustre/tests/ll_sparseness_verify.c
new file mode 100644 (file)
index 0000000..574f064
--- /dev/null
@@ -0,0 +1,102 @@
+/* -*- 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 <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdarg.h>
+
+#define BUFSIZE (1024*1024)    
+
+void error(char *fmt, ...)
+{
+        va_list ap;
+        va_start(ap, fmt);
+        vfprintf(stderr, fmt, ap);
+        va_end(ap);
+        exit(1);
+}
+
+int compare_offsets(const void *a, const void *b)
+{
+        off_t *A = (off_t *)a;
+        off_t *B = (off_t *)b;
+        return *A - *B;
+}
+
+int main(int argc, char **argv)
+{
+        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;
+
+        if (argc < 3)
+                error("Usage: %s <filename> <offset> [ offset ... ]\n", 
+                       argv[0]);
+
+        fd = open(argv[1], O_RDONLY);
+        if (fd < 0)
+                error("couldn't open %s: %s\n", argv[1], strerror(errno));
+
+        buf = malloc(BUFSIZE);
+        if (buf == NULL)
+                error("can't allocate buffer\n");
+
+        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;
+                }
+
+                /* 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;
+                }
+
+                /* 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);
+
+                /* skip over duplicate offset arguments */
+                while (cur_off < num_offsets && offsets[cur_off] == pos)
+                        cur_off++;
+        }
+        /* don't bother freeing or closing.. */
+        return 0;
+}