Whamcloud - gitweb
LU-213 using direct io for quota test to avoid cache problem
[fs/lustre-release.git] / lustre / tests / sanity-quota.sh
index 6d9f8aa..f749443 100644 (file)
@@ -19,7 +19,9 @@ 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"
+# We have changed the mechanism of quota, test_12 is meanless now.
+# b=20877
+ALWAYS_EXCEPT="10 12 $SANITY_QUOTA_EXCEPT"
 # UPDATE THE COMMENT ABOVE WITH BUG NUMBERS WHEN CHANGING ALWAYS_EXCEPT!
 
 case `uname -r` in
@@ -42,6 +44,11 @@ BUNIT_SZ=${BUNIT_SZ:-1024}   # min block quota unit(kB)
 IUNIT_SZ=${IUNIT_SZ:-10}       # min inode quota unit
 MAX_DQ_TIME=604800
 MAX_IQ_TIME=604800
+SANITY_QUOTA_USERS="quota15_1 quota15_2 quota15_3 quota15_4 quota15_5 quota15_6 \
+                    quota15_7 quota15_8 quota15_9 quota15_10 quota15_11 quota15_12 \
+                    quota15_13 quota15_14 quota15_15 quota15_16 quota15_17 quota15_18 \
+                    quota15_19 quota15_20 quota15_21 quota15_22 quota15_23 quota15_24 \
+                    quota15_25 quota15_26 quota15_27 quota15_28 quota15_29 quota15_30"
 
 TRACE=${TRACE:-""}
 LUSTRE=${LUSTRE:-`dirname $0`/..}
@@ -92,7 +99,7 @@ build_test_filter
 set_blk_tunesz() {
        local btune=$(($1 * BLK_SZ))
        # set btune size on all obdfilters
-       do_facet ost1 "lctl set_param lquota.${FSNAME}-OST*.quota_btune_sz=$btune"
+       do_nodes $(comma_list $(osts_nodes)) "lctl set_param lquota.${FSNAME}-OST*.quota_btune_sz=$btune"
        # set btune size on mds
        do_facet $SINGLEMDS "lctl set_param lquota.mdd_obd-${FSNAME}-MDT*.quota_btune_sz=$btune"
 }
