[LTP] [PATCH 1/2] syscalls/quotatcl01.c: Rewrite && Convert to new API

Xiao Yang yangx.jy@cn.fujitsu.com
Fri Oct 21 08:53:54 CEST 2016


1) quotactl(2) succeeds to turn on quota with Q_QUOTAON flag for user.
2) quotactl(2) succeeds to set disk quota limits with Q_SETQUOTA flag
   for user.
3) quotactl(2) succeeds to get disk quota limits with Q_GETQUOTA flag
   for user.
4) quotactl(2) succeeds to set information about quotafile with Q_SETINFO
   flag for user.
5) quotactl(2) succeeds to get information about quotafile with Q_GETINFO
   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
    for group.
11) 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
    flag for group.
13) 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.

Signed-off-by: Xiao Yang <yangx.jy@cn.fujitsu.com>
---
 testcases/kernel/syscalls/quotactl/quotactl01.c | 412 +++++++++++-------------
 1 file changed, 195 insertions(+), 217 deletions(-)

diff --git a/testcases/kernel/syscalls/quotactl/quotactl01.c b/testcases/kernel/syscalls/quotactl/quotactl01.c
index fcac469..cfd1c35 100644
--- a/testcases/kernel/syscalls/quotactl/quotactl01.c
+++ b/testcases/kernel/syscalls/quotactl/quotactl01.c
@@ -1,260 +1,238 @@
-/******************************************************************************/
-/* Copyright (c) Crackerjack Project., 2007				      */
-/*									      */
-/* 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, write to the Free Software		      */
-/* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA    */
-/*									      */
-/******************************************************************************/
-/******************************************************************************/
-/*									      */
-/* File:		quotactl01.c					      */
-/*									      */
-/* Description: This tests the quotactl() syscall			      */
-/*									      */
-/* Usage:  <for command-line>						      */
-/* quotactl01 [-c n] [-e][-i n] [-I x] [-p x] [-t]			      */
-/*	  where,  -c n : Run n copies concurrently.			      */
-/*			  -e   : Turn on errno logging.			      */
-/*			  -i n : Execute test n times.			      */
-/*			  -I x : Execute test for x seconds.		      */
-/*			  -P x : Pause for x seconds between iterations.      */
-/*			  -t   : Turn on syscall timing.		      */
-/*									      */
-/* Total Tests: 1							      */
-/*									      */
-/* Test Name:   quotactl01						      */
-/* History:	 Porting from Crackerjack to LTP is done by		      */
-/*			  Manas Kumar Nayak maknayak@in.ibm.com>	      */
-/******************************************************************************/
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif
-#include <fcntl.h>
+/*
+* Copyright (c) Crackerjack Project., 2007
+* Copyright (c) 2016 Fujitsu Ltd.
+* 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.
+*
+* Test Name: quotactl01
+*
+* Description:
+* This testcase checks the basic flag of quotactl(2) for non-XFS filesystems:
+* 1) quotactl(2) succeeds to turn on quota with Q_QUOTAON flag for user.
+* 2) quotactl(2) succeeds to set disk quota limits with Q_SETQUOTA flag
+*    for user.
+* 3) quotactl(2) succeeds to get disk quota limits with Q_GETQUOTA flag
+*    for user.
+* 4) quotactl(2) succeeds to set information about quotafile with Q_SETINFO
+*    flag for user.
+* 5) quotactl(2) succeeds to get information about quotafile with Q_GETINFO
+*    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
+*     for group.
+* 11) 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
+*     flag for group.
+* 13) 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.
+*
+*/
+
+#include <errno.h>
+#include <string.h>
 #include <unistd.h>
-#include <sys/syscall.h>
 #include <stdio.h>
-#include <errno.h>
-#include <linux/fs.h>
-#include <sys/types.h>
 #include "config.h"
+
+#include "tst_test.h"
+
 #if defined(HAVE_QUOTAV2) || defined(HAVE_QUOTAV1)
 #if defined(HAVE_QUOTAV2)
-#define _LINUX_QUOTA_VERSION 2
+#define _LINUX_QUOTA_VERSION	2
 #else /* HAVE_QUOTAV1 */
-#define _LINUX_QUOTA_VERSION 1
+#define _LINUX_QUOTA_VERSION	1
 #endif
+
 #include <sys/quota.h>
