Whamcloud - gitweb
Branch: HEAD
authorwangdi <wangdi>
Fri, 4 Jul 2008 22:25:35 +0000 (22:25 +0000)
committerwangdi <wangdi>
Fri, 4 Jul 2008 22:25:35 +0000 (22:25 +0000)
add stride read-ahead test case
b=16172
i=adilger,nikita

lustre/tests/Makefile.am
lustre/tests/reads.c [moved from lustre/tests/random-reads.c with 63% similarity]
lustre/tests/sanity.sh

index 4d4017b..f2b2c65 100644 (file)
@@ -34,7 +34,7 @@ noinst_PROGRAMS += wantedi statone runas openfile getdents o_directory rmdirmany
 noinst_PROGRAMS += small_write multiop sleeptest ll_sparseness_verify cmknod
 noinst_PROGRAMS += ll_sparseness_write mrename ll_dirstripe_verify mkdirmany
 noinst_PROGRAMS += openfilleddirunlink rename_many memhog iopentest1 iopentest2
-noinst_PROGRAMS += mmap_sanity flock_test writemany random-reads flocks_test
+noinst_PROGRAMS += mmap_sanity flock_test writemany reads flocks_test
 noinst_PROGRAMS += ll_getstripe_info write_time_limit
 if MPITESTS
 noinst_PROGRAMS += parallel_grouplock write_append_truncate createmany_mpi
similarity index 63%
rename from lustre/tests/random-reads.c
rename to lustre/tests/reads.c
index 1722afb..77ebeaa 100644 (file)
@@ -1,7 +1,8 @@
 /*
- * 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 {
@@ -82,6 +84,8 @@ int main(int argc, char **argv)
        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;
@@ -95,9 +99,10 @@ int main(int argc, char **argv)
        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;
@@ -113,28 +118,81 @@ int main(int argc, char **argv)
                        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);
@@ -171,6 +229,7 @@ int main(int argc, char **argv)
                        if (ret < 0) {
                                LOG(LOG_CRIT, "write() failure: %s\n",
                                    strerror(errno));
+                               close(fd);
                                return RR_PRECLEAN;
                        }
                }
@@ -183,7 +242,12 @@ int main(int argc, char **argv)
                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);
@@ -193,6 +257,7 @@ int main(int argc, char **argv)
                                LOG(LOG_CRIT,
                                    "pread(...%zi, %li) got: %zi, %s\n", bsize,
                                    block_nr * bsize, ret, strerror(errno));
+                               close(fd);
                                return RR_READ;
                        }
                }
@@ -200,6 +265,7 @@ int main(int argc, char **argv)
                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.,
index 33dba9c..f2fc49d 100644 (file)
@@ -45,7 +45,7 @@ LCTL=${LCTL:-lctl}
 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}
@@ -3655,7 +3655,7 @@ test_101() {
        # 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
@@ -3672,6 +3672,78 @@ test_101() {
 }
 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