Whamcloud - gitweb
LU-1031: add grouplock test to sanity.sh
[fs/lustre-release.git] / lustre / tests / sanity-quota.sh
index a77fb1a..96d1ab0 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,7 +44,13 @@ 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"
 
+export MULTIOP=${MULTIOP:-multiop}
 TRACE=${TRACE:-""}
 LUSTRE=${LUSTRE:-`dirname $0`/..}
 . $LUSTRE/tests/test-framework.sh
@@ -92,7 +100,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 +109,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 +117,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 +124,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 +264,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,12 +296,13 @@ quota_show_check() {
 
 # set quota
 quota_init() {
-       $LFS quotacheck -ug $DIR
+       do_nodes $(comma_list $(nodes_list)) "lctl set_param debug=+quota"
 
-       resetquota -u $TSTUSR
-       resetquota -g $TSTUSR
+       log "do the quotacheck ..."
+       $LFS quotacheck -ug $DIR
 
-        do_nodes $(comma_list $(nodes_list)) "lctl set_param debug=+quota"
+       resetquota -u $TSTUSR
+       resetquota -g $TSTUSR
 }
 quota_init
 
@@ -952,7 +957,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}'`
@@ -990,7 +995,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
 
@@ -1017,64 +1022,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() {
@@ -1246,10 +1195,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
@@ -1303,67 +1252,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() {
@@ -1545,7 +1435,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
 
@@ -1574,14 +1464,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
 
@@ -1602,17 +1494,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
@@ -1823,7 +1716,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"
@@ -1852,13 +1745,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 ==========="
 
@@ -2116,14 +2013,16 @@ test_29()
                 timeout=$(lctl get_param -n timeout)
                 lctl set_param timeout=10
         fi
+       # actually send a RPC to make service at_current confined within at_max
+        $LFS setquota -u $TSTUSR -b 0 -B $BLK_LIMIT -i 0 -I 0 $DIR || error "should succeed"
 
         #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))
+        echo "sleeping for 10 * 1.25 + 5 + 10 seconds"
+        sleep 28
         ps -p $pid && error "lfs hadn't finished by timeout"
         wait $pid && error "succeeded, but should have failed"
 
@@ -2226,6 +2125,244 @@ 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) =========================================="
+
+cleanup_quota_test() {
+        trap 0
+        echo "Delete files..."
+        rm -rf $DIR/$tdir
+}
+
+# basic usage tracking for user & group
+test_33() {
+        mkdir -p $DIR/$tdir
+        chmod 0777 $DIR/$tdir
+        INODES=10
+        BLK_CNT=1024
+        TOTAL_BLKS=$(($INODES * $BLK_CNT))
+
+        trap cleanup_quota_test EXIT
+
+        # make sure the system is clean
+        USED=`getquota -u $TSTID global curspace`
+        [ $USED -ne 0 ] && \
+                error "Used space ($USED) for user $TSTID isn't 0."
+        USED=`getquota -g $TSTID global curspace`
+        [ $USED -ne 0 ] && \
+                error "Used space ($USED) for group $TSTID isn't 0."
+
+        echo "Write files..."
+        for i in `seq 0 $INODES`; do
+                $RUNAS dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=$BLK_SZ \
+                   count=$BLK_CNT oflag=sync 2>/dev/null || error "write failed"
+        done
+
+        echo "Verify disk usage after write"
+        USED=`getquota -u $TSTID global curspace`
+        [ $USED -lt $TOTAL_BLKS ] && \
+               error "Used space for user $TSTID is $USED, expected $TOTAL_BLKS"
+        USED=`getquota -u $TSTID global curinodes`
+        [ $USED -lt $INODES ] && \
+               error "Used inode for user $TSTID is $USED, expected $INODES"
+
+        USED=`getquota -g $TSTID global curspace`
+        [ $USED -lt $TOTAL_BLKS ] && \
+              error "Used space for group $TSTID is $USED, expected $TOTAL_BLKS"
+        USED=`getquota -g $TSTID global curinodes`
+        [ $USED -lt $INODES ] && \
+              error "Used inode for group $TSTID is $USED, expected $INODES"
+
+        cleanup_quota_test
+
+        echo "Verify disk usage after delete"
+        wait_delete_completed
+        USED=`getquota -u $TSTID global curspace`
+        [ $USED -eq 0 ] || error "Used space for user $TSTID isn't 0. $USED"
+        USED=`getquota -u $TSTID global curinodes`
+        [ $USED -eq 0 ] || error "Used inodes for user $TSTID isn't 0. $USED"
+        USED=`getquota -g $TSTID global curspace`
+        [ $USED -eq 0 ] || error "Used space for group $TSTID isn't 0. $USED"
+        USED=`getquota -g $TSTID global curinodes`
+        [ $USED -eq 0 ] || error "Used inodes for group $TSTID isn't 0. $USED"
+}
+run_test 33 "basic usage tracking for user & group =============================="
+
+# usage transfer test for user & group
+test_34() {
+        BLK_CNT=1024
+        mkdir -p $DIR/$tdir
+        chmod 0777 $DIR/$tdir
+        
+        trap cleanup_quota_test EXIT
+
+        # make sure the system is clean
+        USED=`getquota -u $TSTID global curspace`
+        [ $USED -ne 0 ] && error "Used space ($USED) for user $TSTID isn't 0."
+        USED=`getquota -g $TSTID global curspace`
+        [ $USED -ne 0 ] && error "Used space ($USED) for group $TSTID isn't 0."
+
+        echo "Write file..."
+        dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$BLK_SZ count=$BLK_CNT \
+                oflag=sync 2>/dev/null || error "write failed"
+
+        echo "chown the file to user $TSTID"
+        chown $TSTID $DIR/$tdir/$tfile || error "chown failed"
+
+        echo "Verify disk usage for user $TSTID"
+        USED=`getquota -u $TSTID global curspace`
+        [ $USED -lt $BLK_CNT ] && \
+                error "Used space for user $TSTID is $USED, expected $BLK_CNT"
+        USED=`getquota -u $TSTID global curinodes`
+        [ $USED -ne 1 ] && \
+                error "Used inodes for user $TSTID is $USED, expected 1"
+
+        echo "chgrp the file to group $TSTID"
+        chgrp $TSTID $DIR/$tdir/$tfile || error "chgrp failed"
+
+        echo "Verify disk usage for group $TSTID"
+        USED=`getquota -g $TSTID global curspace`
+        [ $USED -ge $BLK_CNT ] || \
+                error "Used space for group $TSTID is $USED, expected $BLK_CNT"
+        USED=`getquota -g $TSTID global curinodes`
+        [ $USED -eq 1 ] || \
+                error "Used inodes for group $TSTID is $USED, expected 1"
+
+        cleanup_quota_test
+}
+run_test 34 "usage transfer for user & group ===================================="
+
+# usage is still accessible across restart
+test_35() {
+        mkdir -p $DIR/$tdir
+        chmod 0777 $DIR/$tdir
+        BLK_CNT=1024
+
+        trap cleanup_quota_test EXIT
+
+        echo "Write file..."
+        $RUNAS dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$BLK_SZ \
+                count=$BLK_CNT oflag=sync 2>/dev/null || error "write failed"
+
+        echo "Save disk usage before restart"
+        ORIG_USR_SPACE=`getquota -u $TSTID global curspace`
+        [ $ORIG_USR_SPACE -eq 0 ] && \
+                error "Used space for user $TSTID is 0, expected $BLK_CNT"
+        ORIG_USR_INODES=`getquota -u $TSTID global curinodes`
+        [ $ORIG_USR_INODES -eq 0 ] && \
+                error "Used inodes for user $TSTID is 0, expected 1"
+        ORIG_GRP_SPACE=`getquota -g $TSTID global curspace`
+        [ $ORIG_GRP_SPACE -eq 0 ] && \
+                error "Used space for group $TSTID is 0, expected $BLK_CNT"
+        ORIG_GRP_INODES=`getquota -g $TSTID global curinodes`
+        [ $ORIG_GRP_INODES -eq 0 ] && \
+                error "Used inodes for group $TSTID is 0, expected 1"
+
+        log "Restart..."
+        local ORIG_REFORMAT=$REFORMAT
+        REFORMAT=""
+        cleanup_and_setup_lustre
+        REFORMAT=$ORIG_REFORMAT
+        quota_init
+
+        echo "Verify disk usage after restart"
+        USED=`getquota -u $TSTID global curspace`
+        [ $USED -eq $ORIG_USR_SPACE ] || \
+                error "Used space for user $TSTID changed from " \
+                        "$ORIG_USR_SPACE to $USED"
+        USED=`getquota -u $TSTID global curinodes`
+        [ $USED -eq $ORIG_USR_INODES ] || \
+                error "Used inodes for user $TSTID changed from " \
+                        "$ORIG_USR_INODES to $USED"
+        USED=`getquota -g $TSTID global curspace`
+        [ $USED -eq $ORIG_GRP_SPACE ] || \
+                error "Used space for group $TSTID changed from " \
+                        "$ORIG_GRP_SPACE to $USED"
+        USED=`getquota -g $TSTID global curinodes`
+        [ $USED -eq $ORIG_GRP_INODES ] || \
+                error "Used inodes for group $TSTID changed from " \
+                        "$ORIG_GRP_INODES to $USED"
+
+        cleanup_quota_test
+}
+run_test 35 "usage is still accessible across reboot ============================"
+
+
 # turn off quota
 quota_fini()
 {
@@ -2234,10 +2371,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