Whamcloud - gitweb
LU-760 obdecho: initialization and awk problem
[fs/lustre-release.git] / lustre / tests / sanity.sh
index 8b828d7..e54a142 100644 (file)
@@ -9,10 +9,8 @@
 set -e
 
 ONLY=${ONLY:-"$*"}
-# bug number for skipped test: 13297 2108 9789 3637 9789 3561 12622 12653 12653 5188 16260 19742 
-ALWAYS_EXCEPT="                27u   42a  42b  42c  42d  45   51d   65a   65e   68b  $SANITY_EXCEPT"
-# bug number for skipped test: 2108 9789 3637 9789 3561 5188/5749 1443
-#ALWAYS_EXCEPT=${ALWAYS_EXCEPT:-"27m 42a 42b 42c 42d 45 68 76"}
+# bug number for skipped test: 13297 2108 9789 3637 9789 3561 12622 5188
+ALWAYS_EXCEPT="                27u   42a  42b  42c  42d  45   51d   68b  $SANITY_EXCEPT"
 # UPDATE THE COMMENT ABOVE WITH BUG NUMBERS WHEN CHANGING ALWAYS_EXCEPT!
 
 # Tests that fail on uml
@@ -47,8 +45,6 @@ READS=${READS:-"reads"}
 MUNLINK=${MUNLINK:-munlink}
 SOCKETSERVER=${SOCKETSERVER:-socketserver}
 SOCKETCLIENT=${SOCKETCLIENT:-socketclient}
-IOPENTEST1=${IOPENTEST1:-iopentest1}
-IOPENTEST2=${IOPENTEST2:-iopentest2}
 MEMHOG=${MEMHOG:-memhog}
 DIRECTIO=${DIRECTIO:-directio}
 ACCEPTOR_PORT=${ACCEPTOR_PORT:-988}
@@ -72,7 +68,6 @@ init_logging
 
 [ "$SLOW" = "no" ] && EXCEPT_SLOW="24o 24v 27m 36f 36g 36h 51b 51c 60c 63 64b 68 71 73 77f 78 101 103 115 120g 124b"
 
