4 * Copyright (c) 2005 Cluster File Systems, Inc.
5 * Copyright (c) 2008 SUN Microsystems.
7 * Author: Nikita Danilov <nikita@clusterfs.com>
9 * This file is part of Lustre, http://www.lustre.org.
11 * Lustre is free software; you can redistribute it and/or modify it under the
12 * terms of version 2 of the GNU General Public License as published by the
13 * Free Software Foundation.
15 * Lustre is distributed in the hope that it will be useful, but WITHOUT ANY
16 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
20 * You should have received a copy of the GNU General Public License along
21 * with Lustre; if not, write to the Free Software Foundation, Inc., 675 Mass
22 * Ave, Cambridge, MA 02139, USA.
25 #define _XOPEN_SOURCE 500 /* for pread(2) */
35 #include <sys/types.h>
38 static void usage(void)
40 printf("reads: read random or stride chunks of a file.\n");
42 printf("reads -f <filename> -s <filesize> -b <buffersize>"
43 "-a <adjacent reads> [-v] [-h] [-C] [-l <stride_length> ] "
44 "[ -o <stride_offset> ] [-S <seed>] [-n <iterations>]"
45 "[-w <width>] [-t <timelimit>]\n");
49 BSIZE_DEFAULT = 16 * 4096
52 #define LOG(level, ...) \
54 if ((level) <= verbosity) \
55 fprintf(stderr, __VA_ARGS__); \
75 int main(int argc, char **argv)
77 int verbosity = LOG_CRIT;
84 unsigned int seed = 0;
85 unsigned long iterations = 0;
86 unsigned long timelimit = 24 * 3600;
87 unsigned long stride_length = 0;
88 unsigned long stride_offset = 0;
92 unsigned long nblocks;
105 opt = getopt(argc, argv, "f:s:b:va:hCS:n:t:l:o:w:");
110 LOG(LOG_CRIT, "Unable to parse command line.\n");
118 fname = strdup(optarg);
121 size = strtol(optarg, &term, 0);
122 if (term == optarg) {
123 fprintf (stderr, "Can't parse size %s\n", optarg);
129 bsize = strtol(optarg, &term, 0);
130 if (term == optarg) {
131 fprintf (stderr, "Can't parse bsize %s\n", optarg);
137 ad = (int)strtol(optarg, &term, 0);
138 if (term == optarg) {
139 fprintf (stderr, "Can't parse ad %s\n", optarg);
148 seed = strtol(optarg, &term, 0);
149 if (term == optarg) {
150 fprintf (stderr, "Can't parse seed %s\n", optarg);
156 iterations = strtol(optarg, &term, 0);
157 if (term == optarg) {
158 fprintf (stderr, "Can't parse seed %s\n", optarg);
166 timelimit = strtol(optarg, &term, 0);
167 if (term == optarg) {
168 fprintf (stderr, "Can't parse seed %s\n", optarg);
174 stride_length = strtol(optarg, &term, 0);
175 if (term == optarg) {
176 fprintf (stderr, "Can't parse seed %s\n", optarg);
182 stride_offset = strtol(optarg, &term, 0);
183 if (term == optarg) {
184 fprintf (stderr, "Can't parse seed %s\n", optarg);
190 width = (int)strtol(optarg, &term, 0);
191 if (term == optarg) {
192 fprintf (stderr, "Can't parse seed %s\n", optarg);
200 if (fname == NULL || size == 0 || bsize == 0 || ad <= 0) {
206 nblocks = size / bsize;
209 LOG(LOG_CRIT, "malloc(%lu) failure: %s\n", (long)bsize,
214 fd = open(fname, (preclean ? O_RDWR : O_RDONLY) | O_CREAT, 0700);
216 LOG(LOG_CRIT, "malloc(\"%s\") failure: %s\n", fname,
224 LOG(LOG_INFO, "precleaning");
225 for (i = 0, towrite = size; towrite > 0; towrite -= ret) {
226 count = bsize < towrite ? bsize : towrite;
227 memset(buf, bsize, seed + i++);
228 ret = write(fd, buf, count);
230 LOG(LOG_CRIT, "write() failure: %s\n",
239 gettimeofday(&start, NULL);
240 timelimit += start.tv_sec;
241 for (i = 0; !iterations || i < iterations; i ++) {
242 unsigned long block_nr;
246 block_nr = (unsigned long)(i*stride_length +
247 stride_offset) % nblocks;
249 block_nr = (unsigned long)((double)nblocks*rand()/
252 LOG(LOG_INFO, "\n%9lu: ", i);
253 LOG(LOG_INFO, "%7lu ", block_nr);
254 for (j = 0; j < ad; j++) {
255 ret = pread(fd, buf, bsize, (block_nr + j) * bsize);
258 "pread(...%zi, %li) got: %zi, %s\n", bsize,
259 block_nr * bsize, ret, strerror(errno));
264 gettimeofday(&stop, NULL);
265 if (stop.tv_sec > timelimit)
269 usecs = (stop.tv_sec - start.tv_sec) * 1000000. +
270 stop.tv_usec - start.tv_usec;
271 printf("\n%fs, %gMB/s\n", usecs / 1000000.,
272 (double)bsize * ad * i / usecs);