• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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@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 /******************************************************************************/
cleanup(void)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 /******************************************************************************/
setup(void)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
main(void)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 
main(int ac,char ** av)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