[LTP] [PATCH v2 3/6] syscalls/quotactl01.c: Add Q_GETNEXQUOTA test
Yang Xu
xuyang2018.jy@cn.fujitsu.com
Fri Oct 25 10:49:59 CEST 2019
on 2019/10/24 16:25, Jan Kara wrote:
> On Wed 23-10-19 17:00:28, Yang Xu wrote:
>> Q_GETNEXTQUOTA was introduced since linux 4.6, this operation is the
>> same as Q_GETQUOTA, but it returns quota information for the next ID
>> greater than or equal to id that has a quota set.
>>
>> Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
>
> I was thinking about how much these tests are actually needed. The thing is
> that fstests have also quota tests. And as part of these tests we do run
> e.g. repquota(8) and verify its output and that uses Q_GETNEXTQUOTA inside.
> So Q_GETNEXTQUOTA gets testing as part of fstests. On the other hand
> fstests are focused on testing the general quota functionality as user
> would use it so we don't really try to make sure all quotactl calls are
> covered. So there's still some value in low level testing of each
> quotactl like you do here.
IMO, fstests tests quota more deeply and it coverS more user scenes(also
some regresstion tests). But in ltp, in syscalls/quotactl, I try my
best to test various subcmds (it may stay in API level but not actual
quota actions) and three quota types(user,group,project).
In addition, I am writing quotactl error tests as man-pages mentioned.
>
> Honza
>
>> ---
>> include/lapi/quotactl.h | 23 ++---
>> m4/ltp-quota.m4 | 36 +-------
>> .../kernel/syscalls/quotactl/quotactl01.c | 86 ++++++++++++-------
>> 3 files changed, 67 insertions(+), 78 deletions(-)
>>
>> diff --git a/include/lapi/quotactl.h b/include/lapi/quotactl.h
>> index 729472f69..99f4e5fc5 100644
>> --- a/include/lapi/quotactl.h
>> +++ b/include/lapi/quotactl.h
>> @@ -1,26 +1,21 @@
>> +// SPDX-License-Identifier: GPL-2.0-or-later
>> /*
>> - * Copyright (c) 2017 Fujitsu Ltd.
>> + * Copyright (c) 2016-2019 FUJITSU LIMITED. All rights reserved.
>> * Author: Xiao Yang <yangx.jy@cn.fujitsu.com>
>> - *
>> - * This program is free software: you can redistribute it and/or modify
>> - * it under the terms of the GNU General Public License as published by
>> - * the Free Software Foundation, either version 2 of the License, or
>> - * (at your option) any later version.
>> - *
>> - * This program is distributed in the hope that it will be useful,
>> - * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>> - * GNU General Public License for more details.
>> - *
>> - * You should have received a copy of the GNU General Public License
>> - * along with this program. If not, see <http://www.gnu.org/licenses/>.
>> + * Author: Yang Xu <xuyang2018.jy@cn.jujitsu.com>
>> */
>>
>> #ifndef LAPI_QUOTACTL_H__
>> # define LAPI_QUOTACTL_H__
>>
>> +#include <linux/quota.h>
>> +
>> # ifndef Q_XGETNEXTQUOTA
>> # define Q_XGETNEXTQUOTA XQM_CMD(9)
>> # endif
>>
>> +# ifndef Q_GETNEXTQUOTA
>> +# define Q_GETNEXTQUOTA 0x800009 /* get disk limits and usage >= ID */
>> +# endif
>> +
>> #endif /* LAPI_QUOTACTL_H__ */
>> diff --git a/m4/ltp-quota.m4 b/m4/ltp-quota.m4
>> index c5e233ca1..964c34925 100644
>> --- a/m4/ltp-quota.m4
>> +++ b/m4/ltp-quota.m4
>> @@ -1,39 +1,7 @@
>> dnl SPDX-License-Identifier: GPL-2.0-or-later
>> dnl Copyright (c) Cisco Systems, Inc, 2008
>> +dnl Copyright (c) 2019 Fujitsu Ltd.
>>
>> AC_DEFUN([LTP_CHECK_SYSCALL_QUOTACTL],[
>> - AC_LINK_IFELSE([AC_LANG_SOURCE([
>> -#define _LINUX_QUOTA_VERSION 2
>> -#include <sys/types.h>
>> -#include <sys/quota.h>
>> -#include <unistd.h>
>> -int main(void) {
>> - struct dqblk dq;
>> - return quotactl(QCMD(Q_GETINFO, USRQUOTA), (const char *) "/dev/null",
>> - geteuid(), (caddr_t) &dq);
>> -}])],[has_quotav2="yes"])
>> -
>> -if test "x$has_quotav2" = xyes; then
>> - AC_DEFINE(HAVE_QUOTAV2,1,[Define to 1 if you have quota v2])
>> -else
>> -
>> - # got quota v1?
>> - AC_LINK_IFELSE([AC_LANG_SOURCE([
>> -#define _LINUX_QUOTA_VERSION 1
>> -#include <sys/types.h>
>> -#include <sys/quota.h>
>> -#include <unistd.h>
>> -int main(void) {
>> - struct dqblk dq;
>> - return quotactl(QCMD(Q_GETQUOTA, USRQUOTA), (const char *) "/dev/null",
>> - geteuid(), (caddr_t) &dq);
>> -}])],[has_quotav1="yes"])
>> -
>> - if test "x$has_quotav1" = xyes; then
>> - AC_DEFINE(HAVE_QUOTAV1,1,[Define to 1 if you have quota v1])
>> - else
>> - AC_MSG_WARN(Couldn't determine quota version (please submit config.log and manpage to ltp@lists.linux.it))
>> - fi
>> -
>> -fi
>> +AC_CHECK_TYPES([struct if_nextdqblk],,,[#include <linux/quota.h>])
>> ])
>> diff --git a/testcases/kernel/syscalls/quotactl/quotactl01.c b/testcases/kernel/syscalls/quotactl/quotactl01.c
>> index b0be525d6..af78646e4 100644
>> --- a/testcases/kernel/syscalls/quotactl/quotactl01.c
>> +++ b/testcases/kernel/syscalls/quotactl/quotactl01.c
>> @@ -1,7 +1,7 @@
>> // SPDX-License-Identifier: GPL-2.0-or-later
>> /*
>> * Copyright (c) Crackerjack Project., 2007
>> -* Copyright (c) 2016 Fujitsu Ltd.
>> +* Copyright (c) 2016-2019 FUJITSU LIMITED. All rights reserved
>> * Author: Xiao Yang <yangx.jy@cn.fujitsu.com>
>> *
>> * This testcase checks the basic flag of quotactl(2) for non-XFS filesystems:
>> @@ -16,19 +16,23 @@
>> * flag for user.
>> * 6) quotactl(2) succeeds to get quota format with Q_GETFMT flag for user.
>> * 7) quotactl(2) succeeds to update quota usages with Q_SYNC flag for user.
>> -* 8) quotactl(2) succeeds to turn off quota with Q_QUOTAOFF flag for user.
>> -* 9) quotactl(2) succeeds to turn on quota with Q_QUOTAON flag for group.
>> -* 10) quotactl(2) succeeds to set disk quota limits with Q_SETQUOTA flag
>> +* 8) quotactl(2) succeeds to get disk quota limit greater than or equal to
>> +* ID with Q_GETNEXTSTAT flag for user.
>> +* 9) quotactl(2) succeeds to turn off quota with Q_QUOTAOFF flag for user.
>> +* 10) quotactl(2) succeeds to turn on quota with Q_QUOTAON flag for group.
>> +* 11) quotactl(2) succeeds to set disk quota limits with Q_SETQUOTA flag
>> * for group.
>> -* 11) quotactl(2) succeeds to get disk quota limits with Q_GETQUOTA flag
>> +* 12) quotactl(2) succeeds to get disk quota limits with Q_GETQUOTA flag
>> * for group.
>> -* 12) quotactl(2) succeeds to set information about quotafile with Q_SETINFO
>> +* 13) quotactl(2) succeeds to set information about quotafile with Q_SETINFO
>> * flag for group.
>> -* 13) quotactl(2) succeeds to get information about quotafile with Q_GETINFO
>> +* 14) quotactl(2) succeeds to get information about quotafile with Q_GETINFO
>> * flag for group.
>> -* 14) quotactl(2) succeeds to get quota format with Q_GETFMT flag for group.
>> -* 15) quotactl(2) succeeds to update quota usages with Q_SYNC flag for group.
>> -* 16) quotactl(2) succeeds to turn off quota with Q_QUOTAOFF flag for group.
>> +* 15) quotactl(2) succeeds to get quota format with Q_GETFMT flag for group.
>> +* 16) quotactl(2) succeeds to update quota usages with Q_SYNC flag for group.
>> +* 17) quotactl(2) succeeds to get disk quota limit greater than or equal to
>> +* ID with Q_GETNEXTSTAT flag for group.
>> +* 18) quotactl(2) succeeds to turn off quota with Q_QUOTAOFF flag for group.
>> */
>>
>> #include <errno.h>
>> @@ -36,10 +40,9 @@
>> #include <unistd.h>
>> #include <stdio.h>
>> #include "config.h"
>> -
>> +#include <sys/quota.h>
>> #include "tst_test.h"
>> -
>> -# include <sys/quota.h>
>> +#include "lapi/quotactl.h"
>>
>> # define QFMT_VFS_V0 2
>> # define USRPATH MNTPOINT "/aquota.user"
>> @@ -63,6 +66,10 @@ static struct dqinfo set_qf = {
>> static struct dqinfo res_qf;
>> static int32_t fmt_buf;
>>
>> +#if defined(HAVE_STRUCT_IF_NEXTDQBLK)
>> +static struct if_nextdqblk res_ndq;
>> +#endif
>> +
>> static struct tcase {
>> int cmd;
>> int *id;
>> @@ -70,60 +77,73 @@ static struct tcase {
>> void *set_data;
>> void *res_data;
>> int sz;
>> + int nflag;
>> char *des;
>> } tcases[] = {
>> {QCMD(Q_QUOTAON, USRQUOTA), &fmt_id, USRPATH,
>> - NULL, NULL, 0, "turn on quota for user"},
>> + NULL, NULL, 0, 0, "turn on quota for user"},
>>
>> {QCMD(Q_SETQUOTA, USRQUOTA), &test_id, &set_dq,
>> - NULL, NULL, 0, "set disk quota limit for user"},
>> + NULL, NULL, 0, 0, "set disk quota limit for user"},
>>
>> {QCMD(Q_GETQUOTA, USRQUOTA), &test_id, &res_dq,
>> &set_dq.dqb_bsoftlimit, &res_dq.dqb_bsoftlimit,
>> - sizeof(res_dq.dqb_bsoftlimit), "get disk quota limit for user"},
>> + sizeof(res_dq.dqb_bsoftlimit), 0, "get disk quota limit for user"},
>>
>> {QCMD(Q_SETINFO, USRQUOTA), &test_id, &set_qf,
>> - NULL, NULL, 0, "set information about quotafile for user"},
>> + NULL, NULL, 0, 0, "set information about quotafile for user"},
>>
>> {QCMD(Q_GETINFO, USRQUOTA), &test_id, &res_qf,
>> - &set_qf.dqi_bgrace, &res_qf.dqi_bgrace, sizeof(res_qf.dqi_bgrace),
>> + &set_qf.dqi_bgrace, &res_qf.dqi_bgrace, sizeof(res_qf.dqi_bgrace), 0,
>> "get information about quotafile for user"},
>>
>> {QCMD(Q_GETFMT, USRQUOTA), &test_id, &fmt_buf,
>> - &fmt_id, &fmt_buf, sizeof(fmt_buf),
>> + &fmt_id, &fmt_buf, sizeof(fmt_buf), 0,
>> "get quota format for user"},
>>
>> {QCMD(Q_SYNC, USRQUOTA), &test_id, &res_dq,
>> - NULL, NULL, 0, "update quota usages for user"},
>> + NULL, NULL, 0, 0, "update quota usages for user"},
>> +
>> +#if defined(HAVE_STRUCT_IF_NEXTDQBLK)
>> + {QCMD(Q_GETNEXTQUOTA, USRQUOTA), &test_id, &res_ndq,
>> + &test_id, &res_ndq.dqb_id, sizeof(res_ndq.dqb_id), 1,
>> + "get next disk quota limit for user"},
>> +#endif
>>
>> {QCMD(Q_QUOTAOFF, USRQUOTA), &test_id, USRPATH,
>> - NULL, NULL, 0, "turn off quota for user"},
>> + NULL, NULL, 0, 0, "turn off quota for user"},
>>
>> {QCMD(Q_QUOTAON, GRPQUOTA), &fmt_id, GRPPATH,
>> - NULL, NULL, 0, "turn on quota for group"},
>> + NULL, NULL, 0, 0, "turn on quota for group"},
>>
>> {QCMD(Q_SETQUOTA, GRPQUOTA), &test_id, &set_dq,
>> - NULL, NULL, 0, "set disk quota limit for group"},
>> + NULL, NULL, 0, 0, "set disk quota limit for group"},
>>
>> {QCMD(Q_GETQUOTA, GRPQUOTA), &test_id, &res_dq, &set_dq.dqb_bsoftlimit,
>> - &res_dq.dqb_bsoftlimit, sizeof(res_dq.dqb_bsoftlimit),
>> + &res_dq.dqb_bsoftlimit, sizeof(res_dq.dqb_bsoftlimit), 0,
>> "set disk quota limit for group"},
>>
>> {QCMD(Q_SETINFO, GRPQUOTA), &test_id, &set_qf,
>> - NULL, NULL, 0, "set information about quotafile for group"},
>> + NULL, NULL, 0, 0, "set information about quotafile for group"},
>>
>> {QCMD(Q_GETINFO, GRPQUOTA), &test_id, &res_qf, &set_qf.dqi_bgrace,
>> - &res_qf.dqi_bgrace, sizeof(res_qf.dqi_bgrace),
>> + &res_qf.dqi_bgrace, sizeof(res_qf.dqi_bgrace), 0,
>> "get information about quotafile for group"},
>>
>> {QCMD(Q_GETFMT, GRPQUOTA), &test_id, &fmt_buf,
>> - &fmt_id, &fmt_buf, sizeof(fmt_buf), "get quota format for group"},
>> + &fmt_id, &fmt_buf, sizeof(fmt_buf), 0, "get quota format for group"},
>>
>> {QCMD(Q_SYNC, GRPQUOTA), &test_id, &res_dq,
>> - NULL, NULL, 0, "update quota usages for group"},
>> + NULL, NULL, 0, 0, "update quota usages for group"},
>> +
>> +#if defined(HAVE_STRUCT_IF_NEXTDQBLK)
>> + {QCMD(Q_GETNEXTQUOTA, GRPQUOTA), &test_id, &res_ndq,
>> + &test_id, &res_ndq.dqb_id, sizeof(res_ndq.dqb_id), 1,
>> + "get next disk quota limit for group"},
>> +#endif
>>
>> {QCMD(Q_QUOTAOFF, GRPQUOTA), &test_id, GRPPATH,
>> - NULL, NULL, 0, "turn off quota for group"}
>> + NULL, NULL, 0, 0, "turn off quota for group"}
>> };
>>
>> static void setup(void)
>> @@ -156,9 +176,15 @@ static void verify_quota(unsigned int n)
>>
>> res_dq.dqb_bsoftlimit = 0;
>> res_qf.dqi_igrace = 0;
>> +#if defined(HAVE_STRUCT_IF_NEXTDQBLK)
>> + res_ndq.dqb_id = -1;
>> +#endif
>> fmt_buf = 0;
>> -
>> TEST(quotactl(tc->cmd, tst_device->dev, *tc->id, tc->addr));
>> + if (TST_ERR == ENOSYS && tc->nflag) {
>> + tst_res(TCONF, "Current system doesn't support Q_GETNEXTQUOTA, it needs kernel>=4.6!");
>> + return;
>> + }
>> if (TST_RET == -1) {
>> tst_res(TFAIL | TTERRNO, "quotactl failed to %s", tc->des);
>> return;
>> --
>> 2.18.0
>>
>>
>>
More information about the ltp
mailing list