/*
- * Lustre Random Reads test
+ * Lustre Reads test
*
* Copyright (c) 2005 Cluster File Systems, Inc.
+ * Copyright (c) 2008 SUN Microsystems.
*
* Author: Nikita Danilov <nikita@clusterfs.com>
*
#include <sys/types.h>
#include <sys/time.h>
-long long atoll(const char *nptr);
-
static void usage(void)
{
- printf("random-reads: read random chunks of a file.\n");
+ printf("reads: read random or stride chunks of a file.\n");
printf("Usage:\n\n");
- printf("random-reads -f <filename> -s <filesize> -b <buffersize> -a <adjacent reads> [-v] [-h] [-C] [-S <seed>] [-n <iterations>] [-w <width>] [-t <timelimit>]\n");
+ printf("reads -f <filename> -s <filesize> -b <buffersize>"
+ "-a <adjacent reads> [-v] [-h] [-C] [-l <stride_length> ] "
+ "[ -o <stride_offset> ] [-S <seed>] [-n <iterations>]"
+ "[-w <width>] [-t <timelimit>]\n");
}
enum {
unsigned int seed = 0;
unsigned long iterations = 0;
unsigned long timelimit = 24 * 3600;
+ unsigned long stride_length = 0;
+ unsigned long stride_offset = 0;
int opt;
int fd;
double usecs;
char *buf;
+ char *term;
do {
- opt = getopt(argc, argv, "f:s:b:va:hCS:n:t:w:");
+ opt = getopt(argc, argv, "f:s:b:va:hCS:n:t:l:o:w:");
switch (opt) {
case -1:
break;
fname = strdup(optarg);
break;
case 's':
- size = atoll(optarg);
+ size = strtol(optarg, &term, 0);
+ if (term == optarg) {
+ fprintf (stderr, "Can't parse size %s\n", optarg);
+ usage();
+ return RR_SET;
+ }
break;
case 'b':
- bsize = atol(optarg);
+ bsize = strtol(optarg, &term, 0);
+ if (term == optarg) {
+ fprintf (stderr, "Can't parse bsize %s\n", optarg);
+ usage();
+ return RR_SET;
+ }
break;
case 'a':
- ad = atoi(optarg);
+ ad = (int)strtol(optarg, &term, 0);
+ if (term == optarg) {
+ fprintf (stderr, "Can't parse ad %s\n", optarg);
+ usage();
+ return RR_SET;
+ }
break;
case 'C':
preclean = 1;
break;
case 'S':
- seed = atol(optarg);
+ seed = strtol(optarg, &term, 0);
+ if (term == optarg) {
+ fprintf (stderr, "Can't parse seed %s\n", optarg);
+ usage();
+ return RR_SET;
+ }
break;
case 'n':
- iterations = atoll(optarg);
+ iterations = strtol(optarg, &term, 0);
+ if (term == optarg) {
+ fprintf (stderr, "Can't parse seed %s\n", optarg);
+ usage();
+ return RR_SET;
+ }
+ break;
+
break;
case 't':
- timelimit = atoll(optarg);
+ timelimit = strtol(optarg, &term, 0);
+ if (term == optarg) {
+ fprintf (stderr, "Can't parse seed %s\n", optarg);
+ usage();
+ return RR_SET;
+ }
+ break;
+ case 'l':
+ stride_length = strtol(optarg, &term, 0);
+ if (term == optarg) {
+ fprintf (stderr, "Can't parse seed %s\n", optarg);
+ usage();
+ return RR_SET;
+ }
+ break;
+ case 'o':
+ stride_offset = strtol(optarg, &term, 0);
+ if (term == optarg) {
+ fprintf (stderr, "Can't parse seed %s\n", optarg);
+ usage();
+ return RR_SET;
+ }
break;
case 'w':
- width = atoi(optarg);
+ width = (int)strtol(optarg, &term, 0);
+ if (term == optarg) {
+ fprintf (stderr, "Can't parse seed %s\n", optarg);
+ usage();
+ return RR_SET;
+ }
break;
}
} while (opt != -1);
if (ret < 0) {
LOG(LOG_CRIT, "write() failure: %s\n",
strerror(errno));
+ close(fd);
return RR_PRECLEAN;
}
}
unsigned long block_nr;
int j;
- block_nr = (int) ((double)nblocks*rand()/(RAND_MAX+1.0));
+ if (stride_length)
+ block_nr = (unsigned long)(i*stride_length +
+ stride_offset) % nblocks;
+ else
+ block_nr = (unsigned long)((double)nblocks*rand()/
+ (RAND_MAX+1.0));
if (i % width == 0)
LOG(LOG_INFO, "\n%9lu: ", i);
LOG(LOG_INFO, "%7lu ", block_nr);
LOG(LOG_CRIT,
"pread(...%zi, %li) got: %zi, %s\n", bsize,
block_nr * bsize, ret, strerror(errno));
+ close(fd);
return RR_READ;
}
}
if (stop.tv_sec > timelimit)
break;
}
+ close(fd);
usecs = (stop.tv_sec - start.tv_sec) * 1000000. +
stop.tv_usec - start.tv_usec;
printf("\n%fs, %gMB/s\n", usecs / 1000000.,
MCREATE=${MCREATE:-mcreate}
OPENFILE=${OPENFILE:-openfile}
OPENUNLINK=${OPENUNLINK:-openunlink}
-RANDOM_READS=${RANDOM_READS:-"random-reads"}
+READS=${READS:-"reads"}
TOEXCL=${TOEXCL:-toexcl}
TRUNCATE=${TRUNCATE:-truncate}
MUNLINK=${MUNLINK:-munlink}
# randomly read 10000 of 64K chunks from file 3x 32MB in size
#
echo "nreads: $nreads file size: $((cache_limit * 3))MB"
- $RANDOM_READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
+ $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
discard=0
for s in `lctl get_param -n llite.*.read_ahead_stats | get_named_value 'read but discarded'`; do
}
run_test 101 "check read-ahead for random reads ================"
+export SETUP_TEST101=no
+setup_test101() {
+ [ "$SETUP_TEST101" = "yes" ] && return
+ mkdir -p $DIR/$tdir
+ STRIPE_SIZE=1048576
+ STRIPE_COUNT=$OSTCOUNT
+ STRIPE_OFFSET=0
+
+ trap cleanup_test101 EXIT
+ # prepare the read-ahead file
+ $SETSTRIPE $DIR/$tfile -s $STRIPE_SIZE -i $STRIPE_OFFSET -c $OSTCOUNT
+
+ dd if=/dev/zero of=$DIR/$tfile bs=1024k count=100 2> /dev/null
+ SETUP_TEST102=yes
+}
+
+cleanup_test101() {
+ [ "$SETUP_TEST101" = "yes" ] || return
+ trap 0
+ rm -rf $DIR/$tdir
+ SETUP_TEST102=no
+}
+
+calc_total() {
+ awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
+}
+
+ra_check_101() {
+ local READ_SIZE=$1
+ local STRIPE_SIZE=1048576
+ local RA_INC=1048576
+ local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
+ local FILE_LENGTH=$((64*100))
+ local discard_limit=$(((((((STRIDE_LENGTH - 1))*3)/(STRIDE_LENGTH*OSTCOUNT))* \
+ (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH))))
+ DISCARD=`$LCTL get_param -n llite.*.read_ahead_stats | \
+ get_named_value 'read but discarded' | calc_total`
+
+ if [ $DISCARD -gt $discard_limit ]; then
+ lctl get_param llite.*.read_ahead_stats
+ error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
+ else
+ echo "Read-ahead success for size ${READ_SIZE}"
+ fi
+}
+
+test_101b() {
+ [ "$OSTCOUNT" -lt "2" ] && skip "skipping stride IO stride-ahead test" && return
+ local STRIPE_SIZE=1048576
+ local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
+ local FILE_LENGTH=$((STRIPE_SIZE*100))
+ local ITERATION=$((FILE_LENGTH/STRIDE_SIZE))
+ # prepare the read-ahead file
+ setup_test101
+ cancel_lru_locks osc
+ for BIDX in 2 4 8 16 32 64 128 256
+ do
+ local BSIZE=$((BIDX*4096))
+ local READ_COUNT=$((STRIPE_SIZE/BSIZE))
+ local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
+ local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
+ $LCTL set_param -n llite.*.read_ahead_stats 0
+ $READS -f $DIR/$tfile -l $STRIDE_LENGTH -o $OFFSET \
+ -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
+ cancel_lru_locks osc
+ ra_check_101 $BSIZE
+ done
+ cleanup_test101
+ true
+}
+run_test 101b "check stride-io mode read-ahead ================="
+
export SETUP_TEST102=no
setup_test102() {
[ "$SETUP_TEST102" = "yes" ] && return