diff mbox series

[v2] generic: soft quota limits testing within grace time

Message ID 20220509183523.1809778-1-zlang@kernel.org (mailing list archive)
State New, archived
Headers show
Series [v2] generic: soft quota limits testing within grace time | expand

Commit Message

Zorro Lang May 9, 2022, 6:35 p.m. UTC
After soft limits are exceeded, within the grace time, fs quota
should allow more space allocation before exceeding hard limits,
even if allocating many small files.

This case can cover bc37e4fb5cac (xfs: revert "xfs: actually bump
warning counts when we send warnings"). And will help to expose
later behavior changes on this side.

Signed-off-by: Zorro Lang <zlang@redhat.com>
---

Thanks review points from Darrick, V2 move _create_project_quota and
_restore_project_quota to common/quota and help them to be common.

Thanks,
Zorro

 common/quota          | 48 +++++++++++++++++++++++
 tests/generic/999     | 88 +++++++++++++++++++++++++++++++++++++++++++
 tests/generic/999.out |  2 +
 3 files changed, 138 insertions(+)
 create mode 100755 tests/generic/999
 create mode 100644 tests/generic/999.out

Comments

Darrick J. Wong May 11, 2022, 4:01 p.m. UTC | #1
On Tue, May 10, 2022 at 02:35:23AM +0800, Zorro Lang wrote:
> After soft limits are exceeded, within the grace time, fs quota
> should allow more space allocation before exceeding hard limits,
> even if allocating many small files.
> 
> This case can cover bc37e4fb5cac (xfs: revert "xfs: actually bump
> warning counts when we send warnings"). And will help to expose
> later behavior changes on this side.
> 
> Signed-off-by: Zorro Lang <zlang@redhat.com>
> ---
> 
> Thanks review points from Darrick, V2 move _create_project_quota and
> _restore_project_quota to common/quota and help them to be common.
> 
> Thanks,
> Zorro
> 
>  common/quota          | 48 +++++++++++++++++++++++
>  tests/generic/999     | 88 +++++++++++++++++++++++++++++++++++++++++++
>  tests/generic/999.out |  2 +
>  3 files changed, 138 insertions(+)
>  create mode 100755 tests/generic/999
>  create mode 100644 tests/generic/999.out
> 
> diff --git a/common/quota b/common/quota
> index 7fa1a61a..67698f74 100644
> --- a/common/quota
> +++ b/common/quota
> @@ -351,5 +351,53 @@ _qsetup()
>  	echo "Using type=$type id=$id" >> $seqres.full
>  }
>  
> +# Help to create project quota on directory, works for xfs and other fs.
> +# Usage: _create_project_quota <dirname> <projid> [name]
> +# Although the [name] is optional, better to specify it if need a fixed name.
> +_create_project_quota()
> +{
> +	local prjdir=$1
> +	local id=$2
> +	local name=$3
> +
> +	if [ -z "$name" ];then
> +		name=`echo $projdir | tr \/ \_`
> +	fi
> +
> +	rm -rf $prjdir
> +	mkdir $prjdir
> +	chmod ugo+rwx $prjdir
> +
> +	if [ -f /etc/projects -a ! -f $tmp.projects.bk ];then
> +		cat /etc/projects > $tmp.projects.bk
> +		echo >/etc/projects
> +	fi
> +	if [ -f /etc/projid -a ! -f $tmp.projid.bk ];then
> +		cat /etc/projid > $tmp.projid.bk
> +		echo >/etc/projid
> +	fi
> +
> +	cat >>/etc/projects <<EOF
> +$id:$prjdir
> +EOF
> +	cat >>/etc/projid <<EOF
> +$name:$id
> +EOF
> +	$XFS_IO_PROG -r -c "chproj $id" -c "chattr +P" $prjdir
> +}
> +
> +# If you've called _create_project_quota, then use this function in _cleanup
> +_restore_project_quota()
> +{
> +	if [ -f $tmp.projects.bk ];then
> +		cat $tmp.projects.bk > /etc/projects && \
> +			rm -f $tmp.projects.bk
> +	fi
> +	if [ -f $tmp.projid.bk ];then
> +		cat $tmp.projid.bk > /etc/projid && \
> +			rm -f $tmp.projid.bk
> +	fi
> +}

When I asked you to hoist this, to common/quota, I also meant that you
should port generic/603 to use the new common helpers.

(That /can/ be a followup patch though, since 603 does a few more things
in its project quota setup code.)

> +
>  # make sure this script returns success
>  /bin/true
> diff --git a/tests/generic/999 b/tests/generic/999
> new file mode 100755
> index 00000000..103a74f9
> --- /dev/null
> +++ b/tests/generic/999
> @@ -0,0 +1,88 @@
> +#! /bin/bash
> +# SPDX-License-Identifier: GPL-2.0
> +# Copyright (c) 2022 Red Hat Inc.  All Rights Reserved.
> +#
> +# FS QA Test No. 999
> +#
> +# Make sure filesystem quota works well, after soft limits are exceeded. The
> +# fs quota should allow more space allocation before exceeding hard limits
> +# and with in grace time.
> +#
> +# But different with other similar testing, this case trys to write many small

"tries"

> +# files, to cover bc37e4fb5cac (xfs: revert "xfs: actually bump warning counts
> +# when we send warnings"). If there's a behavior change in one day, this case

"If there's a behavior change some day,"

> +# might help to detect that too.
> +#
> +. ./common/preamble
> +_begin_fstest auto quota
> +
> +# Override the default cleanup function.
> +_cleanup()
> +{
> +	_restore_project_quota
> +	cd /
> +	rm -r -f $tmp.*
> +}
> +
> +# Import common functions.
> +. ./common/quota
> +
> +# real QA test starts here
> +_supported_fs generic
> +_require_scratch
> +_require_quota
> +_require_user
> +_require_group
> +
> +# Make sure the kernel supports project quota
> +_scratch_mkfs >$seqres.full 2>&1
> +_scratch_enable_pquota
> +_qmount_option "prjquota"
> +_qmount
> +_require_prjquota $SCRATCH_DEV
> +
> +exercise()
> +{
> +	local type=$1
> +	local file=$SCRATCH_MNT/testfile
> +
> +	echo "= Test type=$type quota =" >>$seqres.full
> +	_scratch_unmount
> +	_scratch_mkfs >>$seqres.full 2>&1
> +	if [ "$1" = "P" ];then
> +		_scratch_enable_pquota
> +	fi
> +	_qmount
> +	if [ "$1" = "P" ];then
> +		_create_project_quota $SCRATCH_MNT/t 100 $qa_user
> +		file=$SCRATCH_MNT/t/testfile
> +	fi
> +
> +	setquota -${type} $qa_user 1M 500M 0 0 $SCRATCH_MNT
> +	setquota -${type} -t 86400 86400 $SCRATCH_MNT
> +	repquota -v -${type} $SCRATCH_MNT | grep -v "^root" >>$seqres.full 2>&1
> +	# Exceed the soft quota limit a bit at first
> +	su $qa_user -c "$XFS_IO_PROG -f -t -c 'pwrite 0 2m' -c fsync ${file}.0" >>$seqres.full 2>&1
> +	# Write more data more times under soft quota limit exhausted condition,
> +	# but not reach hard limit. To make sure the it won't trigger EDQUOT.
> +	for ((i=1; i<=100; i++));do

I forget, is there a test like this that also goes to the hard limit?

(The rest of the logic here looks sound, fwiw)

--D

> +		su "$qa_user" -c "$XFS_IO_PROG -f -c 'pwrite 0 1m' -c fsync ${file}.$i" >>$seqres.full 2>&1
> +		if [ $? -ne 0 ];then
> +			echo "Unexpected error (type=$type)!"
> +			break
> +		fi
> +	done
> +	repquota -v -${type} $SCRATCH_MNT | grep -v "^root" >>$seqres.full 2>&1
> +}
> +
> +_qmount_option "usrquota"
> +exercise u
> +_qmount_option "grpquota"
> +exercise g
> +_qmount_option "prjquota"
> +exercise P
> +
> +echo "Silence is golden"
> +# success, all done
> +status=0
> +exit
> diff --git a/tests/generic/999.out b/tests/generic/999.out
> new file mode 100644
> index 00000000..3b276ca8
> --- /dev/null
> +++ b/tests/generic/999.out
> @@ -0,0 +1,2 @@
> +QA output created by 999
> +Silence is golden
> -- 
> 2.31.1
>
Zorro Lang May 11, 2022, 4:38 p.m. UTC | #2
On Wed, May 11, 2022 at 09:01:06AM -0700, Darrick J. Wong wrote:
> On Tue, May 10, 2022 at 02:35:23AM +0800, Zorro Lang wrote:
> > After soft limits are exceeded, within the grace time, fs quota
> > should allow more space allocation before exceeding hard limits,
> > even if allocating many small files.
> > 
> > This case can cover bc37e4fb5cac (xfs: revert "xfs: actually bump
> > warning counts when we send warnings"). And will help to expose
> > later behavior changes on this side.
> > 
> > Signed-off-by: Zorro Lang <zlang@redhat.com>
> > ---
> > 
> > Thanks review points from Darrick, V2 move _create_project_quota and
> > _restore_project_quota to common/quota and help them to be common.
> > 
> > Thanks,
> > Zorro
> > 
> >  common/quota          | 48 +++++++++++++++++++++++
> >  tests/generic/999     | 88 +++++++++++++++++++++++++++++++++++++++++++
> >  tests/generic/999.out |  2 +
> >  3 files changed, 138 insertions(+)
> >  create mode 100755 tests/generic/999
> >  create mode 100644 tests/generic/999.out
> > 
> > diff --git a/common/quota b/common/quota
> > index 7fa1a61a..67698f74 100644
> > --- a/common/quota
> > +++ b/common/quota
> > @@ -351,5 +351,53 @@ _qsetup()
> >  	echo "Using type=$type id=$id" >> $seqres.full
> >  }
> >  
> > +# Help to create project quota on directory, works for xfs and other fs.
> > +# Usage: _create_project_quota <dirname> <projid> [name]
> > +# Although the [name] is optional, better to specify it if need a fixed name.
> > +_create_project_quota()
> > +{
> > +	local prjdir=$1
> > +	local id=$2
> > +	local name=$3
> > +
> > +	if [ -z "$name" ];then
> > +		name=`echo $projdir | tr \/ \_`
> > +	fi
> > +
> > +	rm -rf $prjdir
> > +	mkdir $prjdir
> > +	chmod ugo+rwx $prjdir
> > +
> > +	if [ -f /etc/projects -a ! -f $tmp.projects.bk ];then
> > +		cat /etc/projects > $tmp.projects.bk
> > +		echo >/etc/projects
> > +	fi
> > +	if [ -f /etc/projid -a ! -f $tmp.projid.bk ];then
> > +		cat /etc/projid > $tmp.projid.bk
> > +		echo >/etc/projid
> > +	fi
> > +
> > +	cat >>/etc/projects <<EOF
> > +$id:$prjdir
> > +EOF
> > +	cat >>/etc/projid <<EOF
> > +$name:$id
> > +EOF
> > +	$XFS_IO_PROG -r -c "chproj $id" -c "chattr +P" $prjdir
> > +}
> > +
> > +# If you've called _create_project_quota, then use this function in _cleanup
> > +_restore_project_quota()
> > +{
> > +	if [ -f $tmp.projects.bk ];then
> > +		cat $tmp.projects.bk > /etc/projects && \
> > +			rm -f $tmp.projects.bk
> > +	fi
> > +	if [ -f $tmp.projid.bk ];then
> > +		cat $tmp.projid.bk > /etc/projid && \
> > +			rm -f $tmp.projid.bk
> > +	fi
> > +}
> 
> When I asked you to hoist this, to common/quota, I also meant that you
> should port generic/603 to use the new common helpers.

Oh, yes, g/603 is another quota related case written by me. I'll change that
too.

> 
> (That /can/ be a followup patch though, since 603 does a few more things
> in its project quota setup code.)

Sure.

> 
> > +
> >  # make sure this script returns success
> >  /bin/true
> > diff --git a/tests/generic/999 b/tests/generic/999
> > new file mode 100755
> > index 00000000..103a74f9
> > --- /dev/null
> > +++ b/tests/generic/999
> > @@ -0,0 +1,88 @@
> > +#! /bin/bash
> > +# SPDX-License-Identifier: GPL-2.0
> > +# Copyright (c) 2022 Red Hat Inc.  All Rights Reserved.
> > +#
> > +# FS QA Test No. 999
> > +#
> > +# Make sure filesystem quota works well, after soft limits are exceeded. The
> > +# fs quota should allow more space allocation before exceeding hard limits
> > +# and with in grace time.
> > +#
> > +# But different with other similar testing, this case trys to write many small
> 
> "tries"
> 
> > +# files, to cover bc37e4fb5cac (xfs: revert "xfs: actually bump warning counts
> > +# when we send warnings"). If there's a behavior change in one day, this case
> 
> "If there's a behavior change some day,"

Thanks for the english teaching :)

