Xiao Yang | d40d74e | 2016-10-25 14:15:38 +0800 | [diff] [blame] | 1 | /* |
| 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_modak | bdb9a15 | 2009-06-15 18:42:32 +0000 | [diff] [blame] | 50 | #include <errno.h> |
Xiao Yang | d40d74e | 2016-10-25 14:15:38 +0800 | [diff] [blame] | 51 | #include <string.h> |
| 52 | #include <unistd.h> |
| 53 | #include <stdio.h> |
yaberauneya | ef77253 | 2009-10-09 17:55:43 +0000 | [diff] [blame] | 54 | #include "config.h" |
Xiao Yang | d40d74e | 2016-10-25 14:15:38 +0800 | [diff] [blame] | 55 | |
| 56 | #include "tst_test.h" |
| 57 | |
Garrett Cooper | 40be648 | 2010-11-03 21:00:55 -0700 | [diff] [blame] | 58 | #if defined(HAVE_QUOTAV2) || defined(HAVE_QUOTAV1) |
Xiao Yang | d40d74e | 2016-10-25 14:15:38 +0800 | [diff] [blame] | 59 | # include <sys/quota.h> |
subrata_modak | bdb9a15 | 2009-06-15 18:42:32 +0000 | [diff] [blame] | 60 | |
Xiao Yang | d40d74e | 2016-10-25 14:15:38 +0800 | [diff] [blame] | 61 | # 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_modak | bdb9a15 | 2009-06-15 18:42:32 +0000 | [diff] [blame] | 78 | |
Xiao Yang | d40d74e | 2016-10-25 14:15:38 +0800 | [diff] [blame] | 79 | # define MNTPOINT "mntpoint" |
subrata_modak | bdb9a15 | 2009-06-15 18:42:32 +0000 | [diff] [blame] | 80 | |
Xiao Yang | d40d74e | 2016-10-25 14:15:38 +0800 | [diff] [blame] | 81 | static int mount_flag; |
Jan Stancek | f73d2ae | 2017-01-13 12:31:24 +0100 | [diff] [blame^] | 82 | static int32_t fmt_id = FMTID; |
| 83 | static int test_id; |
Xiao Yang | d40d74e | 2016-10-25 14:15:38 +0800 | [diff] [blame] | 84 | static struct dqblk set_dq = { |
| 85 | .dqb_bsoftlimit = 100, |
| 86 | .dqb_valid = QIF_BLIMITS |
| 87 | }; |
| 88 | static struct dqblk res_dq; |
| 89 | # if defined(HAVE_QUOTAV2) |
| 90 | static struct dqinfo set_qf = { |
| 91 | .dqi_bgrace = 80, |
| 92 | .dqi_valid = IIF_BGRACE |
| 93 | }; |
| 94 | static struct dqinfo res_qf; |
Jan Stancek | f73d2ae | 2017-01-13 12:31:24 +0100 | [diff] [blame^] | 95 | static int32_t fmt_buf; |
Xiao Yang | d40d74e | 2016-10-25 14:15:38 +0800 | [diff] [blame] | 96 | # endif |
yaberauneya | c2a3ba5 | 2010-01-10 22:27:14 +0000 | [diff] [blame] | 97 | |
Xiao Yang | d40d74e | 2016-10-25 14:15:38 +0800 | [diff] [blame] | 98 | static struct tcase { |
| 99 | int cmd; |
Jan Stancek | f73d2ae | 2017-01-13 12:31:24 +0100 | [diff] [blame^] | 100 | int *id; |
Xiao Yang | d40d74e | 2016-10-25 14:15:38 +0800 | [diff] [blame] | 101 | void *addr; |
Jan Stancek | f73d2ae | 2017-01-13 12:31:24 +0100 | [diff] [blame^] | 102 | void *set_data; |
| 103 | void *res_data; |
| 104 | int sz; |
Xiao Yang | d40d74e | 2016-10-25 14:15:38 +0800 | [diff] [blame] | 105 | char *des; |
| 106 | } tcases[] = { |
Jan Stancek | f73d2ae | 2017-01-13 12:31:24 +0100 | [diff] [blame^] | 107 | {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 Yang | d40d74e | 2016-10-25 14:15:38 +0800 | [diff] [blame] | 116 | # if defined(HAVE_QUOTAV2) |
Jan Stancek | f73d2ae | 2017-01-13 12:31:24 +0100 | [diff] [blame^] | 117 | {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 Yang | d40d74e | 2016-10-25 14:15:38 +0800 | [diff] [blame] | 126 | "get quota format for user"}, |
| 127 | # endif |
Jan Stancek | f73d2ae | 2017-01-13 12:31:24 +0100 | [diff] [blame^] | 128 | {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 Yang | d40d74e | 2016-10-25 14:15:38 +0800 | [diff] [blame] | 140 | {QCMD(Q_GETQUOTA, GRPQUOTA), &test_id, &res_dq, &set_dq.dqb_bsoftlimit, |
Jan Stancek | f73d2ae | 2017-01-13 12:31:24 +0100 | [diff] [blame^] | 141 | &res_dq.dqb_bsoftlimit, sizeof(res_dq.dqb_bsoftlimit), |
| 142 | "set disk quota limit for group"}, |
Xiao Yang | d40d74e | 2016-10-25 14:15:38 +0800 | [diff] [blame] | 143 | # if defined(HAVE_QUOTAV2) |
Jan Stancek | f73d2ae | 2017-01-13 12:31:24 +0100 | [diff] [blame^] | 144 | {QCMD(Q_SETINFO, GRPQUOTA), &test_id, &set_qf, |
| 145 | NULL, NULL, 0, "set information about quotafile for group"}, |
| 146 | |
Xiao Yang | d40d74e | 2016-10-25 14:15:38 +0800 | [diff] [blame] | 147 | {QCMD(Q_GETINFO, GRPQUOTA), &test_id, &res_qf, &set_qf.dqi_bgrace, |
Jan Stancek | f73d2ae | 2017-01-13 12:31:24 +0100 | [diff] [blame^] | 148 | &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 Yang | d40d74e | 2016-10-25 14:15:38 +0800 | [diff] [blame] | 153 | # endif |
Jan Stancek | f73d2ae | 2017-01-13 12:31:24 +0100 | [diff] [blame^] | 154 | {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"} |
yaberauneya | b8709bf | 2009-12-20 00:36:35 +0000 | [diff] [blame] | 159 | }; |
subrata_modak | bdb9a15 | 2009-06-15 18:42:32 +0000 | [diff] [blame] | 160 | |
Xiao Yang | d40d74e | 2016-10-25 14:15:38 +0800 | [diff] [blame] | 161 | static void setup(void) |
yaberauneya | 4df2865 | 2009-10-22 08:25:30 +0000 | [diff] [blame] | 162 | { |
Xiao Yang | d40d74e | 2016-10-25 14:15:38 +0800 | [diff] [blame] | 163 | const char *const cmd[] = {"quotacheck", "-ug", MNTPOINT, NULL}; |
yaberauneya | b8709bf | 2009-12-20 00:36:35 +0000 | [diff] [blame] | 164 | int ret; |
yaberauneya | cfb7063 | 2010-01-10 08:01:15 +0000 | [diff] [blame] | 165 | |
Xiao Yang | d40d74e | 2016-10-25 14:15:38 +0800 | [diff] [blame] | 166 | SAFE_MKDIR(MNTPOINT, 0755); |
subrata_modak | bdb9a15 | 2009-06-15 18:42:32 +0000 | [diff] [blame] | 167 | |
Xiao Yang | d40d74e | 2016-10-25 14:15:38 +0800 | [diff] [blame] | 168 | SAFE_MKFS(tst_device->dev, "ext4", NULL, NULL); |
subrata_modak | bdb9a15 | 2009-06-15 18:42:32 +0000 | [diff] [blame] | 169 | |
Xiao Yang | d40d74e | 2016-10-25 14:15:38 +0800 | [diff] [blame] | 170 | SAFE_MOUNT(tst_device->dev, MNTPOINT, "ext4", 0, "usrquota,grpquota"); |
| 171 | mount_flag = 1; |
yaberauneya | 4df2865 | 2009-10-22 08:25:30 +0000 | [diff] [blame] | 172 | |
Xiao Yang | d40d74e | 2016-10-25 14:15:38 +0800 | [diff] [blame] | 173 | 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 Cooper | 2c28215 | 2010-12-16 00:55:50 -0800 | [diff] [blame] | 181 | } |
yaberauneya | 4df2865 | 2009-10-22 08:25:30 +0000 | [diff] [blame] | 182 | |
Xiao Yang | d40d74e | 2016-10-25 14:15:38 +0800 | [diff] [blame] | 183 | test_id = geteuid(); |
yaberauneya | 4df2865 | 2009-10-22 08:25:30 +0000 | [diff] [blame] | 184 | |
Xiao Yang | d40d74e | 2016-10-25 14:15:38 +0800 | [diff] [blame] | 185 | if (access(USRPATH, F_OK) == -1) |
| 186 | tst_brk(TFAIL | TERRNO, "user quotafile didn't exist"); |
yaberauneya | 4df2865 | 2009-10-22 08:25:30 +0000 | [diff] [blame] | 187 | |
Xiao Yang | d40d74e | 2016-10-25 14:15:38 +0800 | [diff] [blame] | 188 | if (access(GRPPATH, F_OK) == -1) |
| 189 | tst_brk(TFAIL | TERRNO, "group quotafile didn't exist"); |
subrata_modak | bdb9a15 | 2009-06-15 18:42:32 +0000 | [diff] [blame] | 190 | } |
Xiao Yang | d40d74e | 2016-10-25 14:15:38 +0800 | [diff] [blame] | 191 | |
| 192 | static void cleanup(void) |
| 193 | { |
| 194 | if (mount_flag && tst_umount(MNTPOINT) < 0) |
| 195 | tst_res(TWARN | TERRNO, "umount(2) failed"); |
| 196 | } |
| 197 | |
| 198 | static 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 Stancek | f73d2ae | 2017-01-13 12:31:24 +0100 | [diff] [blame^] | 204 | fmt_buf = 0; |
Xiao Yang | d40d74e | 2016-10-25 14:15:38 +0800 | [diff] [blame] | 205 | |
| 206 | TEST(quotactl(tc->cmd, tst_device->dev, *tc->id, tc->addr)); |
| 207 | if (TEST_RETURN == -1) { |
Xiao Yang | 00b4cde | 2016-11-02 18:27:35 +0800 | [diff] [blame] | 208 | tst_res(TFAIL | TTERRNO, "quotactl failed to %s", tc->des); |
Xiao Yang | d40d74e | 2016-10-25 14:15:38 +0800 | [diff] [blame] | 209 | return; |
| 210 | } |
| 211 | |
Jan Stancek | f73d2ae | 2017-01-13 12:31:24 +0100 | [diff] [blame^] | 212 | 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 Yang | d40d74e | 2016-10-25 14:15:38 +0800 | [diff] [blame] | 216 | return; |
| 217 | } |
| 218 | |
Jan Stancek | f73d2ae | 2017-01-13 12:31:24 +0100 | [diff] [blame^] | 219 | tst_res(TPASS, "quotactl succeeded to %s", tc->des); |
Xiao Yang | d40d74e | 2016-10-25 14:15:38 +0800 | [diff] [blame] | 220 | } |
| 221 | |
| 222 | static 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 Dearman | ec6edca | 2012-10-17 19:54:01 -0700 | [diff] [blame] | 235 | #endif |