Module Name: src
Committed By: pooka
Date: Thu Nov 4 20:54:08 UTC 2010
Modified Files:
src/lib/librumpuser: rumpuser_sp.c
src/sys/rump/include/rump: rump_syscalls.h rumpuser.h
src/sys/rump/librump/rumpkern: rump.c rump_private.h
Added Files:
src/lib/librumpuser: sp_common.c
Log Message:
Refactor the sysproxy code so that rumpuser contains only the server side.
To generate a diff of this commit:
cvs rdiff -u -r1.4 -r1.5 src/lib/librumpuser/rumpuser_sp.c
cvs rdiff -u -r0 -r1.1 src/lib/librumpuser/sp_common.c
cvs rdiff -u -r1.31 -r1.32 src/sys/rump/include/rump/rump_syscalls.h
cvs rdiff -u -r1.48 -r1.49 src/sys/rump/include/rump/rumpuser.h
cvs rdiff -u -r1.195 -r1.196 src/sys/rump/librump/rumpkern/rump.c
cvs rdiff -u -r1.60 -r1.61 src/sys/rump/librump/rumpkern/rump_private.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/lib/librumpuser/rumpuser_sp.c
diff -u src/lib/librumpuser/rumpuser_sp.c:1.4 src/lib/librumpuser/rumpuser_sp.c:1.5
--- src/lib/librumpuser/rumpuser_sp.c:1.4 Mon Nov 1 13:55:19 2010
+++ src/lib/librumpuser/rumpuser_sp.c Thu Nov 4 20:54:07 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: rumpuser_sp.c,v 1.4 2010/11/01 13:55:19 pooka Exp $ */
+/* $NetBSD: rumpuser_sp.c,v 1.5 2010/11/04 20:54:07 pooka Exp $ */
/*
* Copyright (c) 2010 Antti Kantee. All Rights Reserved.
@@ -38,7 +38,7 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: rumpuser_sp.c,v 1.4 2010/11/01 13:55:19 pooka Exp $");
+__RCSID("$NetBSD: rumpuser_sp.c,v 1.5 2010/11/04 20:54:07 pooka Exp $");
#include <sys/types.h>
#include <sys/mman.h>
@@ -61,84 +61,7 @@
#include <rump/rumpuser.h>
-//#define DEBUG
-#ifdef DEBUG
-#include <rump/rump.h>
-#include <rump/rump_syscalls.h>
-#define DPRINTF(x) mydprintf x
-static void
-mydprintf(const char *fmt, ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
- vfprintf(stderr, fmt, ap);
- va_end(ap);
-}
-#else
-#define DPRINTF(x)
-#endif
-
-/*
- * Bah, I hate writing on-off-wire conversions in C
- */
-
-enum {
- RUMPSP_SYSCALL_REQ, RUMPSP_SYSCALL_RESP,
- RUMPSP_COPYIN_REQ, RUMPSP_COPYIN_RESP,
- RUMPSP_COPYOUT_REQ, /* no copyout resp */
- RUMPSP_ANONMMAP_REQ, RUMPSP_ANONMMAP_RESP
-};
-
-struct rsp_hdr {
- uint64_t rsp_len;
- uint64_t rsp_reqno;
- uint32_t rsp_type;
- /*
- * We want this structure 64bit-aligned for typecast fun,
- * so might as well use the following for something.
- */
- uint32_t rsp_sysnum;
-};
-#define HDRSZ sizeof(struct rsp_hdr)
-
-/*
- * Data follows the header. We have two types of structured data.
- */
-
-/* copyin/copyout */
-struct rsp_copydata {
- size_t rcp_len;
- void *rcp_addr;
- uint8_t rcp_data[0];
-};
-
-/* syscall response */
-struct rsp_sysresp {
- int rsys_error;
- register_t rsys_retval[2];
-};
-
-
-struct spclient {
- int spc_fd;
- struct lwp *spc_lwp;
-
- /* incoming */
- struct rsp_hdr spc_hdr;
- uint8_t *spc_buf;
- size_t spc_off;
-
-#if 0
- /* outgoing */
- int spc_obusy;
- pthread_mutex_t spc_omtx;
- pthread_cond_t spc_cv;
-#endif
-};
-
-typedef int (*addrparse_fn)(const char *, int, struct sockaddr **);
-typedef int (*connecthook_fn)(int);
+#include "sp_common.c"
#define MAXCLI 4
@@ -148,8 +71,6 @@
static uint64_t nextreq;
static pthread_key_t spclient_tls;
-static struct spclient clispc;
-
static struct rumpuser_sp_ops spops;
/*
@@ -212,57 +133,6 @@
}
static int
-dosend(struct spclient *spc, const void *data, size_t dlen)
-{
- struct pollfd pfd;
- const uint8_t *sdata = data;
- ssize_t n;
- size_t sent;
- int fd = spc->spc_fd;
-
- pfd.fd = fd;
- pfd.events = POLLOUT;
-
- for (sent = 0, n = 0; sent < dlen; ) {
- if (n) {
- if (poll(&pfd, 1, INFTIM) == -1) {
- if (errno == EINTR)
- continue;
- return errno;
- }
- }
-
- n = write(fd, sdata + sent, dlen - sent);
- if (n == 0) {
- return EFAULT;
- }
- if (n == -1 && errno != EAGAIN) {
- return EFAULT;
- }
- sent += n;
- }
-
- return 0;
-}
-
-static int
-send_syscall_req(struct spclient *spc, int sysnum,
- const void *data, size_t dlen)
-{
- struct rsp_hdr rhdr;
-
- rhdr.rsp_len = sizeof(rhdr) + dlen;
- rhdr.rsp_reqno = nextreq++;
- rhdr.rsp_type = RUMPSP_SYSCALL_REQ;
- rhdr.rsp_sysnum = sysnum;
-
- dosend(spc, &rhdr, sizeof(rhdr));
- dosend(spc, data, dlen);
-
- return 0;
-}
-
-static int
send_syscall_resp(struct spclient *spc, uint64_t reqno, int error,
register_t retval[2])
{
@@ -304,22 +174,6 @@
}
static int
-send_copyin_resp(struct spclient *spc, uint64_t reqno, void *data, size_t dlen)
-{
- struct rsp_hdr rhdr;
-
- rhdr.rsp_len = sizeof(rhdr) + dlen;
- rhdr.rsp_reqno = reqno;
- rhdr.rsp_type = RUMPSP_COPYIN_RESP;
- rhdr.rsp_sysnum = 0;
-
- dosend(spc, &rhdr, sizeof(rhdr));
- dosend(spc, data, dlen);
-
- return 0;
-}
-
-static int
send_copyout_req(struct spclient *spc, const void *remaddr,
const void *data, size_t dlen)
{
@@ -357,22 +211,6 @@
return 0;
}
-static int
-send_anonmmap_resp(struct spclient *spc, uint64_t reqno, void *addr)
-{
- struct rsp_hdr rhdr;
-
- rhdr.rsp_len = sizeof(rhdr) + sizeof(addr);
- rhdr.rsp_reqno = reqno;
- rhdr.rsp_type = RUMPSP_ANONMMAP_RESP;
- rhdr.rsp_sysnum = 0;
-
- dosend(spc, &rhdr, sizeof(rhdr));
- dosend(spc, &addr, sizeof(addr));
-
- return 0;
-}
-
static void
serv_handledisco(unsigned int idx)
{
@@ -455,7 +293,7 @@
maxidx = i;
DPRINTF(("rump_sp: added new connection at idx %u, pid %d\n",
- i, rump_sys_getpid())); /* XXX: getpid not spop */
+ i, 9)); /* XXX: getpid not spop */
lwproc_switch(NULL);
@@ -478,83 +316,9 @@
lwproc_switch(NULL);
pthread_setspecific(spclient_tls, NULL);
- send_syscall_resp(spc, rhdr->rsp_reqno, rv, retval);
-}
-
-static int
-readframe(struct spclient *spc)
-{
- int fd = spc->spc_fd;
- size_t left;
- size_t framelen;
- ssize_t n;
-
- /* still reading header? */
- if (spc->spc_off < HDRSZ) {
- DPRINTF(("rump_sp: readframe getting header at offset %zu\n",
- spc->spc_off));
-
- left = HDRSZ - spc->spc_off;
- /*LINTED: cast ok */
- n = read(fd, (uint8_t *)&spc->spc_hdr + spc->spc_off, left);
- if (n == 0) {
- return -1;
- }
- if (n == -1) {
- if (errno == EAGAIN)
- return 0;
- return -1;
- }
-
- spc->spc_off += n;
- if (spc->spc_off < HDRSZ)
- return -1;
-
- /*LINTED*/
- framelen = spc->spc_hdr.rsp_len;
-
- if (framelen < HDRSZ) {
- return -1;
- } else if (framelen == HDRSZ) {
- return 1;
- }
-
- spc->spc_buf = malloc(framelen - HDRSZ);
- if (spc->spc_buf == NULL) {
- return -1;
- }
- memset(spc->spc_buf, 0, framelen - HDRSZ);
-
- /* "fallthrough" */
- } else {
- /*LINTED*/
- framelen = spc->spc_hdr.rsp_len;
- }
-
- left = framelen - spc->spc_off;
-
- DPRINTF(("rump_sp: readframe getting body at offset %zu, left %zu\n",
- spc->spc_off, left));
-
- if (left == 0)
- return 1;
- n = read(fd, spc->spc_buf + (spc->spc_off - HDRSZ), left);
- if (n == 0) {
- return -1;
- }
- if (n == -1) {
- if (errno == EAGAIN)
- return 0;
- return -1;
- }
- spc->spc_off += n;
- left -= n;
+ DPRINTF(("rump_sp: got return value %d\n", rv));
- /* got everything? */
- if (left == 0)
- return 1;
- else
- return 0;
+ send_syscall_resp(spc, rhdr->rsp_reqno, rv, retval);
}
int
@@ -636,203 +400,12 @@
return 0;
}
-int
-rumpuser_sp_syscall(int sysnum, const void *data, size_t dlen,
- register_t *retval)
-{
- struct rsp_sysresp *resp;
- struct rsp_copydata *copydata;
- struct pollfd pfd;
- size_t maplen;
- void *mapaddr;
- int gotresp;
-
- DPRINTF(("rump_sp_syscall: executing syscall %d\n", sysnum));
-
- send_syscall_req(&clispc, sysnum, data, dlen);
-
- DPRINTF(("rump_sp_syscall: syscall %d request sent. "
- "waiting for response\n", sysnum));
-
- pfd.fd = clispc.spc_fd;
- pfd.events = POLLIN;
-
- gotresp = 0;
- while (!gotresp) {
- while (readframe(&clispc) < 1)
- poll(&pfd, 1, INFTIM);
-
- switch (clispc.spc_hdr.rsp_type) {
- case RUMPSP_COPYIN_REQ:
- /*LINTED*/
- copydata = (struct rsp_copydata *)clispc.spc_buf;
- DPRINTF(("rump_sp_syscall: copyin request: %p/%zu\n",
- copydata->rcp_addr, copydata->rcp_len));
- send_copyin_resp(&clispc, clispc.spc_hdr.rsp_reqno,
- copydata->rcp_addr, copydata->rcp_len);
- clispc.spc_off = 0;
- break;
- case RUMPSP_COPYOUT_REQ:
- /*LINTED*/
- copydata = (struct rsp_copydata *)clispc.spc_buf;
- DPRINTF(("rump_sp_syscall: copyout request: %p/%zu\n",
- copydata->rcp_addr, copydata->rcp_len));
- /*LINTED*/
- memcpy(copydata->rcp_addr, copydata->rcp_data,
- copydata->rcp_len);
- clispc.spc_off = 0;
- break;
- case RUMPSP_ANONMMAP_REQ:
- /*LINTED*/
- maplen = *(size_t *)clispc.spc_buf;
- mapaddr = mmap(NULL, maplen, PROT_READ|PROT_WRITE,
- MAP_ANON, -1, 0);
- if (mapaddr == MAP_FAILED)
- mapaddr = NULL;
- send_anonmmap_resp(&clispc,
- clispc.spc_hdr.rsp_reqno, mapaddr);
- clispc.spc_off = 0;
- break;
- case RUMPSP_SYSCALL_RESP:
- DPRINTF(("rump_sp_syscall: got response \n"));
- gotresp = 1;
- break;
- }
- }
-
- /*LINTED*/
- resp = (struct rsp_sysresp *)clispc.spc_buf;
- memcpy(retval, &resp->rsys_retval, sizeof(resp->rsys_retval));
- clispc.spc_off = 0;
-
- return resp->rsys_error;
-}
-
/*
*
* Startup routines and mainloop for server.
*
*/
-static int
-tcp_parse(const char *addr, int type, struct sockaddr **sa)
-{
- struct sockaddr_in sin;
- char buf[64];
- const char *p;
- size_t l;
- int port;
-
- memset(&sin, 0, sizeof(sin));
- sin.sin_len = sizeof(sin);
- sin.sin_family = AF_INET;
-
- p = strchr(addr, ':');
- if (!p) {
- fprintf(stderr, "rump_sp_tcp: missing port specifier\n");
- return EINVAL;
- }
-
- l = p - addr;
- if (l > sizeof(buf)-1) {
- fprintf(stderr, "rump_sp_tcp: address too long\n");
- return EINVAL;
- }
- strncpy(buf, addr, l);
- buf[l] = '\0';
-
- /* special INADDR_ANY treatment */
- if (strcmp(buf, "*") == 0 || strcmp(buf, "0") == 0) {
- sin.sin_addr.s_addr = INADDR_ANY;
- } else {
- switch (inet_pton(AF_INET, buf, &sin.sin_addr)) {
- case 1:
- break;
- case 0:
- fprintf(stderr, "rump_sp_tcp: cannot parse %s\n", buf);
- return EINVAL;
- case -1:
- fprintf(stderr, "rump_sp_tcp: inet_pton failed\n");
- return errno;
- default:
- assert(/*CONSTCOND*/0);
- return EINVAL;
- }
- }
-
- if (type == RUMP_SP_CLIENT && sin.sin_addr.s_addr == INADDR_ANY) {
- fprintf(stderr, "rump_sp_tcp: client needs !INADDR_ANY\n");
- return EINVAL;
- }
-
- /* advance to port number & parse */
- p++;
- l = strspn(p, "0123456789");
- if (l == 0) {
- fprintf(stderr, "rump_sp_tcp: port now found: %s\n", p);
- return EINVAL;
- }
- strncpy(buf, p, l);
- buf[l] = '\0';
-
- if (*(p+l) != '/' && *(p+l) != '\0') {
- fprintf(stderr, "rump_sp_tcp: junk at end of port: %s\n", addr);
- return EINVAL;
- }
-
- port = atoi(buf);
- if (port < 0 || port >= (1<<(8*sizeof(in_port_t)))) {
- fprintf(stderr, "rump_sp_tcp: port %d out of range\n", port);
- return ERANGE;
- }
- sin.sin_port = htons(port);
-
- *sa = malloc(sizeof(sin));
- if (*sa == NULL)
- return errno;
- memcpy(*sa, &sin, sizeof(sin));
- return 0;
-}
-
-static int
-tcp_connecthook(int s)
-{
- int x;
-
- x = 1;
- setsockopt(s, IPPROTO_TCP, TCP_NODELAY, &x, sizeof(x));
-
- return 0;
-}
-
-/*ARGSUSED*/
-static int
-notsupp(void)
-{
-
- fprintf(stderr, "rump_sp: support not yet implemented\n");
- return EOPNOTSUPP;
-}
-
-static int
-success(void)
-{
-
- return 0;
-}
-
-struct {
- const char *id;
- int domain;
- addrparse_fn ap;
- connecthook_fn connhook;
-} parsetab[] = {
- { "tcp", PF_INET, tcp_parse, tcp_connecthook },
- { "unix", PF_LOCAL, (addrparse_fn)notsupp, (connecthook_fn)success },
- { "tcp6", PF_INET6, (addrparse_fn)notsupp, (connecthook_fn)success },
-};
-#define NPARSE (sizeof(parsetab)/sizeof(parsetab[0]))
-
struct spservarg {
int sps_sock;
connecthook_fn sps_connhook;
@@ -909,119 +482,60 @@
}
int
-rumpuser_sp_init(const struct rumpuser_sp_ops *spopsp, int *typep)
+rumpuser_sp_init(const struct rumpuser_sp_ops *spopsp, const char *url)
{
+ pthread_t pt;
struct spservarg *sarg;
struct sockaddr *sap;
- char id[16];
- char *p, *p2;
- size_t l;
- unsigned i;
- int error, type, s;
-
- p = NULL;
- error = 0;
- spops = *spopsp;
-
- type = RUMP_SP_NONE;
- if ((p = getenv("RUMP_SP_SERVER")) != NULL) {
- type = RUMP_SP_SERVER;
- }
- if ((p2 = getenv("RUMP_SP_CLIENT")) != NULL) {
- if (type != RUMP_SP_NONE)
- return EEXIST;
- type = RUMP_SP_CLIENT;
- p = p2;
- }
-
- /*
- * Parse the url
- */
-
- if (type == RUMP_SP_NONE)
- return RUMP_SP_NONE;
-
- p2 = strstr(p, "://");
- if (!p2) {
- fprintf(stderr, "rump_sp: invalid locator ``%s''\n", p);
- return EINVAL;
- }
- l = p2-p;
- if (l > sizeof(id)-1) {
- fprintf(stderr, "rump_sp: identifier too long in ``%s''\n", p);
- return EINVAL;
- }
+ char *p;
+ unsigned idx;
+ int error, s;
- strncpy(id, p, l);
- id[l] = '\0';
- p2 += 3; /* beginning of address */
-
- for (i = 0; i < NPARSE; i++) {
- if (strcmp(id, parsetab[i].id) == 0) {
- error = parsetab[i].ap(p2, type, &sap);
- if (error)
- return error;
- break;
- }
- }
- if (i == NPARSE) {
- fprintf(stderr, "rump_sp: invalid identifier ``%s''\n", p);
- return EINVAL;
- }
+ p = strdup(url);
+ if (p == NULL)
+ return ENOMEM;
+ error = parseurl(p, &sap, &idx, 1);
+ free(p);
+ if (error)
+ return error;
- s = socket(parsetab[i].domain, SOCK_STREAM, 0);
+ s = socket(parsetab[idx].domain, SOCK_STREAM, 0);
if (s == -1)
return errno;
- if (type == RUMP_SP_CLIENT) {
- /*LINTED*/
- if (connect(s, sap, sap->sa_len) == -1) {
- fprintf(stderr, "rump_sp: client connect failed\n");
- return errno;
- }
- if ((error = parsetab[i].connhook(s)) != 0) {
- fprintf(stderr, "rump_sp: connect hook failed\n");
- return error;
- }
-
- clispc.spc_fd = s;
- } else {
- pthread_t pt;
-
- sarg = malloc(sizeof(*sarg));
- if (sarg == NULL) {
- close(s);
- return ENOMEM;
- }
+ spops = *spopsp;
+ sarg = malloc(sizeof(*sarg));
+ if (sarg == NULL) {
+ close(s);
+ return ENOMEM;
+ }
- sarg->sps_sock = s;
- sarg->sps_connhook = parsetab[i].connhook;
+ sarg->sps_sock = s;
+ sarg->sps_connhook = parsetab[idx].connhook;
- /* sloppy error recovery */
+ /* sloppy error recovery */
- error = pthread_key_create(&spclient_tls, NULL);
- if (error) {
- fprintf(stderr, "rump_sp: tls create failed\n");
- return error;
- }
+ error = pthread_key_create(&spclient_tls, NULL);
+ if (error) {
+ fprintf(stderr, "rump_sp: tls create failed\n");
+ return error;
+ }
- /*LINTED*/
- if (bind(s, sap, sap->sa_len) == -1) {
- fprintf(stderr, "rump_sp: server bind failed\n");
- return errno;
- }
- if (listen(s, 20) == -1) {
- fprintf(stderr, "rump_sp: server listen failed\n");
- return errno;
- }
+ /*LINTED*/
+ if (bind(s, sap, sap->sa_len) == -1) {
+ fprintf(stderr, "rump_sp: server bind failed\n");
+ return errno;
+ }
+ if (listen(s, 20) == -1) {
+ fprintf(stderr, "rump_sp: server listen failed\n");
+ return errno;
+ }
- if ((error = pthread_create(&pt, NULL, spserver, sarg)) != 0) {
- fprintf(stderr, "rump_sp: cannot create wrkr thread\n");
- return errno;
- }
- pthread_detach(pt);
+ if ((error = pthread_create(&pt, NULL, spserver, sarg)) != 0) {
+ fprintf(stderr, "rump_sp: cannot create wrkr thread\n");
+ return errno;
}
+ pthread_detach(pt);
- *typep = type;
return 0;
}
Index: src/sys/rump/include/rump/rump_syscalls.h
diff -u src/sys/rump/include/rump/rump_syscalls.h:1.31 src/sys/rump/include/rump/rump_syscalls.h:1.32
--- src/sys/rump/include/rump/rump_syscalls.h:1.31 Tue Sep 7 17:10:48 2010
+++ src/sys/rump/include/rump/rump_syscalls.h Thu Nov 4 20:54:07 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: rump_syscalls.h,v 1.31 2010/09/07 17:10:48 pooka Exp $ */
+/* $NetBSD: rump_syscalls.h,v 1.32 2010/11/04 20:54:07 pooka Exp $ */
/*
* System call protos in rump namespace.
Index: src/sys/rump/include/rump/rumpuser.h
diff -u src/sys/rump/include/rump/rumpuser.h:1.48 src/sys/rump/include/rump/rumpuser.h:1.49
--- src/sys/rump/include/rump/rumpuser.h:1.48 Mon Nov 1 13:55:19 2010
+++ src/sys/rump/include/rump/rumpuser.h Thu Nov 4 20:54:08 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: rumpuser.h,v 1.48 2010/11/01 13:55:19 pooka Exp $ */
+/* $NetBSD: rumpuser.h,v 1.49 2010/11/04 20:54:08 pooka Exp $ */
/*
* Copyright (c) 2007 Antti Kantee. All Rights Reserved.
@@ -215,14 +215,9 @@
int (*spop_syscall)(int, void *, register_t *);
};
-int rumpuser_sp_init(const struct rumpuser_sp_ops *, int *);
+int rumpuser_sp_init(const struct rumpuser_sp_ops *, const char *);
int rumpuser_sp_copyin(const void *, void *, size_t);
int rumpuser_sp_copyout(const void *, void *, size_t);
-int rumpuser_sp_syscall(int, const void *, size_t, register_t *);
int rumpuser_sp_anonmmap(size_t, void **);
-#define RUMP_SP_NONE 0
-#define RUMP_SP_CLIENT 1
-#define RUMP_SP_SERVER 2
-
#endif /* _RUMP_RUMPUSER_H_ */
Index: src/sys/rump/librump/rumpkern/rump.c
diff -u src/sys/rump/librump/rumpkern/rump.c:1.195 src/sys/rump/librump/rumpkern/rump.c:1.196
--- src/sys/rump/librump/rumpkern/rump.c:1.195 Mon Nov 1 13:55:20 2010
+++ src/sys/rump/librump/rumpkern/rump.c Thu Nov 4 20:54:07 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: rump.c,v 1.195 2010/11/01 13:55:20 pooka Exp $ */
+/* $NetBSD: rump.c,v 1.196 2010/11/04 20:54:07 pooka Exp $ */
/*
* Copyright (c) 2007 Antti Kantee. All Rights Reserved.
@@ -28,7 +28,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rump.c,v 1.195 2010/11/01 13:55:20 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rump.c,v 1.196 2010/11/04 20:54:07 pooka Exp $");
#include <sys/systm.h>
#define ELFSIZE ARCH_ELFSIZE
@@ -105,7 +105,7 @@
* but good enough for now.
*/
static struct vmspace sp_vmspace;
-static int rumpsp_type;
+static bool iamtheserver = false;
static char rump_msgbuf[16*1024]; /* 16k should be enough for std rump needs */
@@ -215,16 +215,12 @@
spops.spop_lwproc_newproc = rump_lwproc_newproc;
spops.spop_lwproc_curlwp = rump_lwproc_curlwp;
spops.spop_syscall = rump_syscall;
- if ((error = rumpuser_sp_init(&spops, &rumpsp_type)) != 0)
- return error;
- /* If we're a client, we can return directly. Otherwise, proceed. */
- switch (rumpsp_type) {
- case RUMP_SP_CLIENT:
- return 0;
- case RUMP_SP_SERVER:
- case RUMP_SP_NONE:
- break;
+ if (rumpuser_getenv("RUMP_SP_SERVER", buf, sizeof(buf), &error) == 0) {
+ error = rumpuser_sp_init(&spops, buf);
+ if (error)
+ return error;
+ iamtheserver = true;
}
if (rumpuser_getversion() != RUMPUSER_VERSION) {
@@ -637,7 +633,6 @@
return 0;
}
-void *rump_sysproxy_arg; /* XXX: nukeme */
int
rump_syscall(int num, void *arg, register_t *retval)
{
@@ -650,33 +645,16 @@
callp = rump_sysent + num;
l = curlwp;
- if (rumpsp_type == RUMP_SP_SERVER)
+ if (iamtheserver)
curproc->p_vmspace = &sp_vmspace;
rv = sy_call(callp, l, (void *)arg, retval);
- if (rumpsp_type == RUMP_SP_SERVER)
+ if (iamtheserver)
curproc->p_vmspace = &vmspace0;
return rv;
}
int
-rump_sysproxy(int num, void *arg, uint8_t *data, size_t dlen,
- register_t *retval)
-{
- int rv;
-
- if (rumpsp_type == RUMP_SP_CLIENT) {
- rv = rumpuser_sp_syscall(num, data, dlen, retval);
- } else {
- rump_schedule();
- rv = rump_syscall(num, data, retval);
- rump_unschedule();
- }
-
- return rv;
-}
-
-int
rump_boot_gethowto()
{
Index: src/sys/rump/librump/rumpkern/rump_private.h
diff -u src/sys/rump/librump/rumpkern/rump_private.h:1.60 src/sys/rump/librump/rumpkern/rump_private.h:1.61
--- src/sys/rump/librump/rumpkern/rump_private.h:1.60 Fri Oct 29 15:32:24 2010
+++ src/sys/rump/librump/rumpkern/rump_private.h Thu Nov 4 20:54:07 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: rump_private.h,v 1.60 2010/10/29 15:32:24 pooka Exp $ */
+/* $NetBSD: rump_private.h,v 1.61 2010/11/04 20:54:07 pooka Exp $ */
/*
* Copyright (c) 2007 Antti Kantee. All Rights Reserved.
@@ -138,7 +138,4 @@
void *rump_hypermalloc(size_t, int, bool, const char *);
void rump_hyperfree(void *, size_t);
-int rump_sysproxy(int, void *, uint8_t *, size_t, register_t *);
-extern void *rump_sysproxy_arg;
-
#endif /* _SYS_RUMP_PRIVATE_H_ */
Added files:
Index: src/lib/librumpuser/sp_common.c
diff -u /dev/null src/lib/librumpuser/sp_common.c:1.1
--- /dev/null Thu Nov 4 20:54:08 2010
+++ src/lib/librumpuser/sp_common.c Thu Nov 4 20:54:07 2010
@@ -0,0 +1,405 @@
+/* $NetBSD: sp_common.c,v 1.1 2010/11/04 20:54:07 pooka Exp $ */
+
+/*
+ * Copyright (c) 2010 Antti Kantee. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Common client/server sysproxy routines. #included.
+ */
+
+#include <sys/cdefs.h>
+
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/socket.h>
+
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <poll.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+//#define DEBUG
+#ifdef DEBUG
+#define DPRINTF(x) mydprintf x
+static void
+mydprintf(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+}
+#else
+#define DPRINTF(x)
+#endif
+
+/*
+ * Bah, I hate writing on-off-wire conversions in C
+ */
+
+enum {
+ RUMPSP_SYSCALL_REQ, RUMPSP_SYSCALL_RESP,
+ RUMPSP_COPYIN_REQ, RUMPSP_COPYIN_RESP,
+ RUMPSP_COPYOUT_REQ, /* no copyout resp */
+ RUMPSP_ANONMMAP_REQ, RUMPSP_ANONMMAP_RESP
+};
+
+struct rsp_hdr {
+ uint64_t rsp_len;
+ uint64_t rsp_reqno;
+ uint32_t rsp_type;
+ /*
+ * We want this structure 64bit-aligned for typecast fun,
+ * so might as well use the following for something.
+ */
+ uint32_t rsp_sysnum;
+};
+#define HDRSZ sizeof(struct rsp_hdr)
+
+/*
+ * Data follows the header. We have two types of structured data.
+ */
+
+/* copyin/copyout */
+struct rsp_copydata {
+ size_t rcp_len;
+ void *rcp_addr;
+ uint8_t rcp_data[0];
+};
+
+/* syscall response */
+struct rsp_sysresp {
+ int rsys_error;
+ register_t rsys_retval[2];
+};
+
+
+struct spclient {
+ int spc_fd;
+ struct lwp *spc_lwp;
+
+ /* incoming */
+ struct rsp_hdr spc_hdr;
+ uint8_t *spc_buf;
+ size_t spc_off;
+
+#if 0
+ /* outgoing */
+ int spc_obusy;
+ pthread_mutex_t spc_omtx;
+ pthread_cond_t spc_cv;
+#endif
+};
+
+typedef int (*addrparse_fn)(const char *, struct sockaddr **, int);
+typedef int (*connecthook_fn)(int);
+
+static uint64_t nextreq;
+
+static int
+dosend(struct spclient *spc, const void *data, size_t dlen)
+{
+ struct pollfd pfd;
+ const uint8_t *sdata = data;
+ ssize_t n;
+ size_t sent;
+ int fd = spc->spc_fd;
+
+ pfd.fd = fd;
+ pfd.events = POLLOUT;
+
+ for (sent = 0, n = 0; sent < dlen; ) {
+ if (n) {
+ if (poll(&pfd, 1, INFTIM) == -1) {
+ if (errno == EINTR)
+ continue;
+ return errno;
+ }
+ }
+
+ n = write(fd, sdata + sent, dlen - sent);
+ if (n == 0) {
+ return EFAULT;
+ }
+ if (n == -1 && errno != EAGAIN) {
+ return EFAULT;
+ }
+ sent += n;
+ }
+
+ return 0;
+}
+
+static int
+readframe(struct spclient *spc)
+{
+ int fd = spc->spc_fd;
+ size_t left;
+ size_t framelen;
+ ssize_t n;
+
+ /* still reading header? */
+ if (spc->spc_off < HDRSZ) {
+ DPRINTF(("rump_sp: readframe getting header at offset %zu\n",
+ spc->spc_off));
+
+ left = HDRSZ - spc->spc_off;
+ /*LINTED: cast ok */
+ n = read(fd, (uint8_t *)&spc->spc_hdr + spc->spc_off, left);
+ if (n == 0) {
+ return -1;
+ }
+ if (n == -1) {
+ if (errno == EAGAIN)
+ return 0;
+ return -1;
+ }
+
+ spc->spc_off += n;
+ if (spc->spc_off < HDRSZ)
+ return -1;
+
+ /*LINTED*/
+ framelen = spc->spc_hdr.rsp_len;
+
+ if (framelen < HDRSZ) {
+ return -1;
+ } else if (framelen == HDRSZ) {
+ return 1;
+ }
+
+ spc->spc_buf = malloc(framelen - HDRSZ);
+ if (spc->spc_buf == NULL) {
+ return -1;
+ }
+ memset(spc->spc_buf, 0, framelen - HDRSZ);
+
+ /* "fallthrough" */
+ } else {
+ /*LINTED*/
+ framelen = spc->spc_hdr.rsp_len;
+ }
+
+ left = framelen - spc->spc_off;
+
+ DPRINTF(("rump_sp: readframe getting body at offset %zu, left %zu\n",
+ spc->spc_off, left));
+
+ if (left == 0)
+ return 1;
+ n = read(fd, spc->spc_buf + (spc->spc_off - HDRSZ), left);
+ if (n == 0) {
+ return -1;
+ }
+ if (n == -1) {
+ if (errno == EAGAIN)
+ return 0;
+ return -1;
+ }
+ spc->spc_off += n;
+ left -= n;
+
+ /* got everything? */
+ if (left == 0)
+ return 1;
+ else
+ return 0;
+}
+
+static int
+tcp_parse(const char *addr, struct sockaddr **sa, int allow_wildcard)
+{
+ struct sockaddr_in sin;
+ char buf[64];
+ const char *p;
+ size_t l;
+ int port;
+
+ memset(&sin, 0, sizeof(sin));
+ sin.sin_len = sizeof(sin);
+ sin.sin_family = AF_INET;
+
+ p = strchr(addr, ':');
+ if (!p) {
+ fprintf(stderr, "rump_sp_tcp: missing port specifier\n");
+ return EINVAL;
+ }
+
+ l = p - addr;
+ if (l > sizeof(buf)-1) {
+ fprintf(stderr, "rump_sp_tcp: address too long\n");
+ return EINVAL;
+ }
+ strncpy(buf, addr, l);
+ buf[l] = '\0';
+
+ /* special INADDR_ANY treatment */
+ if (strcmp(buf, "*") == 0 || strcmp(buf, "0") == 0) {
+ sin.sin_addr.s_addr = INADDR_ANY;
+ } else {
+ switch (inet_pton(AF_INET, buf, &sin.sin_addr)) {
+ case 1:
+ break;
+ case 0:
+ fprintf(stderr, "rump_sp_tcp: cannot parse %s\n", buf);
+ return EINVAL;
+ case -1:
+ fprintf(stderr, "rump_sp_tcp: inet_pton failed\n");
+ return errno;
+ default:
+ assert(/*CONSTCOND*/0);
+ return EINVAL;
+ }
+ }
+
+ if (!allow_wildcard && sin.sin_addr.s_addr == INADDR_ANY) {
+ fprintf(stderr, "rump_sp_tcp: client needs !INADDR_ANY\n");
+ return EINVAL;
+ }
+
+ /* advance to port number & parse */
+ p++;
+ l = strspn(p, "0123456789");
+ if (l == 0) {
+ fprintf(stderr, "rump_sp_tcp: port now found: %s\n", p);
+ return EINVAL;
+ }
+ strncpy(buf, p, l);
+ buf[l] = '\0';
+
+ if (*(p+l) != '/' && *(p+l) != '\0') {
+ fprintf(stderr, "rump_sp_tcp: junk at end of port: %s\n", addr);
+ return EINVAL;
+ }
+
+ port = atoi(buf);
+ if (port < 0 || port >= (1<<(8*sizeof(in_port_t)))) {
+ fprintf(stderr, "rump_sp_tcp: port %d out of range\n", port);
+ return ERANGE;
+ }
+ sin.sin_port = htons(port);
+
+ *sa = malloc(sizeof(sin));
+ if (*sa == NULL)
+ return errno;
+ memcpy(*sa, &sin, sizeof(sin));
+ return 0;
+}
+
+static int
+tcp_connecthook(int s)
+{
+ int x;
+
+ x = 1;
+ setsockopt(s, IPPROTO_TCP, TCP_NODELAY, &x, sizeof(x));
+
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+notsupp(void)
+{
+
+ fprintf(stderr, "rump_sp: support not yet implemented\n");
+ return EOPNOTSUPP;
+}
+
+static int
+success(void)
+{
+
+ return 0;
+}
+
+struct {
+ const char *id;
+ int domain;
+ addrparse_fn ap;
+ connecthook_fn connhook;
+} parsetab[] = {
+ { "tcp", PF_INET, tcp_parse, tcp_connecthook },
+ { "unix", PF_LOCAL, (addrparse_fn)notsupp, (connecthook_fn)success },
+ { "tcp6", PF_INET6, (addrparse_fn)notsupp, (connecthook_fn)success },
+};
+#define NPARSE (sizeof(parsetab)/sizeof(parsetab[0]))
+
+static int
+parseurl(const char *url, struct sockaddr **sap, unsigned *idxp,
+ int allow_wildcard)
+{
+ char id[16];
+ const char *p, *p2;
+ size_t l;
+ unsigned i;
+ int error;
+
+ /*
+ * Parse the url
+ */
+
+ p = url;
+ p2 = strstr(p, "://");
+ if (!p2) {
+ fprintf(stderr, "rump_sp: invalid locator ``%s''\n", p);
+ return EINVAL;
+ }
+ l = p2-p;
+ if (l > sizeof(id)-1) {
+ fprintf(stderr, "rump_sp: identifier too long in ``%s''\n", p);
+ return EINVAL;
+ }
+
+ strncpy(id, p, l);
+ id[l] = '\0';
+ p2 += 3; /* beginning of address */
+
+ for (i = 0; i < NPARSE; i++) {
+ if (strcmp(id, parsetab[i].id) == 0) {
+ error = parsetab[i].ap(p2, sap, allow_wildcard);
+ if (error)
+ return error;
+ break;
+ }
+ }
+ if (i == NPARSE) {
+ fprintf(stderr, "rump_sp: invalid identifier ``%s''\n", p);
+ return EINVAL;
+ }
+
+ *idxp = i;
+ return 0;
+}