X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Ftests%2Fsanity-quota.sh;h=0b5e2f34cea356c518a1ef8f96274c62dd3ca3a8;hp=6734587efe96576abf087f072740ab712ec9dc9f;hb=b54b7ce43929ce7ff6e48cd219623c264ca6b6b3;hpb=c44b2bea1bacc3cb9173353037cf3a616f13669f diff --git a/lustre/tests/sanity-quota.sh b/lustre/tests/sanity-quota.sh index 6734587..0b5e2f3 100755 --- a/lustre/tests/sanity-quota.sh +++ b/lustre/tests/sanity-quota.sh @@ -39,7 +39,6 @@ BLK_SZ=1024 MAX_DQ_TIME=604800 MAX_IQ_TIME=604800 QTYPE="ugp" -# QP exists since this version. Should be finally set before landing. VERSION_WITH_QP="2.13.53" mds_supports_qp() { [ $MDS1_VERSION -lt $(version_code $VERSION_WITH_QP) ] && @@ -129,17 +128,20 @@ resetquota() { quota_scan() { local local_ugp=$1 local local_id=$2 + local count if [ "$local_ugp" == "a" -o "$local_ugp" == "u" ]; then $LFS quota -v -u $local_id $DIR - log "Files for user ($local_id):" + count=$($LFS find --user $local_id $DIR | wc -l) + log "Files for user ($local_id), count=$count:" ($LFS find --user $local_id $DIR | head -n 4 | xargs stat 2>/dev/null) fi if [ "$local_ugp" == "a" -o "$local_ugp" == "g" ]; then $LFS quota -v -g $local_id $DIR - log "Files for group ($local_id):" + count=$($LFS find --group $local_id $DIR | wc -l) + log "Files for group ($local_id), count=$count:" ($LFS find --group $local_id $DIR | head -n 4 | xargs stat 2>/dev/null) fi @@ -147,7 +149,8 @@ quota_scan() { is_project_quota_supported || return 0 if [ "$local_ugp" == "a" -o "$local_ugp" == "p" ]; then $LFS quota -v -p $TSTPRJID $DIR - log "Files for project ($TSTPRJID):" + count=$($LFS find --projid $TSTPRJID $DIR | wc -l) + log "Files for project ($TSTPRJID), count=$count:" ($LFS find --projid $TSTPRJID $DIR | head -n 4 | xargs stat 2>/dev/null) fi @@ -564,7 +567,7 @@ test_1_check_write() { cancel_lru_locks osc sync; sync_all_data || true # sync means client wrote all it's cache, but id doesn't - # garantee that slave got new edquot trough glimpse. + # guarantee that slave received new edquot through glimpse. # so wait a little to be sure slave got it. sleep 5 $RUNAS $DD of=$testfile count=1 seek=$limit && @@ -705,6 +708,12 @@ test_1b() { pool_add_targets $qpool 0 $(($OSTCOUNT - 1)) || error "pool_add_targets failed" + # check qmt_pool_add dmesg error + local msg_rgx="QMT0000: can't add to $FSNAME-OST0000.*pool.*$qpool" + local dmesg_err + dmesg_err=$(do_facet mds1 dmesg | grep "$msg_rgx" | tail -1) + [[ -z "$dmesg_err" ]] || error "found qmt_pool_add error: $dmesg_err" + $LFS setquota -u $TSTUSR -B ${limit}M --pool $qpool $DIR || error "set user quota failed" @@ -1109,23 +1118,93 @@ test_1h() { } run_test 1h "Block hard limit test using fallocate" +test_1i() { + local global_limit=200 # 200M + local limit1=10 # 10M + local TESTDIR="$DIR/$tdir/" + local testfile="$TESTDIR/$tfile-0" + local testfile1="$TESTDIR/$tfile-1" + local testfile2="$TESTDIR/$tfile-2" + local qpool1="qpool1" + + mds_supports_qp + setup_quota_test || error "setup quota failed with $?" + stack_trap cleanup_quota_test EXIT + + # enable ost quota + set_ost_qtype $QTYPE || error "enable ost quota failed" + + log "User quota (block hardlimit:$global_limit MB)" + $LFS setquota -u $TSTUSR -b 0 -B ${global_limit}M -i 0 -I 0 $DIR || + error "set user quota failed" + + pool_add $qpool1 || error "pool_add failed" + pool_add_targets $qpool1 0 0 || + error "pool_add_targets failed" + + $LFS setquota -u $TSTUSR -B ${limit1}M --pool $qpool1 $DIR || + error "set user quota failed" + + # make sure the system is clean + local used=$(getquota -u $TSTUSR global curspace) + [ $used -ne 0 ] && error "Used space($used) for user $TSTUSR isn't 0." + + $LFS setstripe $TESTDIR -c 1 -i 0 || error "setstripe $TESTDIR failed" + + # hit pool limit + test_1_check_write $testfile "user" $limit1 + $LFS setquota -u $TSTUSR -B 0 --pool $qpool1 $DIR || + error "set user quota failed" + + $LFS quota -uv $TSTUSR --pool $qpool1 $DIR + $RUNAS $DD of=$testfile1 count=$((limit1/2)) || + quota_error u $TSTUSR "write failure, but expect success" + + rm -f $testfile + rm -f $testfile1 + wait_delete_completed || error "wait_delete_completed failed" + sync_all_data || true + + $LFS setquota -u $TSTUSR -B ${limit1}M --pool $qpool1 $DIR || + error "set user quota failed" + test_1_check_write $testfile "user" $limit1 + local tmp_limit=$(($limit1*2)) + # increase pool limit + $LFS setquota -u $TSTUSR -B ${tmp_limit}M --pool $qpool1 $DIR || + error "set user quota failed" + # now write shouldn't fail + $RUNAS $DD of=$testfile1 count=$((limit1/3)) || + quota_error u $TSTUSR "write failure, but expect success" + # decrease pool limit + $LFS setquota -u $TSTUSR -B ${limit1}M --pool $qpool1 $DIR || + error "set user quota failed" + $RUNAS $DD of=$testfile2 count=$((limit1/3)) + # flush cache, ensure noquota flag is set on client + cancel_lru_locks osc + sync; sync_all_data || true + $RUNAS $DD of=$testfile2 seek=$((limit1/3)) count=1 && + quota_error u $TSTUSR "write success, but expect failure" + return 0 +} +run_test 1i "Quota pools: different limit and usage relations" + # test inode hardlimit test_2() { - local TESTFILE="$DIR/$tdir/$tfile-0" - local LIMIT=$(do_facet mds1 $LCTL get_param -n \ + local testfile="$DIR/$tdir/$tfile-0" + local least_qunit=$(do_facet mds1 $LCTL get_param -n \ qmt.$FSNAME-QMT0000.md-0x0.info | - awk '/least qunit/{ print $3 }') - local L2=$(do_facet mds1 $LCTL get_param -n \ - qmt.$FSNAME-QMT0000.md-0x0.soft_least_qunit) - - [ $L2 -le $LIMIT ] || LIMIT=$L2 + sed -e 's/least qunit/least_qunit/' | + awk '/least_qunit/{ print $2 }') + local limit - [ "$SLOW" = "no" ] || LIMIT=$((LIMIT * 1024)) + [ "$SLOW" = "no" ] && limit=$((least_qunit * 2)) || + limit=$((least_qunit * 1024)) + echo "least_qunit: '$least_qunit', limit: '$limit'" - local FREE_INODES=$(mdt_free_inodes 0) - echo "$FREE_INODES free inodes on master MDT" - [ $FREE_INODES -lt $LIMIT ] && - skip "not enough free inodes $FREE_INODES required $LIMIT" + local free_inodes=$(mdt_free_inodes 0) + echo "$free_inodes free inodes on master MDT" + [ $free_inodes -lt $limit ] && + skip "not enough free inodes $free_inodes required $limit" setup_quota_test || error "setup quota failed with $?" @@ -1133,56 +1212,64 @@ test_2() { set_mdt_qtype $QTYPE || error "enable mdt quota failed" # test for user - log "User quota (inode hardlimit:$LIMIT files)" - $LFS setquota -u $TSTUSR -b 0 -B 0 -i 0 -I $LIMIT $DIR || + log "User quota (inode hardlimit:$limit files)" + $LFS setquota -u $TSTUSR -b 0 -B 0 -i 0 -I $limit $DIR || error "set user quota failed" # make sure the system is clean - local USED=$(getquota -u $TSTUSR global curinodes) - [ $USED -ne 0 ] && error "Used inodes($USED) for user $TSTUSR isn't 0." + local used=$(getquota -u $TSTUSR global curinodes) + [ $used -ne 0 ] && error "Used inodes($used) for user $TSTUSR isn't 0." - log "Create $LIMIT files ..." - $RUNAS createmany -m ${TESTFILE} $LIMIT || + log "Create $((limit - least_qunit)) files ..." + $RUNAS createmany -m ${testfile} $((limit - least_qunit)) || quota_error u $TSTUSR "user create failure, but expect success" + # it is ok, if it fails on the last qunit + $RUNAS createmany -m ${testfile}_yyy $least_qunit || true log "Create out of file quota ..." - $RUNAS touch ${TESTFILE}_xxx && + $RUNAS touch ${testfile}_xxx && quota_error u $TSTUSR "user create success, but expect EDQUOT" # cleanup - unlinkmany ${TESTFILE} $LIMIT || error "unlinkmany $TESTFILE failed" - rm -f ${TESTFILE}_xxx + unlinkmany ${testfile} $((limit - least_qunit)) || + error "unlinkmany $testfile failed" + # if 2nd createmany got EDQUOT, not all of nodes would be created + unlinkmany ${testfile}_yyy $least_qunit || true + rm -f ${testfile}_xxx wait_delete_completed - USED=$(getquota -u $TSTUSR global curinodes) - [ $USED -ne 0 ] && quota_error u $TSTUSR \ + used=$(getquota -u $TSTUSR global curinodes) + [ $used -ne 0 ] && quota_error u $TSTUSR \ "user quota isn't released after deletion" resetquota -u $TSTUSR # test for group log "--------------------------------------" - log "Group quota (inode hardlimit:$LIMIT files)" - $LFS setquota -g $TSTUSR -b 0 -B 0 -i 0 -I $LIMIT $DIR || + log "Group quota (inode hardlimit:$limit files)" + $LFS setquota -g $TSTUSR -b 0 -B 0 -i 0 -I $limit $DIR || error "set group quota failed" - TESTFILE=$DIR/$tdir/$tfile-1 + testfile=$DIR/$tdir/$tfile-1 # make sure the system is clean - USED=$(getquota -g $TSTUSR global curinodes) - [ $USED -ne 0 ] && error "Used inodes($USED) for group $TSTUSR isn't 0." + used=$(getquota -g $TSTUSR global curinodes) + [ $used -ne 0 ] && error "Used inodes($used) for group $TSTUSR isn't 0." - log "Create $LIMIT files ..." - $RUNAS createmany -m ${TESTFILE} $LIMIT || + log "Create $limit files ..." + $RUNAS createmany -m ${testfile} $((limit - least_qunit)) || quota_error g $TSTUSR "group create failure, but expect success" + $RUNAS createmany -m ${testfile}_yyy $least_qunit || log "Create out of file quota ..." - $RUNAS touch ${TESTFILE}_xxx && + $RUNAS touch ${testfile}_xxx && quota_error g $TSTUSR "group create success, but expect EDQUOT" # cleanup - unlinkmany ${TESTFILE} $LIMIT || error "unlinkmany $TESTFILE failed" - rm -f ${TESTFILE}_xxx + unlinkmany ${testfile} $((limit - least_qunit)) || + error "unlinkmany $testfile failed" + unlinkmany ${testfile}_yyy $least_qunit || true + rm -f ${testfile}_xxx wait_delete_completed - USED=$(getquota -g $TSTUSR global curinodes) - [ $USED -ne 0 ] && quota_error g $TSTUSR \ + used=$(getquota -g $TSTUSR global curinodes) + [ $used -ne 0 ] && quota_error g $TSTUSR \ "user quota isn't released after deletion" resetquota -g $TSTUSR @@ -1191,28 +1278,30 @@ test_2() { # test for project log "--------------------------------------" - log "Project quota (inode hardlimit:$LIMIT files)" - $LFS setquota -p $TSTPRJID -b 0 -B 0 -i 0 -I $LIMIT $DIR || + log "Project quota (inode hardlimit:$limit files)" + $LFS setquota -p $TSTPRJID -b 0 -B 0 -i 0 -I $limit $DIR || error "set project quota failed" - TESTFILE=$DIR/$tdir/$tfile-1 + testfile=$DIR/$tdir/$tfile-1 # make sure the system is clean - USED=$(getquota -p $TSTPRJID global curinodes) - [ $USED -ne 0 ] && - error "Used inodes($USED) for project $TSTPRJID isn't 0" + used=$(getquota -p $TSTPRJID global curinodes) + [ $used -ne 0 ] && + error "Used inodes($used) for project $TSTPRJID isn't 0" change_project -sp $TSTPRJID $DIR/$tdir - log "Create $LIMIT files ..." - $RUNAS createmany -m ${TESTFILE} $((LIMIT-1)) || quota_error p \ - $TSTPRJID "project create fail, but expect success" + log "Create $limit files ..." + $RUNAS createmany -m ${testfile} $((limit-least_qunit)) || + quota_error p $TSTPRJID \ + "project create fail, but expect success" + $RUNAS createmany -m ${testfile}_yyy $least_qunit || true log "Create out of file quota ..." - $RUNAS touch ${TESTFILE}_xxx && quota_error p $TSTPRJID \ + $RUNAS touch ${testfile}_xxx && quota_error p $TSTPRJID \ "project create success, but expect EDQUOT" change_project -C $DIR/$tdir cleanup_quota_test - USED=$(getquota -p $TSTPRJID global curinodes) - [ $USED -eq 0 ] || quota_error p $TSTPRJID \ + used=$(getquota -p $TSTPRJID global curinodes) + [ $used -eq 0 ] || quota_error p $TSTPRJID \ "project quota isn't released after deletion" } @@ -1531,8 +1620,8 @@ test_3c() { error "set user quota failed" $LFS setquota -u $TSTUSR -b ${limit}M -B 0 --pool $qpool $DIR || error "set user quota failed" - # qpool has minimum soft limit, but it's grace is grater than - # grace period of qpool2. Thus write shouldn't fail when + # qpool has minimum soft limit, but its grace is greater than + # the grace period of qpool2. Thus write shouldn't fail when # hit qpool soft limit - only when reaches up qpool2 limit # after grace2 seconds. $LFS setquota -u $TSTUSR -b ${limit2}M -B 0 --pool $qpool2 $DIR || @@ -1622,6 +1711,7 @@ test_4a() { local TESTFILE=$DIR/$tdir/$tfile-0 local GRACE=12 + [ "$mds1_FSTYPE" = zfs ] && GRACE=20 set_mdt_qtype $QTYPE || error "enable mdt quota failed" echo "User quota (soft limit:$LIMIT files grace:$GRACE seconds)" @@ -1634,8 +1724,6 @@ test_4a() { $LFS setquota -u $TSTUSR -b 0 -B 0 -i $LIMIT -I 0 $DIR || error "set user quota failed" - [ "$mds1_FSTYPE" = zfs ] && GRACE=20 - test_file_soft $TESTFILE $LIMIT $GRACE "u" echo "Group quota (soft limit:$LIMIT files grace:$GRACE seconds)" @@ -2470,6 +2558,108 @@ test_15(){ } run_test 15 "Set over 4T block quota" +test_16a() +{ + (( $CLIENT_VERSION < $(version_code 2.14.55) )) && + skip "Not supported Lustre client before 2.14.55" + + setup_quota_test || error "setup quota failed with $?" + + $LFS setquota -u $TSTUSR -B 500M -I 10K $MOUNT || + error "failed to set quota for user $TSTUSR" + $LFS setquota -g $TSTUSR -B 500M -I 10K $MOUNT || + error "failed to set quota for group $TSTUSR" + + $RUNAS $DD of=$DIR/$tdir/$tfile bs=1M count=50 || + quota_error u $TSTUSR "write failure" + + $LFS quota -u $TSTUSR $MOUNT || + quota_error u $TSTUSR "failed to get quota" + + local OSC=$($LCTL dl | grep OST0000-osc-[^M] | awk '{print $4}') + + $LCTL --device %$OSC deactivate + stack_trap "$LCTL --device %$OSC activate" + + $LFS quota -v -u $TSTUSR $MOUNT || + quota_error u $TSTUSR "failed to get quota after deactivate OSC" + $LFS quota -v -g $TSTUSR $MOUNT || + quota_error g $TSTUSR "failed to get quota after deactivate OSC" + + (( $MDSCOUNT > 1 )) || return 0 + + local MDC=$($LCTL dl | grep MDT0001-mdc-[^M] | awk '{print $4}') + + $LCTL --device %$MDC deactivate + stack_trap "$LCTL --device %$MDC activate" + + $LFS quota -v -u $TSTUSR $MOUNT || + quota_error u $TSTUSR "failed to get quota after deactivate MDC" + $LFS quota -v -g $TSTUSR $MOUNT || + quota_error g $TSTUSR "failed to get quota after deactivate OSC" +} +run_test 16a "lfs quota should skip the inactive MDT/OST" + +cleanup_16b() +{ + stopall + formatall + setupall +} + +test_16b() +{ + (( $CLIENT_VERSION < $(version_code 2.14.55) )) && + skip "Not supported Lustre client before 2.14.55" + + (( $MDSCOUNT >= 3 )) || skip "needs >= 3 MDTs" + + stopall + if ! combined_mgs_mds ; then + format_mgs + start_mgs + fi + + add mds1 $(mkfs_opts mds1 $(mdsdevname 1)) --index=0 --reformat \ + $(mdsdevname 1) $(mdsvdevname 1) + add mds2 $(mkfs_opts mds2 $(mdsdevname 2)) --index=1 --reformat \ + $(mdsdevname 2) $(mdsvdevname 2) + add mds3 $(mkfs_opts mds3 $(mdsdevname 3)) --index=100 --reformat \ + $(mdsdevname 3) $(mdsvdevname 3) + + add ost1 $(mkfs_opts ost1 $(ostdevname 1)) --index=0 --reformat \ + $(ostdevname 1) $(ostvdevname 1) + add ost2 $(mkfs_opts ost2 $(ostdevname 2)) --index=100 --reformat \ + $(ostdevname 2) $(ostvdevname 2) + + stack_trap cleanup_16b + + start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS || error "MDT1 start failed" + start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS || error "MDT2 start failed" + start mds3 $(mdsdevname 3) $MDS_MOUNT_OPTS || error "MDT3 start failed" + start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "OST1 start failed" + start ost2 $(ostdevname 2) $OST_MOUNT_OPTS || error "OST2 start failed" + + mount_client $MOUNT || error "Unable to mount client" + + setup_quota_test || error "setup quota failed with $?" + stack_trap cleanup_quota_test EXIT + + $LFS setquota -u $TSTUSR -B 100M -I 10K $MOUNT || + error "failed to set quota for user $TSTUSR" + $LFS setquota -g $TSTUSR -B 100M -I 10K $MOUNT || + error "failed to set quota for group $TSTUSR" + + $RUNAS $DD of=$DIR/$tdir/$tfile bs=1M count=10 || + quota_error u $TSTUSR "write failure" + + cnt=$($LFS quota -v -u $TSTUSR $MOUNT | grep -ce "^$FSNAME-[MD|OS]T*") + [ $cnt -le 5 ] || quota_error u $TSTUSR "failed to get user quota" + cnt=$($LFS quota -v -g $TSTUSR $MOUNT | grep -ce "^$FSNAME-[MD|OS]T*") + [ $cnt -le 5 ] || quota_error g $TSTUSR "failed to get group quota" +} +run_test 16b "lfs quota should skip the nonexistent MDT/OST" + test_17sub() { local err_code=$1 local BLKS=1 # 1M less than limit @@ -3342,7 +3532,7 @@ test_38() { local procf="osd-$mds1_FSTYPE.$FSNAME-MDT0000" procf=${procf}.quota_slave.acct_user - local accnt_cnt + local acct_cnt acct_cnt=$(do_facet mds1 $LCTL get_param $procf | grep "id:" | \ awk '{if ($3 < 10000) {print $3}}' | wc -l) @@ -3513,6 +3703,68 @@ test_41() { } run_test 41 "df should return projid-specific values" +test_delete_qid() +{ + local qslv_file=$1 + local qtype_file=$2 + local qtype=$3 + local qid=$4 + local osd="osd-ldiskfs" + + [ "$ost1_FSTYPE" = zfs ] && osd="osd-zfs" + + rm -f $DIR/$tdir/$tfile + $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile + chmod a+rw $DIR/$tdir/$tfile + + $LFS setquota $qtype $qid -B 300M $MOUNT + $RUNAS dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || + error "failed to dd" + + do_facet $SINGLEMDS \ + "cat /proc/fs/lustre/qmt/$FSNAME-QMT0000/dt-0x0/$qtype_file | + grep -E 'id: *$qid'" || error "QMT: no qid $qid is found" + echo $osd + do_facet ost1 \ + "cat /proc/fs/lustre/$osd/$FSNAME-OST0000/$qslv_file | + grep -E 'id: *$qid'" || error "QSD: no qid $qid is found" + + $LFS setquota $qtype $qid --delete $MOUNT + do_facet $SINGLEMDS \ + "cat /proc/fs/lustre/qmt/$FSNAME-QMT0000/dt-0x0/$qtype_file | + grep -E 'id: *$qid'" && error "QMT: qid $qid is not deleted" + sleep 5 + do_facet ost1 \ + "cat /proc/fs/lustre/$osd/$FSNAME-OST0000/$qslv_file | + grep -E 'id: *$qid'" && error "QSD: qid $qid is not deleted" + + $LFS setquota $qtype $qid -B 500M $MOUNT + $RUNAS dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || + error "failed to dd" + do_facet $SINGLEMDS \ + "cat /proc/fs/lustre/qmt/$FSNAME-QMT0000/dt-0x0/$qtype_file | + grep -E 'id: *$qid'" || error "QMT: qid $pid is not recreated" + cat /proc/fs/lustre/$osd/$FSNAME-OST0000/$qslv_file + do_facet ost1 \ + "cat /proc/fs/lustre/$osd/$FSNAME-OST0000/$qslv_file | + grep -E 'id: *$qid'" || error "QSD: qid $qid is not recreated" +} + +test_48() +{ + setup_quota_test || error "setup quota failed with $?" + set_ost_qtype $QTYPE || error "enable ost quota failed" + quota_init + + test_delete_qid "quota_slave/limit_user" "glb-usr" "-u" $TSTID + test_delete_qid "quota_slave/limit_group" "glb-grp" "-g" $TSTID + is_project_quota_supported && + test_delete_qid "quota_slave/limit_project" "glb-prj" "-p" "10000" + + cleanup_quota_test +} +run_test 48 "lfs quota --delete should delete quota project ID" + test_50() { ! is_project_quota_supported && skip "Project quota is not supported" @@ -3570,19 +3822,64 @@ run_test 51 "Test project accounting with mv/cp" test_52() { ! is_project_quota_supported && skip "Project quota is not supported" + + (( MDS1_VERSION >= $(version_code 2.14.55) )) || + skip "Need MDS version at least 2.14.55" + setup_quota_test || error "setup quota failed with $?" - local dir="$DIR/$tdir/dir" - mkdir $dir && change_project -sp 1 $dir - touch $DIR/$tdir/file - #Try renaming a file into the project. This should fail. - for num in $(seq 1 2000); do - mrename $DIR/$tdir/file $dir/file >&/dev/null && - error "rename should fail" - done - return 0 + local dir1=$DIR/$tdir/t52_dir1 + local dir2=$DIR/$tdir/t52_dir2 + + mkdir $dir1 || error "failed to mkdir $dir1" + mkdir $dir2 || error "failed to mkdir $dir2" + + $LFS project -sp 1000 $dir1 || error "fail to set project on $dir1" + $LFS project -sp 1001 $dir2 || error "fail to set project on $dir2" + + $DD if=/dev/zero of=/$dir1/$tfile bs=1M count=100 || + error "failed to create and write $tdir1/$tfile" + + cancel_lru_locks osc + sync; sync_all_data || true + + local attrs=($(lsattr -p $dir1/$tfile)) + (( ${attrs[0]} == 1000 )) || + error "project ID on $dir1/$tfile is not inherited" + + $LFS quota -p 1000 $DIR + $LFS quota -p 1001 $DIR + + local prev_used=$(getquota -p 1000 global curspace) + local prev_used2=$(getquota -p 1001 global curspace) + + mrename $dir1 $dir2/tdir || log "rename directory return $?" + + local inum_before=$(ls -i $dir1/$tfile | awk '{print $1}') + mrename $dir1/$tfile $dir2/$tfile || error "failed to rename file" + local inum_after=$(ls -i $dir2/$tfile | awk '{print $1}') + + attrs=($(lsattr -p $dir2/$tfile)) + (( ${attrs[0]} == 1001 )) || + error "project ID is not updated after rename" + + (( $inum_before == $inum_after )) || + error "inode is changed after rename: $inum_before, $inum_after" + + sync_all_data || true + + $LFS quota -p 1000 $DIR + $LFS quota -p 1001 $DIR + + local new_used=$(getquota -p 1000 global curspace) + local new_used2=$(getquota -p 1001 global curspace) + + (( $prev_used >= $new_used + 102400 )) || + error "quota is not deducted from old project ID" + (( $prev_used2 <= $new_used2 - 102400 )) || + error "quota is not added for the new project ID" } -run_test 52 "Rename across different project ID" +run_test 52 "Rename normal file across project ID" test_53() { ! is_project_quota_supported && @@ -3963,7 +4260,8 @@ run_test 61 "default quota tests" test_62() { ! is_project_quota_supported && skip "Project quota is not supported" - [[ "$(chattr -h 2>&1)" =~ "project" ]] || + [[ "$(chattr -h 2>&1)" =~ "project" || + "$(chattr -h 2>&1)" =~ "pRVf" ]] || skip "chattr did not support project quota" setup_quota_test || error "setup quota failed with $?" local testdir=$DIR/$tdir/ @@ -4153,8 +4451,8 @@ test_66() { local testdir=$DIR/$tdir/foo do_facet mds1 $LCTL set_param mdt.*.enable_chprojid_gid=0 - stack_trap "do_facet mds1 $LCTL set_param mdt.*.enable_chprojid_gid=0" \ - EXIT + stack_trap "do_facet mds1 $LCTL \ + set_param mdt.*.enable_chprojid_gid=$old" EXIT mkdir_on_mdt0 $testdir || error "failed to mkdir" chown -R $TSTID:$TSTID $testdir @@ -4347,6 +4645,11 @@ get_slave_nr() { local qtype=$2 local nr + wait_update_facet mds1 \ + "$LCTL get_param -n qmt.$FSNAME-QMT0000.dt-$pool.info \ + >/dev/null 2>&1 || echo foo" "" || + error "mds1: failed to create quota pool $pool" + do_facet mds1 $LCTL get_param -n qmt.$FSNAME-QMT0000.dt-$pool.info | awk '/usr/ {getline; print $2}' } @@ -4459,7 +4762,7 @@ test_69() } run_test 69 "EDQUOT at one of pools shouldn't affect DOM" -test_70() +test_70a() { local qpool="qpool1" local limit=20 # MB @@ -4494,7 +4797,31 @@ test_70() rc=$? [ $rc -eq $err ] || error "quota res $rc != $err" } -run_test 70 "check lfs setquota/quota with a pool option" +run_test 70a "check lfs setquota/quota with a pool option" + +test_70b() +{ + local glbl_hard=200 # 200M + local glbl_soft=100 # 100M + local pool_hard=10 # 10M + local qpool="qpool1" + + pool_add $qpool || error "pool_add failed" + pool_add_targets $qpool 0 1 || error "pool_add_targets failed" + + $LFS setquota -u $TSTUSR -b ${glbl_soft}M -B ${glbl_hard}M $DIR || + error "set user quota failed" + $LFS setquota -u $TSTUSR -B ${pool_hard}M --pool $qpool $DIR || + error "set user quota failed" + + local tmp=$(getquota -u $TSTUSR global bhardlimit $qpool) + [ $tmp -eq $((pool_hard * 1024)) ] || + error "wrong block hard limit $tmp for $qpool" + local tmp=$(getquota -u $TSTUSR global bsoftlimit $qpool) + # soft limit hasn't been set and should be zero + [ $tmp -eq 0 ] || error "wrong soft block limit $tmp for $qpool" +} +run_test 70b "lfs setquota pool works properly" test_71a() { @@ -4994,6 +5321,241 @@ test_77() } run_test 77 "lfs setquota should fail in Lustre mount with 'ro'" +test_78() +{ + (( $OST1_VERSION >= $(version_code 2.14.55) )) || + skip "need OST at least 2.14.55" + check_set_fallocate_or_skip + + setup_quota_test || error "setup quota failed with $?" + + # enable ost quota + set_ost_qtype $QTYPE || error "enable ost quota failed" + + mkdir -p $DIR/$tdir || error "failed to create $tdir" + chown $TSTUSR $DIR/$tdir || error "failed to chown $tdir" + + # setup quota limit + $LFS setquota -u $TSTUSR -b25M -B25M $DIR/$tdir || + error "lfs setquota failed" + + # call fallocate + runas -u $TSTUSR -g $TSTUSR fallocate -l 204800 $DIR/$tdir/$tfile + + kbytes=$(lfs quota -u $TSTUSR $DIR | + awk -v pattern=$DIR 'match($0, pattern) {printf $2}') + echo "kbytes returned:$kbytes" + + # For file size of 204800. We should be having roughly 200 kbytes + # returned. Anything alarmingly low (50 taken as arbitrary value) + # would bail out this TC. Also this also avoids $kbytes of 0 + # to be used in calculation below. + (( $kbytes > 50 )) || + error "fallocate did not use quota. kbytes returned:$kbytes" + + local expect_lo=$(($kbytes * 95 / 100)) # 5% below + local expect_hi=$(($kbytes * 105 / 100)) # 5% above + + # Verify kbytes is 200 (204800/1024). With a permited 5% drift + (( $kbytes >= $expect_lo && $kbytes <= $expect_hi )) || + error "fallocate did not use quota correctly" +} +run_test 78 "Check fallocate increase quota usage" + +test_78a() +{ + (( $CLIENT_VERSION >= $(version_code 2.15.0) )) || + skip "need client at least 2.15.0" + (( $OST1_VERSION >= $(version_code 2.15.0) )) || + skip "need OST at least 2.15.0" + check_set_fallocate_or_skip + + setup_quota_test || error "setup quota failed with $?" + + # enable ost quota + set_ost_qtype $QTYPE || error "enable ost quota failed" + + mkdir -p $DIR/$tdir || error "failed to create $tdir" + + local projectid=5200 # Random project id to test + + change_project -sp $projectid $DIR/$tdir + + # setup quota limit + $LFS setquota -p $projectid -b25M -B25M $DIR/$tdir || + error "lfs setquota project failed" + + # call fallocate + fallocate -l 204800 $DIR/$tdir/$tfile + + # Get curspace (kbytes) for $projectid + local kbytes=$(getquota -p $projectid global curspace) + + echo "kbytes returned:$kbytes" + + # For file size of 204800. We should be having roughly 200 kbytes + # returned. Anything alarmingly low (50 taken as arbitrary value) + # would bail out this TC. Also this also avoids $kbytes of 0 + # to be used in calculation below. + (( $kbytes > 50 )) || + error "fallocate did not use projectid. kbytes returned:$kbytes" + + local expect_lo=$(($kbytes * 95 / 100)) # 5% below + local expect_hi=$(($kbytes * 105 / 100)) # 5% above + + # Verify kbytes is 200 (204800/1024). With a permited 5% drift + (( $kbytes >= $expect_lo && $kbytes <= $expect_hi )) || + error "fallocate did not use quota projectid correctly" +} +run_test 78a "Check fallocate increase projectid usage" + +test_79() +{ + local qpool="qpool1" + local cmd="$LCTL get_param -n qmt.$FSNAME-QMT0000.dt-$qpool.info" + local stopf=$TMP/$tfile + + do_facet mds1 "touch $stopf" + stack_trap "do_facet mds1 'rm -f $stopf'" + do_facet mds1 "while [ -e $stopf ]; do $cmd &>/dev/null; done"& + local pid=$! + pool_add $qpool || error "pool_add failed" + do_facet mds1 "rm $stopf" + wait $pid +} +run_test 79 "access to non-existed dt-pool/info doesn't cause a panic" + +test_80() +{ + local dir1="$DIR/$tdir/dir1" + local dir2="$DIR/$tdir/dir2" + local TESTFILE0="$dir1/$tfile-0" + local TESTFILE1="$dir1/$tfile-1" + local TESTFILE2="$dir1/$tfile-2" + local TESTFILE3="$dir2/$tfile-0" + local global_limit=100 # 100M + local limit=10 # 10M + local qpool="qpool1" + + [ "$OSTCOUNT" -lt "2" ] && skip "needs >= 2 OSTs" + mds_supports_qp + [ "$ost1_FSTYPE" == zfs ] && + skip "ZFS grants some block space together with inode" + setup_quota_test || error "setup quota failed with $?" + set_ost_qtype $QTYPE || error "enable ost quota failed" + + # make sure the system is clean + local used=$(getquota -u $TSTUSR global curspace) + [ $used -ne 0 ] && error "Used space($used) for user $TSTUSR is not 0." + + pool_add $qpool || error "pool_add failed" + pool_add_targets $qpool 0 1 || + error "pool_add_targets failed" + + $LFS setquota -u $TSTUSR -b 0 -B ${global_limit}M -i 0 -I 0 $DIR || + error "set user quota failed" + + $LFS setquota -u $TSTUSR -B ${global_limit}M --pool $qpool $DIR || + error "set user quota failed" + $LFS setquota -u $TSTUSR -B ${limit}M --pool $qpool $DIR || + error "set user quota failed" + + mkdir -p $dir1 || error "failed to mkdir" + chown $TSTUSR.$TSTUSR $dir1 || error "chown $dir1 failed" + mkdir -p $dir2 || error "failed to mkdir" + chown $TSTUSR.$TSTUSR $dir2 || error "chown $dir2 failed" + + $LFS setstripe $dir1 -i 1 -c 1|| error "setstripe $testfile failed" + $LFS setstripe $dir2 -i 0 -c 1|| error "setstripe $testfile failed" + lfs getstripe $dir1 + lfs getstripe $dir2 + sleep 3 + + $LFS quota -uv $TSTUSR $DIR + #define OBD_FAIL_QUOTA_PREACQ 0xA06 + do_facet mds1 $LCTL set_param fail_loc=0xa06 + $RUNAS $DD of=$TESTFILE3 count=3 || + quota_error u $TSTUSR "write failed" + $RUNAS $DD of=$TESTFILE2 count=7 || + quota_error u $TSTUSR "write failed" + $RUNAS $DD of=$TESTFILE1 count=1 oflag=direct || + quota_error u $TSTUSR "write failed" + sync + sleep 3 + $LFS quota -uv --pool $qpool $TSTUSR $DIR + + rm -f $TESTFILE2 + stop ost2 + do_facet mds1 $LCTL set_param fail_loc=0 + start ost2 $(ostdevname 2) $OST_MOUNT_OPTS || error "start ost2 failed" + $LFS quota -uv $TSTUSR --pool $qpool $DIR + # OST0 needs some time to update quota usage after removing TESTFILE2 + sleep 4 + $LFS quota -uv $TSTUSR --pool $qpool $DIR + $RUNAS $DD of=$TESTFILE0 count=2 oflag=direct || + quota_error u $TSTUSR "write failure, but expect success" +} +run_test 80 "check for EDQUOT after OST failover" + +test_81() { + local global_limit=20 # 100M + local testfile="$DIR/$tdir/$tfile-0" + local qpool="qpool1" + + mds_supports_qp + setup_quota_test || error "setup quota failed with $?" + + # enable ost quota + set_ost_qtype $QTYPE || error "enable ost quota failed" + + # test for user + log "User quota (block hardlimit:$global_limit MB)" + $LFS setquota -u $TSTUSR -B 1G $DIR || error "set user quota failed" + + pool_add $qpool || error "pool_add failed" + #define OBD_FAIL_QUOTA_RECALC 0xA07 + do_facet mds1 $LCTL set_param fail_loc=0x80000A07 fail_val=30 + # added OST casues to start pool recalculation + pool_add_targets $qpool 0 0 1 + stop mds1 -f || error "MDS umount failed" + + #start mds1 back to destroy created pool + start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS + clients_up || true +} +run_test 81 "Race qmt_start_pool_recalc with qmt_pool_free" + +test_82() +{ + (( $MDS1_VERSION >= $(version_code 2.14.55) )) || + skip "need MDS 2.14.55 or later" + is_project_quota_supported || + skip "skip project quota unsupported" + + setup_quota_test || error "setup quota failed with $?" + stack_trap cleanup_quota_test + quota_init + + local parent_dir="$DIR/$tdir.parent" + local child_dir="$parent_dir/child" + + mkdir -p $child_dir + stack_trap "chown -R 0:0 $parent_dir" + + chown $TSTUSR:$TSTUSR $parent_dir || + error "failed to chown on $parent_dir" + chown $TSTUSR2:$TSTUSRS2 $child_dir || + error "failed to chown on $parent_dir" + + $LFS project -p 1000 $parent_dir || + error "failed to set project id on $parent_dir" + $LFS project -p 1001 $child_dir || + error "failed to set project id on $child_dir" + + rmdir $child_dir || error "cannot remove child dir, test failed" +} +run_test 82 "verify more than 8 qids for single operation" + quota_fini() { do_nodes $(comma_list $(nodes_list)) \