Module Name: src Committed By: pooka Date: Mon Nov 29 16:08:03 UTC 2010
Modified Files: src/lib/librumpclient: rumpclient.c src/lib/librumpuser: rumpuser_sp.c sp_common.c Log Message: Remove remaining panic()s from server-side code. Also, allow to send an out-of-band error. Make the client retry syscall requests if this error is EAGAIN, fail them otherwise. To generate a diff of this commit: cvs rdiff -u -r1.5 -r1.6 src/lib/librumpclient/rumpclient.c cvs rdiff -u -r1.20 -r1.21 src/lib/librumpuser/rumpuser_sp.c cvs rdiff -u -r1.12 -r1.13 src/lib/librumpuser/sp_common.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/lib/librumpclient/rumpclient.c diff -u src/lib/librumpclient/rumpclient.c:1.5 src/lib/librumpclient/rumpclient.c:1.6 --- src/lib/librumpclient/rumpclient.c:1.5 Thu Nov 25 17:59:03 2010 +++ src/lib/librumpclient/rumpclient.c Mon Nov 29 16:08:03 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: rumpclient.c,v 1.5 2010/11/25 17:59:03 pooka Exp $ */ +/* $NetBSD: rumpclient.c,v 1.6 2010/11/29 16:08:03 pooka Exp $ */ /* * Copyright (c) 2010 Antti Kantee. All Rights Reserved. @@ -70,15 +70,18 @@ rhdr.rsp_type = RUMPSP_SYSCALL; rhdr.rsp_sysnum = sysnum; - putwait(spc, &rw, &rhdr); - rv = dosend(spc, &rhdr, sizeof(rhdr)); - rv = dosend(spc, data, dlen); - if (rv) { - unputwait(spc, &rw); - return rv; - } + do { + putwait(spc, &rw, &rhdr); + rv = dosend(spc, &rhdr, sizeof(rhdr)); + rv = dosend(spc, data, dlen); + if (rv) { + unputwait(spc, &rw); + return rv; + } + + rv = waitresp(spc, &rw); + } while (rv == EAGAIN); - rv = waitresp(spc, &rw); *resp = rw.rw_data; return rv; } @@ -198,9 +201,7 @@ break; } - free(spc->spc_buf); - spc->spc_off = 0; - spc->spc_buf = NULL; + spcfreebuf(spc); } int Index: src/lib/librumpuser/rumpuser_sp.c diff -u src/lib/librumpuser/rumpuser_sp.c:1.20 src/lib/librumpuser/rumpuser_sp.c:1.21 --- src/lib/librumpuser/rumpuser_sp.c:1.20 Mon Nov 29 11:40:54 2010 +++ src/lib/librumpuser/rumpuser_sp.c Mon Nov 29 16:08:03 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: rumpuser_sp.c,v 1.20 2010/11/29 11:40:54 pooka Exp $ */ +/* $NetBSD: rumpuser_sp.c,v 1.21 2010/11/29 16:08:03 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.20 2010/11/29 11:40:54 pooka Exp $"); +__RCSID("$NetBSD: rumpuser_sp.c,v 1.21 2010/11/29 16:08:03 pooka Exp $"); #include <sys/types.h> #include <sys/atomic.h> @@ -178,6 +178,22 @@ return nw; } +static void +send_error_resp(struct spclient *spc, uint64_t reqno, int error) +{ + struct rsp_hdr rhdr; + + rhdr.rsp_len = sizeof(rhdr); + rhdr.rsp_reqno = reqno; + rhdr.rsp_class = RUMPSP_ERROR; + rhdr.rsp_type = 0; + rhdr.rsp_error = error; + + sendlock(spc); + (void)dosend(spc, &rhdr, sizeof(rhdr)); + sendunlock(spc); +} + static int send_syscall_resp(struct spclient *spc, uint64_t reqno, int error, register_t *retval) @@ -605,21 +621,29 @@ { struct sysbouncearg *sba; pthread_t pt; + int retries; - /* XXX: check that it's a syscall */ + if (__predict_false(spc->spc_hdr.rsp_type != RUMPSP_SYSCALL)) { + send_error_resp(spc, spc->spc_hdr.rsp_reqno, EINVAL); + spcfreebuf(spc); + return; + } - sba = malloc(sizeof(*sba)); - if (sba == NULL) { - /* panic */ - abort(); + retries = 0; + while ((sba = malloc(sizeof(*sba))) == NULL) { + if (nworker == 0 || retries > 10) { + send_error_resp(spc, spc->spc_hdr.rsp_reqno, EAGAIN); + spcfreebuf(spc); + return; + } + /* slim chance of more memory? */ + usleep(10000); } sba->sba_spc = spc; sba->sba_hdr = spc->spc_hdr; sba->sba_data = spc->spc_buf; - - spc->spc_buf = NULL; - spc->spc_off = 0; + spcresetbuf(spc); spcref(spc); @@ -731,8 +755,10 @@ handlereq(spc); break; default: - printf("PANIC\n"); - abort(); + send_error_resp(spc, + spc->spc_hdr.rsp_reqno, + ENOENT); + spcfreebuf(spc); break; } break; Index: src/lib/librumpuser/sp_common.c diff -u src/lib/librumpuser/sp_common.c:1.12 src/lib/librumpuser/sp_common.c:1.13 --- src/lib/librumpuser/sp_common.c:1.12 Fri Nov 26 18:51:03 2010 +++ src/lib/librumpuser/sp_common.c Mon Nov 29 16:08:03 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: sp_common.c,v 1.12 2010/11/26 18:51:03 pooka Exp $ */ +/* $NetBSD: sp_common.c,v 1.13 2010/11/29 16:08:03 pooka Exp $ */ /* * Copyright (c) 2010 Antti Kantee. All Rights Reserved. @@ -44,6 +44,7 @@ #include <assert.h> #include <errno.h> #include <fcntl.h> +#include <inttypes.h> #include <poll.h> #include <pthread.h> #include <stdarg.h> @@ -73,7 +74,7 @@ * Bah, I hate writing on-off-wire conversions in C */ -enum { RUMPSP_REQ, RUMPSP_RESP }; +enum { RUMPSP_REQ, RUMPSP_RESP, RUMPSP_ERROR }; enum { RUMPSP_SYSCALL, RUMPSP_COPYIN, RUMPSP_COPYINSTR, RUMPSP_COPYOUT, RUMPSP_COPYOUTSTR, @@ -88,9 +89,14 @@ * We want this structure 64bit-aligned for typecast fun, * so might as well use the following for something. */ - uint32_t rsp_sysnum; + union { + uint32_t sysnum; + uint32_t error; + } u; }; #define HDRSZ sizeof(struct rsp_hdr) +#define rsp_sysnum u.sysnum +#define rsp_error u.error /* * Data follows the header. We have two types of structured data. @@ -113,6 +119,7 @@ uint64_t rw_reqno; void *rw_data; size_t rw_dlen; + int rw_error; pthread_cond_t rw_cv; @@ -153,6 +160,22 @@ static int readframe(struct spclient *); static void handlereq(struct spclient *); +static __inline void +spcresetbuf(struct spclient *spc) +{ + + spc->spc_buf = NULL; + spc->spc_off = 0; +} + +static __inline void +spcfreebuf(struct spclient *spc) +{ + + free(spc->spc_buf); + spcresetbuf(spc); +} + static void sendlockl(struct spclient *spc) { @@ -266,18 +289,25 @@ break; } if (rw == NULL) { - printf("PANIC: no waiter\n"); - abort(); + DPRINTF(("no waiter found, invalid reqno %" PRIu64 "?\n", + spc->spc_hdr.rsp_reqno)); return; } DPRINTF(("rump_sp: client %p woke up waiter at %p\n", spc, rw)); rw->rw_data = spc->spc_buf; rw->rw_dlen = (size_t)(spc->spc_off - HDRSZ); + if (spc->spc_hdr.rsp_class == RUMPSP_ERROR) { + rw->rw_error = spc->spc_hdr.rsp_error; + } else { + rw->rw_error = 0; + } pthread_cond_signal(&rw->rw_cv); pthread_mutex_unlock(&spc->spc_mtx); - spc->spc_buf = NULL; - spc->spc_off = 0; + if (rw->rw_error) + spcfreebuf(spc); + else + spcresetbuf(spc); } static void @@ -298,7 +328,8 @@ sendunlockl(spc); - while (rw->rw_data == NULL && spc->spc_dying == 0) { + rw->rw_error = 0; + while (rw->rw_data == NULL && rw->rw_error == 0 && spc->spc_dying == 0){ /* are we free to receive? */ if (spc->spc_istatus == SPCSTATUS_FREE) { int gotresp; @@ -324,6 +355,7 @@ switch (spc->spc_hdr.rsp_class) { case RUMPSP_RESP: + case RUMPSP_ERROR: kickwaiter(spc); gotresp = spc->spc_hdr.rsp_reqno == rw->rw_reqno; @@ -352,9 +384,11 @@ pthread_cond_destroy(&rw->rw_cv); - if (rv == 0 && spc->spc_dying) - rv = ENOTCONN; - return rv; + if (rv) + return rv; + if (spc->spc_dying) + return ENOTCONN; + return rw->rw_error; } static int