Whamcloud - gitweb
b=1028 drop SOM dependency on quota
[fs/lustre-release.git] / lustre / tests / sanity-quota.sh
index e928e14..589bc6a 100644 (file)
@@ -17,6 +17,8 @@ SRCDIR=`dirname $0`
 export PATH=$PWD/$SRCDIR:$SRCDIR:$PWD/$SRCDIR/../utils:$PATH:/sbin
 
 ONLY=${ONLY:-"$*"}
+# test_11 has been used to protect a kernel bug(bz10912), now it isn't
+# useful any more. Then add it to ALWAYS_EXCEPT. b=19835
 ALWAYS_EXCEPT="10 $SANITY_QUOTA_EXCEPT"
 # UPDATE THE COMMENT ABOVE WITH BUG NUMBERS WHEN CHANGING ALWAYS_EXCEPT!
 
@@ -46,11 +48,13 @@ LUSTRE=${LUSTRE:-`dirname $0`/..}
 . $LUSTRE/tests/test-framework.sh
 init_test_env $@
 . ${CONFIG:=$LUSTRE/tests/cfg/$NAME.sh}
+init_logging
 DIRECTIO=${DIRECTIO:-$LUSTRE/tests/directio}
 
 [ $MDSCOUNT -gt 1 ] && skip "CMD case" && exit 0
-remote_mds_nodsh && skip "remote MDS with nodsh" && exit 0
-remote_ost_nodsh && skip "remote OST with nodsh" && exit 0
+
+require_dsh_mds || exit 0
+require_dsh_ost || exit 0
 
 [ "$SLOW" = "no" ] && EXCEPT_SLOW="9 10 11 18b 21"
 
@@ -61,16 +65,22 @@ QUOTALOG=${TESTSUITELOG:-$TMP/$(basename $0 .sh).log}
 DIR=${DIR:-$MOUNT}
 DIR2=${DIR2:-$MOUNT2}
 
+QUOTA_AUTO_OLD=$QUOTA_AUTO
+export QUOTA_AUTO=0
+
 check_and_setup_lustre
 
 LOVNAME=`lctl get_param -n llite.*.lov.common_name | tail -n 1`
 OSTCOUNT=`lctl get_param -n lov.$LOVNAME.numobd`
 
 SHOW_QUOTA_USER="$LFS quota -v -u $TSTUSR $DIR"
+SHOW_QUOTA_USERID="$LFS quota -v -u $TSTID $DIR"
 SHOW_QUOTA_USER2="$LFS quota -v -u $TSTUSR2 $DIR"
 SHOW_QUOTA_GROUP="$LFS quota -v -g $TSTUSR $DIR"
+SHOW_QUOTA_GROUPID="$LFS quota -v -g $TSTID $DIR"
 SHOW_QUOTA_GROUP2="$LFS quota -v -g $TSTUSR2 $DIR"
-SHOW_QUOTA_INFO="$LFS quota -t $DIR"
+SHOW_QUOTA_INFO_USER="$LFS quota -t -u $DIR"
+SHOW_QUOTA_INFO_GROUP="$LFS quota -t -g $DIR"
 
 # control the time of tests
 cycle=30
@@ -78,9 +88,6 @@ cycle=30
 
 build_test_filter
 