> 
> > +# might help to detect that too.
> > +#
> > +. ./common/preamble
> > +_begin_fstest auto quota
> > +
> > +# Override the default cleanup function.
> > +_cleanup()
> > +{
> > +	_restore_project_quota
> > +	cd /
> > +	rm -r -f $tmp.*
> > +}
> > +
> > +# Import common functions.
> > +. ./common/quota
> > +
> > +# real QA test starts here
> > +_supported_fs generic
> > +_require_scratch
> > +_require_quota
> > +_require_user
> > +_require_group
> > +
> > +# Make sure the kernel supports project quota
> > +_scratch_mkfs >$seqres.full 2>&1
> > +_scratch_enable_pquota
> > +_qmount_option "prjquota"
> > +_qmount
> > +_require_prjquota $SCRATCH_DEV
> > +
> > +exercise()
> > +{
> > +	local type=$1
> > +	local file=$SCRATCH_MNT/testfile
> > +
> > +	echo "= Test type=$type quota =" >>$seqres.full
> > +	_scratch_unmount
> > +	_scratch_mkfs >>$seqres.full 2>&1
> > +	if [ "$1" = "P" ];then
> > +		_scratch_enable_pquota
> > +	fi
> > +	_qmount
> > +	if [ "$1" = "P" ];then
> > +		_create_project_quota $SCRATCH_MNT/t 100 $qa_user
> > +		file=$SCRATCH_MNT/t/testfile
> > +	fi
> > +
> > +	setquota -${type} $qa_user 1M 500M 0 0 $SCRATCH_MNT
> > +	setquota -${type} -t 86400 86400 $SCRATCH_MNT
> > +	repquota -v -${type} $SCRATCH_MNT | grep -v "^root" >>$seqres.full 2>&1
> > +	# Exceed the soft quota limit a bit at first
> > +	su $qa_user -c "$XFS_IO_PROG -f -t -c 'pwrite 0 2m' -c fsync ${file}.0" >>$seqres.full 2>&1
> > +	# Write more data more times under soft quota limit exhausted condition,
> > +	# but not reach hard limit. To make sure the it won't trigger EDQUOT.
> > +	for ((i=1; i<=100; i++));do
> 
> I forget, is there a test like this that also goes to the hard limit?

I can't rememeber all, below generic cases might about hardlimt

g/327: Ensure that we can't go over the hard block limit when reflinking
g/328: Ensure that we can't go over the hard block limit when CoWing a file
g/385: Test renames accross project boundaries
g/566: Test chgrp with group quota hard limit
g/681: Test unprivileged link files with project quota limit
g/682: Test unprivileged move files with project quota limit

There maybe not generic case to do basic quota hard/soft limig test, but
there're some xfs specific cases might do what you said above, likes xfs/050,
xfs/299, xfs/153.

Thanks,
Zorro

> 
> (The rest of the logic here looks sound, fwiw)
> 
> --D
> 
> > +		su "$qa_user" -c "$XFS_IO_PROG -f -c 'pwrite 0 1m' -c fsync ${file}.$i" >>$seqres.full 2>&1
> > +		if [ $? -ne 0 ];then
> > +			echo "Unexpected error (type=$type)!"
> > +			break
> > +		fi
> > +	done
> > +	repquota -v -${type} $SCRATCH_MNT | grep -v "^root" >>$seqres.full 2>&1
> > +}
> > +
> > +_qmount_option "usrquota"
> > +exercise u
> > +_qmount_option "grpquota"
> > +exercise g
> > +_qmount_option "prjquota"
> > +exercise P
> > +
> > +echo "Silence is golden"
> > +# success, all done
> > +status=0
> > +exit
> > diff --git a/tests/generic/999.out b/tests/generic/999.out
> > new file mode 100644
> > index 00000000..3b276ca8
> > --- /dev/null
> > +++ b/tests/generic/999.out
> > @@ -0,0 +1,2 @@
> > +QA output created by 999
> > +Silence is golden
> > -- 
> > 2.31.1
> > 
>
diff mbox series

