xref: /netbsd-src/sys/rump/fs/lib/libsyspuffs/puffs_rumpglue.c (revision 6bb51422881aa32822c80737814503e72f496e36)
1*6bb51422Spooka /*	$NetBSD: puffs_rumpglue.c,v 1.16 2016/01/26 23:12:17 pooka Exp $	*/
24f69d01dSpooka 
34f69d01dSpooka /*
44f69d01dSpooka  * Copyright (c) 2008 Antti Kantee.  All Rights Reserved.
54f69d01dSpooka  *
64f69d01dSpooka  * Development of this software was supported by the
74f69d01dSpooka  * Research Foundation of Helsinki University of Technology
84f69d01dSpooka  *
94f69d01dSpooka  * Redistribution and use in source and binary forms, with or without
104f69d01dSpooka  * modification, are permitted provided that the following conditions
114f69d01dSpooka  * are met:
124f69d01dSpooka  * 1. Redistributions of source code must retain the above copyright
134f69d01dSpooka  *    notice, this list of conditions and the following disclaimer.
144f69d01dSpooka  * 2. Redistributions in binary form must reproduce the above copyright
154f69d01dSpooka  *    notice, this list of conditions and the following disclaimer in the
164f69d01dSpooka  *    documentation and/or other materials provided with the distribution.
174f69d01dSpooka  *
184f69d01dSpooka  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
194f69d01dSpooka  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
204f69d01dSpooka  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
214f69d01dSpooka  * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
224f69d01dSpooka  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
234f69d01dSpooka  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
244f69d01dSpooka  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
254f69d01dSpooka  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
264f69d01dSpooka  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
274f69d01dSpooka  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
284f69d01dSpooka  * SUCH DAMAGE.
294f69d01dSpooka  */
304f69d01dSpooka 
314f69d01dSpooka #include <sys/cdefs.h>
32*6bb51422Spooka __KERNEL_RCSID(0, "$NetBSD: puffs_rumpglue.c,v 1.16 2016/01/26 23:12:17 pooka Exp $");
334f69d01dSpooka 
344f69d01dSpooka #include <sys/param.h>
354f69d01dSpooka #include <sys/conf.h>
364f69d01dSpooka #include <sys/file.h>
374f69d01dSpooka #include <sys/filedesc.h>
384f69d01dSpooka #include <sys/kthread.h>
394f69d01dSpooka #include <sys/mount.h>
404f69d01dSpooka 
414b9a5d92Spooka #include <dev/putter/putter.h>
424f69d01dSpooka #include <dev/putter/putter_sys.h>
434f69d01dSpooka 
44*6bb51422Spooka #include <rump-sys/vfs.h>
45*6bb51422Spooka 
46bdf6e0b0Spooka #include <rump/rump.h>
47bdf6e0b0Spooka #include <rump/rumpuser.h>
484f69d01dSpooka 
494f69d01dSpooka void putterattach(void); /* XXX: from autoconf */
504f69d01dSpooka dev_type_open(puttercdopen);
514f69d01dSpooka 
524f69d01dSpooka struct ptargs {
534f69d01dSpooka 	int comfd;
544f69d01dSpooka 	int fpfd;
554f69d01dSpooka 	struct filedesc *fdp;
564f69d01dSpooka };
574f69d01dSpooka 
584f69d01dSpooka #define BUFSIZE (64*1024)
594f69d01dSpooka extern int hz;
604f69d01dSpooka 
614f69d01dSpooka /*
624f69d01dSpooka  * Read requests from /dev/puffs and forward them to comfd
634f69d01dSpooka  *
644f69d01dSpooka  * XXX: the init detection is really sucky, but let's not
654f69d01dSpooka  * waste too much energy for a better one here
664f69d01dSpooka  */
674f69d01dSpooka static void
readthread(void * arg)684f69d01dSpooka readthread(void *arg)
694f69d01dSpooka {
704f69d01dSpooka 	struct ptargs *pap = arg;
714f69d01dSpooka 	struct file *fp;
724f69d01dSpooka 	register_t rv;
734f69d01dSpooka 	char *buf;
744f69d01dSpooka 	off_t off;
754f69d01dSpooka 	int error, inited;
764f69d01dSpooka 
774f69d01dSpooka 	buf = kmem_alloc(BUFSIZE, KM_SLEEP);
784f69d01dSpooka 	inited = 0;
794f69d01dSpooka 
804f69d01dSpooka  retry:
814f69d01dSpooka 	kpause(NULL, 0, hz/4, NULL);
824f69d01dSpooka 
834f69d01dSpooka 	for (;;) {
8432a34307Spooka 		size_t n;
854f69d01dSpooka 
864f69d01dSpooka 		off = 0;
87a9ca7a37Sad 		fp = fd_getfile(pap->fpfd);
8865bd814eSchristos 		if (fp == NULL)
8965bd814eSchristos 			error = EINVAL;
9065bd814eSchristos 		else
914f69d01dSpooka 			error = dofileread(pap->fpfd, fp, buf, BUFSIZE,
924f69d01dSpooka 			    &off, 0, &rv);
934f69d01dSpooka 		if (error) {
944f69d01dSpooka 			if (error == ENOENT && inited == 0)
954f69d01dSpooka 				goto retry;
964f69d01dSpooka 			if (error == ENXIO)
974b9a5d92Spooka 				break;
984f69d01dSpooka 			panic("fileread failed: %d", error);
994f69d01dSpooka 		}
1004f69d01dSpooka 		inited = 1;
1014f69d01dSpooka 
1024f69d01dSpooka 		while (rv) {
1030dc3609eSpooka 			struct rumpuser_iovec iov;
1040dc3609eSpooka 
1050dc3609eSpooka 			iov.iov_base = buf;
1060dc3609eSpooka 			iov.iov_len = rv;
1070dc3609eSpooka 
10832a34307Spooka 			error = rumpuser_iovwrite(pap->comfd, &iov, 1,
10932a34307Spooka 			    RUMPUSER_IOV_NOSEEK, &n);
11032a34307Spooka 			if (error)
1114f69d01dSpooka 				panic("fileread failed: %d", error);
1124f69d01dSpooka 			if (n == 0)
1134f69d01dSpooka 				panic("fileread failed: closed");
1144f69d01dSpooka 			rv -= n;
1154f69d01dSpooka 		}
1164f69d01dSpooka 	}
1174b9a5d92Spooka 
1184b9a5d92Spooka 	kthread_exit(0);
1194f69d01dSpooka }
1204f69d01dSpooka 
1214f69d01dSpooka /* Read requests from comfd and proxy them to /dev/puffs */
1224f69d01dSpooka static void
writethread(void * arg)1234f69d01dSpooka writethread(void *arg)
1244f69d01dSpooka {
1254f69d01dSpooka 	struct ptargs *pap = arg;
1264f69d01dSpooka 	struct file *fp;
1274b9a5d92Spooka 	struct putter_hdr *phdr;
1284f69d01dSpooka 	register_t rv;
1294f69d01dSpooka 	char *buf;
130827e91ddSpooka 	off_t off;
131827e91ddSpooka 	size_t toread;
1324f69d01dSpooka 	int error;
1334f69d01dSpooka 
1344f69d01dSpooka 	buf = kmem_alloc(BUFSIZE, KM_SLEEP);
1354b9a5d92Spooka 	phdr = (struct putter_hdr *)buf;
1364f69d01dSpooka 
1374f69d01dSpooka 	for (;;) {
13832a34307Spooka 		size_t n;
1394f69d01dSpooka 
1404b9a5d92Spooka 		/*
1414b9a5d92Spooka 		 * Need to write everything to the "kernel" in one chunk,
1424b9a5d92Spooka 		 * so make sure we have it here.
1434b9a5d92Spooka 		 */
144827e91ddSpooka 		off = 0;
1454b9a5d92Spooka 		toread = sizeof(struct putter_hdr);
1464b9a5d92Spooka 		do {
1470dc3609eSpooka 			struct rumpuser_iovec iov;
1480dc3609eSpooka 
1490dc3609eSpooka 			iov.iov_base = buf+off;
1500dc3609eSpooka 			iov.iov_len = toread;
15132a34307Spooka 			error = rumpuser_iovread(pap->comfd, &iov, 1,
15232a34307Spooka 			    RUMPUSER_IOV_NOSEEK, &n);
15332a34307Spooka 			if (error)
15432a34307Spooka 				panic("rumpuser_read %zd %d", n, error);
1554b9a5d92Spooka 			if (n == 0)
156aa224b94Spooka 				goto out;
157827e91ddSpooka 			off += n;
158827e91ddSpooka 			if (off >= sizeof(struct putter_hdr))
159827e91ddSpooka 				toread = phdr->pth_framelen - off;
1604b9a5d92Spooka 			else
161827e91ddSpooka 				toread = off - sizeof(struct putter_hdr);
1624b9a5d92Spooka 		} while (toread);
1634b9a5d92Spooka 
164827e91ddSpooka 		off = 0;
165827e91ddSpooka 		rv = 0;
1664b9a5d92Spooka 		fp = fd_getfile(pap->fpfd);
16765bd814eSchristos 		if (fp == NULL)
16865bd814eSchristos 			error = EINVAL;
16965bd814eSchristos 		else
17065bd814eSchristos 			error = dofilewrite(pap->fpfd, fp, buf,
17165bd814eSchristos 			    phdr->pth_framelen, &off, 0, &rv);
1724b9a5d92Spooka 		if (error == ENXIO)
173aa224b94Spooka 			goto out;
1744b9a5d92Spooka 		KASSERT(rv == phdr->pth_framelen);
1754b9a5d92Spooka 	}
176aa224b94Spooka  out:
1774b9a5d92Spooka 
1784b9a5d92Spooka 	kthread_exit(0);
1794f69d01dSpooka }
1804f69d01dSpooka 
1814f69d01dSpooka int
rump_syspuffs_glueinit(int fd,int * newfd)182d09e2773Spooka rump_syspuffs_glueinit(int fd, int *newfd)
1834f69d01dSpooka {
1844f69d01dSpooka 	struct ptargs *pap;
1854f69d01dSpooka 	int rv;
1864f69d01dSpooka 
187f4ce96e8Spooka 	if ((rv = rump_init()) != 0)
188f4ce96e8Spooka 		return rv;
189f4ce96e8Spooka 
1904f69d01dSpooka 	putterattach();
1914f69d01dSpooka 	rv = puttercdopen(makedev(178, 0), 0, 0, curlwp);
1924f69d01dSpooka 	if (rv && rv != EMOVEFD)
1934f69d01dSpooka 		return rv;
1944f69d01dSpooka 
1954f69d01dSpooka 	pap = kmem_alloc(sizeof(struct ptargs), KM_SLEEP);
1964f69d01dSpooka 	pap->comfd = fd;
1974f69d01dSpooka 	pap->fpfd = curlwp->l_dupfd;
1984f69d01dSpooka 	pap->fdp = curlwp->l_proc->p_fd;
1994f69d01dSpooka 
200524046d7Schristos 	rv = kthread_create(PRI_NONE, 0, NULL, readthread, pap, NULL,
201524046d7Schristos 	    "rputter");
202524046d7Schristos 	if (rv)
203524046d7Schristos 		return rv;
204524046d7Schristos 
205524046d7Schristos 	rv = kthread_create(PRI_NONE, 0, NULL, writethread, pap, NULL,
206524046d7Schristos 	    "wputter");
207524046d7Schristos 	if (rv)
208524046d7Schristos 		return rv;
2094f69d01dSpooka 
2104f69d01dSpooka 	*newfd = curlwp->l_dupfd;
2114f69d01dSpooka 	return 0;
2124f69d01dSpooka }
213