xref: /freebsd/contrib/netbsd-tests/fs/puffs/t_basic.c (revision 1a36faad54665288ed4eb839d2a4699ae2ead45e)
1*63d1fd59SEnji Cooper /*	$NetBSD: t_basic.c,v 1.14 2017/01/13 21:30:40 christos Exp $	*/
257718be8SEnji Cooper 
357718be8SEnji Cooper #include <sys/types.h>
457718be8SEnji Cooper #include <sys/mount.h>
557718be8SEnji Cooper #include <sys/socket.h>
657718be8SEnji Cooper 
757718be8SEnji Cooper #include <assert.h>
857718be8SEnji Cooper #include <atf-c.h>
957718be8SEnji Cooper #include <err.h>
1057718be8SEnji Cooper #include <errno.h>
1157718be8SEnji Cooper #include <fcntl.h>
1257718be8SEnji Cooper #include <pthread.h>
1357718be8SEnji Cooper #include <puffs.h>
1457718be8SEnji Cooper #include <puffsdump.h>
1557718be8SEnji Cooper #include <stdio.h>
1657718be8SEnji Cooper #include <unistd.h>
1757718be8SEnji Cooper #include <string.h>
1857718be8SEnji Cooper #include <stdlib.h>
1957718be8SEnji Cooper 
2057718be8SEnji Cooper #include <rump/rump.h>
2157718be8SEnji Cooper #include <rump/rump_syscalls.h>
2257718be8SEnji Cooper 
23*63d1fd59SEnji Cooper #include "h_macros.h"
2457718be8SEnji Cooper #include "../common/h_fsmacros.h"
2557718be8SEnji Cooper 
2657718be8SEnji Cooper /*
2757718be8SEnji Cooper  * Do a synchronous operation.  When this returns, all FAF operations
2857718be8SEnji Cooper  * have at least been delivered to the file system.
2957718be8SEnji Cooper  *
3057718be8SEnji Cooper  * XXX: is this really good enough considering puffs(9)-issued
3157718be8SEnji Cooper  * callback operations?
3257718be8SEnji Cooper  */
3357718be8SEnji Cooper static void
syncbar(const char * fs)3457718be8SEnji Cooper syncbar(const char *fs)
3557718be8SEnji Cooper {
3657718be8SEnji Cooper 	struct statvfs svb;
3757718be8SEnji Cooper 
3857718be8SEnji Cooper 	if (rump_sys_statvfs1(fs, &svb, ST_WAIT) == -1)
3957718be8SEnji Cooper 		atf_tc_fail_errno("statvfs");
4057718be8SEnji Cooper }
4157718be8SEnji Cooper 
4257718be8SEnji Cooper #ifdef PUFFSDUMP
4357718be8SEnji Cooper static void __unused
dumpopcount(struct puffstestargs * args)4457718be8SEnji Cooper dumpopcount(struct puffstestargs *args)
4557718be8SEnji Cooper {
4657718be8SEnji Cooper 	size_t i;
4757718be8SEnji Cooper 
4857718be8SEnji Cooper 	printf("VFS OPS:\n");
4957718be8SEnji Cooper 	for (i = 0; i < MIN(puffsdump_vfsop_count, PUFFS_VFS_MAX); i++) {
5057718be8SEnji Cooper 		printf("\t%s: %d\n",
5157718be8SEnji Cooper 		    puffsdump_vfsop_revmap[i], args->pta_vfs_toserv_ops[i]);
5257718be8SEnji Cooper 	}
5357718be8SEnji Cooper 
5457718be8SEnji Cooper 	printf("VN OPS:\n");
5557718be8SEnji Cooper 	for (i = 0; i < MIN(puffsdump_vnop_count, PUFFS_VN_MAX); i++) {
5657718be8SEnji Cooper 		printf("\t%s: %d\n",
5757718be8SEnji Cooper 		    puffsdump_vnop_revmap[i], args->pta_vn_toserv_ops[i]);
5857718be8SEnji Cooper 	}
5957718be8SEnji Cooper }
6057718be8SEnji Cooper #endif
6157718be8SEnji Cooper 
6257718be8SEnji Cooper ATF_TC(mount);
ATF_TC_HEAD(mount,tc)6357718be8SEnji Cooper ATF_TC_HEAD(mount, tc)
6457718be8SEnji Cooper {
6557718be8SEnji Cooper 
6657718be8SEnji Cooper 	atf_tc_set_md_var(tc, "descr", "puffs+dtfs un/mount test");
6757718be8SEnji Cooper }
6857718be8SEnji Cooper 
ATF_TC_BODY(mount,tc)6957718be8SEnji Cooper ATF_TC_BODY(mount, tc)
7057718be8SEnji Cooper {
7157718be8SEnji Cooper 	void *args;
7257718be8SEnji Cooper 
7357718be8SEnji Cooper 	FSTEST_CONSTRUCTOR(tc, puffs, args);
7457718be8SEnji Cooper 	FSTEST_DESTRUCTOR(tc, puffs, args);
7557718be8SEnji Cooper }
7657718be8SEnji Cooper 
7757718be8SEnji Cooper ATF_TC(root_reg);
ATF_TC_HEAD(root_reg,tc)7857718be8SEnji Cooper ATF_TC_HEAD(root_reg, tc)
7957718be8SEnji Cooper {
8057718be8SEnji Cooper 	atf_tc_set_md_var(tc, "descr", "root is a regular file");
8157718be8SEnji Cooper }
8257718be8SEnji Cooper 
8357718be8SEnji Cooper #define MAKEOPTS(...) \
8457718be8SEnji Cooper     char *theopts[] = {NULL, "-s", __VA_ARGS__, "dtfs", "n/a", NULL}
8557718be8SEnji Cooper 
ATF_TC_BODY(root_reg,tc)8657718be8SEnji Cooper ATF_TC_BODY(root_reg, tc)
8757718be8SEnji Cooper {
8857718be8SEnji Cooper 	MAKEOPTS("-r", "reg");
8957718be8SEnji Cooper 	void *args;
9057718be8SEnji Cooper 	int fd, rv;
9157718be8SEnji Cooper 
9257718be8SEnji Cooper 	FSTEST_CONSTRUCTOR_FSPRIV(tc, puffs, args, theopts);
9357718be8SEnji Cooper 
9457718be8SEnji Cooper 	fd = rump_sys_open(FSTEST_MNTNAME, O_RDWR);
9557718be8SEnji Cooper 	if (fd == -1)
9657718be8SEnji Cooper 		atf_tc_fail_errno("open root");
9757718be8SEnji Cooper 	if (rump_sys_write(fd, &fd, sizeof(fd)) != sizeof(fd))
9857718be8SEnji Cooper 		atf_tc_fail_errno("write to root");
9957718be8SEnji Cooper 	rv = rump_sys_mkdir(FSTEST_MNTNAME "/test", 0777);
10057718be8SEnji Cooper 	ATF_REQUIRE(errno == ENOTDIR);
10157718be8SEnji Cooper 	ATF_REQUIRE(rv == -1);
10257718be8SEnji Cooper 	rump_sys_close(fd);
10357718be8SEnji Cooper 
10457718be8SEnji Cooper 	FSTEST_DESTRUCTOR(tc, puffs, args);
10557718be8SEnji Cooper }
10657718be8SEnji Cooper 
10757718be8SEnji Cooper ATF_TC(root_lnk);
ATF_TC_HEAD(root_lnk,tc)10857718be8SEnji Cooper ATF_TC_HEAD(root_lnk, tc)
10957718be8SEnji Cooper {
11057718be8SEnji Cooper 
11157718be8SEnji Cooper 	atf_tc_set_md_var(tc, "descr", "root is a symbolic link");
11257718be8SEnji Cooper }
11357718be8SEnji Cooper 
11457718be8SEnji Cooper #define LINKSTR "/path/to/nowhere"
ATF_TC_BODY(root_lnk,tc)11557718be8SEnji Cooper ATF_TC_BODY(root_lnk, tc)
11657718be8SEnji Cooper {
11757718be8SEnji Cooper 	MAKEOPTS("-r", "lnk " LINKSTR);
11857718be8SEnji Cooper 	void *args;
11957718be8SEnji Cooper 	char buf[PATH_MAX];
12057718be8SEnji Cooper 	ssize_t len;
12157718be8SEnji Cooper 
12257718be8SEnji Cooper 	FSTEST_CONSTRUCTOR_FSPRIV(tc, puffs, args, theopts);
12357718be8SEnji Cooper 
12457718be8SEnji Cooper 	if ((len = rump_sys_readlink(FSTEST_MNTNAME, buf, sizeof(buf)-1)) == -1)
12557718be8SEnji Cooper 		atf_tc_fail_errno("readlink");
12657718be8SEnji Cooper 	buf[len] = '\0';
12757718be8SEnji Cooper 
12857718be8SEnji Cooper 	ATF_REQUIRE_STREQ(buf, LINKSTR);
12957718be8SEnji Cooper 
13057718be8SEnji Cooper #if 0 /* XXX: unmount uses FOLLOW */
13157718be8SEnji Cooper 	if (rump_sys_unmount("/mp", 0) == -1)
13257718be8SEnji Cooper 		atf_tc_fail_errno("unmount");
13357718be8SEnji Cooper #endif
13457718be8SEnji Cooper }
13557718be8SEnji Cooper 
13657718be8SEnji Cooper ATF_TC(root_fifo);
ATF_TC_HEAD(root_fifo,tc)13757718be8SEnji Cooper ATF_TC_HEAD(root_fifo, tc)
13857718be8SEnji Cooper {
13957718be8SEnji Cooper 
14057718be8SEnji Cooper 	atf_tc_set_md_var(tc, "descr", "root is a symbolic link");
14157718be8SEnji Cooper }
14257718be8SEnji Cooper 
14357718be8SEnji Cooper #define MAGICSTR "nakit ja muusiperunat maustevoilla"
14457718be8SEnji Cooper static void *
dofifow(void * arg)14557718be8SEnji Cooper dofifow(void *arg)
14657718be8SEnji Cooper {
14757718be8SEnji Cooper 	int fd = (int)(uintptr_t)arg;
14857718be8SEnji Cooper 	char buf[512];
14957718be8SEnji Cooper 
15057718be8SEnji Cooper 	printf("writing\n");
15157718be8SEnji Cooper 	strcpy(buf, MAGICSTR);
15257718be8SEnji Cooper 	if (rump_sys_write(fd, buf, strlen(buf)+1) != strlen(buf)+1)
15357718be8SEnji Cooper 		atf_tc_fail_errno("write to fifo");
15457718be8SEnji Cooper 
15557718be8SEnji Cooper 	return NULL;
15657718be8SEnji Cooper }
15757718be8SEnji Cooper 
ATF_TC_BODY(root_fifo,tc)15857718be8SEnji Cooper ATF_TC_BODY(root_fifo, tc)
15957718be8SEnji Cooper {
16057718be8SEnji Cooper 	MAKEOPTS("-r", "fifo");
16157718be8SEnji Cooper 	void *args;
16257718be8SEnji Cooper 	pthread_t pt;
16357718be8SEnji Cooper 	char buf[512];
16457718be8SEnji Cooper 	int fd;
16557718be8SEnji Cooper 
16657718be8SEnji Cooper 	FSTEST_CONSTRUCTOR_FSPRIV(tc, puffs, args, theopts);
16757718be8SEnji Cooper 
16857718be8SEnji Cooper 	fd = rump_sys_open(FSTEST_MNTNAME, O_RDWR);
16957718be8SEnji Cooper 	if (fd == -1)
17057718be8SEnji Cooper 		atf_tc_fail_errno("open fifo");
17157718be8SEnji Cooper 
17257718be8SEnji Cooper 	pthread_create(&pt, NULL, dofifow, (void *)(uintptr_t)fd);
17357718be8SEnji Cooper 
17457718be8SEnji Cooper 	memset(buf, 0, sizeof(buf));
17557718be8SEnji Cooper 	if (rump_sys_read(fd, buf, sizeof(buf)) == -1)
17657718be8SEnji Cooper 		atf_tc_fail_errno("read fifo");
17757718be8SEnji Cooper 
17857718be8SEnji Cooper 	ATF_REQUIRE_STREQ(buf, MAGICSTR);
17957718be8SEnji Cooper 	rump_sys_close(fd);
18057718be8SEnji Cooper 
18157718be8SEnji Cooper 	FSTEST_DESTRUCTOR(tc, puffs, args);
18257718be8SEnji Cooper }
18357718be8SEnji Cooper 
18457718be8SEnji Cooper ATF_TC(root_chrdev);
ATF_TC_HEAD(root_chrdev,tc)18557718be8SEnji Cooper ATF_TC_HEAD(root_chrdev, tc)
18657718be8SEnji Cooper {
18757718be8SEnji Cooper 
18857718be8SEnji Cooper 	atf_tc_set_md_var(tc, "descr", "root is /dev/null");
18957718be8SEnji Cooper }
19057718be8SEnji Cooper 
ATF_TC_BODY(root_chrdev,tc)19157718be8SEnji Cooper ATF_TC_BODY(root_chrdev, tc)
19257718be8SEnji Cooper {
19357718be8SEnji Cooper 	MAKEOPTS("-r", "chr 2 2");
19457718be8SEnji Cooper 	void *args;
19557718be8SEnji Cooper 	ssize_t rv;
19657718be8SEnji Cooper 	char buf[512];
19757718be8SEnji Cooper 	int fd;
19857718be8SEnji Cooper 
19957718be8SEnji Cooper 	FSTEST_CONSTRUCTOR_FSPRIV(tc, puffs, args, theopts);
20057718be8SEnji Cooper 
20157718be8SEnji Cooper 	fd = rump_sys_open(FSTEST_MNTNAME, O_RDWR);
20257718be8SEnji Cooper 	if (fd == -1)
20357718be8SEnji Cooper 		atf_tc_fail_errno("open null");
20457718be8SEnji Cooper 
20557718be8SEnji Cooper 	rv = rump_sys_write(fd, buf, sizeof(buf));
20657718be8SEnji Cooper 	ATF_REQUIRE(rv == sizeof(buf));
20757718be8SEnji Cooper 
20857718be8SEnji Cooper 	rv = rump_sys_read(fd, buf, sizeof(buf));
20957718be8SEnji Cooper 	ATF_REQUIRE(rv == 0);
21057718be8SEnji Cooper 
21157718be8SEnji Cooper 	rump_sys_close(fd);
21257718be8SEnji Cooper 
21357718be8SEnji Cooper 	FSTEST_DESTRUCTOR(tc, puffs, args);
21457718be8SEnji Cooper }
21557718be8SEnji Cooper 
21657718be8SEnji Cooper /*
21757718be8SEnji Cooper  * Inactive/reclaim tests
21857718be8SEnji Cooper  */
21957718be8SEnji Cooper 
22057718be8SEnji Cooper ATF_TC(inactive_basic);
ATF_TC_HEAD(inactive_basic,tc)22157718be8SEnji Cooper ATF_TC_HEAD(inactive_basic, tc)
22257718be8SEnji Cooper {
22357718be8SEnji Cooper 
22457718be8SEnji Cooper 	atf_tc_set_md_var(tc, "descr", "inactive gets called");
22557718be8SEnji Cooper }
22657718be8SEnji Cooper 
ATF_TC_BODY(inactive_basic,tc)22757718be8SEnji Cooper ATF_TC_BODY(inactive_basic, tc)
22857718be8SEnji Cooper {
22957718be8SEnji Cooper 	struct puffstestargs *pargs;
23057718be8SEnji Cooper 	void *args;
23157718be8SEnji Cooper 	int fd;
23257718be8SEnji Cooper 
23357718be8SEnji Cooper 	FSTEST_CONSTRUCTOR(tc, puffs, args);
23457718be8SEnji Cooper 	FSTEST_ENTER();
23557718be8SEnji Cooper 	pargs = args;
23657718be8SEnji Cooper 
23757718be8SEnji Cooper 	fd = rump_sys_open("file", O_CREAT | O_RDWR, 0777);
23857718be8SEnji Cooper 	if (fd == -1)
23957718be8SEnji Cooper 		atf_tc_fail_errno("create");
24057718be8SEnji Cooper 
24157718be8SEnji Cooper 	/* none yet */
24257718be8SEnji Cooper 	ATF_REQUIRE_EQ(pargs->pta_vn_toserv_ops[PUFFS_VN_INACTIVE], 0);
24357718be8SEnji Cooper 
24457718be8SEnji Cooper 	rump_sys_close(fd);
24557718be8SEnji Cooper 
24657718be8SEnji Cooper 	/* one for file */
24757718be8SEnji Cooper 	ATF_REQUIRE_EQ(pargs->pta_vn_toserv_ops[PUFFS_VN_INACTIVE], 1);
24857718be8SEnji Cooper 
24957718be8SEnji Cooper 	FSTEST_EXIT();
25057718be8SEnji Cooper 
25157718be8SEnji Cooper 	/* another for the mountpoint */
25257718be8SEnji Cooper 	ATF_REQUIRE_EQ(pargs->pta_vn_toserv_ops[PUFFS_VN_INACTIVE], 2);
25357718be8SEnji Cooper 
25457718be8SEnji Cooper 	FSTEST_DESTRUCTOR(tc, puffs, args);
25557718be8SEnji Cooper }
25657718be8SEnji Cooper 
25757718be8SEnji Cooper ATF_TC(inactive_reclaim);
ATF_TC_HEAD(inactive_reclaim,tc)25857718be8SEnji Cooper ATF_TC_HEAD(inactive_reclaim, tc)
25957718be8SEnji Cooper {
26057718be8SEnji Cooper 
26157718be8SEnji Cooper 	atf_tc_set_md_var(tc, "descr", "inactive/reclaim gets called");
26257718be8SEnji Cooper }
26357718be8SEnji Cooper 
ATF_TC_BODY(inactive_reclaim,tc)26457718be8SEnji Cooper ATF_TC_BODY(inactive_reclaim, tc)
26557718be8SEnji Cooper {
26657718be8SEnji Cooper 	struct puffstestargs *pargs;
26757718be8SEnji Cooper 	void *args;
26857718be8SEnji Cooper 	int fd;
26957718be8SEnji Cooper 
27057718be8SEnji Cooper 	FSTEST_CONSTRUCTOR(tc, puffs, args);
27157718be8SEnji Cooper 	FSTEST_ENTER();
27257718be8SEnji Cooper 	pargs = args;
27357718be8SEnji Cooper 
27457718be8SEnji Cooper 	fd = rump_sys_open("file", O_CREAT | O_RDWR, 0777);
27557718be8SEnji Cooper 	if (fd == -1)
27657718be8SEnji Cooper 		atf_tc_fail_errno("create");
27757718be8SEnji Cooper 
27857718be8SEnji Cooper 	ATF_REQUIRE_EQ(pargs->pta_vn_toserv_ops[PUFFS_VN_INACTIVE], 0);
27957718be8SEnji Cooper 
28057718be8SEnji Cooper 	if (rump_sys_unlink("file") == -1)
28157718be8SEnji Cooper 		atf_tc_fail_errno("remove");
28257718be8SEnji Cooper 
28357718be8SEnji Cooper 	ATF_REQUIRE_EQ(pargs->pta_vn_toserv_ops[PUFFS_VN_INACTIVE], 0);
28457718be8SEnji Cooper 	ATF_REQUIRE_EQ(pargs->pta_vn_toserv_ops[PUFFS_VN_RECLAIM], 0);
28557718be8SEnji Cooper 
28657718be8SEnji Cooper 	rump_sys_close(fd);
28757718be8SEnji Cooper 	syncbar(FSTEST_MNTNAME);
28857718be8SEnji Cooper 
289cdebaff8SEnji Cooper 	ATF_REQUIRE(pargs->pta_vn_toserv_ops[PUFFS_VN_INACTIVE] > 0);
29057718be8SEnji Cooper 	ATF_REQUIRE_EQ(pargs->pta_vn_toserv_ops[PUFFS_VN_RECLAIM], 1);
29157718be8SEnji Cooper 
29257718be8SEnji Cooper 	FSTEST_EXIT();
29357718be8SEnji Cooper 	FSTEST_DESTRUCTOR(tc, puffs, args);
29457718be8SEnji Cooper }
29557718be8SEnji Cooper 
29657718be8SEnji Cooper ATF_TC(reclaim_hardlink);
ATF_TC_HEAD(reclaim_hardlink,tc)29757718be8SEnji Cooper ATF_TC_HEAD(reclaim_hardlink, tc)
29857718be8SEnji Cooper {
29957718be8SEnji Cooper 
30057718be8SEnji Cooper 	atf_tc_set_md_var(tc, "descr", "reclaim gets called only after "
30157718be8SEnji Cooper 	    "final link is gone");
30257718be8SEnji Cooper }
30357718be8SEnji Cooper 
ATF_TC_BODY(reclaim_hardlink,tc)30457718be8SEnji Cooper ATF_TC_BODY(reclaim_hardlink, tc)
30557718be8SEnji Cooper {
30657718be8SEnji Cooper 	struct puffstestargs *pargs;
30757718be8SEnji Cooper 	void *args;
30857718be8SEnji Cooper 	int fd;
30957718be8SEnji Cooper 	int ianow;
31057718be8SEnji Cooper 
31157718be8SEnji Cooper 	FSTEST_CONSTRUCTOR(tc, puffs, args);
31257718be8SEnji Cooper 	FSTEST_ENTER();
31357718be8SEnji Cooper 	pargs = args;
31457718be8SEnji Cooper 
31557718be8SEnji Cooper 	fd = rump_sys_open("file", O_CREAT | O_RDWR, 0777);
31657718be8SEnji Cooper 	if (fd == -1)
31757718be8SEnji Cooper 		atf_tc_fail_errno("create");
31857718be8SEnji Cooper 
31957718be8SEnji Cooper 	if (rump_sys_link("file", "anotherfile") == -1)
32057718be8SEnji Cooper 		atf_tc_fail_errno("create link");
32157718be8SEnji Cooper 	rump_sys_close(fd);
32257718be8SEnji Cooper 
32357718be8SEnji Cooper 	ATF_REQUIRE_EQ(pargs->pta_vn_toserv_ops[PUFFS_VN_RECLAIM], 0);
32457718be8SEnji Cooper 
32557718be8SEnji Cooper 	/* unlink first hardlink */
32657718be8SEnji Cooper 	if (rump_sys_unlink("file") == -1)
32757718be8SEnji Cooper 		atf_tc_fail_errno("unlink 1");
32857718be8SEnji Cooper 
32957718be8SEnji Cooper 	ATF_REQUIRE_EQ(pargs->pta_vn_toserv_ops[PUFFS_VN_RECLAIM], 0);
33057718be8SEnji Cooper 	ianow = pargs->pta_vn_toserv_ops[PUFFS_VN_INACTIVE];
33157718be8SEnji Cooper 
33257718be8SEnji Cooper 	/* unlink second hardlink */
33357718be8SEnji Cooper 	if (rump_sys_unlink("anotherfile") == -1)
33457718be8SEnji Cooper 		atf_tc_fail_errno("unlink 2");
33557718be8SEnji Cooper 
33657718be8SEnji Cooper 	syncbar(FSTEST_MNTNAME);
33757718be8SEnji Cooper 
33857718be8SEnji Cooper 	ATF_REQUIRE(ianow < pargs->pta_vn_toserv_ops[PUFFS_VN_INACTIVE]);
33957718be8SEnji Cooper 	ATF_REQUIRE_EQ(pargs->pta_vn_toserv_ops[PUFFS_VN_RECLAIM], 1);
34057718be8SEnji Cooper 
34157718be8SEnji Cooper 	FSTEST_EXIT();
34257718be8SEnji Cooper 	FSTEST_DESTRUCTOR(tc, puffs, args);
34357718be8SEnji Cooper }
34457718be8SEnji Cooper 
34557718be8SEnji Cooper ATF_TC(unlink_accessible);
ATF_TC_HEAD(unlink_accessible,tc)34657718be8SEnji Cooper ATF_TC_HEAD(unlink_accessible, tc)
34757718be8SEnji Cooper {
34857718be8SEnji Cooper 
34957718be8SEnji Cooper 	atf_tc_set_md_var(tc, "descr", "open file is accessible after "
35057718be8SEnji Cooper 	    "having been unlinked");
35157718be8SEnji Cooper }
35257718be8SEnji Cooper 
ATF_TC_BODY(unlink_accessible,tc)35357718be8SEnji Cooper ATF_TC_BODY(unlink_accessible, tc)
35457718be8SEnji Cooper {
35557718be8SEnji Cooper 	MAKEOPTS("-i", "-o", "nopagecache");
35657718be8SEnji Cooper 	struct puffstestargs *pargs;
35757718be8SEnji Cooper 	void *args;
35857718be8SEnji Cooper 	char buf[512];
35957718be8SEnji Cooper 	int fd, ianow;
36057718be8SEnji Cooper 
36157718be8SEnji Cooper 	assert(sizeof(buf) > sizeof(MAGICSTR));
36257718be8SEnji Cooper 
36357718be8SEnji Cooper 	FSTEST_CONSTRUCTOR_FSPRIV(tc, puffs, args, theopts);
36457718be8SEnji Cooper 	FSTEST_ENTER();
36557718be8SEnji Cooper 	pargs = args;
36657718be8SEnji Cooper 
36757718be8SEnji Cooper 	fd = rump_sys_open("file", O_CREAT | O_RDWR, 0777);
36857718be8SEnji Cooper 	if (fd == -1)
36957718be8SEnji Cooper 		atf_tc_fail_errno("create");
37057718be8SEnji Cooper 
37157718be8SEnji Cooper 	if (rump_sys_write(fd, MAGICSTR, sizeof(MAGICSTR)) != sizeof(MAGICSTR))
37257718be8SEnji Cooper 		atf_tc_fail_errno("write");
37357718be8SEnji Cooper 	if (rump_sys_unlink("file") == -1)
37457718be8SEnji Cooper 		atf_tc_fail_errno("unlink");
37557718be8SEnji Cooper 
37657718be8SEnji Cooper 	ATF_REQUIRE_EQ(pargs->pta_vn_toserv_ops[PUFFS_VN_RECLAIM], 0);
37757718be8SEnji Cooper 	ianow = pargs->pta_vn_toserv_ops[PUFFS_VN_INACTIVE];
37857718be8SEnji Cooper 
37957718be8SEnji Cooper 	if (rump_sys_pread(fd, buf, sizeof(buf), 0) == -1)
38057718be8SEnji Cooper 		atf_tc_fail_errno("read");
38157718be8SEnji Cooper 	rump_sys_close(fd);
38257718be8SEnji Cooper 
38357718be8SEnji Cooper 	syncbar(FSTEST_MNTNAME);
38457718be8SEnji Cooper 
38557718be8SEnji Cooper 	ATF_REQUIRE_EQ(pargs->pta_vn_toserv_ops[PUFFS_VN_RECLAIM], 1);
386cdebaff8SEnji Cooper 	ATF_REQUIRE(pargs->pta_vn_toserv_ops[PUFFS_VN_INACTIVE] > ianow);
38757718be8SEnji Cooper 
38857718be8SEnji Cooper 	ATF_REQUIRE_STREQ(buf, MAGICSTR);
38957718be8SEnji Cooper 
39057718be8SEnji Cooper 	FSTEST_EXIT();
39157718be8SEnji Cooper 	FSTEST_DESTRUCTOR(tc, puffs, args);
39257718be8SEnji Cooper }
39357718be8SEnji Cooper 
39457718be8SEnji Cooper ATF_TC(signals);
ATF_TC_HEAD(signals,tc)39557718be8SEnji Cooper ATF_TC_HEAD(signals, tc)
39657718be8SEnji Cooper {
39757718be8SEnji Cooper 
39857718be8SEnji Cooper 	atf_tc_set_md_var(tc, "descr", "Checks that sending a signal can "
39957718be8SEnji Cooper 	    "cause an interrupt to puffs wait");
40057718be8SEnji Cooper }
40157718be8SEnji Cooper 
40257718be8SEnji Cooper extern struct proc *rumpns_initproc;
40357718be8SEnji Cooper extern void rumpns_psignal(struct proc *, int);
40457718be8SEnji Cooper extern void rumpns_sigclearall(struct proc *, void *, void *);
ATF_TC_BODY(signals,tc)40557718be8SEnji Cooper ATF_TC_BODY(signals, tc)
40657718be8SEnji Cooper {
40757718be8SEnji Cooper 	struct stat sb;
40857718be8SEnji Cooper 	void *args;
40957718be8SEnji Cooper 
41057718be8SEnji Cooper 	rump_boot_setsigmodel(RUMP_SIGMODEL_RECORD);
41157718be8SEnji Cooper 
41257718be8SEnji Cooper 	FSTEST_CONSTRUCTOR(tc, puffs, args);
41357718be8SEnji Cooper 	FSTEST_ENTER();
41457718be8SEnji Cooper 	RL(rump_sys_stat(".", &sb));
41557718be8SEnji Cooper 
41657718be8SEnji Cooper 	/* send SIGUSR1, should not affect puffs ops */
41757718be8SEnji Cooper 	rump_schedule();
41857718be8SEnji Cooper 	rumpns_psignal(rumpns_initproc, SIGUSR1);
41957718be8SEnji Cooper 	rump_unschedule();
42057718be8SEnji Cooper 	RL(rump_sys_stat(".", &sb));
42157718be8SEnji Cooper 
42257718be8SEnji Cooper 	/* send SIGTERM, should get EINTR */
42357718be8SEnji Cooper 	rump_schedule();
42457718be8SEnji Cooper 	rumpns_psignal(rumpns_initproc, SIGTERM);
42557718be8SEnji Cooper 	rump_unschedule();
42657718be8SEnji Cooper 	ATF_REQUIRE_ERRNO(EINTR, rump_sys_stat(".", &sb) == -1);
42757718be8SEnji Cooper 
42857718be8SEnji Cooper 	/* clear sigmask so that we can unmount */
42957718be8SEnji Cooper 	rump_schedule();
43057718be8SEnji Cooper 	rumpns_sigclearall(rumpns_initproc, NULL, NULL);
43157718be8SEnji Cooper 	rump_unschedule();
43257718be8SEnji Cooper 
43357718be8SEnji Cooper 	FSTEST_EXIT();
43457718be8SEnji Cooper 	FSTEST_DESTRUCTOR(tc, puffs, args);
43557718be8SEnji Cooper }
43657718be8SEnji Cooper 
ATF_TP_ADD_TCS(tp)43757718be8SEnji Cooper ATF_TP_ADD_TCS(tp)
43857718be8SEnji Cooper {
43957718be8SEnji Cooper 
44057718be8SEnji Cooper 	ATF_TP_ADD_TC(tp, mount);
44157718be8SEnji Cooper 
44257718be8SEnji Cooper 	ATF_TP_ADD_TC(tp, root_fifo);
44357718be8SEnji Cooper 	ATF_TP_ADD_TC(tp, root_lnk);
44457718be8SEnji Cooper 	ATF_TP_ADD_TC(tp, root_reg);
44557718be8SEnji Cooper 	ATF_TP_ADD_TC(tp, root_chrdev);
44657718be8SEnji Cooper 
44757718be8SEnji Cooper 	ATF_TP_ADD_TC(tp, inactive_basic);
44857718be8SEnji Cooper 	ATF_TP_ADD_TC(tp, inactive_reclaim);
44957718be8SEnji Cooper 	ATF_TP_ADD_TC(tp, reclaim_hardlink);
45057718be8SEnji Cooper 	ATF_TP_ADD_TC(tp, unlink_accessible);
45157718be8SEnji Cooper 
45257718be8SEnji Cooper 	ATF_TP_ADD_TC(tp, signals);
45357718be8SEnji Cooper 
45457718be8SEnji Cooper 	return atf_no_error();
45557718be8SEnji Cooper }
456