xref: /freebsd/contrib/netbsd-tests/fs/puffs/t_basic.c (revision 57718be8fa0bd5edc11ab9a72e68cc71982939a6)
1*57718be8SEnji Cooper /*	$NetBSD: t_basic.c,v 1.12 2013/10/19 17:45:00 christos Exp $	*/
2*57718be8SEnji Cooper 
3*57718be8SEnji Cooper #include <sys/types.h>
4*57718be8SEnji Cooper #include <sys/mount.h>
5*57718be8SEnji Cooper #include <sys/socket.h>
6*57718be8SEnji Cooper 
7*57718be8SEnji Cooper #include <assert.h>
8*57718be8SEnji Cooper #include <atf-c.h>
9*57718be8SEnji Cooper #include <err.h>
10*57718be8SEnji Cooper #include <errno.h>
11*57718be8SEnji Cooper #include <fcntl.h>
12*57718be8SEnji Cooper #include <pthread.h>
13*57718be8SEnji Cooper #include <puffs.h>
14*57718be8SEnji Cooper #include <puffsdump.h>
15*57718be8SEnji Cooper #include <stdio.h>
16*57718be8SEnji Cooper #include <unistd.h>
17*57718be8SEnji Cooper #include <string.h>
18*57718be8SEnji Cooper #include <stdlib.h>
19*57718be8SEnji Cooper 
20*57718be8SEnji Cooper #include <rump/rump.h>
21*57718be8SEnji Cooper #include <rump/rump_syscalls.h>
22*57718be8SEnji Cooper 
23*57718be8SEnji Cooper #include "../../h_macros.h"
24*57718be8SEnji Cooper #include "../common/h_fsmacros.h"
25*57718be8SEnji Cooper 
26*57718be8SEnji Cooper /*
27*57718be8SEnji Cooper  * Do a synchronous operation.  When this returns, all FAF operations
28*57718be8SEnji Cooper  * have at least been delivered to the file system.
29*57718be8SEnji Cooper  *
30*57718be8SEnji Cooper  * XXX: is this really good enough considering puffs(9)-issued
31*57718be8SEnji Cooper  * callback operations?
32*57718be8SEnji Cooper  */
33*57718be8SEnji Cooper static void
34*57718be8SEnji Cooper syncbar(const char *fs)
35*57718be8SEnji Cooper {
36*57718be8SEnji Cooper 	struct statvfs svb;
37*57718be8SEnji Cooper 
38*57718be8SEnji Cooper 	if (rump_sys_statvfs1(fs, &svb, ST_WAIT) == -1)
39*57718be8SEnji Cooper 		atf_tc_fail_errno("statvfs");
40*57718be8SEnji Cooper }
41*57718be8SEnji Cooper 
42*57718be8SEnji Cooper #ifdef PUFFSDUMP
43*57718be8SEnji Cooper static void __unused
44*57718be8SEnji Cooper dumpopcount(struct puffstestargs *args)
45*57718be8SEnji Cooper {
46*57718be8SEnji Cooper 	size_t i;
47*57718be8SEnji Cooper 
48*57718be8SEnji Cooper 	printf("VFS OPS:\n");
49*57718be8SEnji Cooper 	for (i = 0; i < MIN(puffsdump_vfsop_count, PUFFS_VFS_MAX); i++) {
50*57718be8SEnji Cooper 		printf("\t%s: %d\n",
51*57718be8SEnji Cooper 		    puffsdump_vfsop_revmap[i], args->pta_vfs_toserv_ops[i]);
52*57718be8SEnji Cooper 	}
53*57718be8SEnji Cooper 
54*57718be8SEnji Cooper 	printf("VN OPS:\n");
55*57718be8SEnji Cooper 	for (i = 0; i < MIN(puffsdump_vnop_count, PUFFS_VN_MAX); i++) {
56*57718be8SEnji Cooper 		printf("\t%s: %d\n",
57*57718be8SEnji Cooper 		    puffsdump_vnop_revmap[i], args->pta_vn_toserv_ops[i]);
58*57718be8SEnji Cooper 	}
59*57718be8SEnji Cooper }
60*57718be8SEnji Cooper #endif
61*57718be8SEnji Cooper 
62*57718be8SEnji Cooper ATF_TC(mount);
63*57718be8SEnji Cooper ATF_TC_HEAD(mount, tc)
64*57718be8SEnji Cooper {
65*57718be8SEnji Cooper 
66*57718be8SEnji Cooper 	atf_tc_set_md_var(tc, "descr", "puffs+dtfs un/mount test");
67*57718be8SEnji Cooper }
68*57718be8SEnji Cooper 
69*57718be8SEnji Cooper ATF_TC_BODY(mount, tc)
70*57718be8SEnji Cooper {
71*57718be8SEnji Cooper 	void *args;
72*57718be8SEnji Cooper 
73*57718be8SEnji Cooper 	FSTEST_CONSTRUCTOR(tc, puffs, args);
74*57718be8SEnji Cooper 	FSTEST_DESTRUCTOR(tc, puffs, args);
75*57718be8SEnji Cooper }
76*57718be8SEnji Cooper 
77*57718be8SEnji Cooper ATF_TC(root_reg);
78*57718be8SEnji Cooper ATF_TC_HEAD(root_reg, tc)
79*57718be8SEnji Cooper {
80*57718be8SEnji Cooper 	atf_tc_set_md_var(tc, "descr", "root is a regular file");
81*57718be8SEnji Cooper }
82*57718be8SEnji Cooper 
83*57718be8SEnji Cooper #define MAKEOPTS(...) \
84*57718be8SEnji Cooper     char *theopts[] = {NULL, "-s", __VA_ARGS__, "dtfs", "n/a", NULL}
85*57718be8SEnji Cooper 
86*57718be8SEnji Cooper ATF_TC_BODY(root_reg, tc)
87*57718be8SEnji Cooper {
88*57718be8SEnji Cooper 	MAKEOPTS("-r", "reg");
89*57718be8SEnji Cooper 	void *args;
90*57718be8SEnji Cooper 	int fd, rv;
91*57718be8SEnji Cooper 
92*57718be8SEnji Cooper 	FSTEST_CONSTRUCTOR_FSPRIV(tc, puffs, args, theopts);
93*57718be8SEnji Cooper 
94*57718be8SEnji Cooper 	fd = rump_sys_open(FSTEST_MNTNAME, O_RDWR);
95*57718be8SEnji Cooper 	if (fd == -1)
96*57718be8SEnji Cooper 		atf_tc_fail_errno("open root");
97*57718be8SEnji Cooper 	if (rump_sys_write(fd, &fd, sizeof(fd)) != sizeof(fd))
98*57718be8SEnji Cooper 		atf_tc_fail_errno("write to root");
99*57718be8SEnji Cooper 	rv = rump_sys_mkdir(FSTEST_MNTNAME "/test", 0777);
100*57718be8SEnji Cooper 	ATF_REQUIRE(errno == ENOTDIR);
101*57718be8SEnji Cooper 	ATF_REQUIRE(rv == -1);
102*57718be8SEnji Cooper 	rump_sys_close(fd);
103*57718be8SEnji Cooper 
104*57718be8SEnji Cooper 	FSTEST_DESTRUCTOR(tc, puffs, args);
105*57718be8SEnji Cooper }
106*57718be8SEnji Cooper 
107*57718be8SEnji Cooper ATF_TC(root_lnk);
108*57718be8SEnji Cooper ATF_TC_HEAD(root_lnk, tc)
109*57718be8SEnji Cooper {
110*57718be8SEnji Cooper 
111*57718be8SEnji Cooper 	atf_tc_set_md_var(tc, "descr", "root is a symbolic link");
112*57718be8SEnji Cooper }
113*57718be8SEnji Cooper 
114*57718be8SEnji Cooper #define LINKSTR "/path/to/nowhere"
115*57718be8SEnji Cooper ATF_TC_BODY(root_lnk, tc)
116*57718be8SEnji Cooper {
117*57718be8SEnji Cooper 	MAKEOPTS("-r", "lnk " LINKSTR);
118*57718be8SEnji Cooper 	void *args;
119*57718be8SEnji Cooper 	char buf[PATH_MAX];
120*57718be8SEnji Cooper 	ssize_t len;
121*57718be8SEnji Cooper 
122*57718be8SEnji Cooper 	FSTEST_CONSTRUCTOR_FSPRIV(tc, puffs, args, theopts);
123*57718be8SEnji Cooper 
124*57718be8SEnji Cooper 	if ((len = rump_sys_readlink(FSTEST_MNTNAME, buf, sizeof(buf)-1)) == -1)
125*57718be8SEnji Cooper 		atf_tc_fail_errno("readlink");
126*57718be8SEnji Cooper 	buf[len] = '\0';
127*57718be8SEnji Cooper 
128*57718be8SEnji Cooper 	ATF_REQUIRE_STREQ(buf, LINKSTR);
129*57718be8SEnji Cooper 
130*57718be8SEnji Cooper #if 0 /* XXX: unmount uses FOLLOW */
131*57718be8SEnji Cooper 	if (rump_sys_unmount("/mp", 0) == -1)
132*57718be8SEnji Cooper 		atf_tc_fail_errno("unmount");
133*57718be8SEnji Cooper #endif
134*57718be8SEnji Cooper }
135*57718be8SEnji Cooper 
136*57718be8SEnji Cooper ATF_TC(root_fifo);
137*57718be8SEnji Cooper ATF_TC_HEAD(root_fifo, tc)
138*57718be8SEnji Cooper {
139*57718be8SEnji Cooper 
140*57718be8SEnji Cooper 	atf_tc_set_md_var(tc, "descr", "root is a symbolic link");
141*57718be8SEnji Cooper }
142*57718be8SEnji Cooper 
143*57718be8SEnji Cooper #define MAGICSTR "nakit ja muusiperunat maustevoilla"
144*57718be8SEnji Cooper static void *
145*57718be8SEnji Cooper dofifow(void *arg)
146*57718be8SEnji Cooper {
147*57718be8SEnji Cooper 	int fd = (int)(uintptr_t)arg;
148*57718be8SEnji Cooper 	char buf[512];
149*57718be8SEnji Cooper 
150*57718be8SEnji Cooper 	printf("writing\n");
151*57718be8SEnji Cooper 	strcpy(buf, MAGICSTR);
152*57718be8SEnji Cooper 	if (rump_sys_write(fd, buf, strlen(buf)+1) != strlen(buf)+1)
153*57718be8SEnji Cooper 		atf_tc_fail_errno("write to fifo");
154*57718be8SEnji Cooper 
155*57718be8SEnji Cooper 	return NULL;
156*57718be8SEnji Cooper }
157*57718be8SEnji Cooper 
158*57718be8SEnji Cooper ATF_TC_BODY(root_fifo, tc)
159*57718be8SEnji Cooper {
160*57718be8SEnji Cooper 	MAKEOPTS("-r", "fifo");
161*57718be8SEnji Cooper 	void *args;
162*57718be8SEnji Cooper 	pthread_t pt;
163*57718be8SEnji Cooper 	char buf[512];
164*57718be8SEnji Cooper 	int fd;
165*57718be8SEnji Cooper 
166*57718be8SEnji Cooper 	FSTEST_CONSTRUCTOR_FSPRIV(tc, puffs, args, theopts);
167*57718be8SEnji Cooper 
168*57718be8SEnji Cooper 	fd = rump_sys_open(FSTEST_MNTNAME, O_RDWR);
169*57718be8SEnji Cooper 	if (fd == -1)
170*57718be8SEnji Cooper 		atf_tc_fail_errno("open fifo");
171*57718be8SEnji Cooper 
172*57718be8SEnji Cooper 	pthread_create(&pt, NULL, dofifow, (void *)(uintptr_t)fd);
173*57718be8SEnji Cooper 
174*57718be8SEnji Cooper 	memset(buf, 0, sizeof(buf));
175*57718be8SEnji Cooper 	if (rump_sys_read(fd, buf, sizeof(buf)) == -1)
176*57718be8SEnji Cooper 		atf_tc_fail_errno("read fifo");
177*57718be8SEnji Cooper 
178*57718be8SEnji Cooper 	ATF_REQUIRE_STREQ(buf, MAGICSTR);
179*57718be8SEnji Cooper 	rump_sys_close(fd);
180*57718be8SEnji Cooper 
181*57718be8SEnji Cooper 	FSTEST_DESTRUCTOR(tc, puffs, args);
182*57718be8SEnji Cooper }
183*57718be8SEnji Cooper 
184*57718be8SEnji Cooper ATF_TC(root_chrdev);
185*57718be8SEnji Cooper ATF_TC_HEAD(root_chrdev, tc)
186*57718be8SEnji Cooper {
187*57718be8SEnji Cooper 
188*57718be8SEnji Cooper 	atf_tc_set_md_var(tc, "descr", "root is /dev/null");
189*57718be8SEnji Cooper }
190*57718be8SEnji Cooper 
191*57718be8SEnji Cooper ATF_TC_BODY(root_chrdev, tc)
192*57718be8SEnji Cooper {
193*57718be8SEnji Cooper 	MAKEOPTS("-r", "chr 2 2");
194*57718be8SEnji Cooper 	void *args;
195*57718be8SEnji Cooper 	ssize_t rv;
196*57718be8SEnji Cooper 	char buf[512];
197*57718be8SEnji Cooper 	int fd;
198*57718be8SEnji Cooper 
199*57718be8SEnji Cooper 	FSTEST_CONSTRUCTOR_FSPRIV(tc, puffs, args, theopts);
200*57718be8SEnji Cooper 
201*57718be8SEnji Cooper 	fd = rump_sys_open(FSTEST_MNTNAME, O_RDWR);
202*57718be8SEnji Cooper 	if (fd == -1)
203*57718be8SEnji Cooper 		atf_tc_fail_errno("open null");
204*57718be8SEnji Cooper 
205*57718be8SEnji Cooper 	rv = rump_sys_write(fd, buf, sizeof(buf));
206*57718be8SEnji Cooper 	ATF_REQUIRE(rv == sizeof(buf));
207*57718be8SEnji Cooper 
208*57718be8SEnji Cooper 	rv = rump_sys_read(fd, buf, sizeof(buf));
209*57718be8SEnji Cooper 	ATF_REQUIRE(rv == 0);
210*57718be8SEnji Cooper 
211*57718be8SEnji Cooper 	rump_sys_close(fd);
212*57718be8SEnji Cooper 
213*57718be8SEnji Cooper 	FSTEST_DESTRUCTOR(tc, puffs, args);
214*57718be8SEnji Cooper }
215*57718be8SEnji Cooper 
216*57718be8SEnji Cooper /*
217*57718be8SEnji Cooper  * Inactive/reclaim tests
218*57718be8SEnji Cooper  */
219*57718be8SEnji Cooper 
220*57718be8SEnji Cooper ATF_TC(inactive_basic);
221*57718be8SEnji Cooper ATF_TC_HEAD(inactive_basic, tc)
222*57718be8SEnji Cooper {
223*57718be8SEnji Cooper 
224*57718be8SEnji Cooper 	atf_tc_set_md_var(tc, "descr", "inactive gets called");
225*57718be8SEnji Cooper }
226*57718be8SEnji Cooper 
227*57718be8SEnji Cooper ATF_TC_BODY(inactive_basic, tc)
228*57718be8SEnji Cooper {
229*57718be8SEnji Cooper 	struct puffstestargs *pargs;
230*57718be8SEnji Cooper 	void *args;
231*57718be8SEnji Cooper 	int fd;
232*57718be8SEnji Cooper 
233*57718be8SEnji Cooper 	FSTEST_CONSTRUCTOR(tc, puffs, args);
234*57718be8SEnji Cooper 	FSTEST_ENTER();
235*57718be8SEnji Cooper 	pargs = args;
236*57718be8SEnji Cooper 
237*57718be8SEnji Cooper 	fd = rump_sys_open("file", O_CREAT | O_RDWR, 0777);
238*57718be8SEnji Cooper 	if (fd == -1)
239*57718be8SEnji Cooper 		atf_tc_fail_errno("create");
240*57718be8SEnji Cooper 
241*57718be8SEnji Cooper 	/* none yet */
242*57718be8SEnji Cooper 	ATF_REQUIRE_EQ(pargs->pta_vn_toserv_ops[PUFFS_VN_INACTIVE], 0);
243*57718be8SEnji Cooper 
244*57718be8SEnji Cooper 	rump_sys_close(fd);
245*57718be8SEnji Cooper 
246*57718be8SEnji Cooper 	/* one for file */
247*57718be8SEnji Cooper 	ATF_REQUIRE_EQ(pargs->pta_vn_toserv_ops[PUFFS_VN_INACTIVE], 1);
248*57718be8SEnji Cooper 
249*57718be8SEnji Cooper 	FSTEST_EXIT();
250*57718be8SEnji Cooper 
251*57718be8SEnji Cooper 	/* another for the mountpoint */
252*57718be8SEnji Cooper 	ATF_REQUIRE_EQ(pargs->pta_vn_toserv_ops[PUFFS_VN_INACTIVE], 2);
253*57718be8SEnji Cooper 
254*57718be8SEnji Cooper 	FSTEST_DESTRUCTOR(tc, puffs, args);
255*57718be8SEnji Cooper }
256*57718be8SEnji Cooper 
257*57718be8SEnji Cooper ATF_TC(inactive_reclaim);
258*57718be8SEnji Cooper ATF_TC_HEAD(inactive_reclaim, tc)
259*57718be8SEnji Cooper {
260*57718be8SEnji Cooper 
261*57718be8SEnji Cooper 	atf_tc_set_md_var(tc, "descr", "inactive/reclaim gets called");
262*57718be8SEnji Cooper }
263*57718be8SEnji Cooper 
264*57718be8SEnji Cooper ATF_TC_BODY(inactive_reclaim, tc)
265*57718be8SEnji Cooper {
266*57718be8SEnji Cooper 	struct puffstestargs *pargs;
267*57718be8SEnji Cooper 	void *args;
268*57718be8SEnji Cooper 	int fd;
269*57718be8SEnji Cooper 
270*57718be8SEnji Cooper 	FSTEST_CONSTRUCTOR(tc, puffs, args);
271*57718be8SEnji Cooper 	FSTEST_ENTER();
272*57718be8SEnji Cooper 	pargs = args;
273*57718be8SEnji Cooper 
274*57718be8SEnji Cooper 	fd = rump_sys_open("file", O_CREAT | O_RDWR, 0777);
275*57718be8SEnji Cooper 	if (fd == -1)
276*57718be8SEnji Cooper 		atf_tc_fail_errno("create");
277*57718be8SEnji Cooper 
278*57718be8SEnji Cooper 	ATF_REQUIRE_EQ(pargs->pta_vn_toserv_ops[PUFFS_VN_INACTIVE], 0);
279*57718be8SEnji Cooper 
280*57718be8SEnji Cooper 	if (rump_sys_unlink("file") == -1)
281*57718be8SEnji Cooper 		atf_tc_fail_errno("remove");
282*57718be8SEnji Cooper 
283*57718be8SEnji Cooper 	ATF_REQUIRE_EQ(pargs->pta_vn_toserv_ops[PUFFS_VN_INACTIVE], 0);
284*57718be8SEnji Cooper 	ATF_REQUIRE_EQ(pargs->pta_vn_toserv_ops[PUFFS_VN_RECLAIM], 0);
285*57718be8SEnji Cooper 
286*57718be8SEnji Cooper 	rump_sys_close(fd);
287*57718be8SEnji Cooper 	syncbar(FSTEST_MNTNAME);
288*57718be8SEnji Cooper 
289*57718be8SEnji Cooper 	ATF_REQUIRE_EQ(pargs->pta_vn_toserv_ops[PUFFS_VN_INACTIVE], 1);
290*57718be8SEnji Cooper 	ATF_REQUIRE_EQ(pargs->pta_vn_toserv_ops[PUFFS_VN_RECLAIM], 1);
291*57718be8SEnji Cooper 
292*57718be8SEnji Cooper 	FSTEST_EXIT();
293*57718be8SEnji Cooper 	FSTEST_DESTRUCTOR(tc, puffs, args);
294*57718be8SEnji Cooper }
295*57718be8SEnji Cooper 
296*57718be8SEnji Cooper ATF_TC(reclaim_hardlink);
297*57718be8SEnji Cooper ATF_TC_HEAD(reclaim_hardlink, tc)
298*57718be8SEnji Cooper {
299*57718be8SEnji Cooper 
300*57718be8SEnji Cooper 	atf_tc_set_md_var(tc, "descr", "reclaim gets called only after "
301*57718be8SEnji Cooper 	    "final link is gone");
302*57718be8SEnji Cooper }
303*57718be8SEnji Cooper 
304*57718be8SEnji Cooper ATF_TC_BODY(reclaim_hardlink, tc)
305*57718be8SEnji Cooper {
306*57718be8SEnji Cooper 	struct puffstestargs *pargs;
307*57718be8SEnji Cooper 	void *args;
308*57718be8SEnji Cooper 	int fd;
309*57718be8SEnji Cooper 	int ianow;
310*57718be8SEnji Cooper 
311*57718be8SEnji Cooper 	FSTEST_CONSTRUCTOR(tc, puffs, args);
312*57718be8SEnji Cooper 	FSTEST_ENTER();
313*57718be8SEnji Cooper 	pargs = args;
314*57718be8SEnji Cooper 
315*57718be8SEnji Cooper 	fd = rump_sys_open("file", O_CREAT | O_RDWR, 0777);
316*57718be8SEnji Cooper 	if (fd == -1)
317*57718be8SEnji Cooper 		atf_tc_fail_errno("create");
318*57718be8SEnji Cooper 
319*57718be8SEnji Cooper 	if (rump_sys_link("file", "anotherfile") == -1)
320*57718be8SEnji Cooper 		atf_tc_fail_errno("create link");
321*57718be8SEnji Cooper 	rump_sys_close(fd);
322*57718be8SEnji Cooper 
323*57718be8SEnji Cooper 	ATF_REQUIRE_EQ(pargs->pta_vn_toserv_ops[PUFFS_VN_RECLAIM], 0);
324*57718be8SEnji Cooper 
325*57718be8SEnji Cooper 	/* unlink first hardlink */
326*57718be8SEnji Cooper 	if (rump_sys_unlink("file") == -1)
327*57718be8SEnji Cooper 		atf_tc_fail_errno("unlink 1");
328*57718be8SEnji Cooper 
329*57718be8SEnji Cooper 	ATF_REQUIRE_EQ(pargs->pta_vn_toserv_ops[PUFFS_VN_RECLAIM], 0);
330*57718be8SEnji Cooper 	ianow = pargs->pta_vn_toserv_ops[PUFFS_VN_INACTIVE];
331*57718be8SEnji Cooper 
332*57718be8SEnji Cooper 	/* unlink second hardlink */
333*57718be8SEnji Cooper 	if (rump_sys_unlink("anotherfile") == -1)
334*57718be8SEnji Cooper 		atf_tc_fail_errno("unlink 2");
335*57718be8SEnji Cooper 
336*57718be8SEnji Cooper 	syncbar(FSTEST_MNTNAME);
337*57718be8SEnji Cooper 
338*57718be8SEnji Cooper 	ATF_REQUIRE(ianow < pargs->pta_vn_toserv_ops[PUFFS_VN_INACTIVE]);
339*57718be8SEnji Cooper 	ATF_REQUIRE_EQ(pargs->pta_vn_toserv_ops[PUFFS_VN_RECLAIM], 1);
340*57718be8SEnji Cooper 
341*57718be8SEnji Cooper 	FSTEST_EXIT();
342*57718be8SEnji Cooper 	FSTEST_DESTRUCTOR(tc, puffs, args);
343*57718be8SEnji Cooper }
344*57718be8SEnji Cooper 
345*57718be8SEnji Cooper ATF_TC(unlink_accessible);
346*57718be8SEnji Cooper ATF_TC_HEAD(unlink_accessible, tc)
347*57718be8SEnji Cooper {
348*57718be8SEnji Cooper 
349*57718be8SEnji Cooper 	atf_tc_set_md_var(tc, "descr", "open file is accessible after "
350*57718be8SEnji Cooper 	    "having been unlinked");
351*57718be8SEnji Cooper }
352*57718be8SEnji Cooper 
353*57718be8SEnji Cooper ATF_TC_BODY(unlink_accessible, tc)
354*57718be8SEnji Cooper {
355*57718be8SEnji Cooper 	MAKEOPTS("-i", "-o", "nopagecache");
356*57718be8SEnji Cooper 	struct puffstestargs *pargs;
357*57718be8SEnji Cooper 	void *args;
358*57718be8SEnji Cooper 	char buf[512];
359*57718be8SEnji Cooper 	int fd, ianow;
360*57718be8SEnji Cooper 
361*57718be8SEnji Cooper 	assert(sizeof(buf) > sizeof(MAGICSTR));
362*57718be8SEnji Cooper 
363*57718be8SEnji Cooper 	FSTEST_CONSTRUCTOR_FSPRIV(tc, puffs, args, theopts);
364*57718be8SEnji Cooper 	FSTEST_ENTER();
365*57718be8SEnji Cooper 	pargs = args;
366*57718be8SEnji Cooper 
367*57718be8SEnji Cooper 	fd = rump_sys_open("file", O_CREAT | O_RDWR, 0777);
368*57718be8SEnji Cooper 	if (fd == -1)
369*57718be8SEnji Cooper 		atf_tc_fail_errno("create");
370*57718be8SEnji Cooper 
371*57718be8SEnji Cooper 	if (rump_sys_write(fd, MAGICSTR, sizeof(MAGICSTR)) != sizeof(MAGICSTR))
372*57718be8SEnji Cooper 		atf_tc_fail_errno("write");
373*57718be8SEnji Cooper 	if (rump_sys_unlink("file") == -1)
374*57718be8SEnji Cooper 		atf_tc_fail_errno("unlink");
375*57718be8SEnji Cooper 
376*57718be8SEnji Cooper 	ATF_REQUIRE_EQ(pargs->pta_vn_toserv_ops[PUFFS_VN_RECLAIM], 0);
377*57718be8SEnji Cooper 	ianow = pargs->pta_vn_toserv_ops[PUFFS_VN_INACTIVE];
378*57718be8SEnji Cooper 
379*57718be8SEnji Cooper 	if (rump_sys_pread(fd, buf, sizeof(buf), 0) == -1)
380*57718be8SEnji Cooper 		atf_tc_fail_errno("read");
381*57718be8SEnji Cooper 	rump_sys_close(fd);
382*57718be8SEnji Cooper 
383*57718be8SEnji Cooper 	syncbar(FSTEST_MNTNAME);
384*57718be8SEnji Cooper 
385*57718be8SEnji Cooper 	ATF_REQUIRE_EQ(pargs->pta_vn_toserv_ops[PUFFS_VN_RECLAIM], 1);
386*57718be8SEnji Cooper 	ATF_REQUIRE_EQ(pargs->pta_vn_toserv_ops[PUFFS_VN_INACTIVE], ianow+1);
387*57718be8SEnji Cooper 
388*57718be8SEnji Cooper 	ATF_REQUIRE_STREQ(buf, MAGICSTR);
389*57718be8SEnji Cooper 
390*57718be8SEnji Cooper 	FSTEST_EXIT();
391*57718be8SEnji Cooper 	FSTEST_DESTRUCTOR(tc, puffs, args);
392*57718be8SEnji Cooper }
393*57718be8SEnji Cooper 
394*57718be8SEnji Cooper ATF_TC(signals);
395*57718be8SEnji Cooper ATF_TC_HEAD(signals, tc)
396*57718be8SEnji Cooper {
397*57718be8SEnji Cooper 
398*57718be8SEnji Cooper 	atf_tc_set_md_var(tc, "descr", "Checks that sending a signal can "
399*57718be8SEnji Cooper 	    "cause an interrupt to puffs wait");
400*57718be8SEnji Cooper }
401*57718be8SEnji Cooper 
402*57718be8SEnji Cooper extern struct proc *rumpns_initproc;
403*57718be8SEnji Cooper extern void rumpns_psignal(struct proc *, int);
404*57718be8SEnji Cooper extern void rumpns_sigclearall(struct proc *, void *, void *);
405*57718be8SEnji Cooper ATF_TC_BODY(signals, tc)
406*57718be8SEnji Cooper {
407*57718be8SEnji Cooper 	struct stat sb;
408*57718be8SEnji Cooper 	void *args;
409*57718be8SEnji Cooper 
410*57718be8SEnji Cooper 	rump_boot_setsigmodel(RUMP_SIGMODEL_RECORD);
411*57718be8SEnji Cooper 
412*57718be8SEnji Cooper 	FSTEST_CONSTRUCTOR(tc, puffs, args);
413*57718be8SEnji Cooper 	FSTEST_ENTER();
414*57718be8SEnji Cooper 	RL(rump_sys_stat(".", &sb));
415*57718be8SEnji Cooper 
416*57718be8SEnji Cooper 	/* send SIGUSR1, should not affect puffs ops */
417*57718be8SEnji Cooper 	rump_schedule();
418*57718be8SEnji Cooper 	rumpns_psignal(rumpns_initproc, SIGUSR1);
419*57718be8SEnji Cooper 	rump_unschedule();
420*57718be8SEnji Cooper 	RL(rump_sys_stat(".", &sb));
421*57718be8SEnji Cooper 
422*57718be8SEnji Cooper 	/* send SIGTERM, should get EINTR */
423*57718be8SEnji Cooper 	rump_schedule();
424*57718be8SEnji Cooper 	rumpns_psignal(rumpns_initproc, SIGTERM);
425*57718be8SEnji Cooper 	rump_unschedule();
426*57718be8SEnji Cooper 	ATF_REQUIRE_ERRNO(EINTR, rump_sys_stat(".", &sb) == -1);
427*57718be8SEnji Cooper 
428*57718be8SEnji Cooper 	/* clear sigmask so that we can unmount */
429*57718be8SEnji Cooper 	rump_schedule();
430*57718be8SEnji Cooper 	rumpns_sigclearall(rumpns_initproc, NULL, NULL);
431*57718be8SEnji Cooper 	rump_unschedule();
432*57718be8SEnji Cooper 
433*57718be8SEnji Cooper 	FSTEST_EXIT();
434*57718be8SEnji Cooper 	FSTEST_DESTRUCTOR(tc, puffs, args);
435*57718be8SEnji Cooper }
436*57718be8SEnji Cooper 
437*57718be8SEnji Cooper ATF_TP_ADD_TCS(tp)
438*57718be8SEnji Cooper {
439*57718be8SEnji Cooper 
440*57718be8SEnji Cooper 	ATF_TP_ADD_TC(tp, mount);
441*57718be8SEnji Cooper 
442*57718be8SEnji Cooper 	ATF_TP_ADD_TC(tp, root_fifo);
443*57718be8SEnji Cooper 	ATF_TP_ADD_TC(tp, root_lnk);
444*57718be8SEnji Cooper 	ATF_TP_ADD_TC(tp, root_reg);
445*57718be8SEnji Cooper 	ATF_TP_ADD_TC(tp, root_chrdev);
446*57718be8SEnji Cooper 
447*57718be8SEnji Cooper 	ATF_TP_ADD_TC(tp, inactive_basic);
448*57718be8SEnji Cooper 	ATF_TP_ADD_TC(tp, inactive_reclaim);
449*57718be8SEnji Cooper 	ATF_TP_ADD_TC(tp, reclaim_hardlink);
450*57718be8SEnji Cooper 	ATF_TP_ADD_TC(tp, unlink_accessible);
451*57718be8SEnji Cooper 
452*57718be8SEnji Cooper 	ATF_TP_ADD_TC(tp, signals);
453*57718be8SEnji Cooper 
454*57718be8SEnji Cooper 	return atf_no_error();
455*57718be8SEnji Cooper }
456