-#else /* ! (HAVE_QUOTAV2 || HAVE_QUOTAV1) */
-/* Not HAVE_QUOTAV2 */
-#define BROKEN_QUOTACTL 1
-#endif
 
-#include "test.h"
-#include "linux_syscall_numbers.h"
+#define SIZE	1024
 
-char *TCID = "quotactl01";
-int testno;
-int TST_TOTAL = 1;
+static int mount_flag;
+static const char mntpoint[] = "mnt_point";
+static struct dqblk set_dq = {
+	.dqb_bsoftlimit = 100,
+	.dqb_valid = QIF_BLIMITS
+};
+static struct dqblk res_dq;
 
-#define QUOTACTL(cmd, addr) \
-	ltp_syscall(__NR_quotactl, QCMD(cmd, USRQUOTA), block_dev, id, \
-					(caddr_t) addr)
-#ifndef BROKEN_QUOTACTL
+#if defined(HAVE_QUOTAV2)
+static struct dqinfo set_qf = {
+	.dqi_bgrace = 80,
+	.dqi_valid = IIF_BGRACE
+};
+static struct dqinfo res_qf;
+static unsigned long fmt_buf[SIZE/32];
+#endif
 
-#ifndef QUOTAFILE
-/* Default name of the quota file in Fedora 12. */
-#define QUOTAFILE "aquota.user"
+static unsigned long format_id;
+static unsigned long test_id;
+static unsigned long data;
+static char *usr_qf, *grp_qf;
+static char usr_path[SIZE], grp_path[SIZE];
+
+static struct tcase {
+	int cmd;
+	unsigned long *id;
+	void *addr;
+	unsigned long *set_data;
+	unsigned long *res_data;
+	char *des;
+} tcases[] = {
+	{QCMD(Q_QUOTAON, USRQUOTA), &format_id, usr_path, &data, &data,
+	"turn on quota for user"},
+	{QCMD(Q_SETQUOTA, USRQUOTA), &test_id, &set_dq, &data, &data,
+	"set disk quota limit for user"},
+	{QCMD(Q_GETQUOTA, USRQUOTA), &test_id, &res_dq, &set_dq.dqb_bsoftlimit,
+	&res_dq.dqb_bsoftlimit, "get disk quota limit for user"},
+#if defined(HAVE_QUOTAV2)
+	{QCMD(Q_SETINFO, USRQUOTA), &test_id, &set_qf, &data, &data,
+	"set information about quotafile for user"},
+	{QCMD(Q_GETINFO, USRQUOTA), &test_id, &res_qf, &set_qf.dqi_bgrace,
+	&res_qf.dqi_bgrace, "get information about quotafile for user"},
+	{QCMD(Q_GETFMT, USRQUOTA), &test_id, fmt_buf, &format_id, fmt_buf,
+	"get quota format for user"},
+#endif
+	{QCMD(Q_SYNC, USRQUOTA), &test_id, &res_dq, &data, &data,
+	"update quota usages for user"},
+	{QCMD(Q_QUOTAOFF, USRQUOTA), &test_id, usr_path, &data, &data,
+	"turn off quota for user"},
+	{QCMD(Q_QUOTAON, GRPQUOTA), &format_id, grp_path, &data, &data,
+	"turn on quota for group"},
+	{QCMD(Q_SETQUOTA, GRPQUOTA), &test_id, &set_dq, &data, &data,
+	"set disk quota limit for group"},
+	{QCMD(Q_GETQUOTA, GRPQUOTA), &test_id, &res_dq, &set_dq.dqb_bsoftlimit,
+	&res_dq.dqb_bsoftlimit, "set disk quota limit for group"},
+#if defined(HAVE_QUOTAV2)
+	{QCMD(Q_SETINFO, GRPQUOTA), &test_id, &set_qf, &data, &data,
+	"set information about quotafile for group"},
+	{QCMD(Q_GETINFO, GRPQUOTA), &test_id, &res_qf, &set_qf.dqi_bgrace,
+	&res_qf.dqi_bgrace, "get information about quotafile for group"},
+	{QCMD(Q_GETFMT, GRPQUOTA), &test_id, fmt_buf, &format_id, fmt_buf,
+	"get quota format for group"},
 #endif
+	{QCMD(Q_SYNC, GRPQUOTA), &test_id, &res_dq, &data, &data,
+	"update quota usages for group"},
+	{QCMD(Q_QUOTAOFF, GRPQUOTA), &test_id, grp_path, &data, &data,
+	"turn off quota for group"}
+};
 
