blob: e6baa2ef122336a4a63f908a340126c89a552b91 [file] [log] [blame]
Xiao Yangd40d74e2016-10-25 14:15:38 +08001/*
2* Copyright (c) Crackerjack Project., 2007
3* Copyright (c) 2016 Fujitsu Ltd.
4* Author: Xiao Yang <yangx.jy@cn.fujitsu.com>
5*
6* This program is free software; you can redistribute it and/or modify
7* it under the terms of the GNU General Public License as published by
8* the Free Software Foundation; either version 2 of the License, or
9* (at your option) any later version.
10*
11* This program is distributed in the hope that it will be useful,
12* but WITHOUT ANY WARRANTY; without even the implied warranty of
13* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
14* the GNU General Public License for more details.
15*
16* You should have received a copy of the GNU General Public License
17* along with this program.
18*
19* Test Name: quotactl01
20*
21* Description:
22* This testcase checks the basic flag of quotactl(2) for non-XFS filesystems:
23* 1) quotactl(2) succeeds to turn on quota with Q_QUOTAON flag for user.
24* 2) quotactl(2) succeeds to set disk quota limits with Q_SETQUOTA flag
25* for user.
26* 3) quotactl(2) succeeds to get disk quota limits with Q_GETQUOTA flag
27* for user.
28* 4) quotactl(2) succeeds to set information about quotafile with Q_SETINFO
29* flag for user.
30* 5) quotactl(2) succeeds to get information about quotafile with Q_GETINFO
31* flag for user.
32* 6) quotactl(2) succeeds to get quota format with Q_GETFMT flag for user.
33* 7) quotactl(2) succeeds to update quota usages with Q_SYNC flag for user.
34* 8) quotactl(2) succeeds to turn off quota with Q_QUOTAOFF flag for user.
35* 9) quotactl(2) succeeds to turn on quota with Q_QUOTAON flag for group.
36* 10) quotactl(2) succeeds to set disk quota limits with Q_SETQUOTA flag
37* for group.
38* 11) quotactl(2) succeeds to get disk quota limits with Q_GETQUOTA flag
39* for group.
40* 12) quotactl(2) succeeds to set information about quotafile with Q_SETINFO
41* flag for group.
42* 13) quotactl(2) succeeds to get information about quotafile with Q_GETINFO
43* flag for group.
44* 14) quotactl(2) succeeds to get quota format with Q_GETFMT flag for group.
45* 15) quotactl(2) succeeds to update quota usages with Q_SYNC flag for group.
46* 16) quotactl(2) succeeds to turn off quota with Q_QUOTAOFF flag for group.
47*
48*/
49
subrata_modakbdb9a152009-06-15 18:42:32 +000050#include <errno.h>
Xiao Yangd40d74e2016-10-25 14:15:38 +080051#include <string.h>
52#include <unistd.h>
53#include <stdio.h>
yaberauneyaef772532009-10-09 17:55:43 +000054#include "config.h"
Xiao Yangd40d74e2016-10-25 14:15:38 +080055
56#include "tst_test.h"
57
Garrett Cooper40be6482010-11-03 21:00:55 -070058#if defined(HAVE_QUOTAV2) || defined(HAVE_QUOTAV1)
Xiao Yangd40d74e2016-10-25 14:15:38 +080059# include <sys/quota.h>
subrata_modakbdb9a152009-06-15 18:42:32 +000060
Xiao Yangd40d74e2016-10-25 14:15:38 +080061# if defined(HAVE_QUOTAV2)
62# define _LINUX_QUOTA_VERSION 2
63# ifndef QFMT_VFS_V0
64# define QFMT_VFS_V0 2
65# endif
66# define USRPATH MNTPOINT "/aquota.user"
67# define GRPPATH MNTPOINT "/aquota.group"
68# define FMTID QFMT_VFS_V0
69# else
70# define _LINUX_QUOTA_VERSION 1
71# ifndef QFMT_VFS_OLD
72# define QFMT_VFS_OLD 1
73# endif
74# define USRPATH MNTPOINT "/quota.user"
75# define GRPPATH MNTPOINT "/quota.group"
76# define FMTID QFMT_VFS_OLD
77# endif
subrata_modakbdb9a152009-06-15 18:42:32 +000078
Xiao Yangd40d74e2016-10-25 14:15:38 +080079# define MNTPOINT "mntpoint"
subrata_modakbdb9a152009-06-15 18:42:32 +000080
Xiao Yangd40d74e2016-10-25 14:15:38 +080081static int mount_flag;
Jan Stancekf73d2ae2017-01-13 12:31:24 +010082static int32_t fmt_id = FMTID;
83static int test_id;
Xiao Yangd40d74e2016-10-25 14:15:38 +080084static struct dqblk set_dq = {
85 .dqb_bsoftlimit = 100,
86 .dqb_valid = QIF_BLIMITS
87};
88static struct dqblk res_dq;
89# if defined(HAVE_QUOTAV2)
90static struct dqinfo set_qf = {
91 .dqi_bgrace = 80,
92 .dqi_valid = IIF_BGRACE
93};
94static struct dqinfo res_qf;
Jan Stancekf73d2ae2017-01-13 12:31:24 +010095static int32_t fmt_buf;
Xiao Yangd40d74e2016-10-25 14:15:38 +080096# endif
yaberauneyac2a3ba52010-01-10 22:27:14 +000097
Xiao Yangd40d74e2016-10-25 14:15:38 +080098static struct tcase {
99 int cmd;
Jan Stancekf73d2ae2017-01-13 12:31:24 +0100100 int *id;
Xiao Yangd40d74e2016-10-25 14:15:38 +0800101 void *addr;
Jan Stancekf73d2ae2017-01-13 12:31:24 +0100102 void *set_data;
103 void *res_data;
104 int sz;
Xiao Yangd40d74e2016-10-25 14:15:38 +0800105 char *des;
106} tcases[] = {
Jan Stancekf73d2ae2017-01-13 12:31:24 +0100107 {QCMD(Q_QUOTAON, USRQUOTA), &fmt_id, USRPATH,
108 NULL, NULL, 0, "turn on quota for user"},
109
110 {QCMD(Q_SETQUOTA, USRQUOTA), &test_id, &set_dq,
111 NULL, NULL, 0, "set disk quota limit for user"},
112
113 {QCMD(Q_GETQUOTA, USRQUOTA), &test_id, &res_dq,
114 &set_dq.dqb_bsoftlimit, &res_dq.dqb_bsoftlimit,
115 sizeof(res_dq.dqb_bsoftlimit), "get disk quota limit for user"},
Xiao Yangd40d74e2016-10-25 14:15:38 +0800116# if defined(HAVE_QUOTAV2)
Jan Stancekf73d2ae2017-01-13 12:31:24 +0100117 {QCMD(Q_SETINFO, USRQUOTA), &test_id, &set_qf,
118 NULL, NULL, 0, "set information about quotafile for user"},
119
120 {QCMD(Q_GETINFO, USRQUOTA), &test_id, &res_qf,
121 &set_qf.dqi_bgrace, &res_qf.dqi_bgrace, sizeof(res_qf.dqi_bgrace),
122 "get information about quotafile for user"},
123
124 {QCMD(Q_GETFMT, USRQUOTA), &test_id, &fmt_buf,
125 &fmt_id, &fmt_buf, sizeof(fmt_buf),
Xiao Yangd40d74e2016-10-25 14:15:38 +0800126 "get quota format for user"},
127# endif
Jan Stancekf73d2ae2017-01-13 12:31:24 +0100128 {QCMD(Q_SYNC, USRQUOTA), &test_id, &res_dq,
129 NULL, NULL, 0, "update quota usages for user"},
130
131 {QCMD(Q_QUOTAOFF, USRQUOTA), &test_id, USRPATH,
132 NULL, NULL, 0, "turn off quota for user"},
133
134 {QCMD(Q_QUOTAON, GRPQUOTA), &fmt_id, GRPPATH,
135 NULL, NULL, 0, "turn on quota for group"},
136
137 {QCMD(Q_SETQUOTA, GRPQUOTA), &test_id, &set_dq,
138 NULL, NULL, 0, "set disk quota limit for group"},
139
Xiao Yangd40d74e2016-10-25 14:15:38 +0800140 {QCMD(Q_GETQUOTA, GRPQUOTA), &test_id, &res_dq, &set_dq.dqb_bsoftlimit,
Jan Stancekf73d2ae2017-01-13 12:31:24 +0100141 &res_dq.dqb_bsoftlimit, sizeof(res_dq.dqb_bsoftlimit),
142 "set disk quota limit for group"},
Xiao Yangd40d74e2016-10-25 14:15:38 +0800143# if defined(HAVE_QUOTAV2)
Jan Stancekf73d2ae2017-01-13 12:31:24 +0100144 {QCMD(Q_SETINFO, GRPQUOTA), &test_id, &set_qf,
145 NULL, NULL, 0, "set information about quotafile for group"},
146
Xiao Yangd40d74e2016-10-25 14:15:38 +0800147 {QCMD(Q_GETINFO, GRPQUOTA), &test_id, &res_qf, &set_qf.dqi_bgrace,
Jan Stancekf73d2ae2017-01-13 12:31:24 +0100148 &res_qf.dqi_bgrace, sizeof(res_qf.dqi_bgrace),
149 "get information about quotafile for group"},
150
151 {QCMD(Q_GETFMT, GRPQUOTA), &test_id, &fmt_buf,
152 &fmt_id, &fmt_buf, sizeof(fmt_buf), "get quota format for group"},
Xiao Yangd40d74e2016-10-25 14:15:38 +0800153# endif
Jan Stancekf73d2ae2017-01-13 12:31:24 +0100154 {QCMD(Q_SYNC, GRPQUOTA), &test_id, &res_dq,
155 NULL, NULL, 0, "update quota usages for group"},
156
157 {QCMD(Q_QUOTAOFF, GRPQUOTA), &test_id, GRPPATH,
158 NULL, NULL, 0, "turn off quota for group"}
yaberauneyab8709bf2009-12-20 00:36:35 +0000159};
subrata_modakbdb9a152009-06-15 18:42:32 +0000160
Xiao Yangd40d74e2016-10-25 14:15:38 +0800161static void setup(void)
yaberauneya4df28652009-10-22 08:25:30 +0000162{
Xiao Yangd40d74e2016-10-25 14:15:38 +0800163 const char *const cmd[] = {"quotacheck", "-ug", MNTPOINT, NULL};
yaberauneyab8709bf2009-12-20 00:36:35 +0000164 int ret;
yaberauneyacfb70632010-01-10 08:01:15 +0000165
Xiao Yangd40d74e2016-10-25 14:15:38 +0800166 SAFE_MKDIR(MNTPOINT, 0755);
subrata_modakbdb9a152009-06-15 18:42:32 +0000167
Xiao Yangd40d74e2016-10-25 14:15:38 +0800168 SAFE_MKFS(tst_device->dev, "ext4", NULL, NULL);
subrata_modakbdb9a152009-06-15 18:42:32 +0000169
Xiao Yangd40d74e2016-10-25 14:15:38 +0800170 SAFE_MOUNT(tst_device->dev, MNTPOINT, "ext4", 0, "usrquota,grpquota");
171 mount_flag = 1;
yaberauneya4df28652009-10-22 08:25:30 +0000172
Xiao Yangd40d74e2016-10-25 14:15:38 +0800173 ret = tst_run_cmd(cmd, NULL, NULL, 1);
174 switch (ret) {
175 case 255:
176 tst_brk(TCONF, "quotacheck binary not installed");
177 default:
178 tst_brk(TBROK, "quotacheck exited with %i", ret);
179 case 0:
180 break;
Garrett Cooper2c282152010-12-16 00:55:50 -0800181 }
yaberauneya4df28652009-10-22 08:25:30 +0000182
Xiao Yangd40d74e2016-10-25 14:15:38 +0800183 test_id = geteuid();
yaberauneya4df28652009-10-22 08:25:30 +0000184
Xiao Yangd40d74e2016-10-25 14:15:38 +0800185 if (access(USRPATH, F_OK) == -1)
186 tst_brk(TFAIL | TERRNO, "user quotafile didn't exist");
yaberauneya4df28652009-10-22 08:25:30 +0000187
Xiao Yangd40d74e2016-10-25 14:15:38 +0800188 if (access(GRPPATH, F_OK) == -1)
189 tst_brk(TFAIL | TERRNO, "group quotafile didn't exist");
subrata_modakbdb9a152009-06-15 18:42:32 +0000190}
Xiao Yangd40d74e2016-10-25 14:15:38 +0800191
192static void cleanup(void)
193{
194 if (mount_flag && tst_umount(MNTPOINT) < 0)
195 tst_res(TWARN | TERRNO, "umount(2) failed");
196}
197
198static void verify_quota(unsigned int n)
199{
200 struct tcase *tc = &tcases[n];
201
202 res_dq.dqb_bsoftlimit = 0;
203 res_qf.dqi_igrace = 0;
Jan Stancekf73d2ae2017-01-13 12:31:24 +0100204 fmt_buf = 0;
Xiao Yangd40d74e2016-10-25 14:15:38 +0800205
206 TEST(quotactl(tc->cmd, tst_device->dev, *tc->id, tc->addr));
207 if (TEST_RETURN == -1) {
Xiao Yang00b4cde2016-11-02 18:27:35 +0800208 tst_res(TFAIL | TTERRNO, "quotactl failed to %s", tc->des);
Xiao Yangd40d74e2016-10-25 14:15:38 +0800209 return;
210 }
211
Jan Stancekf73d2ae2017-01-13 12:31:24 +0100212 if (memcmp(tc->res_data, tc->set_data, tc->sz)) {
213 tst_res(TFAIL, "quotactl failed to %s", tc->des);
214 tst_res_hexd(TINFO, tc->res_data, tc->sz, "retval: ");
215 tst_res_hexd(TINFO, tc->set_data, tc->sz, "expected: ");
Xiao Yangd40d74e2016-10-25 14:15:38 +0800216 return;
217 }
218
Jan Stancekf73d2ae2017-01-13 12:31:24 +0100219 tst_res(TPASS, "quotactl succeeded to %s", tc->des);
Xiao Yangd40d74e2016-10-25 14:15:38 +0800220}
221
222static struct tst_test test = {
223 .tid = "quotactl01",
224 .needs_tmpdir = 1,
225 .needs_root = 1,
226 .test = verify_quota,
227 .tcnt = ARRAY_SIZE(tcases),
228 .needs_device = 1,
229 .setup = setup,
230 .cleanup = cleanup
231};
232
233#else
234 TST_TEST_TCONF("This system didn't support quota");
Chris Dearmanec6edca2012-10-17 19:54:01 -0700235#endif