-eval ONLY_0=true
-eval ONLY_99=true
-
 # set_blk_tunables(btune_sz)
 set_blk_tunesz() {
        local btune=$(($1 * BLK_SZ))
@@ -171,12 +178,35 @@ run_test_with_stat() {
 #        resetquota -g groupname
 
 resetquota() {
-       [ "$#" != 2 ] && error "resetquota: wrong number of arguments: $#"
-       [ "$1" != "-u" -a "$1" != "-g" ] && error "resetquota: wrong specifier $1 passed"
-       $LFS setquota "$1" "$2" -b 0 -B 0 -i 0 -I 0 $MOUNT || error "resetquota failed"
+        [ "$#" != 2 ] && error "resetquota: wrong number of arguments: $#"
+        [ "$1" != "-u" -a "$1" != "-g" ] && error "resetquota: wrong specifier $1 passed"
+
+        count=0
+        if at_is_enabled; then
+           timeout=$(at_max_get mds)
+        else
+           timeout=$(lctl get_param -n timeout)
+        fi
+
+        while [ $((count++)) -lt $timeout ]; do
+                $LFS setquota "$1" "$2" -b 0 -B 0 -i 0 -I 0 $MOUNT
+                RC=$?
+                if [ $RC -ne 0 ]; then
+                        if [ $RC -eq 240 ]; then # 240 means -EBUSY
+                                log "resetquota is blocked for quota master recovery, retry after 1 sec"
+                                sleep 1
+                                continue
+                        else
+                                error "resetquota failed: $RC"
+                        fi
+                fi
+                break
+        done
+
+        [ $count -lt $timeout ] || error "resetquota timeout: $timeout"
 }
 
-quota_error() {
+quota_scan() {
         LOCAL_UG=$1
         LOCAL_ID=$2
 
@@ -189,11 +219,20 @@ quota_error() {
                 log "Files for group ($LOCAL_ID):"
                 ($LFS find -group $LOCAL_ID $DIR | xargs stat 2>/dev/null)
         fi
+}
 
+quota_error() {
+        quota_scan $1 $2
         shift 2
         error "$*"
 }
 
+quota_log() {
+        quota_scan $1 $2
+        shift 2
+        log "$*"
+}
+
 quota_show_check() {
         LOCAL_BF=$1
         LOCAL_UG=$2
@@ -204,30 +243,33 @@ quota_show_check() {
 
         if [ "$LOCAL_BF" == "a" -o "$LOCAL_BF" == "b" ]; then
                USAGE="`$LFS quota -$LOCAL_UG $LOCAL_ID $DIR | awk '/^.*'$PATTERN'.*[[:digit:]+][[:space:]+]/ { print $2 }'`"
-                [ $USAGE -ne 0 ] && quota_error $LOCAL_UG $LOCAL_ID "System is not clean for block ($LOCAL_UG:$LOCAL_ID:$USAGE)."
+                if [ -z $USAGE ]; then
+                        quota_error $LOCAL_UG $LOCAL_ID "System is error when query quota for block ($LOCAL_UG:$LOCAL_ID)."
+                else
+                        [ $USAGE -ne 0 ] && quota_log $LOCAL_UG $LOCAL_ID "System is not clean for block ($LOCAL_UG:$LOCAL_ID:$USAGE)."
+                fi
         fi
 
         if [ "$LOCAL_BF" == "a" -o "$LOCAL_BF" == "f" ]; then
                USAGE="`$LFS quota -$LOCAL_UG $LOCAL_ID $DIR | awk '/^.*'$PATTERN'.*[[:digit:]+][[:space:]+]/ { print $5 }'`"
-                [ $USAGE -ne 0 ] && quota_error $LOCAL_UG $LOCAL_ID "System is not clean for file ($LOCAL_UG:$LOCAL_ID:$USAGE)."
+                if [ -z $USAGE ]; then
+                        quota_error $LOCAL_UG $LOCAL_ID "System is error when query quota for file ($LOCAL_UG:$LOCAL_ID)."
+                else
+                        [ $USAGE -ne 0 ] && quota_log $LOCAL_UG $LOCAL_ID "System is not clean for file ($LOCAL_UG:$LOCAL_ID:$USAGE)."
+                fi
         fi
 }
 
 # set quota
-test_0() {
-       $LFS quotaoff -ug $DIR
+quota_init() {
        $LFS quotacheck -ug $DIR
 
        resetquota -u $TSTUSR
        resetquota -g $TSTUSR
 
-       lctl set_param debug="+quota"
-       do_facet $SINGLEMDS "lctl set_param debug=+quota"
-       for num in `seq $OSTCOUNT`; do
-           do_facet ost$num "lctl set_param debug=+quota"
-       done
+        do_nodes $(comma_list $(nodes_list)) "lctl set_param debug=+quota"
 }
-run_test_with_stat 0 "Set quota ============================="
+quota_init
 
 # test for specific quota limitation, qunit, qtune $1=block_quota_limit
 test_1_sub() {
@@ -248,7 +290,14 @@ test_1_sub() {
         chown $TSTUSR.$TSTUSR $TESTFILE
 
         log "    Write ..."
+        stime=`date +%s`
        $RUNAS dd if=/dev/zero of=$TESTFILE bs=$BLK_SZ count=$(($LIMIT/2)) || quota_error u $TSTUSR "(usr) write failure, but expect success"
+        etime=`date +%s`
+        delta=$((etime - stime))
+        if [ $delta -gt 0 ]; then
+                rate=$((BLK_SZ * LIMIT / 2 / delta / 1024))
+                [ $rate -gt 1024 ] || error "SLOW IO for $TSTUSR (user): $rate KB/sec"
+        fi
         log "    Done"
         log "    Write out of block quota ..."
        # this time maybe cache write,  ignore it's failure
@@ -279,7 +328,14 @@ test_1_sub() {
         chown $TSTUSR.$TSTUSR $TESTFILE
 
         log "    Write ..."
+        stime=`date +%s`
        $RUNAS dd if=/dev/zero of=$TESTFILE bs=$BLK_SZ count=$(($LIMIT/2)) || quota_error g $TSTUSR "(grp) write failure, but expect success"
+        etime=`date +%s`
+        delta=$((etime - stime))
+        if [ $delta -gt 0 ]; then
+               rate=$((BLK_SZ * LIMIT / 2 / delta / 1024))
+               [ $rate -gt 1024 ] || error "SLOW IO for $TSTUSR (group): $rate KB/sec"
+       fi
         log "    Done"
         log "    Write out of block quota ..."
        # this time maybe cache write, ignore it's failure
@@ -306,7 +362,7 @@ test_1() {
            blk_qunit=$(( $RANDOM % 3072 + 1024 ))
            blk_qtune=$(( $RANDOM % $blk_qunit ))
            # other osts and mds will occupy at 1M blk quota
-           b_limit=$(( ($RANDOM - 16384) / 8 +  $OSTCOUNT * $blk_qunit * 4 ))
+           b_limit=$(( ($RANDOM - 16384) / 8 +  ($OSTCOUNT + 1) * $blk_qunit * 4 ))
            set_blk_tunesz $blk_qtune
            set_blk_unitsz $blk_qunit
            echo "cycle: $i(total $cycle) bunit:$blk_qunit, btune:$blk_qtune, blimit:$b_limit"
@@ -424,7 +480,8 @@ test_block_soft() {
 
        $SHOW_QUOTA_USER
        $SHOW_QUOTA_GROUP
-       $SHOW_QUOTA_INFO
+       $SHOW_QUOTA_INFO_USER
+       $SHOW_QUOTA_INFO_GROUP
 
        echo "    Write before timer goes off"
        $RUNDD count=$BUNIT_SZ seek=$OFFSET || \
@@ -438,7 +495,8 @@ test_block_soft() {
 
         $SHOW_QUOTA_USER
         $SHOW_QUOTA_GROUP
-        $SHOW_QUOTA_INFO
+        $SHOW_QUOTA_INFO_USER
+        $SHOW_QUOTA_INFO_GROUP
 
        echo "    Write after timer goes off"
        # maybe cache write, ignore.
@@ -450,7 +508,8 @@ test_block_soft() {
 
         $SHOW_QUOTA_USER
         $SHOW_QUOTA_GROUP
-        $SHOW_QUOTA_INFO
+        $SHOW_QUOTA_INFO_USER
+        $SHOW_QUOTA_INFO_GROUP
 
        echo "    Unlink file to stop timer"
        rm -f $TESTFILE
@@ -459,7 +518,8 @@ test_block_soft() {
 
         $SHOW_QUOTA_USER
         $SHOW_QUOTA_GROUP
-        $SHOW_QUOTA_INFO
+        $SHOW_QUOTA_INFO_USER
+        $SHOW_QUOTA_INFO_GROUP
 
        echo "    Write ..."
        $RUNDD count=$BUNIT_SZ || quota_error a $TSTUSR "write failure, but expect success"
@@ -529,7 +589,8 @@ test_file_soft() {
 
        $SHOW_QUOTA_USER
        $SHOW_QUOTA_GROUP
-       $SHOW_QUOTA_INFO
+       $SHOW_QUOTA_INFO_USER
+       $SHOW_QUOTA_INFO_GROUP
 
        echo "    Create file after timer goes off"
        # the least of inode qunit is 2, so there are at most 3(qunit:2+qtune:1)
@@ -542,7 +603,8 @@ test_file_soft() {
 
        $SHOW_QUOTA_USER
        $SHOW_QUOTA_GROUP
-       $SHOW_QUOTA_INFO
+       $SHOW_QUOTA_INFO_USER
+       $SHOW_QUOTA_INFO_GROUP
 
        echo "    Unlink files to stop timer"
        find `dirname $TESTFILE` -name "`basename ${TESTFILE}`*" | xargs rm -f
@@ -656,7 +718,7 @@ run_test_with_stat 5 "Chown & chgrp successfully even out of block/file quota ==
 # block quota acquire & release
 test_6() {
        if [ $OSTCOUNT -lt 2 ]; then
-               skip "$OSTCOUNT < 2, too few osts"
+               skip_env "$OSTCOUNT < 2, too few osts"
                return 0;
        fi
 
@@ -682,37 +744,76 @@ test_6() {
        chown $TSTUSR.$TSTUSR $FILEB
 
        echo "  Exceed quota limit ..."
-        RUNDD="$RUNAS dd if=/dev/zero of=$FILEB bs=$BLK_SZ"
+        RUNDD="$RUNAS dd if=/dev/zero of=$FILEA bs=$BLK_SZ"
         $RUNDD count=$((LIMIT - BUNIT_SZ * OSTCOUNT)) || \
-               quota_error a $TSTUSR "write fileb failure, but expect success"
+               quota_error a $TSTUSR "write filea failure, but expect success"
 
         cancel_lru_locks osc
         $SHOW_QUOTA_USER
         $SHOW_QUOTA_GROUP
         $RUNDD seek=$LIMIT count=$((BUNIT_SZ * OSTCOUNT)) && \
-               quota_error a $TSTUSR "write fileb success, but expect EDQUOT"
+               quota_error a $TSTUSR "write filea success, but expect EDQUOT"
         cancel_lru_locks osc
-       echo "  Write to OST0 return EDQUOT"
+       echo "  Write to OST1 return EDQUOT"
        # this write maybe cache write, ignore it's failure
-        RUNDD="$RUNAS dd if=/dev/zero of=$FILEA bs=$BLK_SZ"
+        RUNDD="$RUNAS dd if=/dev/zero of=$FILEB bs=$BLK_SZ"
         $RUNDD count=$(($BUNIT_SZ * 2)) || true
         cancel_lru_locks osc
         $SHOW_QUOTA_USER
         $SHOW_QUOTA_GROUP
         $RUNDD count=$((BUNIT_SZ * 2)) seek=$((BUNIT_SZ *2)) && \
-               quota_error a $TSTUSR "write filea success, but expect EDQUOT"
+               quota_error a $TSTUSR "write fileb success, but expect EDQUOT"
 
-       echo "  Remove fileb to let OST1 release quota"
-       rm -f $FILEB
-        sync; sleep 10; sync; # need to allow journal commit for small fs
+       echo "  Remove filea to let OST0 release quota"
+       rm -f $FILEA
+
+        if at_is_enabled; then
+           timeout=$(at_max_get mds)
+        else
+           timeout=$(lctl get_param -n timeout)
+        fi
+        count=$((timeout / 5))
+        OST0_UUID=`do_facet ost1 $LCTL dl | grep -m1 obdfilter | awk '{print $((NF-1))}'`
+
+        while [ $((count--)) -gt 0 ]; do
+                sync && sleep 5
+
+               OST0_QUOTA_HOLD=`$LFS quota -o $OST0_UUID -u $TSTUSR $DIR | awk '/^.*[[:digit:]+][[:space:]+]/ { print $3 }'`
+                if [ -z $OST0_QUOTA_HOLD ]; then
+                        error "System is error when query quota for block (U:$TSTUSR)."
+                else
+                        [ $OST0_QUOTA_HOLD -gt $BUNIT_SZ ] && continue
+                fi
+
+                break
+        done
+
+        [ ! $count -gt 0 ] && error "Release quota for block timeout (U:$TSTUSR)."
+        $SHOW_QUOTA_USER
+
+        while [ $((count--)) -gt 0 ]; do
+                sync && sleep 5
+
+               OST0_QUOTA_HOLD=`$LFS quota -o $OST0_UUID -g $TSTUSR $DIR | awk '/^.*[[:digit:]+][[:space:]+]/ { print $3 }'`
+                if [ -z $OST0_QUOTA_HOLD ]; then
+                        error "System is error when query quota for block (G:$TSTUSR)."
+                else
+                        [ $OST0_QUOTA_HOLD -gt $BUNIT_SZ ] && continue
+                fi
 
-       echo "  Write to OST0"
+                break
+        done
+
+        [ ! $count -gt 0 ] && error "Release quota for block timeout (G:$TSTUSR)."
+        $SHOW_QUOTA_GROUP
+
+       echo "  Write to OST1"
        $RUNDD count=$((LIMIT - BUNIT_SZ * OSTCOUNT)) || \
-               quota_error a $TSTUSR "write filea failure, expect success"
+               quota_error a $TSTUSR "write fileb failure, expect success"
        echo "  Done"
 
        # cleanup
-       rm -f $FILEA
+       rm -f $FILEB
        sync; sleep 3; sync;
 
        resetquota -u $TSTUSR
@@ -791,6 +892,7 @@ test_8() {
        [ "$SLOW" = "no" ] && duration=" -t 120"
        $RUNAS bash rundbench -D $DIR/$tdir 3 $duration || quota_error a $TSTUSR "dbench failed!"
 
+        rm -rf $DIR/$tdir
        sync; sleep 3; sync;
 
        return 0
@@ -928,83 +1030,13 @@ test_10() {
 }
 #run_test_with_stat 10 "run for fixing bug10707(32bit) ==========="
 
-test_11() {
-       wait_delete_completed
-
-       #prepare the test
-       block_limit=`(echo 0; df -t lustre -P | awk '{print $(NF - 4)}') | tail -n 1`
-       echo $block_limit
-       orig_dbr=`sysctl -n vm.dirty_background_ratio`
-       orig_dec=`sysctl -n vm.dirty_expire_centisecs`
-       orig_dr=`sysctl -n vm.dirty_ratio`
-       orig_dwc=`sysctl -n vm.dirty_writeback_centisecs`
-       sysctl -w vm.dirty_background_ratio=1
-       sysctl -w vm.dirty_expire_centisecs=30
-       sysctl -w vm.dirty_ratio=1
-       sysctl -w vm.dirty_writeback_centisecs=50
-       TESTDIR="$DIR/$tdir"
-       local RV=0
-
-       #do the test
-       local SECS=0
-       local REPS=3
-       [ "$SLOW" = no ] && REPS=1
-       local sleep=20
-       local i=1
-       while [ $i -le $REPS ]; do
-          echo "test: cycle($i of $REPS) start at $(date)"
-          mkdir -p $TESTDIR && chmod 777 $TESTDIR
-          echo -n "    create a file for uid "
-          for j in `seq 1 30`; do
-              echo -n "$j "
-               # 30MB per dd for a total of 900MB (if space even permits)
-              runas -u $j dd if=/dev/zero of=$TESTDIR/$tfile  bs=$blksize count=15 > /dev/null 2>&1 &
-          done
-          echo ""
-          PROCS=$(ps -ef | grep -v grep | grep "dd if /dev/zero of $TESTDIR" | wc -l)
-           LAST_USED=0
-          while [ $PROCS -gt 0 ]; do 
-            sleep 20
-            SECS=$((SECS + sleep))
-            PROCS=$(ps -ef | grep -v grep | grep "dd if /dev/zero of $TESTDIR" | wc -l)
-            USED=$(du -s $TESTDIR | awk '{print $1}')
-            PCT=$(($USED * 100 / $block_limit))
-            echo "${i}/${REPS} ${PCT}% p${PROCS} t${SECS}  "
-            if [ $USED -le $LAST_USED ]; then
-                kill -9 $(ps -ef | grep "dd if /dev/zero of $TESTDIR" | grep -v grep | awk '{ print $2 }')
-                i=$REPS
-                RV=2
-                break
-            fi
-             LAST_USED=$USED
-          done
-          echo "    removing the test files..."
-          rm -f $TESTDIR/$tfile
-          echo "cycle $i done at $(date)"
-          i=$[$i+1]
-       done
-       echo "Test took $SECS sec"
-
-       #clean
-       sysctl -w vm.dirty_background_ratio=$orig_dbr
-       sysctl -w vm.dirty_expire_centisecs=$orig_dec
-       sysctl -w vm.dirty_ratio=$orig_dr
-       sysctl -w vm.dirty_writeback_centisecs=$orig_dwc
-       if [ $RV -ne 0 ]; then
-           error "Nothing was written for $SECS sec ... aborting"
-       fi
-       return $RV
-}
-run_test_with_stat 11 "run for fixing bug10912 ==========="
-
-
 # test a deadlock between quota and journal b=11693
 test_12() {
        mkdir -p $DIR/$tdir
        chmod 0777 $DIR/$tdir
 
        [ "$(grep $DIR2 /proc/mounts)" ] || mount_client $DIR2 || \
-               { skip "Need lustre mounted on $MOUNT2 " && retutn 0; }
+               { skip_env "Need lustre mounted on $MOUNT2 " && retutn 0; }
 
        LIMIT=$(( $BUNIT_SZ * $(($OSTCOUNT + 1)) * 10)) # 10 bunits each sever
        TESTFILE="$DIR/$tdir/$tfile-0"
@@ -1031,17 +1063,24 @@ test_12() {
        DDPID=$!
 
        echo  "   step2: testing ......"
-       count=0
-       while [ true ]; do
-           if ! ps -p ${DDPID1} > /dev/null 2>&1; then break; fi
-           count=$[count+1]
-           if [ $count -gt 64 ]; then
+        local last_size=$(stat -c %s $TESTFILE2) 
+        local stall_secs=0
+        local start_secs=$SECONDS
+        while [ -d /proc/${DDPID1} ]; do
+            local size=$(stat -c %s $TESTFILE2) 
+            if [ $size -eq $last_size ]; then
+                stall_secs=$[stall_secs+1]
+            else
+                stall_secs=0
+            fi
+           if [ $stall_secs -gt 30 ]; then
                lustre_fail ost 0
-               quota_error u $TSTUSR2 "dd should be finished!"
+               quota_error u $TSTUSR2 "giving up: dd stalled (i.e. made no progress) for 30 seconds!"
            fi
+            last_size=$size
            sleep 1
        done
-       echo "(dd_pid=$DDPID1, time=$count)successful"
+       echo "(dd_pid=$DDPID1, time=$((SECONDS-start_secs)))successful"
 
        #Recover fail_loc and dd will finish soon
        lustre_fail ost 0
@@ -1153,7 +1192,7 @@ test_14a() {      # was test_14 b=12223 -- setting quota on root
         # reboot the lustre
         sync; sleep 5; sync
         cleanup_and_setup_lustre
-        test_0
+        quota_init
 
        mkdir -p $DIR/$tdir
 
@@ -1184,13 +1223,6 @@ test_14a() {     # was test_14 b=12223 -- setting quota on root
 }
 run_test_with_stat 14a "test setting quota on root ==="
 
-# save quota version (both administrative and operational quotas)
-quota_save_version() {
-        do_facet mgs "lctl conf_param ${FSNAME}-MDT*.mdd.quota_type=$1"
-        do_facet mgs "lctl conf_param ${FSNAME}-OST*.ost.quota_type=$1"
-        sleep 5
-}
-
 test_15(){
         LIMIT=$((24 * 1024 * 1024 * 1024 * 1024)) # 24 TB
         PATTERN="`echo $DIR | sed 's/\//\\\\\//g'`"
@@ -1378,7 +1410,7 @@ test_18() {
 
        echo  "   step2: testing ......"
        count=0
-       if at_is_valid && at_is_enabled; then
+       if at_is_enabled; then
            timeout=$(at_max_get mds)
        else
            timeout=$(lctl get_param -n timeout)
@@ -1392,15 +1424,18 @@ test_18() {
            sleep 1
        done
         log "(dd_pid=$DDPID, time=$count, timeout=$timeout)"
+        sync
+        cancel_lru_locks mdc
+        cancel_lru_locks osc
 
         testfile_size=$(stat -c %s $TESTFILE)
         [ $testfile_size -ne $((BLK_SZ * 1024 * 100)) ] && \
            quota_error u $TSTUSR "expect $((BLK_SZ * 1024 * 100)), got ${testfile_size}. Verifying file failed!"
-       rm -f $TESTFILE
-       sync; sleep 3; sync;
+        $SHOW_QUOTA_USER
+        rm -f $TESTFILE
+        sync
 
        resetquota -u $TSTUSR
-
        set_blk_unitsz $((128 * 1024))
        set_blk_tunesz $((128 * 1024 / 2))
 }
@@ -1433,7 +1468,7 @@ test_18a() {
 
        echo  "   step2: testing ......"
        count=0
-       if at_is_valid && at_is_enabled; then
+       if at_is_enabled; then
            timeout=$(at_max_get mds)
        else
            timeout=$(lctl get_param -n timeout)
@@ -1450,12 +1485,10 @@ test_18a() {
         log "(dd_pid=$DDPID, time=$count, timeout=$timeout)"
 
         lustre_fail mds 0
-
        rm -f $TESTFILE
-       sync; sleep 3; sync;
+       sync
 
        resetquota -u $TSTUSR
-
        set_blk_unitsz $((128 * 1024))
        set_blk_tunesz $((128 * 1024 / 2))
 }
@@ -1507,7 +1540,7 @@ test_18bc_sub() {
         fi
 
         count=0
-        if at_is_valid && at_is_enabled; then
+       if at_is_enabled; then
            timeout=$(at_max_get mds)
         else
            timeout=$(lctl get_param -n timeout)
@@ -1520,15 +1553,20 @@ test_18bc_sub() {
             sleep 1
         done
         log "(dd_pid=$DDPID, time=$count, timeout=$timeout)"
-        sync; sleep 1; sync
+        sync
+        cancel_lru_locks mdc
+        cancel_lru_locks osc
 
         testfile_size=$(stat -c %s $TESTFILE)
         [ $testfile_size -ne $((BLK_SZ * 1024 * 100)) ] && \
            quota_error u $TSTUSR "expect $((BLK_SZ * 1024 * 100)), got ${testfile_size}. Verifying file failed!"
         $SHOW_QUOTA_USER
-        resetquota -u $TSTUSR
-        rm -rf $TESTFILE
-        sync; sleep 1; sync
+        rm -f $TESTFILE
+        sync
+
+       resetquota -u $TSTUSR
+       set_blk_unitsz $((128 * 1024))
+       set_blk_tunesz $((128 * 1024 / 2))
 }
 
 # test when mds does failover, the ost still could work well
@@ -1539,7 +1577,7 @@ test_18b() {
        # check if watchdog is triggered
        do_facet ost1 dmesg > $TMP/lustre-log-${TESTNAME}.log
        watchdog=`awk '/test 18b/ {start = 1;}
-                      /Watchdog triggered/ {
+                      /Service thread pid/ && /was inactive/ {
                               if (start) {
                                       print;
                               }
@@ -1707,43 +1745,21 @@ test_21() {
 run_test_with_stat 21 "run for fixing bug16053 ==========="
 
 test_22() {
-        local SAVEREFORMAT
-
-        SAVEREFORMAT=$REFORMAT
-        $LFS quotaoff -ug $DIR || error "could not turn quotas off"
+        quota_save_version "ug3"
 
-        quota_save_version "ug"
-
-        REFORMAT="reformat"
         stopall
         mount
         setupall
-        REFORMAT=$SAVEREFORMAT
 
         echo "checking parameters"
 
-        do_facet $SINGLEMDS "lctl get_param mdd.${FSNAME}-MDT*.quota_type" | grep "ug" || error "admin failure"
-        do_facet ost1 "lctl get_param obdfilter.*.quota_type" | grep "ug" || error "op failure"
+        do_facet $SINGLEMDS "lctl get_param mdd.${FSNAME}-MDT*.quota_type" | grep "ug3" || error "admin failure"
+        do_facet ost1 "lctl get_param obdfilter.*.quota_type" | grep "ug3" || error "op failure"
 
-        run_test 0 "reboot lustre"
+        quota_init
 }
 run_test_with_stat 22 "test if quota_type saved as permanent parameter ===="
 
-# It is triggered when test_23 failed, diagnostic for bug 18293
-test_23_dumppage()
-{
-        NUM=$1
-        DUMPPAGE=`find /proc/fs/${FSNAME}/llite/ -name dump_page_cache`
-        qtime=`date +%s`
-        cat $DUMPPAGE > $TMP/sanity-quota_test_23_${qtime}_${NUM}.log
-        fsize=`stat -c%s $TMP/sanity-quota_test_23_${qtime}_${NUM}.log`
-        if [ $fsize -eq 0 ]; then
-                rm -f $TMP/sanity-quota_test_23_${qtime}_${NUM}.log
-        else
-                error "some IO error was found during directIO"
-        fi
-}
-
 test_23_sub() {
        mkdir -p $DIR/$tdir
        chmod 0777 $DIR/$tdir
@@ -1766,15 +1782,15 @@ test_23_sub() {
        log "    Step1: trigger quota with 0_DIRECT"
        log "      Write half of file"
        $RUNAS $DIRECTIO write $TESTFILE 0 $(($LIMIT/1024/2)) $bs_unit || \
-                (quota_error u $TSTUSR "(1) write failure, but expect success: $LIMIT" && test_23_dumppage 1)
+                quota_error u $TSTUSR "(1) write failure, but expect success: $LIMIT"
        log "      Write out of block quota ..."
        $RUNAS $DIRECTIO write $TESTFILE $(($LIMIT/1024/2)) $(($LIMIT/1024/2)) $bs_unit && \
-                quota_error u $TSTUSR "(2) write success, but expect EDQUOT: $LIMIT" && test_23_dumppage 2
+                quota_error u $TSTUSR "(2) write success, but expect EDQUOT: $LIMIT"
        log "    Step1: done"
 
        log "    Step2: rewrite should succeed"
-       $RUNAS $DIRECTIO write $TESTFILE $(($LIMIT/1024/2)) 1 $bs_unit || \
-                (quota_error u $TSTUSR "(3) write failure, but expect success: $LIMIT" && test_23_dumppage 3)
+       $RUNAS $DIRECTIO write $TESTFILE 0 1 $bs_unit || \
+                quota_error u $TSTUSR "(3) write failure, but expect success: $LIMIT"
        log "    Step2: done"
 
        rm -f $TESTFILE
@@ -1900,6 +1916,8 @@ test_25_sub() {
         [ $MDS_QUOTA_USED2_NEW -ne $((MDS_QUOTA_USED2_OLD + 1)) ] && \
                 quota_error a $TSTUSR2 "$TSTUSR2 inode quota usage transfer from $TSTUSR to $TSTUSR2 failed: [$MDS_QUOTA_USED2_OLD|$MDS_QUOTA_USED2_NEW]"
        OST0_QUOTA_USED2_NEW=`$LFS quota -o $OST0_UUID $1 $TSTUSR2 $DIR | awk '/^.*[[:digit:]+][[:space:]+]/ { print $1 }'`
+       # when chown, the quota on ost could be displayed out of quota temporarily. Delete the '*' in this situation. b=20433
+       OST0_QUOTA_USED2_NEW=${OST0_QUOTA_USED2_NEW%\*}
         OST0_QUOTA_USED2_DELTA=$((OST0_QUOTA_USED2_NEW - OST0_QUOTA_USED2_OLD))
         [ $OST0_QUOTA_USED2_DELTA -ne $OST0_QUOTA_USED_DELTA ] && \
                 quota_error a $TSTUSR2 "$TSTUSR2 block quota usage transfer from $TSTUSR to $TSTUSR2 failed: [$OST0_QUOTA_USED2_OLD|$OST0_QUOTA_USED2_NEW]"
@@ -1925,20 +1943,245 @@ test_25() {
 }
 run_test_with_stat 25 "test whether quota usage is transfered when chown/chgrp (18081) ==========="
 
-# turn off quota
-test_99()
+test_26() {
+       mkdir -p $DIR/$tdir
+       chmod 0777 $DIR/$tdir
+       TESTFILE="$DIR/$tdir/$tfile-0"
+       TESTFILE2="$DIR/$tdir/$tfile-1"
+       set_blk_tunesz 512
+       set_blk_unitsz 1024
+
+       wait_delete_completed
+
+       # every quota slave gets 20MB
+       b_limit=$(((OSTCOUNT + 1) * 20 * 1024))
+       log "limit: ${b_limit}KB"
+       $LFS setquota -u $TSTUSR -b 0 -B $b_limit -i 0 -I 0 $DIR
+       sleep 3
+       quota_show_check b u $TSTUSR
+
+       $LFS setstripe $TESTFILE  -c 1 -i 0
+       $LFS setstripe $TESTFILE2 -c 1 -i 0
+       chown $TSTUSR.$TSTUSR $TESTFILE
+       chown $TSTUSR.$TSTUSR $TESTFILE2
+
+       #define OBD_FAIL_QUOTA_DELAY_REL         0xA03
+       lustre_fail ost 0xA03
+
+       log "    Write the first file..."
+       $RUNAS $DIRECTIO write $TESTFILE 0 10 $((BLK_SZ * 1024)) || quota_error u $TSTUSR "write failure, but expect success"
+       log "    Delete the first file..."
+       rm -f $TESTFILE
+
+
+       wait_delete_completed
+
+       log "    Write the second file..."
+       $RUNAS $DIRECTIO write $TESTFILE2 0 10 $((BLK_SZ * 1024)) || quota_error u $TSTUSR "write failure, but expect success"
+       log "    Delete the second file..."
+       rm -f $TESTFILE2
+
+       lustre_fail ost 0
+       set_blk_unitsz $((128 * 1024))
+       set_blk_tunesz $((128 * 1024 / 2))
+       resetquota -u $TSTUSR
+}
+run_test_with_stat 26 "test for false quota error(bz18491) ======================================"
+
+test_27a() {
+        $LFS quota $TSTUSR $DIR && error "lfs succeeded with no type, but should have failed"
+        $LFS setquota $TSTUSR $DIR && error "lfs succeeded with no type, but should have failed"
+        return 0
+}
+run_test_with_stat 27a "lfs quota/setquota should handle wrong arguments (19612) ================="
+
+test_27b() {
+        $LFS setquota -u $TSTID -b 1000 -B 1000 -i 1000 -I 1000 $DIR || \
+                error "lfs setquota failed with uid argument"
+        $LFS setquota -g $TSTID -b 1000 -B 1000 -i 1000 -I 1000 $DIR || \
+                error "lfs stequota failed with gid argument"
+        $SHOW_QUOTA_USERID || error "lfs quota failed with uid argument"
+        $SHOW_QUOTA_GROUPID || error "lfs quota failed with gid argument"
+        resetquota -u $TSTUSR
+        resetquota -g $TSTUSR
+        return 0
+}
+run_test 27b "lfs quota/setquota should handle user/group ID (20200) ================="
+
+test_28() {
+        BLK_LIMIT=$((100 * 1024 * 1024)) # 100G
+        echo "Step 1: set enough high limit for user [$TSTUSR:$BLK_LIMIT]"
+        $LFS setquota -u $TSTUSR -b 0 -B $BLK_LIMIT -i 0 -I 0 $DIR
+        $SHOW_QUOTA_USER
+
+        echo "Step 2: reset system ..."
+        cleanup_and_setup_lustre
+        quota_init
+
+        echo "Step 3: change qunit for user [$TSTUSR:512:1024]"
+        set_blk_tunesz 512
+        set_blk_unitsz 1024
+
+        wait_delete_completed
+
+        #define OBD_FAIL_QUOTA_RET_QDATA | OBD_FAIL_ONCE
+        lustre_fail ost 0x80000A02
+
+        TESTFILE="$DIR/$tdir/$tfile"
+        mkdir -p $DIR/$tdir
+
+        BLK_LIMIT=$((100 * 1024)) # 100M
+        echo "Step 4: set enough high limit for user [$TSTUSR:$BLK_LIMIT]"
+        $LFS setquota -u $TSTUSR -b 0 -B $BLK_LIMIT -i 0 -I 0 $DIR
+        $SHOW_QUOTA_USER
+
+        touch $TESTFILE
+        chown $TSTUSR.$TSTUSR $TESTFILE
+
+        echo "Step 5: write the test file1 [10M] ..."
+        $RUNAS dd if=/dev/zero of=$TESTFILE  bs=$BLK_SZ count=$(( 10 * 1024 )) \
+           || quota_error a $TSTUSR "write 10M file failure"
+        $SHOW_QUOTA_USER
+
+        rm -f $TESTFILE
+        sync; sleep 3; sync;
+
+        # make qd_count 64 bit
+        lustre_fail ost 0
+
+        set_blk_unitsz $((128 * 1024))
+        set_blk_tunesz $((128 * 1024 / 2))
+
+        resetquota -u $TSTUSR
+}
+run_test_with_stat 28 "test for consistency for qunit when setquota (18574) ==========="
+
+test_29()
 {
-       $LFS quotaoff $DIR
-       lctl set_param debug="-quota"
+        local BLK_LIMIT=$((100 * 1024 * 1024)) # 100G
+        local timeout
+        local pid
+        local origin_resends
+
+        if at_is_enabled; then
+                timeout=$(at_max_get client)
+                at_max_set 10 client
+        else
+                timeout=$(lctl get_param -n timeout)
+                lctl set_param timeout=10
+        fi
 
-       return 0
+        origin_resends=$(lctl get_param -n mdc.${FSNAME}-*.quota_resend_count | head -1)
+        lctl set_param -n mdc.${FSNAME}-*.quota_resend_count 0
+
+        #define OBD_FAIL_MDS_QUOTACTL_NET 0x12e
+        lustre_fail mds 0x12e
+
+        $LFS setquota -u $TSTUSR -b 0 -B $BLK_LIMIT -i 0 -I 0 $DIR & pid=$!
+
+        echo "sleeping for $((10 * 2)) seconds"
+        sleep $((10 * 2))
+        ps -p $pid && error "lfs hadn't finished by timeout"
+        wait $pid && error "succeeded, but should have failed"
+
+        lustre_fail mds 0
+
+        if at_is_enabled; then
+                at_max_set $timeout client
+        else
+                lctl set_param timeout=$timeout
+        fi
+
+        lctl set_param -n mdc.${FSNAME}-*.quota_resend_count $origin_resends
+        resetquota -u $TSTUSR
+}
+run_test_with_stat 29 "unhandled quotactls must not hang lustre client (19778) ========"
+
+test_30()
+{
+        local output
+        local LIMIT=1024
+        local TESTFILE="$DIR/$tdir/$tfile"
+        local GRACE=10
+
+        mkdir -p $DIR/$tdir
+        chmod 0777 $DIR/$tdir
+
+        $LFS setquota -t -u --block-grace $GRACE --inode-grace $MAX_IQ_TIME $DIR
+        $LFS setquota -u $TSTUSR -b $LIMIT -B 0 -i 0 -I 0 $DIR
+        $RUNAS dd if=/dev/zero of=$TESTFILE bs=1024 count=$((LIMIT * 2)) || true
+        cancel_lru_locks osc
+        sleep 5
+        $LFS setquota -u $TSTUSR -B 0 $DIR
+        $SHOW_QUOTA_USER
+        output=`$SHOW_QUOTA_USER | grep $MOUNT | awk '{ print $5 }' | tr -d s`
+        [ "$output" -le "$((GRACE - 5))" ] || error "grace times were reset or unexpectedly high latency"
+        rm -f $TESTFILE
+        resetquota -u $TSTUSR
+        $LFS setquota -t -u --block-grace $MAX_DQ_TIME --inode-grace $MAX_IQ_TIME $DIR
+}
+run_test_with_stat 30 "hard limit updates should not reset grace times ================"
+
+# test duplicate quota releases b=18630
+test_31() {
+        mkdir -p $DIR/$tdir
+        chmod 0777 $DIR/$tdir
+
+        LIMIT=$(( $BUNIT_SZ * $(($OSTCOUNT + 1)) * 10)) # 10 bunits each sever
+        TESTFILE="$DIR/$tdir/$tfile-0"
+        TESTFILE2="$DIR/$tdir/$tfile-1"
+
+        wait_delete_completed
+
+        log "   User quota (limit: $LIMIT kbytes)"
+        $LFS setquota -u $TSTUSR -b 0 -B $LIMIT -i 0 -I 0 $DIR
+
+        $LFS setstripe $TESTFILE -i 0 -c 1
+        chown $TSTUSR.$TSTUSR $TESTFILE
+        $LFS setstripe $TESTFILE2 -i 0 -c 1
+        chown $TSTUSR.$TSTUSR $TESTFILE2
+
+        log "   step1: write out of block quota ..."
+        $RUNAS dd if=/dev/zero of=$TESTFILE bs=$BLK_SZ count=5120
+        $RUNAS dd if=/dev/zero of=$TESTFILE2 bs=$BLK_SZ count=5120
+
+        #define OBD_FAIL_QUOTA_DELAY_SD      0xA04
+        #define OBD_FAIL_SOME        0x10000000 /* fail N times */
+        lustre_fail ost $((0x00000A04 | 0x10000000)) 1
+
+        log "   step2: delete two files so that triggering duplicate quota release ..."
+        rm -f $TESTFILE $TESTFILE2
+        sync; sleep 5; sync      #  OBD_FAIL_QUOTA_DELAY_SD will delay for 5 seconds
+        wait_delete_completed
+
+        log "   step3: verify if the ost failed"
+        do_facet ost1 dmesg > $TMP/lustre-log-${TESTNAME}.log
+        watchdog=`awk '/test 31/ {start = 1;}
+                       /release quota error/ {
+                               if (start) {
+                                       print;
+                               }
+                       }' $TMP/lustre-log-${TESTNAME}.log`
+        [ "$watchdog" ] && error "$watchdog"
+        rm -f $TMP/lustre-log-${TESTNAME}.log
+
+        lustre_fail ost 0
+        resetquota -u $TSTUSR
 }
-run_test_with_stat 99 "Quota off ==============================="
+run_test_with_stat 31 "test duplicate quota releases ==="
 
+# turn off quota
+quota_fini()
+{
+       $LFS quotaoff $DIR
+        do_nodes $(comma_list $(nodes_list)) "lctl set_param debug=-quota"
+}
+quota_fini
 
 log "cleanup: ======================================================"
 cd $ORIG_PWD
 check_and_cleanup_lustre
 echo '=========================== finished ==============================='
+export QUOTA_AUTO=$QUOTA_AUTO_OLD
 [ -f "$QUOTALOG" ] && cat $QUOTALOG && grep -q FAIL $QUOTALOG && exit 1 || true
 echo "$0: completed"