h_quota2_tests.c revision 1.1.2.3 1 1.1.2.3 bouyer /* $NetBSD: h_quota2_tests.c,v 1.1.2.3 2011/02/07 16:22:50 bouyer Exp $ */
2 1.1.2.1 bouyer
3 1.1.2.1 bouyer /*
4 1.1.2.1 bouyer * rump server for advanced quota tests
5 1.1.2.1 bouyer * this one includes functions to run against the filesystem before
6 1.1.2.1 bouyer * starting to handle rump requests from clients.
7 1.1.2.1 bouyer */
8 1.1.2.1 bouyer
9 1.1.2.1 bouyer #include "../common/h_fsmacros.h"
10 1.1.2.1 bouyer
11 1.1.2.1 bouyer #include <err.h>
12 1.1.2.1 bouyer #include <semaphore.h>
13 1.1.2.1 bouyer #include <sys/types.h>
14 1.1.2.1 bouyer #include <sys/mount.h>
15 1.1.2.1 bouyer
16 1.1.2.1 bouyer #include <stdlib.h>
17 1.1.2.1 bouyer #include <unistd.h>
18 1.1.2.1 bouyer
19 1.1.2.1 bouyer #include <ufs/ufs/ufsmount.h>
20 1.1.2.1 bouyer
21 1.1.2.1 bouyer #include <rump/rump.h>
22 1.1.2.1 bouyer #include <rump/rump_syscalls.h>
23 1.1.2.1 bouyer
24 1.1.2.1 bouyer #include "../../h_macros.h"
25 1.1.2.1 bouyer
26 1.1.2.1 bouyer int background = 0;
27 1.1.2.1 bouyer
28 1.1.2.1 bouyer #define TEST_NONROOT_ID 1
29 1.1.2.1 bouyer
30 1.1.2.1 bouyer static int
31 1.1.2.1 bouyer quota_test0(void)
32 1.1.2.1 bouyer {
33 1.1.2.1 bouyer static char buf[512];
34 1.1.2.1 bouyer int fd;
35 1.1.2.1 bouyer int error;
36 1.1.2.1 bouyer rump_sys_chown(".", TEST_NONROOT_ID, TEST_NONROOT_ID);
37 1.1.2.1 bouyer if (rump_sys_setegid(TEST_NONROOT_ID) != 0) {
38 1.1.2.1 bouyer error = errno;
39 1.1.2.1 bouyer perror("rump_sys_setegid");
40 1.1.2.1 bouyer return error;
41 1.1.2.1 bouyer }
42 1.1.2.1 bouyer if (rump_sys_seteuid(TEST_NONROOT_ID) != 0) {
43 1.1.2.1 bouyer error = errno;
44 1.1.2.1 bouyer perror("rump_sys_seteuid");
45 1.1.2.1 bouyer return error;
46 1.1.2.1 bouyer }
47 1.1.2.1 bouyer fd = rump_sys_open("test_fillup", O_CREAT | O_RDWR, 0644);
48 1.1.2.1 bouyer if (fd < 0) {
49 1.1.2.1 bouyer error = errno;
50 1.1.2.1 bouyer perror("rump_sys_open");
51 1.1.2.1 bouyer } else {
52 1.1.2.1 bouyer while (rump_sys_write(fd, buf, sizeof(buf)) == sizeof(buf))
53 1.1.2.1 bouyer error = 0;
54 1.1.2.1 bouyer error = errno;
55 1.1.2.1 bouyer }
56 1.1.2.1 bouyer rump_sys_close(fd);
57 1.1.2.1 bouyer rump_sys_seteuid(0);
58 1.1.2.1 bouyer rump_sys_setegid(0);
59 1.1.2.1 bouyer return error;
60 1.1.2.1 bouyer }
61 1.1.2.1 bouyer
62 1.1.2.1 bouyer static int
63 1.1.2.1 bouyer quota_test1(void)
64 1.1.2.1 bouyer {
65 1.1.2.1 bouyer static char buf[512];
66 1.1.2.1 bouyer int fd;
67 1.1.2.1 bouyer int error;
68 1.1.2.1 bouyer rump_sys_chown(".", TEST_NONROOT_ID, TEST_NONROOT_ID);
69 1.1.2.1 bouyer if (rump_sys_setegid(TEST_NONROOT_ID) != 0) {
70 1.1.2.1 bouyer error = errno;
71 1.1.2.1 bouyer perror("rump_sys_setegid");
72 1.1.2.1 bouyer return error;
73 1.1.2.1 bouyer }
74 1.1.2.1 bouyer if (rump_sys_seteuid(TEST_NONROOT_ID) != 0) {
75 1.1.2.1 bouyer error = errno;
76 1.1.2.1 bouyer perror("rump_sys_seteuid");
77 1.1.2.1 bouyer return error;
78 1.1.2.1 bouyer }
79 1.1.2.1 bouyer fd = rump_sys_open("test_fillup", O_CREAT | O_RDWR, 0644);
80 1.1.2.1 bouyer if (fd < 0) {
81 1.1.2.1 bouyer error = errno;
82 1.1.2.1 bouyer perror("rump_sys_open");
83 1.1.2.1 bouyer } else {
84 1.1.2.1 bouyer /*
85 1.1.2.1 bouyer * write up to the soft limit, wait a bit, an try to
86 1.1.2.1 bouyer * keep on writing
87 1.1.2.1 bouyer */
88 1.1.2.1 bouyer int i;
89 1.1.2.1 bouyer
90 1.1.2.2 bouyer /* write 2k: with the directory this makes 2.5K */
91 1.1.2.2 bouyer for (i = 0; i < 4; i++) {
92 1.1.2.1 bouyer error = rump_sys_write(fd, buf, sizeof(buf));
93 1.1.2.1 bouyer if (error != sizeof(buf))
94 1.1.2.1 bouyer err(1, "write failed early");
95 1.1.2.1 bouyer }
96 1.1.2.1 bouyer sleep(2);
97 1.1.2.1 bouyer /* now try to write an extra .5k */
98 1.1.2.1 bouyer if (rump_sys_write(fd, buf, sizeof(buf)) != sizeof(buf))
99 1.1.2.1 bouyer error = errno;
100 1.1.2.1 bouyer else
101 1.1.2.1 bouyer error = 0;
102 1.1.2.1 bouyer }
103 1.1.2.1 bouyer rump_sys_close(fd);
104 1.1.2.1 bouyer rump_sys_seteuid(0);
105 1.1.2.1 bouyer rump_sys_setegid(0);
106 1.1.2.1 bouyer return error;
107 1.1.2.1 bouyer }
108 1.1.2.1 bouyer
109 1.1.2.1 bouyer static int
110 1.1.2.1 bouyer quota_test2(void)
111 1.1.2.1 bouyer {
112 1.1.2.1 bouyer static char buf[512];
113 1.1.2.1 bouyer int fd;
114 1.1.2.1 bouyer int error;
115 1.1.2.1 bouyer int i;
116 1.1.2.1 bouyer rump_sys_chown(".", TEST_NONROOT_ID, TEST_NONROOT_ID);
117 1.1.2.1 bouyer if (rump_sys_setegid(TEST_NONROOT_ID) != 0) {
118 1.1.2.1 bouyer error = errno;
119 1.1.2.1 bouyer perror("rump_sys_setegid");
120 1.1.2.1 bouyer return error;
121 1.1.2.1 bouyer }
122 1.1.2.1 bouyer if (rump_sys_seteuid(TEST_NONROOT_ID) != 0) {
123 1.1.2.1 bouyer error = errno;
124 1.1.2.1 bouyer perror("rump_sys_seteuid");
125 1.1.2.1 bouyer return error;
126 1.1.2.1 bouyer }
127 1.1.2.1 bouyer
128 1.1.2.1 bouyer for (i = 0; ; i++) {
129 1.1.2.1 bouyer sprintf(buf, "file%d", i);
130 1.1.2.1 bouyer fd = rump_sys_open(buf, O_CREAT | O_RDWR, 0644);
131 1.1.2.1 bouyer if (fd < 0)
132 1.1.2.1 bouyer break;
133 1.1.2.1 bouyer sprintf(buf, "test file no %d", i);
134 1.1.2.1 bouyer rump_sys_write(fd, buf, strlen(buf));
135 1.1.2.1 bouyer rump_sys_close(fd);
136 1.1.2.1 bouyer }
137 1.1.2.1 bouyer error = errno;
138 1.1.2.1 bouyer
139 1.1.2.1 bouyer rump_sys_close(fd);
140 1.1.2.1 bouyer rump_sys_seteuid(0);
141 1.1.2.1 bouyer rump_sys_setegid(0);
142 1.1.2.1 bouyer return error;
143 1.1.2.1 bouyer }
144 1.1.2.1 bouyer
145 1.1.2.1 bouyer static int
146 1.1.2.1 bouyer quota_test3(void)
147 1.1.2.1 bouyer {
148 1.1.2.1 bouyer static char buf[512];
149 1.1.2.1 bouyer int fd;
150 1.1.2.1 bouyer int error;
151 1.1.2.1 bouyer int i;
152 1.1.2.1 bouyer rump_sys_chown(".", TEST_NONROOT_ID, TEST_NONROOT_ID);
153 1.1.2.1 bouyer if (rump_sys_setegid(TEST_NONROOT_ID) != 0) {
154 1.1.2.1 bouyer error = errno;
155 1.1.2.1 bouyer perror("rump_sys_setegid");
156 1.1.2.1 bouyer return error;
157 1.1.2.1 bouyer }
158 1.1.2.1 bouyer if (rump_sys_seteuid(TEST_NONROOT_ID) != 0) {
159 1.1.2.1 bouyer error = errno;
160 1.1.2.1 bouyer perror("rump_sys_seteuid");
161 1.1.2.1 bouyer return error;
162 1.1.2.1 bouyer }
163 1.1.2.1 bouyer
164 1.1.2.1 bouyer /*
165 1.1.2.2 bouyer * create files one past the soft limit: one less as we already own the
166 1.1.2.1 bouyer * root directory
167 1.1.2.1 bouyer */
168 1.1.2.2 bouyer for (i = 0; i < 4; i++) {
169 1.1.2.1 bouyer sprintf(buf, "file%d", i);
170 1.1.2.1 bouyer fd = rump_sys_open(buf, O_EXCL| O_CREAT | O_RDWR, 0644);
171 1.1.2.1 bouyer if (fd < 0)
172 1.1.2.1 bouyer err(1, "file create failed early");
173 1.1.2.1 bouyer sprintf(buf, "test file no %d", i);
174 1.1.2.1 bouyer rump_sys_write(fd, buf, strlen(buf));
175 1.1.2.1 bouyer rump_sys_close(fd);
176 1.1.2.1 bouyer }
177 1.1.2.1 bouyer /* now create an extra file after grace time: this should fail */
178 1.1.2.1 bouyer sleep(2);
179 1.1.2.1 bouyer sprintf(buf, "file%d", i);
180 1.1.2.1 bouyer fd = rump_sys_open(buf, O_EXCL| O_CREAT | O_RDWR, 0644);
181 1.1.2.1 bouyer if (fd < 0)
182 1.1.2.1 bouyer error = errno;
183 1.1.2.1 bouyer else
184 1.1.2.1 bouyer error = 0;
185 1.1.2.1 bouyer
186 1.1.2.1 bouyer rump_sys_close(fd);
187 1.1.2.1 bouyer rump_sys_seteuid(0);
188 1.1.2.1 bouyer rump_sys_setegid(0);
189 1.1.2.1 bouyer return error;
190 1.1.2.1 bouyer }
191 1.1.2.1 bouyer
192 1.1.2.1 bouyer struct quota_test {
193 1.1.2.1 bouyer int (*func)(void);
194 1.1.2.1 bouyer const char *desc;
195 1.1.2.1 bouyer };
196 1.1.2.1 bouyer
197 1.1.2.1 bouyer struct quota_test quota_tests[] = {
198 1.1.2.1 bouyer { quota_test0, "write up to hard limit"},
199 1.1.2.1 bouyer { quota_test1, "write beyond the soft limit after grace time"},
200 1.1.2.1 bouyer { quota_test2, "create file up to hard limit"},
201 1.1.2.1 bouyer { quota_test3, "create file beyond the soft limit after grace time"},
202 1.1.2.1 bouyer };
203 1.1.2.1 bouyer
204 1.1.2.1 bouyer static void
205 1.1.2.1 bouyer usage(void)
206 1.1.2.1 bouyer {
207 1.1.2.3 bouyer fprintf(stderr, "usage: %s [-b] [-l] test# diskimage bindurl\n",
208 1.1.2.1 bouyer getprogname());
209 1.1.2.1 bouyer exit(1);
210 1.1.2.1 bouyer }
211 1.1.2.1 bouyer
212 1.1.2.1 bouyer static void
213 1.1.2.1 bouyer die(const char *reason, int error)
214 1.1.2.1 bouyer {
215 1.1.2.1 bouyer
216 1.1.2.1 bouyer warnx("%s: %s", reason, strerror(error));
217 1.1.2.1 bouyer if (background)
218 1.1.2.1 bouyer rump_daemonize_done(error);
219 1.1.2.1 bouyer exit(1);
220 1.1.2.1 bouyer }
221 1.1.2.1 bouyer
222 1.1.2.1 bouyer static sem_t sigsem;
223 1.1.2.1 bouyer static void
224 1.1.2.1 bouyer sigreboot(int sig)
225 1.1.2.1 bouyer {
226 1.1.2.1 bouyer
227 1.1.2.1 bouyer sem_post(&sigsem);
228 1.1.2.1 bouyer }
229 1.1.2.1 bouyer
230 1.1.2.1 bouyer int
231 1.1.2.1 bouyer main(int argc, char **argv)
232 1.1.2.1 bouyer {
233 1.1.2.1 bouyer int error;
234 1.1.2.1 bouyer u_long test;
235 1.1.2.1 bouyer char *end;
236 1.1.2.1 bouyer struct ufs_args uargs;
237 1.1.2.1 bouyer const char *filename;
238 1.1.2.1 bouyer const char *serverurl;
239 1.1.2.1 bouyer int log = 0;
240 1.1.2.1 bouyer int ch;
241 1.1.2.1 bouyer
242 1.1.2.3 bouyer while ((ch = getopt(argc, argv, "bl")) != -1) {
243 1.1.2.1 bouyer switch(ch) {
244 1.1.2.1 bouyer case 'b':
245 1.1.2.1 bouyer background = 1;
246 1.1.2.1 bouyer break;
247 1.1.2.3 bouyer case 'l':
248 1.1.2.3 bouyer log = 1;
249 1.1.2.3 bouyer break;
250 1.1.2.1 bouyer default:
251 1.1.2.1 bouyer usage();
252 1.1.2.1 bouyer }
253 1.1.2.1 bouyer }
254 1.1.2.1 bouyer argc -= optind;
255 1.1.2.1 bouyer argv += optind;
256 1.1.2.1 bouyer
257 1.1.2.1 bouyer if (argc != 3)
258 1.1.2.1 bouyer usage();
259 1.1.2.1 bouyer
260 1.1.2.1 bouyer filename = argv[1];
261 1.1.2.1 bouyer serverurl = argv[2];
262 1.1.2.1 bouyer
263 1.1.2.1 bouyer test = strtoul(argv[0], &end, 10);
264 1.1.2.1 bouyer if (*end != '\0') {
265 1.1.2.1 bouyer usage();
266 1.1.2.1 bouyer }
267 1.1.2.1 bouyer if (test > sizeof(quota_tests) / sizeof(quota_tests[0])) {
268 1.1.2.1 bouyer fprintf(stderr, "test number %lu too big\n", test);
269 1.1.2.1 bouyer exit(1);
270 1.1.2.1 bouyer }
271 1.1.2.1 bouyer
272 1.1.2.1 bouyer if (background) {
273 1.1.2.1 bouyer error = rump_daemonize_begin();
274 1.1.2.1 bouyer if (error)
275 1.1.2.1 bouyer errx(1, "rump daemonize: %s", strerror(error));
276 1.1.2.1 bouyer }
277 1.1.2.1 bouyer
278 1.1.2.1 bouyer error = rump_init();
279 1.1.2.1 bouyer if (error)
280 1.1.2.1 bouyer die("rump init failed", error);
281 1.1.2.1 bouyer
282 1.1.2.1 bouyer if (rump_sys_mkdir(FSTEST_MNTNAME, 0777) == -1)
283 1.1.2.1 bouyer err(1, "mount point create");
284 1.1.2.1 bouyer rump_pub_etfs_register("/diskdev", filename, RUMP_ETFS_BLK);
285 1.1.2.1 bouyer uargs.fspec = __UNCONST("/diskdev");
286 1.1.2.1 bouyer if (rump_sys_mount(MOUNT_FFS, FSTEST_MNTNAME, (log) ? MNT_LOG : 0,
287 1.1.2.1 bouyer &uargs, sizeof(uargs)) == -1)
288 1.1.2.1 bouyer die("mount ffs", errno);
289 1.1.2.1 bouyer
290 1.1.2.1 bouyer if (rump_sys_chdir(FSTEST_MNTNAME) == -1)
291 1.1.2.1 bouyer err(1, "cd %s", FSTEST_MNTNAME);
292 1.1.2.1 bouyer rump_sys_chown(".", 0, 0);
293 1.1.2.1 bouyer rump_sys_chmod(".", 0777);
294 1.1.2.1 bouyer error = quota_tests[test].func();
295 1.1.2.1 bouyer if (error) {
296 1.1.2.1 bouyer fprintf(stderr, " test %lu: %s returned %d: %s\n",
297 1.1.2.1 bouyer test, quota_tests[test].desc, error, strerror(error));
298 1.1.2.1 bouyer }
299 1.1.2.1 bouyer if (rump_sys_chdir("/") == -1)
300 1.1.2.1 bouyer err(1, "cd /");
301 1.1.2.1 bouyer
302 1.1.2.1 bouyer error = rump_init_server(serverurl);
303 1.1.2.1 bouyer if (error)
304 1.1.2.1 bouyer die("rump server init failed", error);
305 1.1.2.1 bouyer if (background)
306 1.1.2.1 bouyer rump_daemonize_done(RUMP_DAEMONIZE_SUCCESS);
307 1.1.2.1 bouyer
308 1.1.2.1 bouyer sem_init(&sigsem, 0, 0);
309 1.1.2.1 bouyer signal(SIGTERM, sigreboot);
310 1.1.2.1 bouyer signal(SIGINT, sigreboot);
311 1.1.2.1 bouyer sem_wait(&sigsem);
312 1.1.2.1 bouyer
313 1.1.2.1 bouyer rump_sys_reboot(0, NULL);
314 1.1.2.1 bouyer /*NOTREACHED*/
315 1.1.2.1 bouyer return 0;
316 1.1.2.1 bouyer }
317