@@ -101,7 +108,7 @@ set_blk_tunesz() {
 set_blk_unitsz() {
        local bunit=$(($1 * BLK_SZ))
        # set bunit size on all obdfilters
-       do_facet ost1 "lctl set_param lquota.${FSNAME}-OST*.quota_bunit_sz=$bunit"
+       do_nodes $(comma_list $(osts_nodes)) "lctl set_param lquota.${FSNAME}-OST*.quota_bunit_sz=$bunit"
        # set bunit size on mds
        do_facet $SINGLEMDS "lctl set_param lquota.mdd_obd-${FSNAME}-MDT*.quota_bunit_sz=$bunit"
 }
@@ -109,8 +116,6 @@ set_blk_unitsz() {
 # set_file_tunesz(itune_sz)
 set_file_tunesz() {
        local itune=$1
-       # set itune size on all obdfilters
-       do_facet ost1 "lctl set_param lquota.${FSNAME}-OST*.quota_itune_sz=$itune"
        # set itune size on mds
        do_facet $SINGLEMDS "lctl set_param lquota.mdd_obd-${FSNAME}-MDT*.quota_itune_sz=$itune"
 }
@@ -118,8 +123,6 @@ set_file_tunesz() {
 # set_file_unitsz(iunit_sz)
 set_file_unitsz() {
        local iunit=$1
-       # set iunit size on all obdfilters
-       do_facet ost1 "lctl set_param lquota.${FSNAME}-OST*.quota_iunit_sz=$iunit"
        # set iunit size on mds
        do_facet $SINGLEMDS "lctl set_param lquota.mdd_obd-${FSNAME}-MDT*.quota_iunit_sz=$iunit"
 }
@@ -260,7 +263,7 @@ getquota() {
 
         [ "$uuid" = "global" ] && uuid=$DIR
 
-        $LFS quota -v "$1" "$2" $DIR | awk 'BEGIN { num='$spec' } { if ($1 == "'$uuid'") { if (NF == 1) { getline } else { num++ } ; print $num;} }'
+        $LFS quota -v "$1" "$2" $DIR | awk 'BEGIN { num='$spec' } { if ($1 == "'$uuid'") { if (NF == 1) { getline } else { num++ } ; print $num;} }' | tr -d "*"
 }
 
 quota_show_check() {
@@ -292,15 +295,46 @@ quota_show_check() {
 
 # set quota
 quota_init() {
+       do_nodes $(comma_list $(nodes_list)) "lctl set_param debug=+quota"
+
+       log "do the quotacheck ..."
        $LFS quotacheck -ug $DIR
 
        resetquota -u $TSTUSR
        resetquota -g $TSTUSR
-
-        do_nodes $(comma_list $(nodes_list)) "lctl set_param debug=+quota"
 }
 quota_init
 
+test_quota_performance() {
+       TESTFILE="$DIR/$tdir/$tfile-0"
+       local size=$1
+       local stime=`date +%s`
+       $RUNAS dd if=/dev/zero of=$TESTFILE bs=1M count=$size || quota_error u $TSTUSR "write failure"
+       local etime=`date +%s`
+       delta=$((etime - stime))
+       if [ $delta -gt 0 ]; then
+           rate=$((size * 1024 / delta))
+           [ $rate -gt 1024 ] || error "SLOW IO for $TSTUSR (user): $rate KB/sec"
+       fi
+       rm -f $TESTFILE
+}
+
+# test basic quota performance b=21696
+test_0() {
+       mkdir -p $DIR/$tdir
+       chmod 0777 $DIR/$tdir
+       MB=100
+       [ "$SLOW" = "no" ] && MB=10
+
+       test_quota_performance $MB
+
+       $LFS setquota -u $TSTUSR -b 0 -B $((1024*1024)) -i 0 -I 0 $DIR
+       test_quota_performance $MB
+
+       resetquota -u $TSTUSR
+}
+run_test_with_stat 0 "Test basic quota performance ==="
+
 # test for specific quota limitation, qunit, qtune $1=block_quota_limit
 test_1_sub() {
         LIMIT=$1
@@ -320,14 +354,7 @@ 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
@@ -358,14 +385,7 @@ 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
@@ -936,7 +956,7 @@ GB=$((KB * 1024 * 1024))
 # inode->i_blkbits = min(PTLRPC_MAX_BRW_BITS+1, LL_MAX_BLKSIZE_BITS);
 blksize=$((1 << 21)) # 2Mb
 size_file=$((GB * 9 / 2))
-# this check is just for test9 and test10
+# this check is just for test_9
 OST0_MIN=4900000 #4.67G
 check_whether_skip () {
     OST0_SIZE=`$LFS df $DIR | awk '/\[OST:0\]/ {print $4}'`
@@ -974,7 +994,7 @@ test_9() {
         quota_show_check a g $TSTUSR
 
         echo "  Set stripe"
-       $LFS setstripe $TESTFILE -c 1
+       $LFS setstripe $TESTFILE -c 1 -i 0
         touch $TESTFILE
         chown $TSTUSR.$TSTUSR $TESTFILE
 
@@ -1001,64 +1021,8 @@ test_9() {
 }
 run_test_with_stat 9 "run for fixing bug10707(64bit) ==========="
 
-# run for fixing bug10707, it need a big room. test for 32bit
-# 2.0 version does not support 32 bit qd_count, so such test is obsolete.
-test_10() {
-       mkdir -p $DIR/$tdir
-       chmod 0777 $DIR/$tdir
-       check_whether_skip && return 0
-
-       wait_delete_completed
-
-       set_blk_tunesz 512
-       set_blk_unitsz 1024
-
-       # make qd_count 32 bit
-       lustre_fail mds_ost 0xA00
-
-       TESTFILE="$DIR/$tdir/$tfile-0"
-
-       BLK_LIMIT=$((100 * KB * KB)) # 100G
-       FILE_LIMIT=1000000
-
-       log "  Set enough high limit(block:$BLK_LIMIT; file: $FILE_LIMIT) for user: $TSTUSR"
-       $LFS setquota -u $TSTUSR -b 0 -B $BLK_LIMIT -i 0 -I $FILE_LIMIT $DIR
-       log "  Set enough high limit(block:$BLK_LIMIT; file: $FILE_LIMIT) for group: $TSTUSR"
-       $LFS setquota -g $TSTUSR -b 0 -B $BLK_LIMIT -i 0 -I $FILE_LIMIT $DIR
-
-        quota_show_check a u $TSTUSR
-        quota_show_check a g $TSTUSR
-
-       echo "  Set stripe"
-       $LFS setstripe $TESTFILE -c 1
-       touch $TESTFILE
-       chown $TSTUSR.$TSTUSR $TESTFILE
-
-        log "    Write the big file of 4.5 G ..."
-        $RUNAS dd if=/dev/zero of=$TESTFILE  bs=$blksize count=$((size_file / blksize)) || \
-               quota_error a $TSTUSR "(usr) write 4.5 G file failure, but expect success"
-
-        $SHOW_QUOTA_USER
-        $SHOW_QUOTA_GROUP
-
-        log "    delete the big file of 4.5 G..."
-        $RUNAS rm -f $TESTFILE
-       sync; sleep 3; sync;
-
-        $SHOW_QUOTA_USER
-        $SHOW_QUOTA_GROUP
-
-       RC=$?
-
-       # make qd_count 64 bit
-       lustre_fail mds_ost 0
-
-       set_blk_unitsz $((128 * 1024))
-       set_blk_tunesz $((128 * 1024 / 2))
-
-       return $RC
-}
-#run_test_with_stat 10 "run for fixing bug10707(32bit) ==========="
+# 2.0 version does not support 32 bit qd_count,
+# test_10 "run for fixing bug10707(32bit) " is obsolete
 
 # test a deadlock between quota and journal b=11693
 test_12() {
@@ -1230,10 +1194,10 @@ test_14a() {    # was test_14 b=12223 -- setting quota on root
        $LFS setquota -u root -b 10 -B 10 -i 10 -I 10 $DIR
        createmany -m ${TESTFILE} 20 || \
            quota_error u root "unexpected: user(root) create files failly!"
-       dd if=/dev/zero of=$TESTFILE bs=4k count=4096 || \
+        multiop ${TESTFILE} oO_CREAT:O_WRONLY:O_DIRECT:w$((4096 * 4096))c || \
            quota_error u root "unexpected: user(root) write files failly!"
        chmod 666 $TESTFILE
-       $RUNAS dd if=/dev/zero of=${TESTFILE} seek=4096 bs=4k count=4096 && \
+        $RUNAS multiop ${TESTFILE} oO_WRONLY:O_APPEND:O_DIRECT:w$((4096 * 4096))c && \
            quota_error u root "unexpected: user(quota_usr) write a file successfully!"
 
        # trigger the llog
@@ -1287,67 +1251,8 @@ test_15(){
 }
 run_test_with_stat 15 "set block quota more than 4T ==="
 
-# $1=u/g $2=with qunit adjust or not
-test_16_tub() {
-       LIMIT=$(( $BUNIT_SZ * $(($OSTCOUNT + 1)) * 4))
-       TESTFILE="$DIR/$tdir/$tfile"
-       mkdir -p $DIR/$tdir
-
-       wait_delete_completed
-
-       echo "  User quota (limit: $LIMIT kbytes)"
-       if [ $1 == "u" ]; then
-           $LFS setquota -u $TSTUSR -b 0 -B $LIMIT -i 0 -I 0 $DIR
-            quota_show_check b u $TSTUSR
-       else
-           $LFS setquota -g $TSTUSR -b 0 -B $LIMIT -i 0 -I 0 $DIR
-            quota_show_check b g $TSTUSR
-       fi
-
-       $LFS setstripe $TESTFILE -c 1
-       chown $TSTUSR.$TSTUSR $TESTFILE
-
-       echo "    Write ..."
-       $RUNAS dd if=/dev/zero of=$TESTFILE bs=$BLK_SZ count=$((BUNIT_SZ * 4)) || \
-           quota_error a $TSTUSR "(usr) write failure, but expect success"
-       echo "    Done"
-       echo "    Write out of block quota ..."
-       # this time maybe cache write,  ignore it's failure
-       $RUNAS dd if=/dev/zero of=$TESTFILE bs=$BLK_SZ count=$BUNIT_SZ seek=$((BUNIT_SZ * 4)) || true
-       # flush cache, ensure noquota flag is setted on client
-        cancel_lru_locks osc
-       if [ $2 -eq 1 ]; then
-           $RUNAS dd if=/dev/zero of=$TESTFILE bs=$BLK_SZ count=$BUNIT_SZ seek=$((BUNIT_SZ * 4)) || \
-               quota_error a $TSTUSR "(write failure, but expect success"
-       else
-           $RUNAS dd if=/dev/zero of=$TESTFILE bs=$BLK_SZ count=$BUNIT_SZ seek=$((BUNIT_SZ * 4)) && \
-               quota_error a $TSTUSR "(write success, but expect EDQUOT"
-       fi
-
-       rm -f $TESTFILE
-       sync; sleep 3; sync;
-       resetquota -$1 $TSTUSR
-}
-
-# test without adjusting qunit
-# 2.0 version does not support WITHOUT_CHANGE_QS, so such test is obsolete
-test_16 () {
-       set_blk_tunesz $((BUNIT_SZ * 2))
-       set_blk_unitsz $((BUNIT_SZ * 4))
-       for i in u g; do
-           for j in 0 1; do
-                # define OBD_FAIL_QUOTA_WITHOUT_CHANGE_QS    0xA01
-               echo " grp/usr: $i, adjust qunit: $j"
-               echo "-------------------------------"
-               [ $j -eq 1 ] && lustre_fail mds_ost 0
-               [ $j -eq 0 ] && lustre_fail mds_ost 0xA01
-               test_16_tub $i $j
-           done
-       done
-       set_blk_unitsz $((128 * 1024))
-       set_blk_tunesz $((128 * 1024 / 2))
-}
-#run_test_with_stat 16 "test without adjusting qunit"
+# 2.0 version does not support WITHOUT_CHANGE_QS,
+# test_16 "test without adjusting qunit" is obsolete
 
 # run for fixing bug14526, failed returned quota reqs shouldn't ruin lustre.
 test_17() {
@@ -1529,7 +1434,7 @@ run_test_with_stat 18a "run for fixing bug14840 ==========="
 test_18bc_sub() {
         type=$1
 
-        LIMIT=$((110 * 1024 )) # 110M
+        LIMIT=$(((100 + $OSTCOUNT * 3) * 1024))
         TESTFILE="$DIR/$tdir/$tfile"
         mkdir -p $DIR/$tdir
 
@@ -1558,14 +1463,16 @@ test_18bc_sub() {
         DDPID=$!
         do_facet $SINGLEMDS "$LCTL conf_param ${FSNAME}-MDT*.mdd.quota_type=ug"
 
+       replay_barrier $SINGLEMDS
+
        log "failing mds for $((2 * timeout)) seconds"
         fail $SINGLEMDS $((2 * timeout))
 
         # check if quotaon successful
         $LFS quota -u $TSTUSR $MOUNT 2>&1 | grep -q "quotas are not enabled"
         if [ $? -eq 0 ]; then
-            error "quotaon failed!"
             rm -rf $TESTFILE
+            error "quotaon failed!"
             return
         fi
 
@@ -1586,17 +1493,18 @@ test_18bc_sub() {
         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
-        rm -f $TESTFILE
-        sync
 
        resetquota -u $TSTUSR
        set_blk_unitsz $((128 * 1024))
        set_blk_tunesz $((128 * 1024 / 2))
+       testfile_size=$(stat -c %s $TESTFILE)
+       if [ $testfile_size -ne $((BLK_SZ * 1024 * 100)) ] ; then
+            rm -f $TESTFILE
+            quota_error u $TSTUSR "expect $((BLK_SZ * 1024 * 100)), got ${testfile_size}. Verifying file failed!"
+       fi
+       rm -f $TESTFILE
+
 }
 
 # test when mds does failover, the ost still could work well
@@ -1807,7 +1715,7 @@ test_23_sub() {
        sleep 3
         quota_show_check b u $TSTUSR
 
-       $LFS setstripe $TESTFILE -c 1
+       $LFS setstripe $TESTFILE -c 1 -i 0
        chown $TSTUSR.$TSTUSR $TESTFILE
 
        log "    Step1: trigger quota with 0_DIRECT"
@@ -1836,13 +1744,17 @@ test_23_sub() {
 }
 
 test_23() {
-       log "run for $((OSTCOUNT * 4))MB test file"
-       test_23_sub $((OSTCOUNT * 4 * 1024))
+        local slave_cnt=$((OSTCOUNT + 1)) # 1 mds, n osts
 
-       OST0_MIN=120000
+        OST0_MIN=$((6 * $slave_cnt * 1024)) # extra space for meta blocks.
        check_whether_skip && return 0
-       log "run for $((OSTCOUNT * 40))MB test file"
-       test_23_sub $((OSTCOUNT * 40 * 1024))
+       log "run for $((4 * $slave_cnt))MB test file"
+       test_23_sub $((4 * $slave_cnt * 1024))
+
+       OST0_MIN=$((60 * $slave_cnt * 1024)) # extra space for meta blocks.
+       check_whether_skip && return 0
+       log "run for $((40 * $slave_cnt))MB test file"
+       test_23_sub $((40 * $slave_cnt * 1024))
 }
 run_test_with_stat 23 "run for fixing bug16125 ==========="
 
@@ -2210,6 +2122,84 @@ test_31() {
 }
 run_test_with_stat 31 "test duplicate quota releases ==="
 
+# check hash_cur_bits
+check_quota_hash_cur_bits() {
+        local bits=$1
+
+        # check quota_hash_cur_bits on all obdfilters
+        for num in `seq $OSTCOUNT`; do
+           cb=`do_facet ost$num "cat /sys/module/lquota/parameters/hash_lqs_cur_bits"`
+           if [ $cb -gt $bits ]; then
+               echo "hash_lqs_cur_bits of ost$num is too large(cur_bits=$cb)"
+               return 1;
+           fi
+        done
+        # check quota_hash_cur_bits on mds
+        cb=`do_facet $SINGLEMDS "cat /sys/module/lquota/parameters/hash_lqs_cur_bits"`
+        if [ $cb -gt $bits ]; then
+           echo "hash_lqs_cur_bits of mds is too large(cur_bits=$cb)"
+           return 1;
+        fi
+        return 0;
+}
+
+# check lqs hash
+check_lqs_hash() {
+        # check distribution of all obdfilters
+        for num in `seq $OSTCOUNT`; do
+           do_facet ost$num "lctl get_param obdfilter.${FSNAME}-OST*.hash_stats | grep LQS_HASH" | while read line; do
+               rehash_count=`echo $line | awk '{print $9}'`
+               if [ $rehash_count -eq 0 ]; then
+                   echo -e "ost$num:\n $line"
+                   error "Rehearsh didn't happen"
+               fi
+           done
+        done
+        # check distribution of mds
+        do_facet $SINGLEMDS "lctl get_param mdt.${FSNAME}-MDT*.hash_stats | grep LQS_HASH" | while read line; do
+           rehash_count=`echo $line | awk '{print $9}'`
+           if [ $rehash_count -eq 0 ]; then
+               echo -e "mdt:\n $line"
+               error "Rehearsh didn't happen"
+           fi
+        done
+}
+
+test_32()
+{
+        # reset system so that quota_hash_cur_bits==3
+        echo "Reset system ..."
+        local LMR_orig=$LOAD_MODULES_REMOTE
+        LOAD_MODULES_REMOTE=true
+        cleanup_and_setup_lustre
+        LOAD_MODULES_REMOTE=$LMR_orig
+
+        client_up
+        wait_mds_ost_sync
+        quota_init
+
+        for user in $SANITY_QUOTA_USERS; do
+           check_runas_id_ret $user quota_usr "runas -u $user -g quota_usr" >/dev/null 2>/dev/null || \
+               missing_users="$missing_users $user"
+        done
+        [ -n "$missing_users" ] && { skip_env "the following users are missing: $missing_users" ; return 0 ; }
+        check_quota_hash_cur_bits 3 || { skip_env "hash_lqs_cur_bits isn't set properly"; return 0;}
+
+        $LFS quotaoff -ug $DIR
+        $LFS quotacheck -ug $DIR
+
+        for user in $SANITY_QUOTA_USERS; do
+           $LFS setquota -u $user --block-hardlimit 1048576 $DIR
+        done
+
+        check_lqs_hash
+
+        for user in $SANITY_QUOTA_USERS; do
+           resetquota -u $user
+        done
+}
+run_test 32 "check lqs hash(bug 21846) =========================================="
+
 # turn off quota
 quota_fini()
 {
@@ -2218,10 +2208,8 @@ quota_fini()
 }
 quota_fini
 
-log "cleanup: ======================================================"
 cd $ORIG_PWD
+complete $(basename $0) $SECONDS
 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"
+exit_status