Whamcloud - gitweb
b=18801
authoranserper <anserper>
Mon, 11 May 2009 02:48:35 +0000 (02:48 +0000)
committeranserper <anserper>
Mon, 11 May 2009 02:48:35 +0000 (02:48 +0000)
i=Johann Lombardi

a test for O_DIRECT and unaligned writes

lustre/tests/multiop.c
lustre/tests/sanityN.sh

index a8de99b..871ac95 100755 (executable)
@@ -45,6 +45,7 @@
 #include <sys/stat.h>
 #include <sys/mman.h>
 #include <sys/vfs.h>
+#include <sys/time.h>
 #include <signal.h>
 #include <stdlib.h>
 #include <unistd.h>
@@ -58,10 +59,12 @@ char *buf, *buf_align;
 int bufsize = 0;
 sem_t sem;
 #define ALIGN 65535
+#define MAX_SHIFT 4096
 
 char usage[] = 
 "Usage: %s filename command-sequence\n"
 "    command-sequence items:\n"
+"        b[num] write optional length from random in-memory offset\n"
 "        c  close\n"
 "        C[num] create with optional stripes\n"
 "        d  mkdir\n"
@@ -204,6 +207,8 @@ int main(int argc, char **argv)
         /* use sigaction instead of signal to avoid SA_ONESHOT semantics */
         sigaction(SIGUSR1, &(const struct sigaction){.sa_handler = &usr1_handler},
                   NULL);
+        srandom(time(NULL));
+
         fname = argv[1];
 
         for (commands = argv[2]; *commands; commands++) {
@@ -407,12 +412,15 @@ int main(int argc, char **argv)
                 case 'v':
                         verbose = 1;
                         break;
+                case 'b':
                 case 'w':
                         len = atoi(commands+1);
                         if (len <= 0)
                                 len = 1;
                         if (bufsize < len) {
-                                buf = realloc(buf, len + ALIGN);
+                                int shift = (*commands == 'b') ?
+                                            (random() % MAX_SHIFT) : 0;
+                                buf = realloc(buf, len + ALIGN + shift);
                                 if (buf == NULL) {
                                         save_errno = errno;
                                         perror("allocating buf for write\n");
@@ -420,7 +428,7 @@ int main(int argc, char **argv)
                                 }
                                 bufsize = len;
                                 buf_align = (char *)((long)(buf + ALIGN) &
-                                                     ~ALIGN);
+                                                     ~ALIGN) + shift;
                                 strncpy(buf_align, msg, bufsize);
                         }
                         while (len > 0) {
index fefcc72..94ec95b 100644 (file)
@@ -827,10 +827,49 @@ test_37() { # bug 18695
        kill -USR1 $MULTIPID
        nr_files=`lfs find $DIR1/$tdir -type f | wc -l`
        [ $nr_files -eq 10000 ] || error "$nr_files != 10000 truncated directory?"
-
 }
 run_test 37 "check i_size is not updated for directory on close (bug 18695) =============="
 
+test_38() { # bug 18801, based on the code of test_32b
+        remote_ost_nodsh && skip "remote OST with nodsh" && return
+
+        local node
+        local p="$TMP/sanityN-$TESTNAME.parameters"
+        local random="$TMP/sanityN-$TESTNAME.random"
+        # 1. locked unaligned non-DIRECT_IO write of 8192 bytes to file A
+        # 2a. locked unaligned DIRECT_IO write of 4000 bytes to file B
+        # 2b. locked unaligned DIRECT_IO write of 4000 bytes to file B
+        # 3. unaligned "lockless DIRECT_IO" write of 192 bytes in the end of file B
+        # 4. compare A and B
+        log "creating the initial file"
+        multiop $random Ob4000b4000b192c || error "failed creating random file"
+        log "creating a file with the same contents"
+        multiop $DIR1/$tfile oO_CREAT:O_DIRECT:O_RDWR:b4000c || error "first multiop failed"
+        multiop $DIR1/$tfile oO_CREAT:O_DIRECT:O_RDWR:z4000b4000c || error "second multiop failed"
+        save_lustre_params $HOSTNAME "llite.*.contention_seconds" > $p
+        for node in $(osts_nodes); do
+                save_lustre_params $node "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
+                save_lustre_params $node "ldlm.namespaces.filter-*.contended_locks" >> $p
+                save_lustre_params $node "ldlm.namespaces.filter-*.contention_seconds" >> $p
+        done
+        log "enforcing lockless I/O"
+        clear_llite_stats
+        # agressive lockless i/o settings 
+        for node in $(osts_nodes); do
+                do_node $node 'lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes 2000000; lctl set_param -n ldlm.namespaces.filter-*.contended_locks 0; lctl set_param -n ldlm.namespaces.filter-*.contention_seconds 60'
+        done
+        lctl set_param -n llite.*.contention_seconds 60
+        multiop $DIR2/$tfile oO_DIRECT:O_RDWR:z8000b192c || error "the last multiop failed"
+        [ $(calc_llite_stats lockless_write_bytes) -ne 0 ] || error "lockless i/o was not triggered" 
+        restore_lustre_params <$p
+        log "comparing"
+        cmp $DIR1/$tfile $random || error "O_DIRECT+lockless results do not match the original file"
+        rm -f $DIR1/$tfile
+        rm -f $p
+        rm -f $random
+}
+run_test 38 "lockless i/o with O_DIRECT and unaligned writes"
+
 log "cleanup: ======================================================"
 
 check_and_cleanup_lustre