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 = "a_file_FLAG,.arg = "a_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