Home | History | Annotate | Line # | Download | only in common
fstest_puffs.c revision 1.13
      1  1.13     kamil /*	$NetBSD: fstest_puffs.c,v 1.13 2020/06/17 00:16:21 kamil Exp $	*/
      2   1.1     pooka 
      3   1.1     pooka /*
      4   1.8     pooka  * Copyright (c) 2010, 2011 The NetBSD Foundation, Inc.
      5   1.1     pooka  *
      6   1.1     pooka  * Redistribution and use in source and binary forms, with or without
      7   1.1     pooka  * modification, are permitted provided that the following conditions
      8   1.1     pooka  * are met:
      9   1.1     pooka  * 1. Redistributions of source code must retain the above copyright
     10   1.1     pooka  *    notice, this list of conditions and the following disclaimer.
     11   1.1     pooka  * 2. Redistributions in binary form must reproduce the above copyright
     12   1.1     pooka  *    notice, this list of conditions and the following disclaimer in the
     13   1.1     pooka  *    documentation and/or other materials provided with the distribution.
     14   1.1     pooka  *
     15   1.1     pooka  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
     16   1.1     pooka  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     17   1.1     pooka  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     18   1.1     pooka  * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     19   1.1     pooka  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     20   1.1     pooka  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     21   1.1     pooka  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     22   1.1     pooka  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     23   1.1     pooka  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     24   1.1     pooka  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     25   1.1     pooka  * SUCH DAMAGE.
     26   1.1     pooka  */
     27   1.1     pooka 
     28   1.1     pooka #include <sys/types.h>
     29   1.1     pooka #include <sys/mount.h>
     30   1.1     pooka #include <sys/socket.h>
     31   1.1     pooka #include <sys/statvfs.h>
     32   1.1     pooka #include <sys/wait.h>
     33   1.1     pooka 
     34   1.1     pooka #include <assert.h>
     35   1.1     pooka #include <atf-c.h>
     36   1.1     pooka #include <err.h>
     37   1.1     pooka #include <errno.h>
     38   1.1     pooka #include <fcntl.h>
     39   1.1     pooka #include <pthread.h>
     40   1.1     pooka #include <puffs.h>
     41   1.1     pooka #include <puffsdump.h>
     42   1.1     pooka #include <signal.h>
     43   1.1     pooka #include <stdio.h>
     44   1.1     pooka #include <unistd.h>
     45   1.1     pooka #include <string.h>
     46   1.1     pooka #include <stdlib.h>
     47   1.1     pooka 
     48   1.1     pooka #include <rump/rump.h>
     49  1.13     kamil #include <rump/rump_syscallshotgun.h>
     50   1.1     pooka #include <rump/rump_syscalls.h>
     51   1.1     pooka 
     52   1.1     pooka #include "h_fsmacros.h"
     53   1.1     pooka 
     54   1.1     pooka #define BUFSIZE (128*1024)
     55   1.1     pooka #define DTFS_DUMP "-o","dump"
     56   1.1     pooka 
     57   1.6     pooka static bool mayquit = false;
     58   1.6     pooka 
     59   1.7      yamt static ssize_t
     60   1.7      yamt xread(int fd, void *vp, size_t n)
     61   1.7      yamt {
     62   1.7      yamt 	size_t left;
     63   1.7      yamt 
     64   1.7      yamt 	left = n;
     65   1.7      yamt 	do {
     66   1.7      yamt 		ssize_t ssz;
     67   1.7      yamt 
     68   1.7      yamt 		ssz = read(fd, vp, left);
     69   1.7      yamt 		if (ssz == -1) {
     70   1.7      yamt 			return ssz;
     71   1.7      yamt 		}
     72   1.7      yamt 		left -= ssz;
     73   1.7      yamt 		vp = (char *)vp + ssz;
     74   1.7      yamt 	} while (left > 0);
     75   1.7      yamt 	return n;
     76   1.7      yamt }
     77   1.7      yamt 
     78   1.7      yamt static ssize_t
     79   1.7      yamt xwrite(int fd, const void *vp, size_t n)
     80   1.7      yamt {
     81   1.7      yamt 	size_t left;
     82   1.7      yamt 
     83   1.7      yamt 	left = n;
     84   1.7      yamt 	do {
     85   1.7      yamt 		ssize_t ssz;
     86   1.7      yamt 
     87   1.7      yamt 		ssz = write(fd, vp, left);
     88   1.7      yamt 		if (ssz == -1) {
     89   1.7      yamt 			return ssz;
     90   1.7      yamt 		}
     91   1.7      yamt 		left -= ssz;
     92   1.7      yamt 		vp = (const char *)vp + ssz;
     93   1.7      yamt 	} while (left > 0);
     94   1.7      yamt 	return n;
     95   1.7      yamt }
     96   1.7      yamt 
     97   1.1     pooka /*
     98   1.1     pooka  * Threads which shovel data between comfd and /dev/puffs.
     99   1.1     pooka  * (cannot use polling since fd's are in different namespaces)
    100   1.1     pooka  */
    101   1.1     pooka static void *
    102   1.1     pooka readshovel(void *arg)
    103   1.1     pooka {
    104   1.1     pooka 	struct putter_hdr *phdr;
    105   1.1     pooka 	struct puffs_req *preq;
    106   1.2     pooka 	struct puffstestargs *args = arg;
    107   1.1     pooka 	char buf[BUFSIZE];
    108   1.6     pooka 	ssize_t n;
    109   1.1     pooka 	int comfd, puffsfd;
    110   1.1     pooka 
    111   1.2     pooka 	comfd = args->pta_servfd;
    112   1.2     pooka 	puffsfd = args->pta_rumpfd;
    113   1.1     pooka 
    114   1.1     pooka 	phdr = (void *)buf;
    115   1.1     pooka 	preq = (void *)buf;
    116   1.1     pooka 
    117   1.4     pooka 	rump_pub_lwproc_newlwp(1);
    118   1.1     pooka 
    119   1.1     pooka 	for (;;) {
    120   1.1     pooka 		n = rump_sys_read(puffsfd, buf, sizeof(*phdr));
    121   1.4     pooka 		if (n <= 0) {
    122   1.5  pgoyette 			fprintf(stderr, "readshovel r1 %zd / %d\n", n, errno);
    123   1.1     pooka 			break;
    124   1.4     pooka 		}
    125   1.1     pooka 
    126   1.1     pooka 		assert(phdr->pth_framelen < BUFSIZE);
    127   1.1     pooka 		n = rump_sys_read(puffsfd, buf+sizeof(*phdr),
    128   1.1     pooka 		    phdr->pth_framelen - sizeof(*phdr));
    129   1.4     pooka 		if (n <= 0) {
    130   1.5  pgoyette 			fprintf(stderr, "readshovel r2 %zd / %d\n", n, errno);
    131   1.1     pooka 			break;
    132   1.4     pooka 		}
    133   1.1     pooka 
    134   1.1     pooka 		/* Analyze request */
    135   1.1     pooka 		if (PUFFSOP_OPCLASS(preq->preq_opclass) == PUFFSOP_VFS) {
    136   1.1     pooka 			assert(preq->preq_optype < PUFFS_VFS_MAX);
    137   1.2     pooka 			args->pta_vfs_toserv_ops[preq->preq_optype]++;
    138   1.1     pooka 		} else if (PUFFSOP_OPCLASS(preq->preq_opclass) == PUFFSOP_VN) {
    139   1.1     pooka 			assert(preq->preq_optype < PUFFS_VN_MAX);
    140   1.2     pooka 			args->pta_vn_toserv_ops[preq->preq_optype]++;
    141   1.1     pooka 		}
    142   1.1     pooka 
    143   1.1     pooka 		n = phdr->pth_framelen;
    144   1.7      yamt 		if (xwrite(comfd, buf, n) != n) {
    145   1.5  pgoyette 			fprintf(stderr, "readshovel write %zd / %d\n", n, errno);
    146   1.1     pooka 			break;
    147   1.4     pooka 		}
    148   1.1     pooka 	}
    149   1.1     pooka 
    150   1.6     pooka 	if (n != 0 && mayquit == false)
    151   1.6     pooka 		abort();
    152   1.6     pooka 	return NULL;
    153   1.1     pooka }
    154   1.1     pooka 
    155   1.1     pooka static void *
    156   1.1     pooka writeshovel(void *arg)
    157   1.1     pooka {
    158   1.2     pooka 	struct puffstestargs *args = arg;
    159   1.1     pooka 	struct putter_hdr *phdr;
    160   1.6     pooka 	struct puffs_req *preq;
    161   1.1     pooka 	char buf[BUFSIZE];
    162   1.1     pooka 	size_t toread;
    163   1.6     pooka 	ssize_t n;
    164   1.1     pooka 	int comfd, puffsfd;
    165   1.1     pooka 
    166   1.4     pooka 	rump_pub_lwproc_newlwp(1);
    167   1.1     pooka 
    168   1.2     pooka 	comfd = args->pta_servfd;
    169   1.2     pooka 	puffsfd = args->pta_rumpfd;
    170   1.1     pooka 
    171   1.1     pooka 	phdr = (struct putter_hdr *)buf;
    172   1.6     pooka 	preq = (void *)buf;
    173   1.1     pooka 
    174   1.1     pooka 	for (;;) {
    175   1.1     pooka 		uint64_t off;
    176   1.1     pooka 
    177   1.1     pooka 		/*
    178   1.1     pooka 		 * Need to write everything to the "kernel" in one chunk,
    179   1.1     pooka 		 * so make sure we have it here.
    180   1.1     pooka 		 */
    181   1.1     pooka 		off = 0;
    182   1.1     pooka 		toread = sizeof(struct putter_hdr);
    183   1.1     pooka 		assert(toread < BUFSIZE);
    184   1.1     pooka 		do {
    185   1.7      yamt 			n = xread(comfd, buf+off, toread);
    186   1.1     pooka 			if (n <= 0) {
    187   1.5  pgoyette 				fprintf(stderr, "writeshovel read %zd / %d\n",
    188   1.4     pooka 				    n, errno);
    189   1.6     pooka 				goto out;
    190   1.1     pooka 			}
    191   1.1     pooka 			off += n;
    192   1.1     pooka 			if (off >= sizeof(struct putter_hdr))
    193   1.1     pooka 				toread = phdr->pth_framelen - off;
    194   1.1     pooka 			else
    195   1.1     pooka 				toread = off - sizeof(struct putter_hdr);
    196   1.1     pooka 		} while (toread);
    197   1.1     pooka 
    198   1.6     pooka 		if (__predict_false(
    199   1.6     pooka 		    PUFFSOP_OPCLASS(preq->preq_opclass) == PUFFSOP_VFS
    200   1.6     pooka 		    && preq->preq_optype == PUFFS_VFS_UNMOUNT)) {
    201   1.6     pooka 			if (preq->preq_rv == 0)
    202   1.6     pooka 				mayquit = true;
    203   1.6     pooka 		}
    204   1.6     pooka 
    205   1.1     pooka 		n = rump_sys_write(puffsfd, buf, phdr->pth_framelen);
    206   1.4     pooka 		if ((size_t)n != phdr->pth_framelen) {
    207   1.5  pgoyette 			fprintf(stderr, "writeshovel wr %zd / %d\n", n, errno);
    208   1.1     pooka 			break;
    209   1.4     pooka 		}
    210   1.1     pooka 	}
    211   1.1     pooka 
    212   1.6     pooka  out:
    213   1.6     pooka 	if (n != 0)
    214   1.6     pooka 		abort();
    215   1.6     pooka 	return NULL;
    216   1.1     pooka }
    217   1.1     pooka 
    218   1.1     pooka static void
    219   1.2     pooka rumpshovels(struct puffstestargs *args)
    220   1.1     pooka {
    221   1.1     pooka 	pthread_t pt;
    222   1.1     pooka 	int rv;
    223   1.1     pooka 
    224   1.1     pooka 	if ((rv = rump_init()) == -1)
    225   1.1     pooka 		err(1, "rump_init");
    226   1.1     pooka 
    227   1.2     pooka 	if (pthread_create(&pt, NULL, readshovel, args) == -1)
    228   1.1     pooka 		err(1, "read shovel");
    229   1.1     pooka 	pthread_detach(pt);
    230   1.2     pooka 
    231   1.2     pooka 	if (pthread_create(&pt, NULL, writeshovel, args) == -1)
    232   1.1     pooka 		err(1, "write shovel");
    233   1.1     pooka 	pthread_detach(pt);
    234   1.1     pooka }
    235   1.1     pooka 
    236   1.1     pooka static void
    237   1.1     pooka childfail(int sign)
    238   1.1     pooka {
    239   1.1     pooka 
    240   1.1     pooka 	atf_tc_fail("child died"); /* almost signal-safe */
    241   1.1     pooka }
    242   1.1     pooka 
    243   1.2     pooka struct puffstestargs *theargs; /* XXX */
    244   1.2     pooka 
    245   1.1     pooka /* XXX: we don't support size */
    246   1.8     pooka static int
    247   1.8     pooka donewfs(const atf_tc_t *tc, void **argp,
    248   1.8     pooka 	const char *image, off_t size, void *fspriv, char **theargv)
    249   1.1     pooka {
    250   1.1     pooka 	struct puffstestargs *args;
    251   1.1     pooka 	pid_t childpid;
    252   1.1     pooka 	int *pflags;
    253   1.1     pooka 	char comfd[16];
    254   1.1     pooka 	int sv[2];
    255   1.1     pooka 	int mntflags;
    256   1.1     pooka 	size_t len;
    257   1.1     pooka 	ssize_t n;
    258   1.1     pooka 
    259   1.1     pooka 	*argp = NULL;
    260   1.1     pooka 
    261   1.1     pooka 	args = malloc(sizeof(*args));
    262   1.1     pooka 	if (args == NULL)
    263   1.1     pooka 		return errno;
    264  1.10     njoly 	memset(args, 0, sizeof(*args));
    265   1.1     pooka 
    266   1.1     pooka 	pflags = &args->pta_pflags;
    267   1.1     pooka 
    268   1.1     pooka 	/* Create sucketpair for communication with the real file server */
    269   1.1     pooka 	if (socketpair(PF_LOCAL, SOCK_STREAM, 0, sv) == -1)
    270   1.1     pooka 		return errno;
    271   1.1     pooka 
    272   1.1     pooka 	signal(SIGCHLD, childfail);
    273   1.1     pooka 
    274   1.1     pooka 	switch ((childpid = fork())) {
    275   1.1     pooka 	case 0:
    276   1.1     pooka 		close(sv[1]);
    277   1.1     pooka 		snprintf(comfd, sizeof(sv[0]), "%d", sv[0]);
    278   1.1     pooka 		if (setenv("PUFFS_COMFD", comfd, 1) == -1)
    279   1.1     pooka 			return errno;
    280   1.1     pooka 
    281  1.12       mrg 		execvp(theargv[0], theargv);
    282  1.12       mrg 		return errno;
    283   1.1     pooka 	case -1:
    284   1.1     pooka 		return errno;
    285   1.1     pooka 	default:
    286   1.1     pooka 		close(sv[0]);
    287   1.1     pooka 		break;
    288   1.1     pooka 	}
    289   1.1     pooka 
    290   1.1     pooka 	/* read args */
    291   1.7      yamt 	if ((n = xread(sv[1], &len, sizeof(len))) != sizeof(len))
    292   1.1     pooka 		err(1, "mp 1 %zd", n);
    293   1.1     pooka 	if (len > MAXPATHLEN)
    294   1.1     pooka 		err(1, "mntpath > MAXPATHLEN");
    295   1.7      yamt 	if ((size_t)xread(sv[1], args->pta_dir, len) != len)
    296   1.1     pooka 		err(1, "mp 2");
    297   1.7      yamt 	if (xread(sv[1], &len, sizeof(len)) != sizeof(len))
    298   1.1     pooka 		err(1, "fn 1");
    299   1.1     pooka 	if (len > MAXPATHLEN)
    300   1.1     pooka 		err(1, "devpath > MAXPATHLEN");
    301   1.7      yamt 	if ((size_t)xread(sv[1], args->pta_dev, len) != len)
    302   1.1     pooka 		err(1, "fn 2");
    303   1.7      yamt 	if (xread(sv[1], &mntflags, sizeof(mntflags)) != sizeof(mntflags))
    304   1.1     pooka 		err(1, "mntflags");
    305   1.7      yamt 	if (xread(sv[1], &args->pta_pargslen, sizeof(args->pta_pargslen))
    306   1.2     pooka 	    != sizeof(args->pta_pargslen))
    307   1.1     pooka 		err(1, "puffstest_args len");
    308   1.1     pooka 	args->pta_pargs = malloc(args->pta_pargslen);
    309   1.1     pooka 	if (args->pta_pargs == NULL)
    310   1.1     pooka 		err(1, "malloc");
    311   1.7      yamt 	if (xread(sv[1], args->pta_pargs, args->pta_pargslen)
    312   1.2     pooka 	    != (ssize_t)args->pta_pargslen)
    313   1.1     pooka 		err(1, "puffstest_args");
    314   1.7      yamt 	if (xread(sv[1], pflags, sizeof(*pflags)) != sizeof(*pflags))
    315   1.1     pooka 		err(1, "pflags");
    316   1.1     pooka 
    317   1.1     pooka 	args->pta_childpid = childpid;
    318   1.1     pooka 	args->pta_servfd = sv[1];
    319   1.1     pooka 	strlcpy(args->pta_dev, image, sizeof(args->pta_dev));
    320   1.1     pooka 
    321   1.2     pooka 	*argp = theargs = args;
    322   1.1     pooka 
    323   1.1     pooka 	return 0;
    324   1.1     pooka }
    325   1.1     pooka 
    326   1.1     pooka int
    327   1.8     pooka puffs_fstest_newfs(const atf_tc_t *tc, void **argp,
    328   1.8     pooka 	const char *image, off_t size, void *fspriv)
    329   1.8     pooka {
    330   1.8     pooka 	char dtfs_path[MAXPATHLEN];
    331   1.8     pooka 	char *dtfsargv[6];
    332   1.8     pooka 	char **theargv;
    333   1.8     pooka 
    334   1.8     pooka 	/* build dtfs exec path from atf test dir */
    335   1.8     pooka 	sprintf(dtfs_path, "%s/../puffs/h_dtfs/h_dtfs",
    336   1.8     pooka 	    atf_tc_get_config_var(tc, "srcdir"));
    337   1.8     pooka 
    338   1.8     pooka 	if (fspriv) {
    339   1.8     pooka 		theargv = fspriv;
    340   1.8     pooka 		theargv[0] = dtfs_path;
    341   1.8     pooka 	} else {
    342   1.8     pooka 		dtfsargv[0] = dtfs_path;
    343   1.8     pooka 		dtfsargv[1] = __UNCONST("-i");
    344   1.8     pooka 		dtfsargv[2] = __UNCONST("-s");
    345   1.8     pooka 		dtfsargv[3] = __UNCONST("dtfs");
    346   1.8     pooka 		dtfsargv[4] = __UNCONST("fictional");
    347   1.8     pooka 		dtfsargv[5] = NULL;
    348   1.8     pooka 
    349   1.8     pooka 		theargv = dtfsargv;
    350   1.8     pooka 	}
    351   1.8     pooka 
    352   1.8     pooka 	return donewfs(tc, argp, image, size, fspriv, theargv);
    353   1.8     pooka }
    354   1.8     pooka 
    355   1.8     pooka int
    356   1.8     pooka p2k_ffs_fstest_newfs(const atf_tc_t *tc, void **argp,
    357   1.8     pooka 	const char *image, off_t size, void *fspriv)
    358   1.8     pooka {
    359   1.8     pooka 	char *rumpffs_argv[5];
    360   1.8     pooka 	int rv;
    361   1.8     pooka 
    362   1.8     pooka 	rump_init();
    363   1.8     pooka 	if ((rv = ffs_fstest_newfs(tc, argp, image, size, fspriv)) != 0)
    364   1.8     pooka 		return rv;
    365   1.9     pooka 	if (mkdir("p2kffsfake", 0777) == -1 && errno != EEXIST)
    366   1.8     pooka 		return errno;
    367   1.8     pooka 
    368   1.8     pooka 	setenv("P2K_NODETACH", "1", 1);
    369   1.8     pooka 	rumpffs_argv[0] = __UNCONST("rump_ffs");
    370   1.8     pooka 	rumpffs_argv[1] = __UNCONST(image);
    371   1.8     pooka 	rumpffs_argv[2] = __UNCONST("p2kffsfake"); /* NOTUSED */
    372   1.8     pooka 	rumpffs_argv[3] = NULL;
    373   1.8     pooka 
    374   1.8     pooka 	if ((rv = donewfs(tc, argp, image, size, fspriv, rumpffs_argv)) != 0)
    375   1.8     pooka 		ffs_fstest_delfs(tc, argp);
    376   1.8     pooka 	return rv;
    377   1.8     pooka }
    378   1.8     pooka 
    379   1.8     pooka int
    380   1.1     pooka puffs_fstest_mount(const atf_tc_t *tc, void *arg, const char *path, int flags)
    381   1.1     pooka {
    382   1.1     pooka 	struct puffstestargs *pargs = arg;
    383   1.1     pooka 	int fd;
    384   1.1     pooka 
    385   1.1     pooka 	rump_init();
    386   1.1     pooka 	fd = rump_sys_open("/dev/puffs", O_RDWR);
    387   1.1     pooka 	if (fd == -1)
    388   1.1     pooka 		return fd;
    389   1.1     pooka 
    390   1.1     pooka 	if (rump_sys_mkdir(path, 0777) == -1)
    391   1.1     pooka 		return -1;
    392   1.1     pooka 
    393   1.1     pooka 	if (rump_sys_mount(MOUNT_PUFFS, path, flags,
    394   1.1     pooka 	    pargs->pta_pargs, pargs->pta_pargslen) == -1) {
    395   1.1     pooka 		/* apply "to kill a child" to avoid atf hang (kludge) */
    396   1.1     pooka 		kill(pargs->pta_childpid, SIGKILL);
    397   1.1     pooka 		return -1;
    398   1.1     pooka 	}
    399   1.1     pooka 
    400   1.2     pooka 	pargs->pta_rumpfd = fd;
    401   1.2     pooka 	rumpshovels(pargs);
    402   1.1     pooka 
    403   1.1     pooka 	return 0;
    404   1.1     pooka }
    405   1.8     pooka __strong_alias(p2k_ffs_fstest_mount,puffs_fstest_mount);
    406   1.1     pooka 
    407   1.1     pooka int
    408   1.1     pooka puffs_fstest_delfs(const atf_tc_t *tc, void *arg)
    409   1.1     pooka {
    410   1.1     pooka 
    411   1.2     pooka 	/* useless ... */
    412   1.1     pooka 	return 0;
    413   1.1     pooka }
    414   1.1     pooka 
    415   1.1     pooka int
    416   1.8     pooka p2k_ffs_fstest_delfs(const atf_tc_t *tc, void *arg)
    417   1.8     pooka {
    418   1.8     pooka 
    419   1.8     pooka 	return ffs_fstest_delfs(tc, arg);
    420   1.8     pooka }
    421   1.8     pooka 
    422   1.8     pooka int
    423   1.1     pooka puffs_fstest_unmount(const atf_tc_t *tc, const char *path, int flags)
    424   1.1     pooka {
    425   1.2     pooka 	struct puffstestargs *pargs = theargs;
    426   1.2     pooka 	int status;
    427   1.1     pooka 	int rv;
    428   1.1     pooka 
    429   1.1     pooka 	/* ok, child might exit here */
    430   1.1     pooka 	signal(SIGCHLD, SIG_IGN);
    431   1.1     pooka 
    432   1.1     pooka 	rv = rump_sys_unmount(path, flags);
    433   1.1     pooka 	if (rv)
    434   1.1     pooka 		return rv;
    435   1.1     pooka 
    436   1.2     pooka 	if ((rv = rump_sys_rmdir(path)) != 0)
    437   1.2     pooka 		return rv;
    438   1.2     pooka 
    439   1.2     pooka 	if (waitpid(pargs->pta_childpid, &status, WNOHANG) > 0)
    440   1.2     pooka 		return 0;
    441   1.2     pooka 	kill(pargs->pta_childpid, SIGTERM);
    442   1.2     pooka 	usleep(10);
    443   1.2     pooka 	if (waitpid(pargs->pta_childpid, &status, WNOHANG) > 0)
    444   1.2     pooka 		return 0;
    445   1.2     pooka 	kill(pargs->pta_childpid, SIGKILL);
    446   1.2     pooka 	usleep(500);
    447   1.2     pooka 	wait(&status);
    448   1.2     pooka 
    449   1.8     pooka 	rmdir("p2kffsfake");
    450   1.8     pooka 
    451   1.2     pooka 	return 0;
    452   1.1     pooka }
    453   1.8     pooka __strong_alias(p2k_ffs_fstest_unmount,puffs_fstest_unmount);
    454