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!
MAX_DQ_TIME=604800
MAX_IQ_TIME=604800
-unset ENABLE_QUOTA
-
TRACE=${TRACE:-""}
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"
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 -u $DIR; $LFS quota -t -g $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
build_test_filter
-eval ONLY_0=true
-eval ONLY_99=true
-
# set_blk_tunables(btune_sz)
set_blk_tunesz() {
local btune=$(($1 * BLK_SZ))
}
# 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() {
$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))
- rate=$((BLK_SZ * LIMIT / 2 / delta / 1024))
- [ $rate -gt 1024 ] || error_exit "SLOW IO for $TSTUSR (user): $rate KB/sec"
+ 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
$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))
- rate=$((BLK_SZ * LIMIT / 2 / delta / 1024))
- [ $rate -gt 1024 ] || error_exit "SLOW IO for $TSTUSR (group): $rate KB/sec"
+ 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
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"
$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 || \
$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.
$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
$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"
$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)
$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
# 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
}
#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"
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
# reboot the lustre
sync; sleep 5; sync
cleanup_and_setup_lustre
- test_0
+ quota_init
mkdir -p $DIR/$tdir
# 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;
}
run_test_with_stat 21 "run for fixing bug16053 ==========="
test_22() {
- quota_save_version "ug"
+ quota_save_version "ug3"
stopall
mount
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 ===="
[ $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]"
wait_delete_completed
# every quota slave gets 20MB
- b_limit=$((OSTCOUNT * 20 * 1024))
+ 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
}
run_test_with_stat 26 "test for false quota error(bz18491) ======================================"
-test_27() {
+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 27 "lfs quota/setquota should handle wrong arguments (19612) ================="
+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) ================="
-# turn off quota
-test_99()
+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
- return 0
+ 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
+
+ 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"