-SANITYLOG=${TESTSUITELOG:-$TMP/$(basename $0 .sh).log}
 FAIL_ON_ERROR=false
 
 cleanup() {
@@ -103,8 +98,6 @@ if [ "$ONLY" == "cleanup" ]; then
        exit 0
 fi
 
-[ "$SANITYLOG" ] && rm -f $SANITYLOG || true
-
 check_and_setup_lustre
 
 DIR=${DIR:-$MOUNT}
@@ -789,6 +782,10 @@ test_24u() { # bug12192
 }
 run_test 24u "create stripe file"
 
+page_size() {
+       getconf PAGE_SIZE
+}
+
 test_24v() {
        local NRFILES=100000
        local FREE_INODES=`lfs df -i|grep "filesystem summary" | awk '{print $5}'`
@@ -798,8 +795,26 @@ test_24v() {
 
        mkdir -p $DIR/d24v
        createmany -m $DIR/d24v/$tfile $NRFILES
+
+       cancel_lru_locks mdc
+       lctl set_param mdc.*.stats clear
+
        ls $DIR/d24v >/dev/null || error "error in listing large dir"
 
+       # LU-5 large readdir
+       # DIRENT_SIZE = 32 bytes for sizeof(struct lu_dirent) +
+       #               8 bytes for name(filename is mostly 5 in this test) +
+       #               8 bytes for luda_type
+       # take into account of overhead in lu_dirpage header and end mark in
+       # each page, plus one in RPC_NUM calculation.
+       DIRENT_SIZE=48
+       RPC_SIZE=$(($(lctl get_param -n mdc.*.max_pages_per_rpc)*$(page_size)))
+       RPC_NUM=$(((NRFILES * DIRENT_SIZE + RPC_SIZE - 1) / RPC_SIZE + 1))
+       mds_readpage=`lctl get_param mdc.*.stats | \
+                               awk '/^mds_readpage/ {print $2}'`
+       [ $mds_readpage -gt $RPC_NUM ] && \
+               error "large readdir doesn't take effect"
+
        rm $DIR/d24v -rf
 }
 run_test 24v "list directory with large files (handle hash collision, bug: 17560)"
@@ -1192,9 +1207,9 @@ test_27u() { # bug 4900
 run_test 27u "skip object creation on OSC w/o objects =========="
 
 test_27v() { # bug 4900
-       [ "$OSTCOUNT" -lt "2" ] && skip_env "too few OSTs" && return
-       remote_mds_nodsh && skip "remote MDS with nodsh" && return
-       remote_ost_nodsh && skip "remote OST with nodsh" && return
+        [ "$OSTCOUNT" -lt "2" ] && skip_env "too few OSTs" && return
+        remote_mds_nodsh && skip "remote MDS with nodsh" && return
+        remote_ost_nodsh && skip "remote OST with nodsh" && return
 
         exhaust_all_precreations 0x215
         reset_enospc
@@ -1213,9 +1228,10 @@ test_27v() { # bug 4900
 
         local FINISH=`date +%s`
         local TIMEOUT=`lctl get_param -n timeout`
-        [ $((FINISH - START)) -ge $((TIMEOUT / 2)) ] && \
+        local PROCESS=$((FINISH - START))
+        [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
                error "$FINISH - $START >= $TIMEOUT / 2"
-
+        sleep $((TIMEOUT / 2 - PROCESS))
         reset_enospc
 }
 run_test 27v "skip object creation on slow OST ================="
@@ -1334,6 +1350,9 @@ check_seq_oid()
                 local group=${lmm[$((j+3))]}
                 local dev=$(ostdevname $devnum)
                 local dir=${MOUNT%/*}/ost$devnum
+                local mntpt=$(facet_mntpt ost$devnum)
+
+                stop ost$devnum
                 do_facet ost$devnum mount -t $FSTYPE $dev $dir $OST_MOUNT_OPTS ||
                         { error "mounting $dev as $FSTYPE failed"; return 3; }
 
@@ -1351,7 +1370,8 @@ check_seq_oid()
                 [ $stripe -eq $i ] || { error "stripe mismatch"; return 6; }
 
                 echo -e "\t\tost $obdidx, objid $objid, group $group"
-                do_facet ost$devnum umount -d $dev
+                do_facet ost$devnum umount -d $mntpt
+                start ost$devnum $dev $OST_MOUNT_OPTS
         done
 }
 
@@ -1444,12 +1464,30 @@ test_29() {
 }
 run_test 29 "IT_GETATTR regression  ============================"
 
-test_30() {
+test_30a() { # was test_30
+       cp `which ls` $DIR || cp /bin/ls $DIR
+       $DIR/ls / || error
+       rm $DIR/ls
+}
+run_test 30a "execute binary from Lustre (execve) =============="
+
+test_30b() {
        cp `which ls` $DIR || cp /bin/ls $DIR
-       $DIR/ls /
+       chmod go+rx $DIR/ls
+       $RUNAS $DIR/ls / || error
        rm $DIR/ls
 }
-run_test 30 "run binary from Lustre (execve) ==================="
+run_test 30b "execute binary from Lustre as non-root ==========="
+
+test_30c() { # b=22376
+       cp `which ls` $DIR || cp /bin/ls $DIR
+       chmod a-rw $DIR/ls
+       cancel_lru_locks mdc
+       cancel_lru_locks osc
+       $RUNAS $DIR/ls / || error
+       rm -f $DIR/ls
+}
+run_test 30c "execute binary from Lustre without read perms ===="
 
 test_31a() {
        $OPENUNLINK $DIR/f31 $DIR/f31 || error
@@ -1848,7 +1886,7 @@ test_33c() {
         for ostnum in $(seq $OSTCOUNT); do
                 # test-framework's OST numbering is one-based, while Lustre's
                 # is zero-based
-                ostname=$(printf "lustre-OST%.4d" $((ostnum - 1)))
+                ostname=$(printf "$FSNAME-OST%.4d" $((ostnum - 1)))
                 # Parsing llobdstat's output sucks; we could grep the /proc
                 # path, but that's likely to not be as portable as using the
                 # llobdstat utility.  So we parse lctl output instead.
@@ -1872,7 +1910,7 @@ test_33c() {
 
         # Total up write_bytes after writing.  We'd better find non-zeros.
         for ostnum in $(seq $OSTCOUNT); do
-                ostname=$(printf "lustre-OST%.4d" $((ostnum - 1)))
+                ostname=$(printf "$FSNAME-OST%.4d" $((ostnum - 1)))
                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
                         obdfilter/$ostname/stats |
                         awk '/^write_bytes/ {print $7}' )
@@ -1887,7 +1925,7 @@ test_33c() {
         if $all_zeros
         then
                 for ostnum in $(seq $OSTCOUNT); do
-                        ostname=$(printf "lustre-OST%.4d" $((ostnum - 1)))
+                        ostname=$(printf "$FSNAME-OST%.4d" $((ostnum - 1)))
                         echo "Check that write_bytes is present in obdfilter/*/stats:"
                         do_facet ost$ostnum lctl get_param -n \
                                 obdfilter/$ostname/stats
@@ -2055,15 +2093,26 @@ run_test 36f "utime on file racing with OST BRW write =========="
 
 test_36g() {
        remote_ost_nodsh && skip "remote OST with nodsh" && return
+       local fmd_max_age
+       local fmd_before
+       local fmd_after
 
        mkdir -p $DIR/$tdir
-       export FMD_MAX_AGE=`do_facet ost1 lctl get_param -n obdfilter.*.client_cache_seconds 2> /dev/null | head -n 1`
-       FMD_BEFORE="`awk '/ll_fmd_cache/ { print $2 }' /proc/slabinfo`"
+       fmd_max_age=$(do_facet ost1 \
+               "lctl get_param -n obdfilter.*.client_cache_seconds 2> /dev/null | \
+               head -n 1")
+
+       fmd_before=$(do_facet ost1 \
+               "awk '/ll_fmd_cache/ {print \\\$2}' /proc/slabinfo")
        touch $DIR/$tdir/$tfile
-       sleep $((FMD_MAX_AGE + 12))
-       FMD_AFTER="`awk '/ll_fmd_cache/ { print $2 }' /proc/slabinfo`"
-       [ "$FMD_AFTER" -gt "$FMD_BEFORE" ] && \
-               echo "AFTER : $FMD_AFTER > BEFORE $FMD_BEFORE" && \
+       sleep $((fmd_max_age + 12))
+       fmd_after=$(do_facet ost1 \
+               "awk '/ll_fmd_cache/ {print \\\$2}' /proc/slabinfo")
+
+       echo "fmd_before: $fmd_before"
+       echo "fmd_after: $fmd_after"
+       [ "$fmd_after" -gt "$fmd_before" ] && \
+               echo "AFTER: $fmd_after > BEFORE: $fmd_before" && \
                error "fmd didn't expire after ping" || true
 }
 run_test 36g "filter mod data cache expiry ====================="
@@ -2213,7 +2262,7 @@ test_39e() {
        local mtime1=`stat -c %Y $DIR1/$tfile`
 
        touch -m -d @$TEST_39_MTIME $DIR1/$tfile
-       
+
        for (( i=0; i < 2; i++ )) ; do
                local mtime2=`stat -c %Y $DIR1/$tfile`
                [ $mtime2 = $TEST_39_MTIME ] || \
@@ -2251,7 +2300,7 @@ test_39g() {
 
        sleep 2
        chmod o+r $DIR1/$tfile
+
        for (( i=0; i < 2; i++ )) ; do
                local mtime2=`stat -c %Y $DIR1/$tfile`
                [ "$mtime1" = "$mtime2" ] || \
@@ -2346,7 +2395,7 @@ test_39k() {
 
        kill -USR1 $multipid
        wait $multipid || error "multiop close failed"
-               
+
        for (( i=0; i < 2; i++ )) ; do
                local mtime2=`stat -c %Y $DIR1/$tfile`
 
@@ -2409,6 +2458,26 @@ test_39l() {
 }
 run_test 39l "directory atime update ==========================="
 
+test_39m() {
+       touch $DIR1/$tfile
+       sleep 2
+       local far_past_mtime=$(date -d "May 29 1953" +%s)
+       local far_past_atime=$(date -d "Dec 17 1903" +%s)
+
+       touch -m -d @$far_past_mtime $DIR1/$tfile
+       touch -a -d @$far_past_atime $DIR1/$tfile
+
+       for (( i=0; i < 2; i++ )) ; do
+               local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
+               [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
+                       error "atime or mtime set incorrectly"
+
+               cancel_lru_locks osc
+               if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
+       done
+}
+run_test 39m "test atime and mtime before 1970"
+
 test_40() {
        dd if=/dev/zero of=$DIR/f40 bs=4096 count=1
        $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/f40 && error
@@ -2566,10 +2635,6 @@ test_42d() {
 }
 run_test 42d "test complete truncate of file with cached dirty data"
 
-page_size() {
-       getconf PAGE_SIZE
-}
-
 test_42e() { # bug22074
        local TDIR=$DIR/${tdir}e
        local pagesz=$(page_size)
@@ -3150,7 +3215,7 @@ test_54e() {
 }
 run_test 54e "console/tty device works in lustre ======================"
 
-#The test_55 used to be iopen test and it was removed by bz#24037. 
+#The test_55 used to be iopen test and it was removed by bz#24037.
 #run_test 55 "check iopen_connect_dentry() ======================"
 
 test_56a() {   # was test_56
@@ -3402,7 +3467,7 @@ run_test 56q "check lfs find -gid and ! -gid ==============================="
 test_56r() {
        setup_56 $NUMFILES $NUMDIRS
        TDIR=$DIR/${tdir}g
-       
+
        EXPECTED=12
        NUMS=`$LFIND -size 0 -t f $TDIR | wc -l`
        [ $NUMS -eq $EXPECTED ] || \
@@ -3470,7 +3535,8 @@ test_57b() {
        sync
        sleep 1
        df $dir  #make sure we get new statfs data
-       local MDSFREE=$(do_facet $mymds lctl get_param -n osd.*MDT000$((num -1)).kbytesfree)
+       local MDSFREE=$(do_facet $mymds \
+               lctl get_param -n osd*.*MDT000$((num -1)).kbytesfree)
        local MDCFREE=$(lctl get_param -n mdc.*MDT000$((num -1))-mdc-*.kbytesfree)
        echo "opening files to create objects/EAs"
        local FILE
@@ -3484,7 +3550,8 @@ test_57b() {
 
        sleep 1  #make sure we get new statfs data
        df $dir
-       local MDSFREE2=$(do_facet $mymds lctl get_param -n osd.*MDT000$((num -1)).kbytesfree)
+       local MDSFREE2=$(do_facet $mymds \
+               lctl get_param -n osd*.*MDT000$((num -1)).kbytesfree)
        local MDCFREE2=$(lctl get_param -n mdc.*MDT000$((num -1))-mdc-*.kbytesfree)
        if [ "$MDCFREE2" -lt "$((MDCFREE - 8))" ]; then
                if [ "$MDSFREE" != "$MDSFREE2" ]; then
@@ -3519,7 +3586,7 @@ TEST60_HEAD="test_60 run $RANDOM"
 test_60a() {
         [ ! -f run-llog.sh ] && skip_env "missing subtest run-llog.sh" && return
        log "$TEST60_HEAD - from kernel mode"
-       sh run-llog.sh
+       do_facet mgs sh run-llog.sh
 }
 run_test 60a "llog sanity tests run from kernel module =========="
 
@@ -3814,7 +3881,7 @@ cleanup_68() {
        if [ ! -z "$LLITELOOPLOAD" ]; then
                rmmod llite_lloop
                unset LLITELOOPLOAD
-       fi 
+       fi
        rm -f $DIR/f68*
 }
 
@@ -3829,6 +3896,8 @@ swap_used() {
 # test case for lloop driver, basic function
 test_68a() {
        [ "$UID" != 0 ] && skip_env "must run as root" && return
+       llite_lloop_enabled || \
+               { skip_env "llite_lloop module disabled" && return; }
 
        trap cleanup_68 EXIT
 
@@ -3924,7 +3993,7 @@ test_71() {
 }
 run_test 71 "Running dbench on lustre (don't segment fault) ===="
 
-test_72() { # bug 5695 - Test that on 2.6 remove_suid works properly
+test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
        check_kernel_version 43 || return 0
        [ "$RUNAS_ID" = "$UID" ] && skip_env "RUNAS_ID = UID = $UID -- skipping" && return
 
@@ -3947,7 +4016,35 @@ test_72() { # bug 5695 - Test that on 2.6 remove_suid works properly
        true
        rm -f $DIR/f72
 }
-run_test 72 "Test that remove suid works properly (bug5695) ===="
+run_test 72a "Test that remove suid works properly (bug5695) ===="
+
+test_72b() { # bug 24226 -- keep mode setting when size is not changing
+       local perm
+
+       [ "$RUNAS_ID" = "$UID" ] && \
+               skip_env "RUNAS_ID = UID = $UID -- skipping" && return
+       [ "$RUNAS_ID" -eq 0 ] && \
+               skip_env "RUNAS_ID = 0 -- skipping" && return
+
+       # Check that testing environment is properly set up. Skip if not
+       FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS || {
+               skip_env "User $RUNAS_ID does not exist - skipping"
+               return 0
+       }
+       touch $DIR/${tfile}-f{g,u}
+       mkdir $DIR/${tfile}-d{g,u}
+       chmod 770 $DIR/${tfile}-{f,d}{g,u}
+       chmod g+s $DIR/${tfile}-{f,d}g
+       chmod u+s $DIR/${tfile}-{f,d}u
+       for perm in 777 2777 4777; do
+               $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
+               $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
+               $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
+               $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
+       done
+       true
+}
+run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
 
 # bug 3462 - multiple simultaneous MDC requests
 test_73() {
@@ -4074,13 +4171,12 @@ set_checksums()
        return 0
 }
 
-export ORIG_CSUM_TYPE=""
+export ORIG_CSUM_TYPE="`lctl get_param -n osc/*osc-[^mM]*/checksum_type |
+                        sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
 CKSUM_TYPES=${CKSUM_TYPES:-"crc32 adler"}
+[ "$ORIG_CSUM_TYPE" = "crc32c" ] && CKSUM_TYPES="$CKSUM_TYPES crc32c"
 set_checksum_type()
 {
-       [ "$ORIG_CSUM_TYPE" ] || \
-               ORIG_CSUM_TYPE=`lctl get_param -n osc/*osc-[^mM]*/checksum_type |
-                                sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`
        lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
        log "set checksum type to $1"
        return 0
@@ -4326,10 +4422,42 @@ test_80() { # bug 10718
                 error "elapsed for 1M@1T = $DIFF"
         fi
         true
-       rm -f $DIR/$tfile
+        rm -f $DIR/$tfile
 }
 run_test 80 "Page eviction is equally fast at high offsets too  ===="
 
+test_81a() { # LU-456
+        # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
+        # MUST OR with the OBD_FAIL_ONCE (0x80000000)
+        do_facet ost0 lctl set_param fail_loc=0x80000228
+
+        # write should trigger a retry and success
+        $SETSTRIPE -i 0 -c 1 $DIR/$tfile
+        multiop $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
+        RC=$?
+        if [ $RC -ne 0 ] ; then
+                error "write should success, but failed for $RC"
+        fi
+}
+run_test 81a "OST should retry write when get -ENOSPC ==============="
+
+test_81b() { # LU-456
+        # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
+        # Don't OR with the OBD_FAIL_ONCE (0x80000000)
+        do_facet ost0 lctl set_param fail_loc=0x228
+
+        # write should retry several times and return -ENOSPC finally
+        $SETSTRIPE -i 0 -c 1 $DIR/$tfile
+        multiop $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
+        RC=$?
+        ENOSPC=28
+        if [ $RC -ne $ENOSPC ] ; then
+                error "dd should fail for -ENOSPC, but succeed."
+        fi
+}
+run_test 81b "OST should return -ENOSPC when retry still fails ======="
+
+
 test_99a() {
         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs" && \
            return
@@ -4961,7 +5089,7 @@ test_104a() {
        OSC=`lctl get_param -n devices | awk '/-osc-/ {print $4}' | head -n 1`
        lctl --device %$OSC deactivate
        lfs df || error "lfs df with deactivated OSC failed"
-       lctl --device %$OSC recover
+       lctl --device %$OSC activate
        lfs df || error "lfs df with reactivated OSC failed"
        rm -f $DIR/$tfile
 }
@@ -5025,6 +5153,14 @@ test_105d() { # bug 15924
 }
 run_test 105d "flock race (should not freeze) ========"
 
+test_105e() { # bug 22660 && 22040
+       [ -z "`mount | grep \"$DIR.*flock\" | grep -v noflock`" ] && \
+               skip "mount w/o flock enabled" && return
+       touch $DIR/$tfile
+       flocks_test 3 $DIR/$tfile
+}
+run_test 105e "Two conflicting flocks from same process ======="
+
 test_106() { #bug 10921
        mkdir -p $DIR/$tdir
        $DIR/$tdir && error "exec $DIR/$tdir succeeded"
@@ -5955,6 +6091,7 @@ test_124a() {
                 LRU_SIZE=$(lctl get_param -n $PARAM)
                 if [ $LRU_SIZE -gt $(default_lru_size) ]; then
                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
+                                               log "NSDIR=$NSDIR"
                         log "NS=$(basename $NSDIR)"
                         break
                 fi
@@ -5972,6 +6109,7 @@ test_124a() {
         # for 10h. After that locks begin to be killed by client.
         local MAX_HRS=10
         local LIMIT=`lctl get_param -n $NSDIR.pool.limit`
+               log "LIMIT=$LIMIT"
 
         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
         # killing locks. Some time was spent for creating locks. This means
@@ -5986,6 +6124,7 @@ test_124a() {
         local LRU_SIZE_B=$LRU_SIZE
         log "LVF=$LVF"
         local OLD_LVF=`lctl get_param -n $NSDIR.pool.lock_volume_factor`
+               log "OLD_LVF=$OLD_LVF"
         lctl set_param -n $NSDIR.pool.lock_volume_factor $LVF
 
         # Let's make sure that we really have some margin. Client checks
@@ -6119,7 +6258,7 @@ test_126() { # bug 12829/13455
 }
 run_test 126 "check that the fsgid provided by the client is taken into account"
 
-test_127() { # bug 15521
+test_127a() { # bug 15521
         $SETSTRIPE -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
         $LCTL set_param osc.*.stats=0
         FSIZE=$((2048 * 1024))
@@ -6155,7 +6294,47 @@ test_127() { # bug 15521
         [ "$read_bytes" != 0 ] || error "no read done"
         [ "$write_bytes" != 0 ] || error "no write done"
 }
-run_test 127 "verify the client stats are sane"
+run_test 127a "verify the client stats are sane"
+
+test_127b() { # bug LU-333
+        $LCTL set_param llite.*.stats=0
+        FSIZE=65536 # sized fixed to match PAGE_SIZE for most clients
+        # perform 2 reads and writes so MAX is different from SUM.
+        dd if=/dev/zero of=$DIR/$tfile bs=$FSIZE count=1
+        dd if=/dev/zero of=$DIR/$tfile bs=$FSIZE count=1
+        cancel_lru_locks osc
+        dd if=$DIR/$tfile of=/dev/null bs=$FSIZE count=1
+        dd if=$DIR/$tfile of=/dev/null bs=$FSIZE count=1
+
+        $LCTL get_param llite.*.stats | grep samples > $TMP/${tfile}.tmp
+        while read NAME COUNT SAMP UNIT MIN MAX SUM SUMSQ; do
+                echo "got $COUNT $NAME"
+                eval $NAME=$COUNT || error "Wrong proc format"
+
+        case $NAME in
+                read_bytes)
+                        [ $COUNT -ne 2 ] && error "count is not 2: $COUNT"
+                        [ $MIN -ne $FSIZE ] && error "min is not $FSIZE: $MIN"
+                        [ $MAX -ne $FSIZE ] && error "max is incorrect: $MAX"
+                        [ $SUM -ne $((FSIZE * 2)) ] && error "sum is wrong: $SUM"
+                        ;;
+                write_bytes)
+                        [ $COUNT -ne 2 ] && error "count is not 2: $COUNT"
+                        [ $MIN -ne $FSIZE ] && error "min is not $FSIZE: $MIN"
+                        [ $MAX -ne $FSIZE ] && error "max is incorrect: $MAX"
+                        [ $SUM -ne $((FSIZE * 2)) ] && error "sum is wrong: $SUM"
+                        ;;
+                        *) ;;
+                esac
+        done < $TMP/${tfile}.tmp
+
+        #check that we actually got some stats
+        [ "$read_bytes" ] || error "Missing read_bytes stats"
+        [ "$write_bytes" ] || error "Missing write_bytes stats"
+        [ "$read_bytes" != 0 ] || error "no read done"
+        [ "$write_bytes" != 0 ] || error "no write done"
+}
+run_test 127b "verify the llite client stats are sane"
 
 test_128() { # bug 15212
        touch $DIR/$tfile
@@ -6586,6 +6765,105 @@ test_132() { #1028, SOM
 }
 run_test 132 "som avoids glimpse rpc"
 
+check_stats() {
+       local res
+       local count
+       case $1 in
+       $SINGLEMDS) res=`do_facet $SINGLEMDS $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$2"`
+                ;;
+       ost) res=`do_facet ost $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$2"`
+                ;;
+       *) error "Wrong argument $1" ;;
+       esac
+       echo $res
+       count=`echo $res | awk '{print $2}'`
+       [ -z "$res" ] && error "The counter for $2 on $1 was not incremented"
+       # if the argument $3 is zero, it means any stat increment is ok.
+       if [ $3 -gt 0 ] ; then
+               [ $count -ne $3 ] && error "The $2 counter on $1 is wrong - expected $3"
+       fi
+}
+
+test_133a() {
+       local testdir=$DIR/${tdir}/stats_testdir
+       mkdir -p $DIR/${tdir}
+
+       # clear stats.
+       do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
+       do_facet ost $LCTL set_param obdfilter.*.stats=clear
+
+       # verify mdt stats first.
+       mkdir ${testdir} || error "mkdir failed"
+       check_stats $SINGLEMDS "mkdir" 1
+       touch ${testdir}/${tfile} || "touch failed"
+       check_stats $SINGLEMDS "open" 1
+       check_stats $SINGLEMDS "close" 1
+       mknod ${testdir}/${tfile}-pipe p || "mknod failed"
+       check_stats $SINGLEMDS "mknod" 1
+       rm -f ${testdir}/${tfile}-pipe || "pipe remove failed"
+       check_stats $SINGLEMDS "unlink" 1
+       rm -f ${testdir}/${tfile} || error "file remove failed"
+       check_stats $SINGLEMDS "unlink" 2
+
+       # remove working dir and check mdt stats again.
+       rmdir ${testdir} || error "rmdir failed"
+       check_stats $SINGLEMDS "rmdir" 1
+
+       rm -rf $DIR/${tdir}
+}
+run_test 133a "Verifying MDT stats ========================================"
+
+test_133b() {
+       local testdir=$DIR/${tdir}/stats_testdir
+       mkdir -p ${testdir} || error "mkdir failed"
+       touch ${testdir}/${tfile} || "touch failed"
+       cancel_lru_locks mdc
+
+       # clear stats.
+       do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
+       do_facet ost $LCTL set_param obdfilter.*.stats=clear
+
+       # extra mdt stats verification.
+       chmod 444 ${testdir}/${tfile} || error "chmod failed"
+       check_stats $SINGLEMDS "setattr" 1
+       $LFS df || error "lfs failed"
+       check_stats $SINGLEMDS "statfs" 1
+
+       rm -rf $DIR/${tdir}
+}
+run_test 133b "Verifying extra MDT stats =================================="
+
+test_133c() {
+       local testdir=$DIR/${tdir}/stats_testdir
+       mkdir -p ${testdir} || error "mkdir failed"
+
+       # verify obdfilter stats.
+       $LFS setstripe -c 1 -o 0 ${testdir}/${tfile}
+       sync
+       cancel_lru_locks osc
+
+       # clear stats.
+       do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
+       do_facet ost $LCTL set_param obdfilter.*.stats=clear
+
+       dd if=/dev/zero of=${testdir}/${tfile} conv=notrunc bs=1024k count=1 || error "dd failed"
+       sync
+       cancel_lru_locks osc
+       check_stats ost "write" 1
+
+       dd if=${testdir}/${tfile} of=/dev/null bs=1k count=1 || error "dd failed"
+       check_stats ost "read" 1
+
+       > ${testdir}/${tfile} || error "truncate failed"
+       check_stats ost "punch" 1
+
+       rm -f ${testdir}/${tfile} || error "file remove failed"
+       check_stats ost "destroy" 1
+
+       rm -rf $DIR/${tdir}
+}
+run_test 133c "Verifying OST stats ========================================"
+
 test_140() { #bug-17379
         mkdir -p $DIR/$tdir || error "Creating dir $DIR/$tdir"
         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
@@ -6758,14 +7036,9 @@ test_154() {
 }
 run_test 154 "Opening a file by FID"
 
-test_155_load() {
+test_155_small_load() {
     local temp=$TMP/$tfile
     local file=$DIR/$tfile
-    local list=$(comma_list $(osts_nodes))
-    local big=$(do_nodes $list grep "cache" /proc/cpuinfo | \
-        awk '{sum+=$4} END{print sum}')
-
-    log big is $big K
 
     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
         error "dd of=$temp bs=6096 count=1 failed"
@@ -6785,44 +7058,94 @@ test_155_load() {
     echo "12345" >>$file
     cmp $temp $file || error "$temp $file differ (append2)"
 
-    dd if=/dev/urandom of=$temp bs=$((big*2)) count=1k || \
-        error "dd of=$temp bs=$((big*2)) count=1k failed"
+    rm -f $temp $file
+    true
+}
+
+test_155_big_load() {
+    local temp=$TMP/$tfile
+    local file=$DIR/$tfile
+
+    free_min_max
+    local cache_size=$(do_facet ost$((MAXI+1)) \
+        "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
+    local large_file_size=$((cache_size * 2))
+
+    echo "OSS cache size: $cache_size KB"
+    echo "Large file size: $large_file_size KB"
+
+    [ $MAXV -le $large_file_size ] && \
+        skip_env "max available OST size needs > $large_file_size KB" && \
+        return 0
+
+    $SETSTRIPE $file -c 1 -i $MAXI || error "$SETSTRIPE $file failed"
+
+    dd if=/dev/urandom of=$temp bs=$large_file_size count=1k || \
+        error "dd of=$temp bs=$large_file_size count=1k failed"
     cp $temp $file
     ls -lh $temp $file
     cancel_lru_locks osc
     cmp $temp $file || error "$temp $file differ"
 
-    rm -f $temp
+    rm -f $temp $file
     true
 }
 
 test_155a() {
     set_cache read on
     set_cache writethrough on
-    test_155_load
+    test_155_small_load
 }
-run_test 155a "Verification of correctness: read cache:on write_cache:on"
+run_test 155a "Verify small file correctness: read cache:on write_cache:on"
 
 test_155b() {
     set_cache read on
     set_cache writethrough off
-    test_155_load
+    test_155_small_load
 }
-run_test 155b "Verification of correctness: read cache:on write_cache:off"
+run_test 155b "Verify small file correctness: read cache:on write_cache:off"
 
 test_155c() {
     set_cache read off
     set_cache writethrough on
-    test_155_load
+    test_155_small_load
 }
-run_test 155c "Verification of correctness: read cache:off write_cache:on"
+run_test 155c "Verify small file correctness: read cache:off write_cache:on"
 
 test_155d() {
     set_cache read off
     set_cache writethrough off
-    test_155_load
+    test_155_small_load
+}
+run_test 155d "Verify small file correctness: read cache:off write_cache:off"
+
+test_155e() {
+    set_cache read on
+    set_cache writethrough on
+    test_155_big_load
 }
-run_test 155d "Verification of correctness: read cache:off write_cache:off "
+run_test 155e "Verify big file correctness: read cache:on write_cache:on"
+
+test_155f() {
+    set_cache read on
+    set_cache writethrough off
+    test_155_big_load
+}
+run_test 155f "Verify big file correctness: read cache:on write_cache:off"
+
+test_155g() {
+    set_cache read off
+    set_cache writethrough on
+    test_155_big_load
+}
+run_test 155g "Verify big file correctness: read cache:off write_cache:on"
+
+test_155h() {
+    set_cache read off
+    set_cache writethrough off
+    test_155_big_load
+}
+run_test 155h "Verify big file correctness: read cache:off write_cache:off"
 
 test_156() {
     local CPAGES=3
@@ -7216,7 +7539,9 @@ test_170() {
         local expected_good=$((good_line1 + good_line2*2))
 
         rm -f $TMP/${tfile}*
-        if [ $bad_line -ne $bad_line_new ]; then
+       # LU-231, short malformed line may not be counted into bad lines
+        if [ $bad_line -ne $bad_line_new ] &&
+                  [ $bad_line -ne $((bad_line_new - 1)) ]; then
                 error "expected $bad_line bad lines, but got $bad_line_new"
                 return 1
         fi
@@ -7233,9 +7558,12 @@ test_171() { # bug20592
 #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
         $LCTL set_param fail_loc=0x50e
         $LCTL set_param fail_val=3000
-        multiop_bg_pause $DIR/$tfile Os || true
+        multiop_bg_pause $DIR/$tfile O_s || true
+        local MULTIPID=$!
+        kill -USR1 $MULTIPID
         # cause log dump
         sleep 3
+        wait $MULTIPID
         if dmesg | grep "recursive fault"; then
                 error "caught a recursive fault"
         fi
@@ -7250,6 +7578,9 @@ setup_obdecho_osc () {
         local ost_nid=$1
         local obdfilter_name=$2
         echo "Creating new osc for $obdfilter_name on $ost_nid"
+        # make sure we can find loopback nid
+        $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
+
         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
                            ${obdfilter_name}_osc_UUID || rc=2; }
         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
@@ -7292,15 +7623,17 @@ test_180a() {
         local rmmod_local=0
 
         if ! module_loaded obdecho; then
-            load_module obdecho/obdecho 
-            rmmod_local=1           
+            load_module obdecho/obdecho
+            rmmod_local=1
         fi
 
         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
-        local host=$(awk '/current_connection:/ {print $2}' /proc/fs/lustre/osc/$osc/import)
-        local target=$(awk '/target:/ {print $2}' /proc/fs/lustre/osc/$osc/import)
+        local host=$(lctl get_param -n osc.$osc.import |
+                             awk '/current_connection:/ {print $2}' )
+        local target=$(lctl get_param -n osc.$osc.import |
+                             awk '/target:/ {print $2}' )
         target=${target%_UUID}
-        
+
         [[ -n $target ]]  && { setup_obdecho_osc $host $target || rc=1; } || rc=1
         [ $rc -eq 0 ] && { obdecho_create_test ${target}_osc client || rc=2; }
         [[ -n $target ]] && cleanup_obdecho_osc $target
@@ -7323,6 +7656,25 @@ test_180b() {
 }
 run_test 180b "test obdecho directly on obdfilter"
 
+test_181() { # bug 22177
+       mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
+       # create enough files to index the directory
+       createmany -o $DIR/$tdir/foobar 4000
+       # print attributes for debug purpose
+       lsattr -d .
+       # open dir
+       multiop_bg_pause $DIR/$tdir D_Sc || return 1
+       MULTIPID=$!
+       # remove the files & current working dir
+       unlinkmany $DIR/$tdir/foobar 4000
+       rmdir $DIR/$tdir
+       kill -USR1 $MULTIPID
+       wait $MULTIPID
+       stat $DIR/$tdir && error "open-unlinked dir was not removed!"
+       return 0
+}
+run_test 181 "Test open-unlinked dir ========================"
+
 # OST pools tests
 POOL=${POOL:-cea1}
 TGT_COUNT=$OSTCOUNT
@@ -7488,8 +7840,8 @@ run_test 201b "Remove all targets from a pool =========================="
 test_201c() {
        remote_mgs_nodsh && skip "remote MGS with nodsh" && return
        do_facet mgs $LCTL pool_destroy $FSNAME.$POOL
-       
-       sleep 2                        
+
+       sleep 2
     # striping on an empty/nonexistant pool should fall back to "pool of everything"
        touch ${POOL_DIR}/$tfile || error "failed to use fallback striping for missing pool"
        # setstripe on an empty pool should fail
@@ -7508,6 +7860,136 @@ run_test 201c "Remove a pool ============================================"
 
 cleanup_pools $FSNAME
 
+# usage: default_attr <count | size | offset>
+default_attr() {
+       $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
+}
+
+# usage: trim <string>
+# Trims leading and trailing whitespace from the parameter string
+trim() {
+    echo $@
+}
+
+# usage: check_default_stripe_attr <count | size | offset>
+check_default_stripe_attr() {
+       # $GETSTRIPE returns trailing whitespace which needs to be trimmed off
+       ACTUAL=$(trim $($GETSTRIPE --$1 $DIR/$tdir))
+       if [ $1 = "count" -o $1 = "size" ]; then
+               EXPECTED=`default_attr $1`;
+       else
+               # the 'stripeoffset' parameter prints as an unsigned int, so
+               # until this is fixed we hard-code -1 here
+               EXPECTED=-1;
+       fi
+       [ "x$ACTUAL" != "x$EXPECTED" ] &&
+               error "$DIR/$tdir has stripe $1 '$ACTUAL', not '$EXPECTED'"
+}
+
+# usage: check_raw_stripe_attr <count | size | offset>
+check_raw_stripe_attr() {
+       # $GETSTRIPE returns trailing whitespace which needs to be trimmed off
+       ACTUAL=$(trim $($GETSTRIPE --raw --$1 $DIR/$tdir))
+       if [ $1 = "count" -o $1 = "size" ]; then
+               EXPECTED=0;
+       else
+               EXPECTED=-1;
+       fi
+       [ "x$ACTUAL" != "x$EXPECTED" ] &&
+               error "$DIR/$tdir has raw stripe $1 '$ACTUAL', not '$EXPECTED'"
+}
+
+
+test_204a() {
+       mkdir -p $DIR/$tdir
+       $SETSTRIPE --count 0 --size 0 --offset -1 $DIR/$tdir
+
+       check_default_stripe_attr count
+       check_default_stripe_attr size
+       check_default_stripe_attr offset
+
+       return 0
+}
+run_test 204a "Print default stripe attributes ================="
+
+test_204b() {
+       mkdir -p $DIR/$tdir
+       $SETSTRIPE --count 1 $DIR/$tdir
+
+       check_default_stripe_attr size
+       check_default_stripe_attr offset
+
+       return 0
+}
+run_test 204b "Print default stripe size and offset  ==========="
+
+test_204c() {
+       mkdir -p $DIR/$tdir
+       $SETSTRIPE --size 65536 $DIR/$tdir
+
+       check_default_stripe_attr count
+       check_default_stripe_attr offset
+
+       return 0
+}
+run_test 204c "Print default stripe count and offset ==========="
+
+test_204d() {
+       mkdir -p $DIR/$tdir
+       $SETSTRIPE --offset 0 $DIR/$tdir
+
+       check_default_stripe_attr count
+       check_default_stripe_attr size
+
+       return 0
+}
+run_test 204d "Print default stripe count and size ============="
+
+test_204e() {
+       mkdir -p $DIR/$tdir
+       $SETSTRIPE -d $DIR/$tdir
+
+       check_raw_stripe_attr count
+       check_raw_stripe_attr size
+       check_raw_stripe_attr offset
+
+       return 0
+}
+run_test 204e "Print raw stripe attributes ================="
+
+test_204f() {
+       mkdir -p $DIR/$tdir
+       $SETSTRIPE --count 1 $DIR/$tdir
+
+       check_raw_stripe_attr size
+       check_raw_stripe_attr offset
+
+       return 0
+}
+run_test 204f "Print raw stripe size and offset  ==========="
+
+test_204g() {
+       mkdir -p $DIR/$tdir
+       $SETSTRIPE --size 65536 $DIR/$tdir
+
+       check_raw_stripe_attr count
+       check_raw_stripe_attr offset
+
+       return 0
+}
+run_test 204g "Print raw stripe count and offset ==========="
+
+test_204h() {
+       mkdir -p $DIR/$tdir
+       $SETSTRIPE --offset 0 $DIR/$tdir
+
+       check_raw_stripe_attr count
+       check_raw_stripe_attr size
+
+       return 0
+}
+run_test 204h "Print raw stripe count and size ============="
+
 test_212() {
        size=`date +%s`
        size=$((size % 8192 + 1))
@@ -7736,6 +8218,69 @@ test_218() {
 }
 run_test 218 "parallel read and truncate should not deadlock ======================="
 
+test_219() {
+        # write one partial page
+        dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
+        # set no grant so vvp_io_commit_write will do sync write
+        $LCTL set_param fail_loc=0x411
+        # write a full page at the end of file
+        dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
+
+        $LCTL set_param fail_loc=0
+        dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
+        $LCTL set_param fail_loc=0x411
+        dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
+}
+run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
+
+test_220() { #LU-325
+       local OSTIDX=0
+
+       mkdir -p $DIR/$tdir
+       local OST=$(lfs osts | grep ${OSTIDX}": " | \
+               awk '{print $2}' | sed -e 's/_UUID$//')
+
+        # on the mdt's osc
+       local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
+       local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
+                       osc.$mdtosc_proc1.prealloc_last_id)
+       local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
+                       osc.$mdtosc_proc1.prealloc_next_id)
+
+       $LFS df -i
+
+       do_facet mgs $LCTL pool_new $FSNAME.$TESTNAME || return 1
+       do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
+
+       $SETSTRIPE $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
+
+       echo "preallocated objects in MDS is $((last_id - next_id))" \
+             "($last_id - $next_id)"
+
+       count=$($LFS df -i $MOUNT | grep ^$OST | awk '{print $4}')
+       echo "OST still has $count objects"
+
+       free=$((count + last_id - next_id))
+       echo "create $((free - next_id)) files @next_id..."
+       createmany -o $DIR/$tdir/f $next_id $free || return 3
+
+       local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
+                       osc.$mdtosc_proc1.prealloc_last_id)
+       local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
+                       osc.$mdtosc_proc1.prealloc_next_id)
+
+       echo "after creation, last_id=$last_id2, next_id=$next_id2"
+       $LFS df -i
+
+       echo "cleanup..."
+
+       do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST || return 4
+       do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME || return 5
+       echo "unlink $((free - next_id)) files @ $next_id..."
+       unlinkmany $DIR/$tdir/f $next_id $free || return 3
+}
+run_test 220 "the preallocated objects in MDS still can be used if ENOSPC is returned by OST with enough disk space"
+
 #
 # tests that do cleanup/setup should be run at the end
 #
@@ -7753,12 +8298,9 @@ test_900() {
 }
 run_test 900 "umount should not race with any mgc requeue thread"
 
-log "cleanup: ======================================================"
+complete $(basename $0) $SECONDS
 check_and_cleanup_lustre
 if [ "$I_MOUNTED" != "yes" ]; then
        lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
 fi
-
-echo '=========================== finished ==============================='
-[ -f "$SANITYLOG" ] && cat $SANITYLOG && grep -q FAIL $SANITYLOG && exit 1 || true
-echo "$0: completed"
+exit_status