-char quota_started = 0;
-static char *block_dev, *mountpoint, *quota_file, *quota_loc = NULL;
-int id;
-struct dqblk dq;
-
-/* Extern Global Functions */
-/******************************************************************************/
-/*									      */
-/* Function:	cleanup							      */
-/*									      */
-/* Description: Performs all one time clean up for this test on successful    */
-/*		completion,  premature exit or  failure. Closes all temporary */
-/*		files, removes all temporary directories exits the test with  */
-/*		appropriate return code by calling tst_exit() function.	      */
-/*									      */
-/* Input:	None.							      */
-/*									      */
-/* Output:	None.							      */
-/*									      */
-/* Return:	On failure - Exits calling tst_exit(). Non '0' return code.   */
-/*		On success - Exits calling tst_exit(). With '0' return code.  */
-/*									      */
-/******************************************************************************/
-void cleanup(void)
+static void create_qf(void)
 {
+	int res;
 
-	tst_rmdir();
-
-	if (block_dev) {
-		if (quota_started == 1 && QUOTACTL(Q_QUOTAOFF, &dq)) {
-			tst_brkm(TBROK | TERRNO, NULL,
-				 "failed to disable the quota on %s",
-				 block_dev);
-		}
-	}
-
+	res = execlp("quotacheck", "quotacheck", "-ug", mntpoint, NULL);
+	if (res == -1)
+		tst_brk(TFAIL | TERRNO, "failed to execute quotacheck");
 }
 
