Whamcloud - gitweb
LU-797 tests: improve test_23b of ost-pools.sh
[fs/lustre-release.git] / lustre / tests / ll_sparseness_verify.c
1 /*
2  * GPL HEADER START
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 only,
8  * as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License version 2 for more details (a copy is included
14  * in the LICENSE file that accompanied this code).
15  *
16  * You should have received a copy of the GNU General Public License
17  * version 2 along with this program; If not, see
18  * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
19  *
20  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21  * CA 95054 USA or visit www.sun.com if you need additional information or
22  * have any questions.
23  *
24  * GPL HEADER END
25  */
26 /*
27  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
28  * Use is subject to license terms.
29  */
30 /*
31  * This file is part of Lustre, http://www.lustre.org/
32  * Lustre is a trademark of Sun Microsystems, Inc.
33  *
34  * lustre/tests/ll_sparseness_verify.c
35  *
36  * The companion to ll_sparseness_write; walk all the bytes in the file.
37  * the bytes at the offsets specified on the command line must be '+', as
38  * previously written by ll_sparseness_write.  All other bytes must be 0.
39  */
40
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <unistd.h>
44 #include <string.h>
45 #include <errno.h>
46 #include <sys/types.h>
47 #include <sys/wait.h>
48 #include <sys/stat.h>
49 #include <fcntl.h>
50 #include <stdarg.h>
51
52 #define BUFSIZE (1024*1024)    
53
54 void error(char *fmt, ...)
55 {
56         va_list ap;
57         va_start(ap, fmt);
58         vfprintf(stderr, fmt, ap);
59         va_end(ap);
60         exit(1);
61 }
62
63 int compare_offsets(const void *a, const void *b)
64 {
65         off_t *A = (off_t *)a;
66         off_t *B = (off_t *)b;
67         return *A - *B;
68 }
69
70 int main(int argc, char **argv)
71 {
72         unsigned int num_offsets, cur_off = 0, i;
73         off_t *offsets, pos = 0, end_of_buf = 0;
74         char *end, *buf;
75         struct stat st;
76         ssize_t ret;
77         int fd;
78
79         if (argc < 3)
80                 error("Usage: %s <filename> <offset> [ offset ... ]\n", 
81                        argv[0]);
82
83         fd = open(argv[1], O_RDONLY);
84         if (fd < 0)
85                 error("couldn't open %s: %s\n", argv[1], strerror(errno));
86
87         buf = malloc(BUFSIZE);
88         if (buf == NULL)
89                 error("can't allocate buffer\n");
90
91         num_offsets = argc - 2;
92         offsets = calloc(sizeof(offsets[0]), num_offsets);
93         for (i = 0; i < num_offsets; i++) {
94                 offsets[i] = strtoul(argv[i + 2], &end, 10);
95                 if (*end) 
96                         error("couldn't parse offset '%s'\n", argv[i + 2]);
97         }
98         qsort(offsets, num_offsets, sizeof(offsets[0]), compare_offsets);
99
100         if (fstat(fd, &st) < 0)
101                 error("stat: %s\n", strerror(errno));
102
103         for (i = 0; pos < st.st_size; i++, pos++) {
104                 if (pos == end_of_buf) {
105                         ret = read(fd, buf, BUFSIZE);
106                         if (ret < 0)
107                                 error("read(): %s\n", strerror(errno));
108                         end_of_buf = pos + ret;
109                         if (end_of_buf > st.st_size)
110                                 error("read %d bytes past file size?\n",
111                                       end_of_buf - st.st_size);
112                         i = 0;
113                 }
114
115                 /* check for 0 when we aren't at a given offset */
116                 if (cur_off >= num_offsets || pos != offsets[cur_off]) {
117                         if (buf[i] != 0) 
118                                 error("found char 0x%x at pos %lu instead of "
119                                        "0x0\n", buf[i], (long)pos);
120                         continue;
121                 }
122
123                 /* the command line asks us to check for + at this offset */
124                 if (buf[i] != '+') 
125                         error("found char 0x%x at pos %lu instead of "
126                                "'.'\n", buf[i], (long)pos);
127
128                 /* skip over duplicate offset arguments */
129                 while (cur_off < num_offsets && offsets[cur_off] == pos)
130                         cur_off++;
131         }
132         /* don't bother freeing or closing.. */
133         return 0;
134 }