Whamcloud - gitweb
branch: HEAD
[fs/lustre-release.git] / lustre / tests / ll_sparseness_verify.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  * The companion to ll_sparseness_write; walk all the bytes in the file.
5  * the bytes at the offsets specified on the command line must be '+', as
6  * previously written by ll_sparseness_write.  All other bytes must be
7  * 0.
8  */
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <unistd.h>
12 #include <string.h>
13 #include <errno.h>
14 #include <sys/types.h>
15 #include <sys/wait.h>
16 #include <sys/stat.h>
17 #include <fcntl.h>
18 #include <stdarg.h>
19
20 #define BUFSIZE (1024*1024)    
21
22 void error(char *fmt, ...)
23 {
24         va_list ap;
25         va_start(ap, fmt);
26         vfprintf(stderr, fmt, ap);
27         va_end(ap);
28         exit(1);
29 }
30
31 int compare_offsets(const void *a, const void *b)
32 {
33         off_t *A = (off_t *)a;
34         off_t *B = (off_t *)b;
35         return *A - *B;
36 }
37
38 int main(int argc, char **argv)
39 {
40         unsigned int num_offsets, cur_off = 0, i;
41         off_t *offsets, pos = 0, end_of_buf = 0;
42         char *end, *buf;
43         struct stat st;
44         ssize_t ret;
45         int fd;
46
47         if (argc < 3)
48                 error("Usage: %s <filename> <offset> [ offset ... ]\n", 
49                        argv[0]);
50
51         fd = open(argv[1], O_RDONLY);
52         if (fd < 0)
53                 error("couldn't open %s: %s\n", argv[1], strerror(errno));
54
55         buf = malloc(BUFSIZE);
56         if (buf == NULL)
57                 error("can't allocate buffer\n");
58
59         num_offsets = argc - 2;
60         offsets = calloc(sizeof(offsets[0]), num_offsets);
61         for (i = 0; i < num_offsets; i++) {
62                 offsets[i] = strtoul(argv[i + 2], &end, 10);
63                 if (*end) 
64                         error("couldn't parse offset '%s'\n", argv[i + 2]);
65         }
66         qsort(offsets, num_offsets, sizeof(offsets[0]), compare_offsets);
67
68         if (fstat(fd, &st) < 0)
69                 error("stat: %s\n", strerror(errno));
70
71         for (i = 0; pos < st.st_size; i++, pos++) {
72                 if (pos == end_of_buf) {
73                         ret = read(fd, buf, BUFSIZE);
74                         if (ret < 0)
75                                 error("read(): %s\n", strerror(errno));
76                         end_of_buf = pos + ret;
77                         if (end_of_buf > st.st_size)
78                                 error("read %d bytes past file size?\n",
79                                       end_of_buf - st.st_size);
80                         i = 0;
81                 }
82
83                 /* check for 0 when we aren't at a given offset */
84                 if (cur_off >= num_offsets || pos != offsets[cur_off]) {
85                         if (buf[i] != 0) 
86                                 error("found char 0x%x at pos %lu instead of "
87                                        "0x0\n", buf[i], (long)pos);
88                         continue;
89                 }
90
91                 /* the command line asks us to check for + at this offset */
92                 if (buf[i] != '+') 
93                         error("found char 0x%x at pos %lu instead of "
94                                "'.'\n", buf[i], (long)pos);
95
96                 /* skip over duplicate offset arguments */
97                 while (cur_off < num_offsets && offsets[cur_off] == pos)
98                         cur_off++;
99         }
100         /* don't bother freeing or closing.. */
101         return 0;
102 }