Home | History | Annotate | Download | only in quotactl
      1 /******************************************************************************/
      2 /* Copyright (c) Crackerjack Project., 2007				      */
      3 /*									      */
      4 /* This program is free software;  you can redistribute it and/or modify      */
      5 /* it under the terms of the GNU General Public License as published by	      */
      6 /* the Free Software Foundation; either version 2 of the License, or	      */
      7 /* (at your option) any later version.					      */
      8 /*									      */
      9 /* This program is distributed in the hope that it will be useful,	      */
     10 /* but WITHOUT ANY WARRANTY;  without even the implied warranty of	      */
     11 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See		      */
     12 /* the GNU General Public License for more details.			      */
     13 /*									      */
     14 /* You should have received a copy of the GNU General Public License	      */
     15 /* along with this program;  if not, write to the Free Software		      */
     16 /* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA    */
     17 /*									      */
     18 /******************************************************************************/
     19 /******************************************************************************/
     20 /*									      */
     21 /* File:		quotactl01.c					      */
     22 /*									      */
     23 /* Description: This tests the quotactl() syscall			      */
     24 /*									      */
     25 /* Usage:  <for command-line>						      */
     26 /* quotactl01 [-c n] [-e][-i n] [-I x] [-p x] [-t]			      */
     27 /*	  where,  -c n : Run n copies concurrently.			      */
     28 /*			  -e   : Turn on errno logging.			      */
     29 /*			  -i n : Execute test n times.			      */
     30 /*			  -I x : Execute test for x seconds.		      */
     31 /*			  -P x : Pause for x seconds between iterations.      */
     32 /*			  -t   : Turn on syscall timing.		      */
     33 /*									      */
     34 /* Total Tests: 1							      */
     35 /*									      */
     36 /* Test Name:   quotactl01						      */
     37 /* History:	 Porting from Crackerjack to LTP is done by		      */
     38 /*			  Manas Kumar Nayak maknayak (at) in.ibm.com>	      */
     39 /******************************************************************************/
     40 #ifndef _GNU_SOURCE
     41 #define _GNU_SOURCE
     42 #endif
     43 #include <fcntl.h>
     44 #include <unistd.h>
     45 #include <sys/syscall.h>
     46 #include <stdio.h>
     47 #include <errno.h>
     48 #include <linux/fs.h>
     49 #include <sys/types.h>
     50 #include "config.h"
     51 #if defined(HAVE_QUOTAV2) || defined(HAVE_QUOTAV1)
     52 #if defined(HAVE_QUOTAV2)
     53 #define _LINUX_QUOTA_VERSION 2
     54 #else /* HAVE_QUOTAV1 */
     55 #define _LINUX_QUOTA_VERSION 1
     56 #endif
     57 #include <sys/quota.h>
     58 #else /* ! (HAVE_QUOTAV2 || HAVE_QUOTAV1) */
     59 /* Not HAVE_QUOTAV2 */
     60 #define BROKEN_QUOTACTL 1
     61 #endif
     62 
     63 #include "test.h"
     64 #include "linux_syscall_numbers.h"
     65 
     66 char *TCID = "quotactl01";
     67 int testno;
     68 int TST_TOTAL = 1;
     69 
     70 #define QUOTACTL(cmd, addr) \
     71 	ltp_syscall(__NR_quotactl, QCMD(cmd, USRQUOTA), block_dev, id, \
     72 					(caddr_t) addr)
     73 #ifndef BROKEN_QUOTACTL
     74 
     75 #ifndef QUOTAFILE
     76 /* Default name of the quota file in Fedora 12. */
     77 #define QUOTAFILE "aquota.user"
     78 #endif
     79 
     80 char quota_started = 0;
     81 static char *block_dev, *mountpoint, *quota_file, *quota_loc = NULL;
     82 int id;
     83 struct dqblk dq;
     84 
     85 /* Extern Global Functions */
     86 /******************************************************************************/
     87 /*									      */
     88 /* Function:	cleanup							      */
     89 /*									      */
     90 /* Description: Performs all one time clean up for this test on successful    */
     91 /*		completion,  premature exit or  failure. Closes all temporary */
     92 /*		files, removes all temporary directories exits the test with  */
     93 /*		appropriate return code by calling tst_exit() function.	      */
     94 /*									      */
     95 /* Input:	None.							      */
     96 /*									      */
     97 /* Output:	None.							      */
     98 /*									      */
     99 /* Return:	On failure - Exits calling tst_exit(). Non '0' return code.   */
    100 /*		On success - Exits calling tst_exit(). With '0' return code.  */
    101 /*									      */
    102 /******************************************************************************/
    103 void cleanup(void)
    104 {
    105 
    106 	tst_rmdir();
    107 
    108 	if (block_dev) {
    109 		if (quota_started == 1 && QUOTACTL(Q_QUOTAOFF, &dq)) {
    110 			tst_brkm(TBROK | TERRNO, NULL,
    111 				 "failed to disable the quota on %s",
    112 				 block_dev);
    113 		}
    114 	}
    115 
    116 }
    117 
    118 /* Local  Functions */
    119 /******************************************************************************/
    120 /*									      */
    121 /* Function:	setup							      */
    122 /*									      */
    123 /* Description: Performs all one time setup for this test. This function is   */
    124 /*		typically used to capture signals, create temporary dirs      */
    125 /*		and temporary files that may be used in the course of this    */
    126 /*		test.							      */
    127 /*									      */
    128 /* Input:	None.							      */
    129 /*									      */
    130 /* Output:	None.							      */
    131 /*									      */
    132 /* Return:	On failure - Exits by calling cleanup().		      */
    133 /*		On success - returns 0.					      */
    134 /*									      */
    135 /******************************************************************************/
    136 void setup(void)
    137 {
    138 
    139 	tst_require_root();
    140 
    141 	/* Capture signals if any */
    142 	/* Create temporary directories */
    143 
    144 	if ((quota_loc = malloc(FILENAME_MAX)) == NULL) {
    145 		tst_brkm(TCONF | TERRNO, NULL,
    146 			 "couldn't allocate memory for the quota loc buffer");
    147 	}
    148 
    149 	TEST_PAUSE;
    150 	tst_tmpdir();
    151 
    152 	snprintf(quota_loc, FILENAME_MAX, "%s/%s", mountpoint, quota_file);
    153 
    154 	if (QUOTACTL(Q_QUOTAON, quota_loc) != 0) {
    155 
    156 		if (errno == ENOENT) {
    157 			tst_brkm(TCONF, cleanup,
    158 				 "quota file - %s - doesn't exist (is the name "
    159 				 "correct?)", quota_loc);
    160 		} else {
    161 			/* Provide a terse explanation for why the command
    162 			 * failed.. */
    163 			tst_brkm(TCONF | TERRNO, cleanup,
    164 				 "failed to enable quotas on block device: %s; "
    165 				 "1. Ensure that the device is mounted with the "
    166 				 "quota option. 2. Check the filesystem status "
    167 				 "with `quotacheck %s'", block_dev, block_dev);
    168 		}
    169 	} else {
    170 		quota_started = 1;
    171 	}
    172 
    173 }
    174 #endif
    175 
    176 /*
    177 *  WARNING!! This test may cause the potential harm to the system, we DO NOT
    178 *  provide any warranty for the safety!!
    179 */
    180 /*
    181 * To use this testcase, the quota function must be turned on and the user must
    182 * be the super user.
    183 */
    184 
    185 #ifdef BROKEN_QUOTACTL
    186 int main(void)
    187 {
    188 	tst_brkm(TBROK, NULL, "This system doesn't support quota v2");
    189 }
    190 #else
    191 int cmd[] = {
    192 	Q_GETQUOTA,
    193 	Q_SETQUOTA,
    194 /* Only available in quota v2 */
    195 #if defined(HAVE_QUOTAV2)
    196 	Q_GETINFO,
    197 	Q_SETINFO,
    198 	Q_GETFMT,
    199 #endif
    200 	Q_SYNC
    201 };
    202 
    203 int main(int ac, char **av)
    204 {
    205 
    206 	static int block_dev_FLAG = 0, mountpoint_FLAG = 0, quota_file_FLAG = 0;
    207 	option_t opts[] = {
    208 		{.option = "b:",.flag = &block_dev_FLAG,.arg = &block_dev},
    209 		{.option = "m:",.flag = &mountpoint_FLAG,.arg = &mountpoint},
    210 		{.option = "q:",.flag = &quota_file_FLAG,.arg = &quota_file},
    211 		{.option = '\0'}
    212 	};
    213 
    214 	int newtid = -1;
    215 	int ret;
    216 	int i;
    217 	int lc;
    218 
    219 	tst_parse_opts(ac, av, (option_t *) opts, NULL);
    220 
    221 	setup();
    222 
    223 	for (lc = 0; TEST_LOOPING(lc); ++lc) {
    224 
    225 		tst_count = 0;
    226 
    227 		for (testno = 0; testno < TST_TOTAL; ++testno) {
    228 
    229 			for (i = 0; i <= sizeof(cmd) / sizeof(cmd[0]); i++) {
    230 
    231 				ret = QUOTACTL(cmd[i], &dq);
    232 				if (ret != 0) {
    233 					tst_resm(TFAIL | TERRNO,
    234 						 "cmd=0x%x failed", cmd[i]);
    235 				} else {
    236 					tst_resm(TPASS,
    237 						 "quotactl call succeeded");
    238 				}
    239 
    240 			}
    241 
    242 			TEST(ltp_syscall(__NR_set_tid_address, &newtid));
    243 
    244 			if (TEST_RETURN == getpid()) {
    245 				cleanup();
    246 			} else {
    247 				cleanup();
    248 				tst_exit();
    249 			}
    250 
    251 		}
    252 
    253 	}
    254 
    255 	cleanup();
    256 
    257 	tst_exit();
    258 
    259 }
    260 #endif
    261