-/* Local  Functions */
-/******************************************************************************/
-/*									      */
-/* Function:	setup							      */
-/*									      */
-/* Description: Performs all one time setup for this test. This function is   */
-/*		typically used to capture signals, create temporary dirs      */
-/*		and temporary files that may be used in the course of this    */
-/*		test.							      */
-/*									      */
-/* Input:	None.							      */
-/*									      */
-/* Output:	None.							      */
-/*									      */
-/* Return:	On failure - Exits by calling cleanup().		      */
-/*		On success - returns 0.					      */
-/*									      */
-/******************************************************************************/
-void setup(void)
+static void setup(void)
 {
+	pid_t pid;
 
-	tst_require_root();
-
-	/* Capture signals if any */
-	/* Create temporary directories */
+	SAFE_MKDIR(mntpoint, 0755);
 
-	if ((quota_loc = malloc(FILENAME_MAX)) == NULL) {
-		tst_brkm(TCONF | TERRNO, NULL,
-			 "couldn't allocate memory for the quota loc buffer");
-	}
+	SAFE_MKFS(tst_device->dev, "ext4", NULL, NULL);
 
-	TEST_PAUSE;
-	tst_tmpdir();
-
-	snprintf(quota_loc, FILENAME_MAX, "%s/%s", mountpoint, quota_file);
-
-	if (QUOTACTL(Q_QUOTAON, quota_loc) != 0) {
-
-		if (errno == ENOENT) {
-			tst_brkm(TCONF, cleanup,
-				 "quota file - %s - doesn't exist (is the name "
-				 "correct?)", quota_loc);
-		} else {
-			/* Provide a terse explanation for why the command
-			 * failed.. */
-			tst_brkm(TCONF | TERRNO, cleanup,
-				 "failed to enable quotas on block device: %s; "
-				 "1. Ensure that the device is mounted with the "
-				 "quota option. 2. Check the filesystem status "
-				 "with `quotacheck %s'", block_dev, block_dev);
-		}
-	} else {
-		quota_started = 1;
-	}
+	SAFE_MOUNT(tst_device->dev, mntpoint, "ext4", 0, "usrquota,grpquota");
 
-}
-#endif
-
-/*
-*  WARNING!! This test may cause the potential harm to the system, we DO NOT
-*  provide any warranty for the safety!!
-*/
-/*
-* To use this testcase, the quota function must be turned on and the user must
-* be the super user.
-*/
-
-#ifdef BROKEN_QUOTACTL
-int main(void)
-{
-	tst_brkm(TBROK, NULL, "This system doesn't support quota v2");
-}
-#else
-int cmd[] = {
-	Q_GETQUOTA,
-	Q_SETQUOTA,
-/* Only available in quota v2 */
 #if defined(HAVE_QUOTAV2)
-	Q_GETINFO,
-	Q_SETINFO,
-	Q_GETFMT,
+#ifndef QFMT_VFS_V0
+#define QFMT_VFS_V0	2
+#endif
+	format_id = QFMT_VFS_V0;
+	usr_qf = "aquota.user";
+	grp_qf = "aquota.group";
 #endif
-	Q_SYNC
-};
-
-int main(int ac, char **av)
-{
-
-	static int block_dev_FLAG = 0, mountpoint_FLAG = 0, quota_file_FLAG = 0;
-	option_t opts[] = {
-		{.option = "b:",.flag = &block_dev_FLAG,.arg = &block_dev},
-		{.option = "m:",.flag = &mountpoint_FLAG,.arg = &mountpoint},
-		{.option = "q:",.flag = &quota_file_FLAG,.arg = &quota_file},
-		{.option = '\0'}
-	};
 
-	int newtid = -1;
-	int ret;
-	int i;
-	int lc;
+#if defined(HAVE_QUOTAV1)
+#ifndef QFMT_VFS_OLD
+#define QFMT_VFS_OLD	1
+#endif
+	format_id = QFMT_VFS_OLD;
+	usr_qf = "quota.user";
+	grp_qf = "quota.group";
+#endif
 
-	tst_parse_opts(ac, av, (option_t *) opts, NULL);
+	pid = SAFE_FORK();
+	if (!pid)
+		create_qf();
 
-	setup();
+	SAFE_WAITPID(pid, NULL, 0);
 
-	for (lc = 0; TEST_LOOPING(lc); ++lc) {
+	test_id = geteuid();
 
-		tst_count = 0;
+	sprintf(usr_path, "%s/%s", mntpoint, usr_qf);
+	sprintf(grp_path, "%s/%s", mntpoint, grp_qf);
 
-		for (testno = 0; testno < TST_TOTAL; ++testno) {
+	if (access(usr_path, F_OK) == -1)
+		tst_brk(TFAIL | TERRNO, "user quotafile didn't exist");
 
-			for (i = 0; i <= sizeof(cmd) / sizeof(cmd[0]); i++) {
+	if (access(grp_path, F_OK) == -1)
+		tst_brk(TFAIL | TERRNO, "group quotafile didn't exist");
 
-				ret = QUOTACTL(cmd[i], &dq);
-				if (ret != 0) {
-					tst_resm(TFAIL | TERRNO,
-						 "cmd=0x%x failed", cmd[i]);
-				} else {
-					tst_resm(TPASS,
-						 "quotactl call succeeded");
-				}
+	mount_flag = 1;
+}
 
-			}
+static void cleanup(void)
+{
+	if (mount_flag && tst_umount(mntpoint) < 0)
+		tst_res(TWARN | TERRNO, "umount(2) failed");
+}
 
-			TEST(ltp_syscall(__NR_set_tid_address, &newtid));
+static void verify_quota(unsigned int n)
+{
+	struct tcase *tc = &tcases[n];
 
-			if (TEST_RETURN == getpid()) {
-				cleanup();
-			} else {
-				cleanup();
-				tst_exit();
-			}
+	res_dq.dqb_bsoftlimit = 0;
+	res_qf.dqi_igrace = 0;
+	memset(fmt_buf, 0, sizeof(fmt_buf));
 
-		}
+	TEST(quotactl(tc->cmd, tst_device->dev, *tc->id, (caddr_t) tc->addr));
+	if (TEST_RETURN == -1) {
+		tst_res(TFAIL | TERRNO, "quotactl failed to %s", tc->des);
+		return;
+	}
 
+	if (*tc->set_data != *tc->res_data) {
+		tst_res(TFAIL | TERRNO, "quotactl got unexpected info %lu, "
+			"expected %lu", *tc->res_data, *tc->set_data);
+		return;
 	}
 
-	cleanup();
+	tst_res(TPASS, "quotactl secceeded to %s", tc->des);
+}
 
-	tst_exit();
+static struct tst_test test = {
+	.tid = "quotactl01",
+	.needs_tmpdir = 1,
+	.needs_root = 1,
+	.test = verify_quota,
+	.tcnt = ARRAY_SIZE(tcases),
+	.needs_device = 1,
+	.forks_child = 1,
+	.setup = setup,
+	.cleanup = cleanup
+};
 
-}
+#else
+	TST_TEST_TCONF("This system didn't support quota");
 #endif
-- 
1.8.3.1





More information about the ltp mailing list