1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
6 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 only,
10 * as published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License version 2 for more details (a copy is included
16 * in the LICENSE file that accompanied this code).
18 * You should have received a copy of the GNU General Public License
19 * version 2 along with this program; If not, see
20 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
22 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23 * CA 95054 USA or visit www.sun.com if you need additional information or
29 * Copyright 2008 Sun Microsystems, Inc. All rights reserved
30 * Use is subject to license terms.
33 * This file is part of Lustre, http://www.lustre.org/
34 * Lustre is a trademark of Sun Microsystems, Inc.
36 * lustre/tests/reads.c
40 * Author: Nikita Danilov <nikita@clusterfs.com>
43 #define _XOPEN_SOURCE 500 /* for pread(2) */
53 #include <sys/types.h>
56 static void usage(void)
58 printf("reads: read random or stride chunks of a file.\n");
60 printf("reads -f <filename> -s <filesize> -b <buffersize>"
61 "-a <adjacent reads> [-v] [-h] [-C] [-l <stride_length> ] "
62 "[ -o <stride_offset> ] [-S <seed>] [-n <iterations>]"
63 "[-w <width>] [-t <timelimit>]\n");
67 BSIZE_DEFAULT = 16 * 4096
70 #define LOG(level, ...) \
72 if ((level) <= verbosity) \
73 fprintf(stderr, __VA_ARGS__); \
93 int main(int argc, char **argv)
95 int verbosity = LOG_CRIT;
102 unsigned int seed = 0;
103 unsigned long iterations = 0;
104 unsigned long timelimit = 24 * 3600;
105 unsigned long stride_length = 0;
106 unsigned long stride_offset = 0;
110 unsigned long nblocks;
114 struct timeval start;
123 opt = getopt(argc, argv, "f:s:b:va:hCS:n:t:l:o:w:");
128 LOG(LOG_CRIT, "Unable to parse command line.\n");
136 fname = strdup(optarg);
139 size = strtol(optarg, &term, 0);
140 if (term == optarg) {
141 fprintf (stderr, "Can't parse size %s\n", optarg);
147 bsize = strtol(optarg, &term, 0);
148 if (term == optarg) {
149 fprintf (stderr, "Can't parse bsize %s\n", optarg);
155 ad = (int)strtol(optarg, &term, 0);
156 if (term == optarg) {
157 fprintf (stderr, "Can't parse ad %s\n", optarg);
166 seed = strtol(optarg, &term, 0);
167 if (term == optarg) {
168 fprintf (stderr, "Can't parse seed %s\n", optarg);
174 iterations = strtol(optarg, &term, 0);
175 if (term == optarg) {
176 fprintf (stderr, "Can't parse seed %s\n", optarg);
184 timelimit = strtol(optarg, &term, 0);
185 if (term == optarg) {
186 fprintf (stderr, "Can't parse seed %s\n", optarg);
192 stride_length = strtol(optarg, &term, 0);
193 if (term == optarg) {
194 fprintf (stderr, "Can't parse seed %s\n", optarg);
200 stride_offset = strtol(optarg, &term, 0);
201 if (term == optarg) {
202 fprintf (stderr, "Can't parse seed %s\n", optarg);
208 width = (int)strtol(optarg, &term, 0);
209 if (term == optarg) {
210 fprintf (stderr, "Can't parse seed %s\n", optarg);
218 if (fname == NULL || size == 0 || bsize == 0 || ad <= 0) {
224 nblocks = size / bsize;
227 LOG(LOG_CRIT, "malloc(%lu) failure: %s\n", (long)bsize,
232 fd = open(fname, (preclean ? O_RDWR : O_RDONLY) | O_CREAT, 0700);
234 LOG(LOG_CRIT, "malloc(\"%s\") failure: %s\n", fname,
242 LOG(LOG_INFO, "precleaning");
243 for (i = 0, towrite = size; towrite > 0; towrite -= ret) {
244 count = bsize < towrite ? bsize : towrite;
245 memset(buf, bsize, seed + i++);
246 ret = write(fd, buf, count);
248 LOG(LOG_CRIT, "write() failure: %s\n",
257 gettimeofday(&start, NULL);
258 timelimit += start.tv_sec;
259 for (i = 0; !iterations || i < iterations; i ++) {
260 unsigned long block_nr;
264 block_nr = (unsigned long)(i*stride_length +
265 stride_offset) % nblocks;
267 block_nr = (unsigned long)((double)nblocks*rand()/
270 LOG(LOG_INFO, "\n%9lu: ", i);
271 LOG(LOG_INFO, "%7lu ", block_nr);
272 for (j = 0; j < ad; j++) {
273 ret = pread(fd, buf, bsize, (block_nr + j) * bsize);
276 "pread(...%zi, %li) got: %zi, %s\n", bsize,
277 block_nr * bsize, ret, strerror(errno));
282 gettimeofday(&stop, NULL);
283 if (stop.tv_sec > timelimit)
287 usecs = (stop.tv_sec - start.tv_sec) * 1000000. +
288 stop.tv_usec - start.tv_usec;
289 printf("\n%fs, %gMB/s\n", usecs / 1000000.,
290 (double)bsize * ad * i / usecs);