Patch

diff --git a/common/quota b/common/quota
index 7fa1a61a..67698f74 100644
--- a/common/quota
+++ b/common/quota
@@ -351,5 +351,53 @@  _qsetup()
 	echo "Using type=$type id=$id" >> $seqres.full
 }
 
+# Help to create project quota on directory, works for xfs and other fs.
+# Usage: _create_project_quota <dirname> <projid> [name]
+# Although the [name] is optional, better to specify it if need a fixed name.
+_create_project_quota()
+{
+	local prjdir=$1
+	local id=$2
+	local name=$3
+
+	if [ -z "$name" ];then
+		name=`echo $projdir | tr \/ \_`
+	fi
+
+	rm -rf $prjdir
+	mkdir $prjdir
+	chmod ugo+rwx $prjdir
+
+	if [ -f /etc/projects -a ! -f $tmp.projects.bk ];then
+		cat /etc/projects > $tmp.projects.bk
+		echo >/etc/projects
+	fi
+	if [ -f /etc/projid -a ! -f $tmp.projid.bk ];then
+		cat /etc/projid > $tmp.projid.bk
+		echo >/etc/projid
+	fi
+
+	cat >>/etc/projects <<EOF
+$id:$prjdir
+EOF
+	cat >>/etc/projid <<EOF
+$name:$id
+EOF
+	$XFS_IO_PROG -r -c "chproj $id" -c "chattr +P" $prjdir
+}
+
+# If you've called _create_project_quota, then use this function in _cleanup
+_restore_project_quota()
+{
+	if [ -f $tmp.projects.bk ];then
+		cat $tmp.projects.bk > /etc/projects && \
+			rm -f $tmp.projects.bk
+	fi
+	if [ -f $tmp.projid.bk ];then
+		cat $tmp.projid.bk > /etc/projid && \
+			rm -f $tmp.projid.bk
+	fi
+}
+
 # make sure this script returns success
 /bin/true
