1*11be35a1SLionel Sambuc /* $NetBSD: h_quota2_tests.c,v 1.4 2012/09/30 21:26:57 bouyer Exp $ */
2*11be35a1SLionel Sambuc
3*11be35a1SLionel Sambuc /*
4*11be35a1SLionel Sambuc * rump server for advanced quota tests
5*11be35a1SLionel Sambuc * this one includes functions to run against the filesystem before
6*11be35a1SLionel Sambuc * starting to handle rump requests from clients.
7*11be35a1SLionel Sambuc */
8*11be35a1SLionel Sambuc
9*11be35a1SLionel Sambuc #include "../common/h_fsmacros.h"
10*11be35a1SLionel Sambuc
11*11be35a1SLionel Sambuc #include <err.h>
12*11be35a1SLionel Sambuc #include <semaphore.h>
13*11be35a1SLionel Sambuc #include <sys/types.h>
14*11be35a1SLionel Sambuc #include <sys/mount.h>
15*11be35a1SLionel Sambuc
16*11be35a1SLionel Sambuc #include <stdlib.h>
17*11be35a1SLionel Sambuc #include <unistd.h>
18*11be35a1SLionel Sambuc
19*11be35a1SLionel Sambuc #include <ufs/ufs/ufsmount.h>
20*11be35a1SLionel Sambuc #include <dev/fssvar.h>
21*11be35a1SLionel Sambuc
22*11be35a1SLionel Sambuc #include <rump/rump.h>
23*11be35a1SLionel Sambuc #include <rump/rump_syscalls.h>
24*11be35a1SLionel Sambuc
25*11be35a1SLionel Sambuc #include "../../h_macros.h"
26*11be35a1SLionel Sambuc
27*11be35a1SLionel Sambuc int background = 0;
28*11be35a1SLionel Sambuc
29*11be35a1SLionel Sambuc #define TEST_NONROOT_ID 1
30*11be35a1SLionel Sambuc
31*11be35a1SLionel Sambuc static int
quota_test0(const char * testopts)32*11be35a1SLionel Sambuc quota_test0(const char *testopts)
33*11be35a1SLionel Sambuc {
34*11be35a1SLionel Sambuc static char buf[512];
35*11be35a1SLionel Sambuc int fd;
36*11be35a1SLionel Sambuc int error;
37*11be35a1SLionel Sambuc unsigned int i;
38*11be35a1SLionel Sambuc int chowner = 1;
39*11be35a1SLionel Sambuc for (i =0; testopts && i < strlen(testopts); i++) {
40*11be35a1SLionel Sambuc switch(testopts[i]) {
41*11be35a1SLionel Sambuc case 'C':
42*11be35a1SLionel Sambuc chowner = 0;
43*11be35a1SLionel Sambuc break;
44*11be35a1SLionel Sambuc default:
45*11be35a1SLionel Sambuc errx(1, "test4: unknown option %c", testopts[i]);
46*11be35a1SLionel Sambuc }
47*11be35a1SLionel Sambuc }
48*11be35a1SLionel Sambuc if (chowner)
49*11be35a1SLionel Sambuc rump_sys_chown(".", TEST_NONROOT_ID, TEST_NONROOT_ID);
50*11be35a1SLionel Sambuc rump_sys_chmod(".", 0777);
51*11be35a1SLionel Sambuc if (rump_sys_setegid(TEST_NONROOT_ID) != 0) {
52*11be35a1SLionel Sambuc error = errno;
53*11be35a1SLionel Sambuc warn("rump_sys_setegid");
54*11be35a1SLionel Sambuc return error;
55*11be35a1SLionel Sambuc }
56*11be35a1SLionel Sambuc if (rump_sys_seteuid(TEST_NONROOT_ID) != 0) {
57*11be35a1SLionel Sambuc error = errno;
58*11be35a1SLionel Sambuc warn("rump_sys_seteuid");
59*11be35a1SLionel Sambuc return error;
60*11be35a1SLionel Sambuc }
61*11be35a1SLionel Sambuc fd = rump_sys_open("test_fillup", O_CREAT | O_RDWR, 0644);
62*11be35a1SLionel Sambuc if (fd < 0) {
63*11be35a1SLionel Sambuc error = errno;
64*11be35a1SLionel Sambuc warn("rump_sys_open");
65*11be35a1SLionel Sambuc } else {
66*11be35a1SLionel Sambuc while (rump_sys_write(fd, buf, sizeof(buf)) == sizeof(buf))
67*11be35a1SLionel Sambuc error = 0;
68*11be35a1SLionel Sambuc error = errno;
69*11be35a1SLionel Sambuc }
70*11be35a1SLionel Sambuc rump_sys_close(fd);
71*11be35a1SLionel Sambuc rump_sys_seteuid(0);
72*11be35a1SLionel Sambuc rump_sys_setegid(0);
73*11be35a1SLionel Sambuc return error;
74*11be35a1SLionel Sambuc }
75*11be35a1SLionel Sambuc
76*11be35a1SLionel Sambuc static int
quota_test1(const char * testopts)77*11be35a1SLionel Sambuc quota_test1(const char *testopts)
78*11be35a1SLionel Sambuc {
79*11be35a1SLionel Sambuc static char buf[512];
80*11be35a1SLionel Sambuc int fd;
81*11be35a1SLionel Sambuc int error;
82*11be35a1SLionel Sambuc rump_sys_chown(".", TEST_NONROOT_ID, TEST_NONROOT_ID);
83*11be35a1SLionel Sambuc rump_sys_chmod(".", 0777);
84*11be35a1SLionel Sambuc if (rump_sys_setegid(TEST_NONROOT_ID) != 0) {
85*11be35a1SLionel Sambuc error = errno;
86*11be35a1SLionel Sambuc warn("rump_sys_setegid");
87*11be35a1SLionel Sambuc return error;
88*11be35a1SLionel Sambuc }
89*11be35a1SLionel Sambuc if (rump_sys_seteuid(TEST_NONROOT_ID) != 0) {
90*11be35a1SLionel Sambuc error = errno;
91*11be35a1SLionel Sambuc warn("rump_sys_seteuid");
92*11be35a1SLionel Sambuc return error;
93*11be35a1SLionel Sambuc }
94*11be35a1SLionel Sambuc fd = rump_sys_open("test_fillup", O_CREAT | O_RDWR, 0644);
95*11be35a1SLionel Sambuc if (fd < 0) {
96*11be35a1SLionel Sambuc error = errno;
97*11be35a1SLionel Sambuc warn("rump_sys_open");
98*11be35a1SLionel Sambuc } else {
99*11be35a1SLionel Sambuc /*
100*11be35a1SLionel Sambuc * write up to the soft limit, wait a bit, an try to
101*11be35a1SLionel Sambuc * keep on writing
102*11be35a1SLionel Sambuc */
103*11be35a1SLionel Sambuc int i;
104*11be35a1SLionel Sambuc
105*11be35a1SLionel Sambuc /* write 2k: with the directory this makes 2.5K */
106*11be35a1SLionel Sambuc for (i = 0; i < 4; i++) {
107*11be35a1SLionel Sambuc error = rump_sys_write(fd, buf, sizeof(buf));
108*11be35a1SLionel Sambuc if (error != sizeof(buf))
109*11be35a1SLionel Sambuc err(1, "write failed early");
110*11be35a1SLionel Sambuc }
111*11be35a1SLionel Sambuc sleep(2);
112*11be35a1SLionel Sambuc /* now try to write an extra .5k */
113*11be35a1SLionel Sambuc if (rump_sys_write(fd, buf, sizeof(buf)) != sizeof(buf))
114*11be35a1SLionel Sambuc error = errno;
115*11be35a1SLionel Sambuc else
116*11be35a1SLionel Sambuc error = 0;
117*11be35a1SLionel Sambuc }
118*11be35a1SLionel Sambuc rump_sys_close(fd);
119*11be35a1SLionel Sambuc rump_sys_seteuid(0);
120*11be35a1SLionel Sambuc rump_sys_setegid(0);
121*11be35a1SLionel Sambuc return error;
122*11be35a1SLionel Sambuc }
123*11be35a1SLionel Sambuc
124*11be35a1SLionel Sambuc static int
quota_test2(const char * testopts)125*11be35a1SLionel Sambuc quota_test2(const char *testopts)
126*11be35a1SLionel Sambuc {
127*11be35a1SLionel Sambuc static char buf[512];
128*11be35a1SLionel Sambuc int fd;
129*11be35a1SLionel Sambuc int error;
130*11be35a1SLionel Sambuc int i;
131*11be35a1SLionel Sambuc rump_sys_chown(".", TEST_NONROOT_ID, TEST_NONROOT_ID);
132*11be35a1SLionel Sambuc rump_sys_chmod(".", 0777);
133*11be35a1SLionel Sambuc if (rump_sys_setegid(TEST_NONROOT_ID) != 0) {
134*11be35a1SLionel Sambuc error = errno;
135*11be35a1SLionel Sambuc warn("rump_sys_setegid");
136*11be35a1SLionel Sambuc return error;
137*11be35a1SLionel Sambuc }
138*11be35a1SLionel Sambuc if (rump_sys_seteuid(TEST_NONROOT_ID) != 0) {
139*11be35a1SLionel Sambuc error = errno;
140*11be35a1SLionel Sambuc warn("rump_sys_seteuid");
141*11be35a1SLionel Sambuc return error;
142*11be35a1SLionel Sambuc }
143*11be35a1SLionel Sambuc
144*11be35a1SLionel Sambuc for (i = 0; ; i++) {
145*11be35a1SLionel Sambuc sprintf(buf, "file%d", i);
146*11be35a1SLionel Sambuc fd = rump_sys_open(buf, O_CREAT | O_RDWR, 0644);
147*11be35a1SLionel Sambuc if (fd < 0)
148*11be35a1SLionel Sambuc break;
149*11be35a1SLionel Sambuc sprintf(buf, "test file no %d", i);
150*11be35a1SLionel Sambuc rump_sys_write(fd, buf, strlen(buf));
151*11be35a1SLionel Sambuc rump_sys_close(fd);
152*11be35a1SLionel Sambuc }
153*11be35a1SLionel Sambuc error = errno;
154*11be35a1SLionel Sambuc
155*11be35a1SLionel Sambuc rump_sys_close(fd);
156*11be35a1SLionel Sambuc rump_sys_seteuid(0);
157*11be35a1SLionel Sambuc rump_sys_setegid(0);
158*11be35a1SLionel Sambuc return error;
159*11be35a1SLionel Sambuc }
160*11be35a1SLionel Sambuc
161*11be35a1SLionel Sambuc static int
quota_test3(const char * testopts)162*11be35a1SLionel Sambuc quota_test3(const char *testopts)
163*11be35a1SLionel Sambuc {
164*11be35a1SLionel Sambuc static char buf[512];
165*11be35a1SLionel Sambuc int fd;
166*11be35a1SLionel Sambuc int error;
167*11be35a1SLionel Sambuc int i;
168*11be35a1SLionel Sambuc rump_sys_chown(".", TEST_NONROOT_ID, TEST_NONROOT_ID);
169*11be35a1SLionel Sambuc rump_sys_chmod(".", 0777);
170*11be35a1SLionel Sambuc if (rump_sys_setegid(TEST_NONROOT_ID) != 0) {
171*11be35a1SLionel Sambuc error = errno;
172*11be35a1SLionel Sambuc warn("rump_sys_setegid");
173*11be35a1SLionel Sambuc return error;
174*11be35a1SLionel Sambuc }
175*11be35a1SLionel Sambuc if (rump_sys_seteuid(TEST_NONROOT_ID) != 0) {
176*11be35a1SLionel Sambuc error = errno;
177*11be35a1SLionel Sambuc warn("rump_sys_seteuid");
178*11be35a1SLionel Sambuc return error;
179*11be35a1SLionel Sambuc }
180*11be35a1SLionel Sambuc
181*11be35a1SLionel Sambuc /*
182*11be35a1SLionel Sambuc * create files one past the soft limit: one less as we already own the
183*11be35a1SLionel Sambuc * root directory
184*11be35a1SLionel Sambuc */
185*11be35a1SLionel Sambuc for (i = 0; i < 4; i++) {
186*11be35a1SLionel Sambuc sprintf(buf, "file%d", i);
187*11be35a1SLionel Sambuc fd = rump_sys_open(buf, O_EXCL| O_CREAT | O_RDWR, 0644);
188*11be35a1SLionel Sambuc if (fd < 0)
189*11be35a1SLionel Sambuc err(1, "file create failed early");
190*11be35a1SLionel Sambuc sprintf(buf, "test file no %d", i);
191*11be35a1SLionel Sambuc rump_sys_write(fd, buf, strlen(buf));
192*11be35a1SLionel Sambuc rump_sys_close(fd);
193*11be35a1SLionel Sambuc }
194*11be35a1SLionel Sambuc /* now create an extra file after grace time: this should fail */
195*11be35a1SLionel Sambuc sleep(2);
196*11be35a1SLionel Sambuc sprintf(buf, "file%d", i);
197*11be35a1SLionel Sambuc fd = rump_sys_open(buf, O_EXCL| O_CREAT | O_RDWR, 0644);
198*11be35a1SLionel Sambuc if (fd < 0)
199*11be35a1SLionel Sambuc error = errno;
200*11be35a1SLionel Sambuc else
201*11be35a1SLionel Sambuc error = 0;
202*11be35a1SLionel Sambuc
203*11be35a1SLionel Sambuc rump_sys_close(fd);
204*11be35a1SLionel Sambuc rump_sys_seteuid(0);
205*11be35a1SLionel Sambuc rump_sys_setegid(0);
206*11be35a1SLionel Sambuc return error;
207*11be35a1SLionel Sambuc }
208*11be35a1SLionel Sambuc
209*11be35a1SLionel Sambuc static int
quota_test4(const char * testopts)210*11be35a1SLionel Sambuc quota_test4(const char *testopts)
211*11be35a1SLionel Sambuc {
212*11be35a1SLionel Sambuc static char buf[512];
213*11be35a1SLionel Sambuc int fd, fssfd;
214*11be35a1SLionel Sambuc struct fss_set fss;
215*11be35a1SLionel Sambuc unsigned int i;
216*11be35a1SLionel Sambuc int unl=0;
217*11be35a1SLionel Sambuc int unconf=0;
218*11be35a1SLionel Sambuc
219*11be35a1SLionel Sambuc /*
220*11be35a1SLionel Sambuc * take an internal snapshot of the filesystem, and create a new
221*11be35a1SLionel Sambuc * file with some data
222*11be35a1SLionel Sambuc */
223*11be35a1SLionel Sambuc rump_sys_chown(".", 0, 0);
224*11be35a1SLionel Sambuc rump_sys_chmod(".", 0777);
225*11be35a1SLionel Sambuc
226*11be35a1SLionel Sambuc for (i =0; testopts && i < strlen(testopts); i++) {
227*11be35a1SLionel Sambuc switch(testopts[i]) {
228*11be35a1SLionel Sambuc case 'L':
229*11be35a1SLionel Sambuc unl++;
230*11be35a1SLionel Sambuc break;
231*11be35a1SLionel Sambuc case 'C':
232*11be35a1SLionel Sambuc unconf++;
233*11be35a1SLionel Sambuc break;
234*11be35a1SLionel Sambuc default:
235*11be35a1SLionel Sambuc errx(1, "test4: unknown option %c", testopts[i]);
236*11be35a1SLionel Sambuc }
237*11be35a1SLionel Sambuc }
238*11be35a1SLionel Sambuc
239*11be35a1SLionel Sambuc /* first create the snapshot */
240*11be35a1SLionel Sambuc
241*11be35a1SLionel Sambuc fd = rump_sys_open(FSTEST_MNTNAME "/le_snap", O_CREAT | O_RDWR, 0777);
242*11be35a1SLionel Sambuc if (fd == -1)
243*11be35a1SLionel Sambuc err(1, "create " FSTEST_MNTNAME "/le_snap");
244*11be35a1SLionel Sambuc rump_sys_close(fd);
245*11be35a1SLionel Sambuc fssfd = rump_sys_open("/dev/rfss0", O_RDWR);
246*11be35a1SLionel Sambuc if (fssfd == -1)
247*11be35a1SLionel Sambuc err(1, "cannot open fss");
248*11be35a1SLionel Sambuc memset(&fss, 0, sizeof(fss));
249*11be35a1SLionel Sambuc fss.fss_mount = __UNCONST("/mnt");
250*11be35a1SLionel Sambuc fss.fss_bstore = __UNCONST(FSTEST_MNTNAME "/le_snap");
251*11be35a1SLionel Sambuc fss.fss_csize = 0;
252*11be35a1SLionel Sambuc if (rump_sys_ioctl(fssfd, FSSIOCSET, &fss) == -1)
253*11be35a1SLionel Sambuc err(1, "create snapshot");
254*11be35a1SLionel Sambuc if (unl) {
255*11be35a1SLionel Sambuc if (rump_sys_unlink(FSTEST_MNTNAME "/le_snap") == -1)
256*11be35a1SLionel Sambuc err(1, "unlink snapshot");
257*11be35a1SLionel Sambuc }
258*11be35a1SLionel Sambuc
259*11be35a1SLionel Sambuc /* now create some extra files */
260*11be35a1SLionel Sambuc
261*11be35a1SLionel Sambuc for (i = 0; i < 4; i++) {
262*11be35a1SLionel Sambuc sprintf(buf, "file%d", i);
263*11be35a1SLionel Sambuc fd = rump_sys_open(buf, O_EXCL| O_CREAT | O_RDWR, 0644);
264*11be35a1SLionel Sambuc if (fd < 0)
265*11be35a1SLionel Sambuc err(1, "create %s", buf);
266*11be35a1SLionel Sambuc sprintf(buf, "test file no %d", i);
267*11be35a1SLionel Sambuc rump_sys_write(fd, buf, strlen(buf));
268*11be35a1SLionel Sambuc rump_sys_close(fd);
269*11be35a1SLionel Sambuc }
270*11be35a1SLionel Sambuc if (unconf)
271*11be35a1SLionel Sambuc if (rump_sys_ioctl(fssfd, FSSIOCCLR, NULL) == -1)
272*11be35a1SLionel Sambuc err(1, "unconfigure snapshot");
273*11be35a1SLionel Sambuc return 0;
274*11be35a1SLionel Sambuc }
275*11be35a1SLionel Sambuc
276*11be35a1SLionel Sambuc static int
quota_test5(const char * testopts)277*11be35a1SLionel Sambuc quota_test5(const char *testopts)
278*11be35a1SLionel Sambuc {
279*11be35a1SLionel Sambuc static char buf[512];
280*11be35a1SLionel Sambuc int fd;
281*11be35a1SLionel Sambuc int remount = 0;
282*11be35a1SLionel Sambuc int unlnk = 0;
283*11be35a1SLionel Sambuc int log = 0;
284*11be35a1SLionel Sambuc unsigned int i;
285*11be35a1SLionel Sambuc
286*11be35a1SLionel Sambuc for (i =0; testopts && i < strlen(testopts); i++) {
287*11be35a1SLionel Sambuc switch(testopts[i]) {
288*11be35a1SLionel Sambuc case 'L':
289*11be35a1SLionel Sambuc log++;
290*11be35a1SLionel Sambuc break;
291*11be35a1SLionel Sambuc case 'R':
292*11be35a1SLionel Sambuc remount++;
293*11be35a1SLionel Sambuc break;
294*11be35a1SLionel Sambuc case 'U':
295*11be35a1SLionel Sambuc unlnk++;
296*11be35a1SLionel Sambuc break;
297*11be35a1SLionel Sambuc default:
298*11be35a1SLionel Sambuc errx(1, "test4: unknown option %c", testopts[i]);
299*11be35a1SLionel Sambuc }
300*11be35a1SLionel Sambuc }
301*11be35a1SLionel Sambuc if (remount) {
302*11be35a1SLionel Sambuc struct ufs_args uargs;
303*11be35a1SLionel Sambuc uargs.fspec = __UNCONST("/diskdev");
304*11be35a1SLionel Sambuc /* remount the fs read/write */
305*11be35a1SLionel Sambuc if (rump_sys_mount(MOUNT_FFS, FSTEST_MNTNAME,
306*11be35a1SLionel Sambuc MNT_UPDATE | (log ? MNT_LOG : 0),
307*11be35a1SLionel Sambuc &uargs, sizeof(uargs)) == -1)
308*11be35a1SLionel Sambuc err(1, "mount ffs rw %s", FSTEST_MNTNAME);
309*11be35a1SLionel Sambuc }
310*11be35a1SLionel Sambuc
311*11be35a1SLionel Sambuc if (unlnk) {
312*11be35a1SLionel Sambuc /*
313*11be35a1SLionel Sambuc * open and unlink a file
314*11be35a1SLionel Sambuc */
315*11be35a1SLionel Sambuc
316*11be35a1SLionel Sambuc fd = rump_sys_open("unlinked_file",
317*11be35a1SLionel Sambuc O_EXCL| O_CREAT | O_RDWR, 0644);
318*11be35a1SLionel Sambuc if (fd < 0)
319*11be35a1SLionel Sambuc err(1, "create %s", "unlinked_file");
320*11be35a1SLionel Sambuc sprintf(buf, "test unlinked_file");
321*11be35a1SLionel Sambuc rump_sys_write(fd, buf, strlen(buf));
322*11be35a1SLionel Sambuc if (rump_sys_unlink("unlinked_file") == -1)
323*11be35a1SLionel Sambuc err(1, "unlink unlinked_file");
324*11be35a1SLionel Sambuc if (rump_sys_fsync(fd) == -1)
325*11be35a1SLionel Sambuc err(1, "fsync unlinked_file");
326*11be35a1SLionel Sambuc rump_sys_reboot(RUMP_RB_NOSYNC, NULL);
327*11be35a1SLionel Sambuc errx(1, "reboot failed");
328*11be35a1SLionel Sambuc return 1;
329*11be35a1SLionel Sambuc }
330*11be35a1SLionel Sambuc return 0;
331*11be35a1SLionel Sambuc }
332*11be35a1SLionel Sambuc
333*11be35a1SLionel Sambuc struct quota_test {
334*11be35a1SLionel Sambuc int (*func)(const char *);
335*11be35a1SLionel Sambuc const char *desc;
336*11be35a1SLionel Sambuc };
337*11be35a1SLionel Sambuc
338*11be35a1SLionel Sambuc struct quota_test quota_tests[] = {
339*11be35a1SLionel Sambuc { quota_test0, "write up to hard limit"},
340*11be35a1SLionel Sambuc { quota_test1, "write beyond the soft limit after grace time"},
341*11be35a1SLionel Sambuc { quota_test2, "create file up to hard limit"},
342*11be35a1SLionel Sambuc { quota_test3, "create file beyond the soft limit after grace time"},
343*11be35a1SLionel Sambuc { quota_test4, "take a snapshot and add some data"},
344*11be35a1SLionel Sambuc { quota_test5, "open and unlink a file"},
345*11be35a1SLionel Sambuc };
346*11be35a1SLionel Sambuc
347*11be35a1SLionel Sambuc static void
usage(void)348*11be35a1SLionel Sambuc usage(void)
349*11be35a1SLionel Sambuc {
350*11be35a1SLionel Sambuc unsigned int test;
351*11be35a1SLionel Sambuc fprintf(stderr, "usage: %s [-b] [-l] test# diskimage bindurl\n",
352*11be35a1SLionel Sambuc getprogname());
353*11be35a1SLionel Sambuc fprintf(stderr, "available tests:\n");
354*11be35a1SLionel Sambuc for (test = 0; test < sizeof(quota_tests) / sizeof(quota_tests[0]);
355*11be35a1SLionel Sambuc test++)
356*11be35a1SLionel Sambuc fprintf(stderr, "\t%d: %s\n", test, quota_tests[test].desc);
357*11be35a1SLionel Sambuc exit(1);
358*11be35a1SLionel Sambuc }
359*11be35a1SLionel Sambuc
360*11be35a1SLionel Sambuc static void
die(const char * reason,int error)361*11be35a1SLionel Sambuc die(const char *reason, int error)
362*11be35a1SLionel Sambuc {
363*11be35a1SLionel Sambuc
364*11be35a1SLionel Sambuc warnx("%s: %s", reason, strerror(error));
365*11be35a1SLionel Sambuc if (background)
366*11be35a1SLionel Sambuc rump_daemonize_done(error);
367*11be35a1SLionel Sambuc exit(1);
368*11be35a1SLionel Sambuc }
369*11be35a1SLionel Sambuc
370*11be35a1SLionel Sambuc static sem_t sigsem;
371*11be35a1SLionel Sambuc static void
sigreboot(int sig)372*11be35a1SLionel Sambuc sigreboot(int sig)
373*11be35a1SLionel Sambuc {
374*11be35a1SLionel Sambuc
375*11be35a1SLionel Sambuc sem_post(&sigsem);
376*11be35a1SLionel Sambuc }
377*11be35a1SLionel Sambuc
378*11be35a1SLionel Sambuc int
main(int argc,char ** argv)379*11be35a1SLionel Sambuc main(int argc, char **argv)
380*11be35a1SLionel Sambuc {
381*11be35a1SLionel Sambuc int error;
382*11be35a1SLionel Sambuc u_long test;
383*11be35a1SLionel Sambuc char *end;
384*11be35a1SLionel Sambuc struct ufs_args uargs;
385*11be35a1SLionel Sambuc const char *filename;
386*11be35a1SLionel Sambuc const char *serverurl;
387*11be35a1SLionel Sambuc const char *topts = NULL;
388*11be35a1SLionel Sambuc int mntopts = 0;
389*11be35a1SLionel Sambuc int ch;
390*11be35a1SLionel Sambuc
391*11be35a1SLionel Sambuc while ((ch = getopt(argc, argv, "blo:r")) != -1) {
392*11be35a1SLionel Sambuc switch(ch) {
393*11be35a1SLionel Sambuc case 'b':
394*11be35a1SLionel Sambuc background = 1;
395*11be35a1SLionel Sambuc break;
396*11be35a1SLionel Sambuc case 'l':
397*11be35a1SLionel Sambuc mntopts |= MNT_LOG;
398*11be35a1SLionel Sambuc break;
399*11be35a1SLionel Sambuc case 'r':
400*11be35a1SLionel Sambuc mntopts |= MNT_RDONLY;
401*11be35a1SLionel Sambuc break;
402*11be35a1SLionel Sambuc case 'o':
403*11be35a1SLionel Sambuc topts = optarg;
404*11be35a1SLionel Sambuc break;
405*11be35a1SLionel Sambuc default:
406*11be35a1SLionel Sambuc usage();
407*11be35a1SLionel Sambuc }
408*11be35a1SLionel Sambuc }
409*11be35a1SLionel Sambuc argc -= optind;
410*11be35a1SLionel Sambuc argv += optind;
411*11be35a1SLionel Sambuc
412*11be35a1SLionel Sambuc if (argc != 3)
413*11be35a1SLionel Sambuc usage();
414*11be35a1SLionel Sambuc
415*11be35a1SLionel Sambuc filename = argv[1];
416*11be35a1SLionel Sambuc serverurl = argv[2];
417*11be35a1SLionel Sambuc
418*11be35a1SLionel Sambuc test = strtoul(argv[0], &end, 10);
419*11be35a1SLionel Sambuc if (*end != '\0') {
420*11be35a1SLionel Sambuc usage();
421*11be35a1SLionel Sambuc }
422*11be35a1SLionel Sambuc if (test > sizeof(quota_tests) / sizeof(quota_tests[0])) {
423*11be35a1SLionel Sambuc usage();
424*11be35a1SLionel Sambuc }
425*11be35a1SLionel Sambuc
426*11be35a1SLionel Sambuc if (background) {
427*11be35a1SLionel Sambuc error = rump_daemonize_begin();
428*11be35a1SLionel Sambuc if (error)
429*11be35a1SLionel Sambuc errx(1, "rump daemonize: %s", strerror(error));
430*11be35a1SLionel Sambuc }
431*11be35a1SLionel Sambuc
432*11be35a1SLionel Sambuc error = rump_init();
433*11be35a1SLionel Sambuc if (error)
434*11be35a1SLionel Sambuc die("rump init failed", error);
435*11be35a1SLionel Sambuc
436*11be35a1SLionel Sambuc if (rump_sys_mkdir(FSTEST_MNTNAME, 0777) == -1)
437*11be35a1SLionel Sambuc err(1, "mount point create");
438*11be35a1SLionel Sambuc rump_pub_etfs_register("/diskdev", filename, RUMP_ETFS_BLK);
439*11be35a1SLionel Sambuc uargs.fspec = __UNCONST("/diskdev");
440*11be35a1SLionel Sambuc if (rump_sys_mount(MOUNT_FFS, FSTEST_MNTNAME, mntopts,
441*11be35a1SLionel Sambuc &uargs, sizeof(uargs)) == -1)
442*11be35a1SLionel Sambuc die("mount ffs", errno);
443*11be35a1SLionel Sambuc
444*11be35a1SLionel Sambuc if (rump_sys_chdir(FSTEST_MNTNAME) == -1)
445*11be35a1SLionel Sambuc err(1, "cd %s", FSTEST_MNTNAME);
446*11be35a1SLionel Sambuc error = quota_tests[test].func(topts);
447*11be35a1SLionel Sambuc if (error) {
448*11be35a1SLionel Sambuc fprintf(stderr, " test %lu: %s returned %d: %s\n",
449*11be35a1SLionel Sambuc test, quota_tests[test].desc, error, strerror(error));
450*11be35a1SLionel Sambuc }
451*11be35a1SLionel Sambuc if (rump_sys_chdir("/") == -1)
452*11be35a1SLionel Sambuc err(1, "cd /");
453*11be35a1SLionel Sambuc
454*11be35a1SLionel Sambuc error = rump_init_server(serverurl);
455*11be35a1SLionel Sambuc if (error)
456*11be35a1SLionel Sambuc die("rump server init failed", error);
457*11be35a1SLionel Sambuc if (background)
458*11be35a1SLionel Sambuc rump_daemonize_done(RUMP_DAEMONIZE_SUCCESS);
459*11be35a1SLionel Sambuc
460*11be35a1SLionel Sambuc sem_init(&sigsem, 0, 0);
461*11be35a1SLionel Sambuc signal(SIGTERM, sigreboot);
462*11be35a1SLionel Sambuc signal(SIGINT, sigreboot);
463*11be35a1SLionel Sambuc sem_wait(&sigsem);
464*11be35a1SLionel Sambuc
465*11be35a1SLionel Sambuc rump_sys_reboot(0, NULL);
466*11be35a1SLionel Sambuc /*NOTREACHED*/
467*11be35a1SLionel Sambuc return 0;
468*11be35a1SLionel Sambuc }
469