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.
This commit is contained in:
parent
240e9917d0
commit
d402686fe2
|
@ -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 @@ syscall_req(struct spclient *spc, int sysnum,
|
|||
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 @@ handlereq(struct spclient *spc)
|
|||
break;
|
||||
}
|
||||
|
||||
free(spc->spc_buf);
|
||||
spc->spc_off = 0;
|
||||
spc->spc_buf = NULL;
|
||||
spcfreebuf(spc);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -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 @@ nextreq(struct spclient *spc)
|
|||
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 @@ handlereq(struct spclient *spc)
|
|||
{
|
||||
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 @@ spserver(void *arg)
|
|||
handlereq(spc);
|
||||
break;
|
||||
default:
|
||||
printf("PANIC\n");
|
||||
abort();
|
||||
send_error_resp(spc,
|
||||
spc->spc_hdr.rsp_reqno,
|
||||
ENOENT);
|
||||
spcfreebuf(spc);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -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 @@ mydprintf(const char *fmt, ...)
|
|||
* 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 @@ struct rsp_hdr {
|
|||
* 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 @@ struct respwait {
|
|||
uint64_t rw_reqno;
|
||||
void *rw_data;
|
||||
size_t rw_dlen;
|
||||
int rw_error;
|
||||
|
||||
pthread_cond_t rw_cv;
|
||||
|
||||
|
@ -153,6 +160,22 @@ typedef int (*connecthook_fn)(int);
|
|||
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 @@ kickwaiter(struct spclient *spc)
|
|||
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 @@ waitresp(struct spclient *spc, struct respwait *rw)
|
|||
|
||||
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 @@ waitresp(struct spclient *spc, struct respwait *rw)
|
|||
|
||||
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 @@ waitresp(struct spclient *spc, struct respwait *rw)
|
|||
|
||||
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
|
||||
|
|
Loading…
Reference in New Issue