Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/tests/fs Add the most basic test for puffs(dtfs): mount/unmo...
details: https://anonhg.NetBSD.org/src/rev/fe77f3261458
branches: trunk
changeset: 756086:fe77f3261458
user: pooka <pooka%NetBSD.org@localhost>
date: Tue Jul 06 14:44:29 2010 +0000
description:
Add the most basic test for puffs(dtfs): mount/unmount. There's
still a lot of work to do here, but I want to get to testbuilding
the tree ;)
TODO examples:
* integrate this with rump_syspuffs (and remove the stupid ``sys'' from there)
* integrate with njoly's fs-independent tests
* cleanup a lot
* write more tests
*sigh*, I wish we'd had testing tools like this 5 years ago when
I was writing puffs. It would have made a lot of things a lot
better and a lot easier.
diffstat:
tests/fs/Makefile | 5 +-
tests/fs/puffs/Makefile | 16 ++
tests/fs/puffs/t_basic.c | 281 +++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 300 insertions(+), 2 deletions(-)
diffs (truncated from 322 to 300 lines):
diff -r ce1331edd7a8 -r fe77f3261458 tests/fs/Makefile
--- a/tests/fs/Makefile Tue Jul 06 14:16:44 2010 +0000
+++ b/tests/fs/Makefile Tue Jul 06 14:44:29 2010 +0000
@@ -1,10 +1,11 @@
-# $NetBSD: Makefile,v 1.13 2010/07/06 14:06:21 pooka Exp $
+# $NetBSD: Makefile,v 1.14 2010/07/06 14:44:29 pooka Exp $
.include <bsd.own.mk>
TESTSDIR= ${TESTSBASE}/fs
-SUBDIR+= ffs kernfs lfs msdosfs nullfs psshfs ptyfs tmpfs umapfs union
+SUBDIR+= ffs kernfs lfs msdosfs nullfs psshfs ptyfs puffs
+SUBDIR+= tmpfs umapfs union
SUBDIR+= vfs
FILES= h_funcs.subr
diff -r ce1331edd7a8 -r fe77f3261458 tests/fs/puffs/Makefile
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/fs/puffs/Makefile Tue Jul 06 14:44:29 2010 +0000
@@ -0,0 +1,16 @@
+# $NetBSD: Makefile,v 1.4 2010/07/06 14:44:30 pooka Exp $
+#
+
+.include <bsd.own.mk>
+
+SUBDIR+= h_dtfs
+
+TESTSDIR= ${TESTSBASE}/fs/puffs
+
+TESTS_C= t_basic
+
+LDADD+= -lrumpdev_putter -lrumpdev
+LDADD+= -lrumpfs_syspuffs -lrumpvfs -lrump -lrumpuser -lpthread
+
+.include <bsd.test.mk>
+.include <bsd.subdir.mk>
diff -r ce1331edd7a8 -r fe77f3261458 tests/fs/puffs/t_basic.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/fs/puffs/t_basic.c Tue Jul 06 14:44:29 2010 +0000
@@ -0,0 +1,281 @@
+/* $NetBSD: t_basic.c,v 1.1 2010/07/06 14:44:30 pooka Exp $ */
+
+#include <sys/types.h>
+#include <sys/mount.h>
+#include <sys/socket.h>
+
+#include <assert.h>
+#include <atf-c.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <puffs.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <rump/rump.h>
+#include <rump/rump_syscalls.h>
+
+#include "../../h_macros.h"
+
+struct puffs_args {
+ uint8_t *us_pargs;
+ size_t us_pargslen;
+
+ int us_pflags;
+ int us_servfd;
+ pid_t us_childpid;
+};
+
+#define BUFSIZE (64*1024)
+
+struct thefds {
+ int rumpfd;
+ int servfd;
+};
+
+/*
+ * Threads which shovel data between comfd and /dev/puffs.
+ * (cannot use polling since fd's are in different namespaces)
+ */
+static void *
+readshovel(void *arg)
+{
+ struct thefds *fds = arg;
+ char buf[BUFSIZE];
+ ssize_t n;
+ int error, comfd, puffsfd;
+
+ comfd = fds->servfd;
+ puffsfd = fds->rumpfd;
+
+ /* use static thread id */
+ rump_pub_lwp_alloc_and_switch(0, 0);
+
+ for (;;) {
+ ssize_t n, n2;
+
+ n = rump_sys_read(puffsfd, buf, BUFSIZE);
+ 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;
+ }
+ }
+
+ return NULL;
+}
+
+static void *
+writeshovel(void *arg)
+{
+ struct thefds *fds = arg;
+ struct putter_hdr *phdr;
+ char buf[BUFSIZE];
+ size_t toread;
+ int error, comfd, puffsfd;
+
+ /* use static thread id */
+ rump_pub_lwp_alloc_and_switch(0, 0);
+
+ comfd = fds->servfd;
+ puffsfd = fds->rumpfd;
+
+ phdr = (struct putter_hdr *)buf;
+
+ for (;;) {
+ off_t off;
+ ssize_t n;
+
+ /*
+ * Need to write everything to the "kernel" in one chunk,
+ * so make sure we have it here.
+ */
+ off = 0;
+ toread = sizeof(struct putter_hdr);
+ do {
+ n = read(comfd, buf+off, toread);
+ if (n <= 0) {
+ break;
+ }
+ off += n;
+ if (off >= sizeof(struct putter_hdr))
+ toread = phdr->pth_framelen - off;
+ else
+ toread = off - sizeof(struct putter_hdr);
+ } while (toread);
+
+ n = rump_sys_write(puffsfd, buf, phdr->pth_framelen);
+ if (n != phdr->pth_framelen)
+ goto out;
+ }
+
+ out:
+ return NULL;
+}
+
+static void
+rumpshovels(int rumpfd, int servfd)
+{
+ struct thefds *fds;
+ pthread_t pt;
+ int rv;
+
+ if ((rv = rump_init()) == -1)
+ err(1, "rump_init");
+
+ fds = malloc(sizeof(*fds));
+ fds->rumpfd = rumpfd;
+ fds->servfd = servfd;
+ if (pthread_create(&pt, NULL, readshovel, fds) == -1)
+ err(1, "read shovel");
+ pthread_detach(pt);
+ if (pthread_create(&pt, NULL, writeshovel, fds) == -1)
+ err(1, "write shovel");
+ pthread_detach(pt);
+}
+
+static int
+parseargs(int argc, char *argv[],
+ struct puffs_args *args, int *mntflags,
+ char *canon_dev, char *canon_dir)
+{
+ pid_t childpid;
+ pthread_t pt;
+ int *pflags = &args->us_pflags;
+ char comfd[16];
+ int sv[2];
+ size_t len;
+ ssize_t n;
+ int rv;
+
+ if (argc < 2)
+ errx(1, "invalid usage");
+
+ /* Create sucketpair for communication with the real file server */
+ if (socketpair(PF_LOCAL, SOCK_STREAM, 0, sv) == -1)
+ err(1, "socketpair");
+
+ switch ((childpid = fork())) {
+ case 0:
+ close(sv[1]);
+ snprintf(comfd, sizeof(sv[0]), "%d", sv[0]);
+ if (setenv("PUFFS_COMFD", comfd, 1) == -1)
+ err(1, "setenv");
+
+ argv++;
+ if (execvp(argv[0], argv) == -1)
+ err(1, "execvp here");
+ /*NOTREACHED*/
+ case -1:
+ err(1, "fork");
+ /*NOTREACHED*/
+ default:
+ close(sv[0]);
+ break;
+ }
+
+ /* read args */
+ if ((n = read(sv[1], &len, sizeof(len))) != sizeof(len))
+ err(1, "mp 1 %zd", n);
+ if (len > MAXPATHLEN)
+ err(1, "mntpath > MAXPATHLEN");
+ if ((size_t)read(sv[1], canon_dir, len) != len)
+ err(1, "mp 2");
+ if (read(sv[1], &len, sizeof(len)) != sizeof(len))
+ err(1, "fn 1");
+ if (len > MAXPATHLEN)
+ err(1, "devpath > MAXPATHLEN");
+ if ((size_t)read(sv[1], canon_dev, len) != len)
+ err(1, "fn 2");
+ if (read(sv[1], mntflags, sizeof(*mntflags)) != sizeof(*mntflags))
+ err(1, "mntflags");
+ if (read(sv[1], &args->us_pargslen, sizeof(args->us_pargslen)) != sizeof(args->us_pargslen))
+ err(1, "puffs_args len");
+ args->us_pargs = malloc(args->us_pargslen);
+ if (args->us_pargs == NULL)
+ err(1, "malloc");
+ if (read(sv[1], args->us_pargs, args->us_pargslen) != args->us_pargslen)
+ err(1, "puffs_args");
+ if (read(sv[1], pflags, sizeof(*pflags)) != sizeof(*pflags))
+ err(1, "pflags");
+
+ args->us_childpid = childpid;
+ args->us_servfd = sv[1];
+
+ return 0;
+}
+
+ATF_TC(mount);
+ATF_TC_HEAD(mount, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "puffs+dtfs un/mount test");
+}
+
+char *dtfsargv[] = {
+ "dtfs",
+ "BUILT_AT_RUNTIME",
+ "dtfs",
+ "/mp",
+ NULL
+};
+
+ATF_TC_BODY(mount, tc)
+{
+ char canon_dev[MAXPATHLEN], canon_dir[MAXPATHLEN];
+ char dtfs_path[MAXPATHLEN];
+ struct puffs_args pargs;
+ int mntflag;
+ int rv;
+ int fd;
+
+ /* build dtfs exec path for atf */
+ sprintf(dtfs_path, "%s/h_dtfs/h_dtfs",
+ atf_tc_get_config_var(tc, "srcdir"));
+ dtfsargv[1] = dtfs_path;
+
+ rump_init();
+
+ rv = parseargs(__arraycount(dtfsargv), dtfsargv,
+ &pargs, &mntflag, canon_dev, canon_dir);
+ if (rv)
+ atf_tc_fail("comfd parseargs");
+
+ fd = rump_sys_open("/dev/puffs", O_RDWR);
+ if (fd == -1)
+ atf_tc_fail_errno("open puffs fd");
+#if 0
+ pargs->pa_fd = fd;
+#else
Home |
Main Index |
Thread Index |
Old Index