check_and_setup_lustre
is_project_quota_supported() {
+ lsattr -dp > /dev/null 2>&1 || return 1
+
[ "$(facet_fstype $SINGLEMDS)" == "ldiskfs" ] &&
- [ $(lustre_version_code $SINGLEMDS) -gt $(version_code 2.9.55) ] &&
- egrep -q "7." /etc/redhat-release
+ [ $(lustre_version_code $SINGLEMDS) -gt \
+ $(version_code 2.9.55) ] &&
+ egrep -q "7." /etc/redhat-release && return 0
+
+ if [ "$(facet_fstype $SINGLEMDS)" == "zfs" ]; then
+ [ $(lustre_version_code $SINGLEMDS) -le \
+ $(version_code 2.10.53) ] && return 1
+
+ $ZPOOL upgrade -v | grep project_quota && return 0
+ fi
+
+ return 1
}
SHOW_QUOTA_USER="$LFS quota -v -u $TSTUSR $DIR"
do_nodes $NODES "lctl set_param fail_val=$fail_val fail_loc=$fail_loc"
}
+change_project()
+{
+ echo "chattr $*"
+ chattr $* || error "chattr $* failed"
+}
+
RUNAS="runas -u $TSTID -g $TSTID"
RUNAS2="runas -u $TSTID2 -g $TSTID2"
DD="dd if=/dev/zero bs=1M"
fi
if [ "$local_ugp" == "a" -o "$local_ugp" == "p" ]; then
- $LFS quota -v -p $local_id $DIR
- log "Files for project ($local_id):"
- ($LFS find --projid $local_id $DIR | head -n 4 |
+ $LFS quota -v -p $TSTPRJID $DIR
+ log "Files for project ($TSTPRJID):"
+ ($LFS find --projid $TSTPRJID $DIR | head -n 4 |
xargs stat 2>/dev/null)
fi
}
local spec
local uuid
+ sync_all_data > /dev/null 2>&1 || true
+
[ "$#" != 4 ] && error "getquota: wrong number of arguments: $#"
[ "$1" != "-u" -a "$1" != "-g" -a "$1" != "-p" ] &&
error "getquota: wrong u/g/p specifier $1 passed"
disable_project_quota() {
is_project_quota_supported || return 0
+ [ "$(facet_fstype $SINGLEMDS)" != "ldiskfs" ] && return 0
stopall || error "failed to stopall (1)"
for num in $(seq $MDSCOUNT); do
}
enable_project_quota() {
- is_project_quota_supported || return 0
+ is_project_quota_supported || return 0
+ [ "$(facet_fstype $SINGLEMDS)" != "ldiskfs" ] && return 0
stopall || error "failed to stopall (1)"
for num in $(seq $MDSCOUNT); do
# test for Project
log "--------------------------------------"
- log "project quota (block hardlimit:$LIMIT mb)"
+ log "Project quota (block hardlimit:$LIMIT mb)"
$LFS setquota -p $TSTPRJID -b 0 -B ${LIMIT}M -i 0 -I 0 $DIR ||
error "set project quota failed"
$SETSTRIPE $TESTFILE -c 1 || error "setstripe $TESTFILE failed"
chown $TSTUSR:$TSTUSR $TESTFILE || error "chown $TESTFILE failed"
- chattr -p $TSTPRJID $TESTFILE
+ change_project -p $TSTPRJID $TESTFILE
log "write ..."
$RUNAS $DD of=$TESTFILE count=$((LIMIT/2)) || quota_error p $TSTPRJID \
cancel_lru_locks osc
sync; sync_all_data || true
$RUNAS $DD of=$TESTFILE count=10 seek=$LIMIT && quota_error p \
- $TSTPRJID "project write success, but expect edquot"
+ $TSTPRJID "project write success, but expect EDQUOT"
# cleanup
cleanup_quota_test
[ $USED -ne 0 ] &&
error "Used inodes($USED) for project $TSTPRJID isn't 0"
- chattr +P $DIR/$tdir/
- chattr -p $TSTPRJID -d $DIR/$tdir
+ change_project +P $DIR/$tdir/
+ change_project -p $TSTPRJID -d $DIR/$tdir
log "Create $LIMIT files ..."
$RUNAS createmany -m ${TESTFILE} $((LIMIT-1)) || quota_error p \
$TSTPRJID "project create fail, but expect success"
log "Create out of file quota ..."
$RUNAS touch ${TESTFILE}_xxx && quota_error p $TSTPRJID \
"project create success, but expect EDQUOT"
- chattr -P $DIR/$tdir
- chattr -p 0 -d $DIR/$tdir
+ change_project -P $DIR/$tdir
+ change_project -p 0 -d $DIR/$tdir
cleanup_quota_test
USED=$(getquota -p $TSTPRJID global curinodes)
$SETSTRIPE $TESTFILE -c 1 -i 0
chown $TSTUSR.$TSTUSR $TESTFILE
[ "$qtype" == "p" ] && is_project_quota_supported &&
- chattr -p $TSTPRJID $TESTFILE
+ change_project -p $TSTPRJID $TESTFILE
echo "Write up to soft limit"
$RUNAS $DD of=$TESTFILE count=$LIMIT ||
$SETSTRIPE $TESTFILE -c 1 -i 0
chown $TSTUSR.$TSTUSR $TESTFILE
- [ "$qtype" == "p" ] && chattr -p $TSTPRJID $TESTFILE
+ [ "$qtype" == "p" ] && change_project -p $TSTPRJID $TESTFILE
echo "Write ..."
$RUNAS $DD of=$TESTFILE count=$LIMIT ||
setup_quota_test
trap cleanup_quota_test EXIT
- is_project_quota_supported && chattr +P $DIR/$tdir/ &&
- chattr -p $TSTPRJID -d $DIR/$tdir
+ is_project_quota_supported && change_project +P $DIR/$tdir/ &&
+ change_project -p $TSTPRJID -d $DIR/$tdir
echo "Create files to exceed soft limit"
$RUNAS createmany -m ${TESTFILE}_ $((LIMIT + 1)) ||
USED=$(getquota -g $TSTUSR global curspace)
[ $USED -ne 0 ] && error "Used block($USED) for group $TSTUSR isn't 0."
if is_project_quota_supported; then
+ USED=$(getquota -p $TSTPRJID global curinodes)
+ [ $USED -ne 0 ] &&
+ error "Used inode($USED) for project $TSTPRJID isn't 0."
USED=$(getquota -p $TSTPRJID global curspace)
[ $USED -ne 0 ] &&
error "Used block($USED) for project $TSTPRJID isn't 0."
echo "Create more than $ILIMIT files and more than $BLIMIT MB ..."
createmany -m $DIR/$tdir/$tfile-0_ $((ILIMIT + 1)) ||
error "create failure, expect success"
- if [ "$(facet_fstype $singlemds)" == "ldiskfs" ]; then
+ if is_project_quota_supported; then
touch $DIR/$tdir/$tfile-0_1
- chattr -p $TSTPRJID $DIR/$tdir/$tfile-0_1
+ change_project -p $TSTPRJID $DIR/$tdir/$tfile-0_1
fi
$DD of=$DIR/$tdir/$tfile-0_1 count=$((BLIMIT+1)) ||
error "write failure, expect success"
# quota reintegration (inode limits)
test_7e() {
- [ "$MDSCOUNT" -lt "2" ] && skip "Required more MDTs" && return
+ [ "$MDSCOUNT" -lt "2" ] && skip "needs >= 2 MDTs" && return
# LU-2435: skip this quota test if underlying zfs version has not
# supported native dnode accounting
[ "$(facet_fstype mds1)" == "zfs" ] && {
- local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
+ local F="feature@userobj_accounting"
+ local pool=$(zpool_name mds1)
+ local feature=$(do_facet mds1 $ZPOOL get -H $F $pool)
- [ $(version_code $zfs_version) -lt $(version_code 0.7.0) ] &&
- skip "requires zfs version at least 0.7.0" && return
+ [[ "$feature" != *" active "* ]] &&
+ skip "requires zpool with active userobj_accounting" &&
+ return
}
local ilimit=$((1024 * 2)) # 2k inodes
# hardlimit should be cleared on slave during reintegration
$RUNAS createmany -m $TESTFILE $((ilimit + 1)) ||
- quota_error -u $TSTUSR "create failed, expect success"
+ quota_error u $TSTUSR "create failed, expect success"
$RUNAS unlinkmany $TESTFILE $((ilimit + 1)) || error "unlink failed"
rmdir $DIR/${tdir}-1 || error "unlink remote dir failed"
$LFS setquota -g $TSTUSR -b 0 -B $BLK_LIMIT -i 0 -I $FILE_LIMIT $DIR ||
error "set group quota failed"
if is_project_quota_supported; then
- chattr +P $DIR/$tdir && chattr -p $TSTPRJID -d $DIR/$tdir
+ change_project +P $DIR/$tdir && change_project -p \
+ $TSTPRJID -d $DIR/$tdir
echo "Set enough high limit for project: $TSTPRJID"
$LFS setquota -p $TSTPRJID -b 0 \
-B $BLK_LIMIT -i 0 -I $FILE_LIMIT $DIR ||
$RUNAS bash rundbench -D $DIR/$tdir 3 $duration ||
quota_error a $TSTUSR "dbench failed!"
- is_project_quota_supported && chattr -P $DIR/$tdir &&
- chattr -dp 0 $DIR/$tdir
+ is_project_quota_supported && change_project -P $DIR/$tdir &&
+ change_project -dp 0 $DIR/$tdir
cleanup_quota_test
resetquota -u $TSTUSR
resetquota -g $TSTUSR
run_test 11 "Chown/chgrp ignores quota"
test_12a() {
- [ "$OSTCOUNT" -lt "2" ] && skip "skipping rebalancing test" && return
+ [ "$OSTCOUNT" -lt "2" ] && skip "needs >= 2 OSTs" && return
local blimit=22 # 22M
local blk_cnt=$((blimit - 5))
run_test 12a "Block quota rebalancing"
test_12b() {
- [ "$MDSCOUNT" -lt "2" ] && skip "skipping rebalancing test" && return
+ [ "$MDSCOUNT" -lt "2" ] && skip "needs >= 2 MDTs" && return
local ilimit=$((1024 * 2)) # 2k inodes
local TESTFILE0=$DIR/$tdir/$tfile
$RUNAS $DD of=$DIR/$tdir/$tfile-$i count=$BLK_CNT 2>/dev/null ||
error "write failed"
is_project_quota_supported &&
- chattr -p $TSTPRJID $DIR/$tdir/$tfile-$i
+ change_project -p $TSTPRJID $DIR/$tdir/$tfile-$i
echo "Iteration $i/$INODES completed"
done
cancel_lru_locks osc
+
+ echo "Wait for setattr on objects finished..."
+ wait_delete_completed
+
sync; sync_all_data || true
echo "Verify disk usage after write"
USED=$(getquota -g $TSTID global curinodes)
[ $USED -eq 0 ] || error "Used inodes for group $TSTID isn't 0. $USED"
if is_project_quota_supported; then
+ USED=$(getquota -p $TSTPRJID global curspace)
+ [ $USED -eq 0 ] ||
+ error "Used space for project $TSTPRJID isn't 0. $USED"
USED=$(getquota -p $TSTPRJID global curinodes)
[ $USED -eq 0 ] ||
error "Used inodes for project $TSTPRJID isn't 0. $USED"
echo "Wait for setattr on objects finished..."
wait_delete_completed
- echo "chattr project id to $TSTPRJID"
+ echo "change_project project id to $TSTPRJID"
[ $project_supported == "yes" ] &&
- chattr -p $TSTPRJID $DIR/$tdir/$tfile
+ change_project -p $TSTPRJID $DIR/$tdir/$tfile
echo "Wait for setattr on objects finished..."
wait_delete_completed
$RUNAS $DD of=$DIR/$tdir/$tfile count=$BLK_CNT 2>/dev/null ||
error "write failed"
is_project_quota_supported &&
- chattr -p $TSTPRJID $DIR/$tdir/$tfile
+ change_project -p $TSTPRJID $DIR/$tdir/$tfile
cancel_lru_locks osc
+
+ echo "Wait for setattr on objects finished..."
+ wait_delete_completed
+
sync; sync_all_data || true
echo "Save disk usage before restart"
projectid=$(lsattr -p $TESTFILE | awk '{print $1}')
[ $projectid -ne 0 ] &&
error "Project id should be 0 not $projectid"
- chattr -p 1024 $TESTFILE
+ change_project -p 1024 $TESTFILE
projectid=$(lsattr -p $TESTFILE | awk '{print $1}')
[ $projectid -ne 1024 ] &&
error "Project id should be 1024 not $projectid"
setup_quota_test || error "setup quota failed with $?"
mkdir -p $dir1 $dir2
- chattr +P $dir1 && chattr -p 1 -d $dir1 && touch $dir1/1
- chattr +P $dir2 && chattr -p 2 -d $dir2
+ change_project +P $dir1 && change_project -p 1 -d $dir1 && touch $dir1/1
+ change_project +P $dir2 && change_project -p 2 -d $dir2
ln $dir1/1 $dir2/1_link &&
error "Hard link across different project quota should fail"
setup_quota_test || error "setup quota failed with $?"
mkdir -p $dir1 $dir2
- chattr +P $dir1 && chattr -p 1 -d $dir1 && touch $dir1/1
- chattr +P $dir2 && chattr -p 2 -d $dir2
+ change_project +P $dir1 && change_project -p 1 -d $dir1 && touch $dir1/1
+ change_project +P $dir2 && change_project -p 2 -d $dir2
mv $dir1/1 $dir2/2 || error "mv failed $?"
local projid=$(lsattr -p $dir2/2 | awk '{print $1}')
run_test 40b "Mv across different project ID"
test_40c() {
- [ "$MDSCOUNT" -lt "2" ] && skip "Required more MDTs" && return
+ [ "$MDSCOUNT" -lt "2" ] && skip "needs >= 2 MDTs" && return
! is_project_quota_supported &&
skip "Project quota is not supported" && return 0
setup_quota_test || error "setup quota failed with $?"
local dir="$DIR/$tdir/dir"
- mkdir -p $dir && chattr +P $dir && chattr -dp 1 $dir
+ mkdir -p $dir && change_project +P $dir && change_project -dp 1 $dir
$LFS mkdir -i 1 $dir/remote_dir || error "create remote dir failed"
local projid=$(lsattr -dp $dir/remote_dir | awk '{print $1}')
[ "$projid" != "1" ] && error "projid id expected 1 not $projid"
setup_quota_test || error "setup quota failed with $?"
local dir="$DIR/$tdir/dir"
- mkdir $dir && chattr -dp 1 $dir
+ mkdir $dir && change_project -dp 1 $dir
count=$($LFS find --projid 1 $DIR | wc -l)
[ "$count" != 1 ] && error "expected 1 but got $count"
setup_quota_test || error "setup quota failed with $?"
local dir="$DIR/$tdir/dir"
- mkdir $dir && chattr -dp 1 $dir && chattr +P $dir
+ mkdir $dir && change_project -dp 1 $dir && change_project +P $dir
local used=$(getquota -p 1 global curinodes)
- [ $used != "1" ] && error "expected 1 got $used"
+ [ $used != "1" ] && error "expected 1 got $used"
touch $dir/1
touch $dir/2
cp $dir/2 $dir/3
used=$(getquota -p 1 global curinodes)
- [ $used != "4" ] && error "expected 4 got $used"
+ [ $used != "4" ] && error "expected 4 got $used"
$DD if=/dev/zero of=$DIR/$tdir/6 bs=1M count=1
#try cp to dir
cp $DIR/$tdir/6 $dir/6
used=$(getquota -p 1 global curinodes)
- [ $used != "5" ] && error "expected 5 got $used"
+ [ $used != "5" ] && error "expected 5 got $used"
#try mv to dir
mv $DIR/$tdir/6 $dir/7
used=$(getquota -p 1 global curinodes)
- [ $used != "6" ] && error "expected 6 got $used"
+ [ $used != "6" ] && error "expected 6 got $used"
rm -rf $dir
cleanup_quota_test
skip "Project quota is not supported" && return 0
setup_quota_test || error "setup quota failed with $?"
local dir="$DIR/$tdir/dir"
- mkdir $dir && chattr -dp 1 $dir && chattr +P $dir
+ mkdir $dir && change_project -dp 1 $dir && change_project +P $dir
touch $DIR/$tdir/file
#Try renaming a file into the project. This should fail.
}
run_test 52 "Rename across different project ID"
+test_53() {
+ ! is_project_quota_supported &&
+ skip "Project quota is not supported" && return 0
+ setup_quota_test || error "setup quota failed with $?"
+ local dir="$DIR/$tdir/dir"
+ mkdir $dir && change_project +P $dir
+ lsattr -pd $dir | grep P || error "inherit attribute should be set"
+
+ change_project -Pd $dir
+ lsattr -pd $dir | grep P && error "inherit attribute should be cleared"
+
+ rm -rf $dir
+ cleanup_quota_test
+}
+run_test 53 "Project inherit attribute could be cleared"
+
quota_fini()
{
do_nodes $(comma_list $(nodes_list)) "lctl set_param debug=-quota"