diff --git a/tests/generic/999 b/tests/generic/999
new file mode 100755
index 00000000..103a74f9
--- /dev/null
+++ b/tests/generic/999
@@ -0,0 +1,88 @@ 
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2022 Red Hat Inc.  All Rights Reserved.
+#
+# FS QA Test No. 999
+#
+# Make sure filesystem quota works well, after soft limits are exceeded. The
+# fs quota should allow more space allocation before exceeding hard limits
+# and with in grace time.
+#
+# But different with other similar testing, this case trys to write many small
+# files, to cover bc37e4fb5cac (xfs: revert "xfs: actually bump warning counts
+# when we send warnings"). If there's a behavior change in one day, this case
+# might help to detect that too.
+#
+. ./common/preamble
+_begin_fstest auto quota
+
+# Override the default cleanup function.
+_cleanup()
+{
+	_restore_project_quota
+	cd /
+	rm -r -f $tmp.*
+}
+
+# Import common functions.
+. ./common/quota
+
+# real QA test starts here
+_supported_fs generic
+_require_scratch
+_require_quota
+_require_user
+_require_group
+
+# Make sure the kernel supports project quota
+_scratch_mkfs >$seqres.full 2>&1
+_scratch_enable_pquota
+_qmount_option "prjquota"
+_qmount
+_require_prjquota $SCRATCH_DEV
+
+exercise()
+{
+	local type=$1
+	local file=$SCRATCH_MNT/testfile
+
+	echo "= Test type=$type quota =" >>$seqres.full
+	_scratch_unmount
+	_scratch_mkfs >>$seqres.full 2>&1
+	if [ "$1" = "P" ];then
+		_scratch_enable_pquota
+	fi
+	_qmount
+	if [ "$1" = "P" ];then
+		_create_project_quota $SCRATCH_MNT/t 100 $qa_user
+		file=$SCRATCH_MNT/t/testfile
+	fi
+
+	setquota -${type} $qa_user 1M 500M 0 0 $SCRATCH_MNT
+	setquota -${type} -t 86400 86400 $SCRATCH_MNT
+	repquota -v -${type} $SCRATCH_MNT | grep -v "^root" >>$seqres.full 2>&1
+	# Exceed the soft quota limit a bit at first
+	su $qa_user -c "$XFS_IO_PROG -f -t -c 'pwrite 0 2m' -c fsync ${file}.0" >>$seqres.full 2>&1
+	# Write more data more times under soft quota limit exhausted condition,
+	# but not reach hard limit. To make sure the it won't trigger EDQUOT.
+	for ((i=1; i<=100; i++));do
+		su "$qa_user" -c "$XFS_IO_PROG -f -c 'pwrite 0 1m' -c fsync ${file}.$i" >>$seqres.full 2>&1
+		if [ $? -ne 0 ];then
+			echo "Unexpected error (type=$type)!"
+			break
+		fi
+	done
+	repquota -v -${type} $SCRATCH_MNT | grep -v "^root" >>$seqres.full 2>&1
+}
+
+_qmount_option "usrquota"
+exercise u
+_qmount_option "grpquota"
+exercise g
+_qmount_option "prjquota"
+exercise P
+
+echo "Silence is golden"
+# success, all done
+status=0
+exit
diff --git a/tests/generic/999.out b/tests/generic/999.out
new file mode 100644
index 00000000..3b276ca8
--- /dev/null
+++ b/tests/generic/999.out
@@ -0,0 +1,2 @@ 
+QA output created by 999
+Silence is golden