Module Name: src Committed By: pooka Date: Sun Jul 11 12:26:19 UTC 2010
Modified Files: src/tests/fs/puffs: Makefile t_basic.c Log Message: Add some basic tests for inactive/reclaim. To make this possible, adjust the read/write shovel threads so, that we can tap into the operations between puffs(9) and the file server. To generate a diff of this commit: cvs rdiff -u -r1.5 -r1.6 src/tests/fs/puffs/Makefile cvs rdiff -u -r1.3 -r1.4 src/tests/fs/puffs/t_basic.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/tests/fs/puffs/Makefile diff -u src/tests/fs/puffs/Makefile:1.5 src/tests/fs/puffs/Makefile:1.6 --- src/tests/fs/puffs/Makefile:1.5 Wed Jul 7 10:49:51 2010 +++ src/tests/fs/puffs/Makefile Sun Jul 11 12:26:19 2010 @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.5 2010/07/07 10:49:51 pooka Exp $ +# $NetBSD: Makefile,v 1.6 2010/07/11 12:26:19 pooka Exp $ # .include <bsd.own.mk> @@ -14,6 +14,7 @@ LDADD+= -lrumpnet_local -lrumpnet_net -lrumpnet LDADD+= -lrumpvfs LDADD+= -lrump -lrumpuser -lpthread +LDADD+= -lpuffs -lutil .include <bsd.test.mk> .include <bsd.subdir.mk> Index: src/tests/fs/puffs/t_basic.c diff -u src/tests/fs/puffs/t_basic.c:1.3 src/tests/fs/puffs/t_basic.c:1.4 --- src/tests/fs/puffs/t_basic.c:1.3 Wed Jul 7 10:49:51 2010 +++ src/tests/fs/puffs/t_basic.c Sun Jul 11 12:26:19 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: t_basic.c,v 1.3 2010/07/07 10:49:51 pooka Exp $ */ +/* $NetBSD: t_basic.c,v 1.4 2010/07/11 12:26:19 pooka Exp $ */ #include <sys/types.h> #include <sys/mount.h> @@ -11,6 +11,7 @@ #include <fcntl.h> #include <pthread.h> #include <puffs.h> +#include <puffsdump.h> #include <stdio.h> #include <unistd.h> #include <string.h> @@ -31,12 +32,49 @@ }; #define BUFSIZE (64*1024) +#define DTFS_DUMP "-o","dump" struct thefds { int rumpfd; int servfd; }; +int vfs_toserv_ops[PUFFS_VFS_MAX]; +int vn_toserv_ops[PUFFS_VN_MAX]; + +/* + * Do a synchronous operation. When this returns, all FAF operations + * have at least been delivered to the file system. + * + * XXX: is this really good enough considering puffs(9)-issued + * callback operations? + */ +static void +syncbar(const char *fs) +{ + struct statvfs svb; + + rump_sys_statvfs1(fs, &svb, ST_WAIT); +} + +static void +dumpopcount(void) +{ + size_t i; + + printf("VFS OPS:\n"); + for (i = 0; i < MIN(puffsdump_vfsop_count, PUFFS_VFS_MAX); i++) { + printf("\t%s: %d\n", + puffsdump_vfsop_revmap[i], vfs_toserv_ops[i]); + } + + printf("VN OPS:\n"); + for (i = 0; i < MIN(puffsdump_vnop_count, PUFFS_VN_MAX); i++) { + printf("\t%s: %d\n", + puffsdump_vnop_revmap[i], vn_toserv_ops[i]); + } +} + /* * Threads which shovel data between comfd and /dev/puffs. * (cannot use polling since fd's are in different namespaces) @@ -44,6 +82,8 @@ static void * readshovel(void *arg) { + struct putter_hdr *phdr; + struct puffs_req *preq; struct thefds *fds = arg; char buf[BUFSIZE]; ssize_t n; @@ -52,25 +92,37 @@ comfd = fds->servfd; puffsfd = fds->rumpfd; + phdr = (void *)buf; + preq = (void *)buf; + /* use static thread id */ - rump_pub_lwp_alloc_and_switch(0, 0); + rump_pub_lwp_alloc_and_switch(0, 10); for (;;) { ssize_t n, n2; - n = rump_sys_read(puffsfd, buf, BUFSIZE); - if (n <= 0) { + n = rump_sys_read(puffsfd, buf, sizeof(*phdr)); + if (n <= 0) break; - } - while (n) { - n2 = write(comfd, buf, n); - if (n2 == -1) - err(1, "readshovel failed write: %d"); - if (n2 == 0) - break; - n -= n2; + assert(phdr->pth_framelen < BUFSIZE); + n = rump_sys_read(puffsfd, buf+sizeof(*phdr), + phdr->pth_framelen - sizeof(*phdr)); + if (n <= 0) + break; + + /* Analyze request */ + if (PUFFSOP_OPCLASS(preq->preq_opclass) == PUFFSOP_VFS) { + assert(preq->preq_optype < PUFFS_VFS_MAX); + vfs_toserv_ops[preq->preq_optype]++; + } else if (PUFFSOP_OPCLASS(preq->preq_opclass) == PUFFSOP_VN) { + assert(preq->preq_optype < PUFFS_VN_MAX); + vn_toserv_ops[preq->preq_optype]++; } + + n = phdr->pth_framelen; + if (write(comfd, buf, n) != n) + break; } return NULL; @@ -86,7 +138,7 @@ int error, comfd, puffsfd; /* use static thread id */ - rump_pub_lwp_alloc_and_switch(0, 0); + rump_pub_lwp_alloc_and_switch(0, 11); comfd = fds->servfd; puffsfd = fds->rumpfd; @@ -103,6 +155,7 @@ */ off = 0; toread = sizeof(struct putter_hdr); + assert(toread < BUFSIZE); do { n = read(comfd, buf+off, toread); if (n <= 0) { @@ -117,10 +170,9 @@ n = rump_sys_write(puffsfd, buf, phdr->pth_framelen); if (n != phdr->pth_framelen) - goto out; + break; } - out: return NULL; } @@ -438,6 +490,179 @@ atf_tc_fail_errno("unmount"); } +/* + * Inactive/reclaim tests + */ + +ATF_TC(inactive_basic); +ATF_TC_HEAD(inactive_basic, tc) +{ + + atf_tc_set_md_var(tc, "descr", "inactive gets called"); +} + +ATF_TC_BODY(inactive_basic, tc) +{ + char *myopts[] = { + "-i", + "dtfs", + }; + int fd; + + dtfsmountv("/mp", myopts); + fd = rump_sys_open("/mp/file", O_CREAT | O_RDWR, 0777); + if (fd == -1) + atf_tc_fail_errno("create"); + + /* one for /mp */ + ATF_REQUIRE_EQ(vn_toserv_ops[PUFFS_VN_INACTIVE], 1); + + rump_sys_close(fd); + + /* one for /mp/file */ + ATF_REQUIRE_EQ(vn_toserv_ops[PUFFS_VN_INACTIVE], 2); + + if (rump_sys_unmount("/mp", 0) == -1) + atf_tc_fail_errno("unmount"); + + /* one for /mp again */ + ATF_REQUIRE_EQ(vn_toserv_ops[PUFFS_VN_INACTIVE], 3); +} + +ATF_TC(inactive_reclaim); +ATF_TC_HEAD(inactive_reclaim, tc) +{ + + atf_tc_set_md_var(tc, "descr", "inactive/reclaim gets called"); +} + +ATF_TC_BODY(inactive_reclaim, tc) +{ + char *myopts[] = { + "-i", + "dtfs", + }; + int fd; + + dtfsmountv("/mp", myopts); + fd = rump_sys_open("/mp/file", O_CREAT | O_RDWR, 0777); + if (fd == -1) + atf_tc_fail_errno("create"); + + ATF_REQUIRE_EQ(vn_toserv_ops[PUFFS_VN_INACTIVE], 1); + + if (rump_sys_unlink("/mp/file") == -1) + atf_tc_fail_errno("remove"); + + ATF_REQUIRE_EQ(vn_toserv_ops[PUFFS_VN_INACTIVE], 2); + ATF_REQUIRE_EQ(vn_toserv_ops[PUFFS_VN_RECLAIM], 0); + + rump_sys_close(fd); + syncbar("/mp"); + + ATF_REQUIRE_EQ(vn_toserv_ops[PUFFS_VN_INACTIVE], 4); + ATF_REQUIRE_EQ(vn_toserv_ops[PUFFS_VN_RECLAIM], 1); + + if (rump_sys_unmount("/mp", 0) == -1) + atf_tc_fail_errno("unmount"); +} + +ATF_TC(reclaim_hardlink); +ATF_TC_HEAD(reclaim_hardlink, tc) +{ + + atf_tc_set_md_var(tc, "descr", "reclaim gets called only after " + "final link is gone"); +} + +ATF_TC_BODY(reclaim_hardlink, tc) +{ + char *myopts[] = { + "-i", + "dtfs", + }; + int fd; + int ianow; + + dtfsmountv("/mp", myopts); + fd = rump_sys_open("/mp/file", O_CREAT | O_RDWR, 0777); + if (fd == -1) + atf_tc_fail_errno("create"); + + if (rump_sys_link("/mp/file", "/mp/anotherfile") == -1) + atf_tc_fail_errno("create link"); + rump_sys_close(fd); + + ATF_REQUIRE_EQ(vn_toserv_ops[PUFFS_VN_RECLAIM], 0); + + /* unlink first hardlink */ + if (rump_sys_unlink("/mp/file") == -1) + atf_tc_fail_errno("unlink 1"); + + ATF_REQUIRE_EQ(vn_toserv_ops[PUFFS_VN_RECLAIM], 0); + ianow = vn_toserv_ops[PUFFS_VN_INACTIVE]; + + /* unlink second hardlink */ + if (rump_sys_unlink("/mp/anotherfile") == -1) + atf_tc_fail_errno("unlink 2"); + + syncbar("/mp"); + + ATF_REQUIRE(ianow < vn_toserv_ops[PUFFS_VN_INACTIVE]); + ATF_REQUIRE_EQ(vn_toserv_ops[PUFFS_VN_RECLAIM], 1); + + if (rump_sys_unmount("/mp", 0) == -1) + atf_tc_fail_errno("unmount"); +} + +ATF_TC(unlink_accessible); +ATF_TC_HEAD(unlink_accessible, tc) +{ + + atf_tc_set_md_var(tc, "descr", "open file is accessible after " + "having been unlinked"); +} + +ATF_TC_BODY(unlink_accessible, tc) +{ + char *myopts[] = { + "-i", + "-o","nopagecache", + "dtfs", + }; + char buf[512]; + int fd, ianow; + + assert(sizeof(buf) > sizeof(MAGICSTR)); + + dtfsmountv("/mp", myopts); + fd = rump_sys_open("/mp/file", O_CREAT | O_RDWR, 0777); + if (fd == -1) + atf_tc_fail_errno("create"); + + if (rump_sys_write(fd, MAGICSTR, sizeof(MAGICSTR)) != sizeof(MAGICSTR)) + atf_tc_fail_errno("write"); + if (rump_sys_unlink("/mp/file") == -1) + atf_tc_fail_errno("unlink"); + + ATF_REQUIRE_EQ(vn_toserv_ops[PUFFS_VN_RECLAIM], 0); + ianow = vn_toserv_ops[PUFFS_VN_INACTIVE]; + + if (rump_sys_pread(fd, buf, sizeof(buf), 0) == -1) + atf_tc_fail_errno("read"); + rump_sys_close(fd); + + syncbar("/mp"); + + ATF_REQUIRE_EQ(vn_toserv_ops[PUFFS_VN_RECLAIM], 1); + ATF_REQUIRE_EQ(vn_toserv_ops[PUFFS_VN_INACTIVE], ianow+2); + + ATF_REQUIRE_STREQ(buf, MAGICSTR); + + if (rump_sys_unmount("/mp", 0) == -1) + atf_tc_fail_errno("unmount"); +} + ATF_TP_ADD_TCS(tp) { @@ -448,5 +673,10 @@ ATF_TP_ADD_TC(tp, root_reg); ATF_TP_ADD_TC(tp, root_chrdev); + ATF_TP_ADD_TC(tp, inactive_basic); + ATF_TP_ADD_TC(tp, inactive_reclaim); + ATF_TP_ADD_TC(tp, reclaim_hardlink); + ATF_TP_ADD_TC(tp, unlink_accessible); + return atf_no_error(); }