For the rumpsp protocol, don't assume that the bit representation of

errnos match on the client and server platforms (the syscall subprotocol
errnos are handled by the server compat code).
This commit is contained in:
pooka 2012-09-21 14:33:03 +00:00
parent 5cb635c383
commit bf01f875b4
2 changed files with 57 additions and 20 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: rumpuser_sp.c,v 1.47 2012/07/27 09:09:05 pooka Exp $ */
/* $NetBSD: rumpuser_sp.c,v 1.48 2012/09/21 14:33:03 pooka Exp $ */
/*
* Copyright (c) 2010, 2011 Antti Kantee. All Rights Reserved.
@ -37,7 +37,7 @@
#include "rumpuser_port.h"
#if !defined(lint)
__RCSID("$NetBSD: rumpuser_sp.c,v 1.47 2012/07/27 09:09:05 pooka Exp $");
__RCSID("$NetBSD: rumpuser_sp.c,v 1.48 2012/09/21 14:33:03 pooka Exp $");
#endif /* !lint */
#include <sys/types.h>
@ -88,7 +88,7 @@ static struct rumpuser_sp_ops spops;
static char banner[MAXBANNER];
#define PROTOMAJOR 0
#define PROTOMINOR 3
#define PROTOMINOR 4
/* how to use atomic ops on Linux? */
@ -283,7 +283,7 @@ nextreq(struct spclient *spc)
*/
static void
send_error_resp(struct spclient *spc, uint64_t reqno, int error)
send_error_resp(struct spclient *spc, uint64_t reqno, enum rumpsp_err error)
{
struct rsp_hdr rhdr;
struct iovec iov[1];
@ -891,7 +891,7 @@ schedulework(struct spclient *spc, enum sbatype sba_type)
reqno = spc->spc_hdr.rsp_reqno;
while ((sba = malloc(sizeof(*sba))) == NULL) {
if (nworker == 0 || retries > 10) {
send_error_resp(spc, reqno, EAGAIN);
send_error_resp(spc, reqno, RUMPSP_ERR_TRYAGAIN);
spcfreebuf(spc);
return;
}
@ -947,7 +947,7 @@ handlereq(struct spclient *spc)
reqno = spc->spc_hdr.rsp_reqno;
if (__predict_false(spc->spc_state == SPCSTATE_NEW)) {
if (spc->spc_hdr.rsp_type != RUMPSP_HANDSHAKE) {
send_error_resp(spc, reqno, EACCES);
send_error_resp(spc, reqno, RUMPSP_ERR_AUTH);
shutdown(spc->spc_fd, SHUT_RDWR);
spcfreebuf(spc);
return;
@ -980,7 +980,8 @@ handlereq(struct spclient *spc)
int cancel;
if (spc->spc_off-HDRSZ != sizeof(*rfp)) {
send_error_resp(spc, reqno, EINVAL);
send_error_resp(spc, reqno,
RUMPSP_ERR_MALFORMED_REQUEST);
shutdown(spc->spc_fd, SHUT_RDWR);
spcfreebuf(spc);
return;
@ -1003,7 +1004,8 @@ handlereq(struct spclient *spc)
spcfreebuf(spc);
if (!pf) {
send_error_resp(spc, reqno, ESRCH);
send_error_resp(spc, reqno,
RUMPSP_ERR_INVALID_PREFORK);
shutdown(spc->spc_fd, SHUT_RDWR);
return;
}
@ -1026,7 +1028,8 @@ handlereq(struct spclient *spc)
* interfaces some day if anyone cares)
*/
if ((error = lwproc_rfork(spc, 0, NULL)) != 0) {
send_error_resp(spc, reqno, error);
send_error_resp(spc, reqno,
RUMPSP_ERR_RFORK_FAILED);
shutdown(spc->spc_fd, SHUT_RDWR);
lwproc_release();
return;
@ -1038,7 +1041,7 @@ handlereq(struct spclient *spc)
send_handshake_resp(spc, reqno, 0);
} else {
send_error_resp(spc, reqno, EACCES);
send_error_resp(spc, reqno, RUMPSP_ERR_AUTH);
shutdown(spc->spc_fd, SHUT_RDWR);
spcfreebuf(spc);
return;
@ -1066,14 +1069,14 @@ handlereq(struct spclient *spc)
inexec = spc->spc_inexec;
pthread_mutex_unlock(&spc->spc_mtx);
if (inexec) {
send_error_resp(spc, reqno, EBUSY);
send_error_resp(spc, reqno, RUMPSP_ERR_INEXEC);
shutdown(spc->spc_fd, SHUT_RDWR);
return;
}
pf = malloc(sizeof(*pf));
if (pf == NULL) {
send_error_resp(spc, reqno, ENOMEM);
send_error_resp(spc, reqno, RUMPSP_ERR_NOMEM);
return;
}
@ -1085,7 +1088,7 @@ handlereq(struct spclient *spc)
lwproc_switch(spc->spc_mainlwp);
if ((error = lwproc_rfork(spc, RUMP_RFFDG, NULL)) != 0) {
DPRINTF(("rump_sp: fork failed: %d (%p)\n",error, spc));
send_error_resp(spc, reqno, error);
send_error_resp(spc, reqno, RUMPSP_ERR_RFORK_FAILED);
lwproc_switch(NULL);
free(pf);
return;
@ -1113,7 +1116,8 @@ handlereq(struct spclient *spc)
int inexec;
if (spc->spc_hdr.rsp_handshake != HANDSHAKE_EXEC) {
send_error_resp(spc, reqno, EINVAL);
send_error_resp(spc, reqno,
RUMPSP_ERR_MALFORMED_REQUEST);
shutdown(spc->spc_fd, SHUT_RDWR);
spcfreebuf(spc);
return;
@ -1123,7 +1127,7 @@ handlereq(struct spclient *spc)
inexec = spc->spc_inexec;
pthread_mutex_unlock(&spc->spc_mtx);
if (inexec) {
send_error_resp(spc, reqno, EBUSY);
send_error_resp(spc, reqno, RUMPSP_ERR_INEXEC);
shutdown(spc->spc_fd, SHUT_RDWR);
spcfreebuf(spc);
return;
@ -1150,7 +1154,7 @@ handlereq(struct spclient *spc)
}
if (__predict_false(spc->spc_hdr.rsp_type != RUMPSP_SYSCALL)) {
send_error_resp(spc, reqno, EINVAL);
send_error_resp(spc, reqno, RUMPSP_ERR_MALFORMED_REQUEST);
spcfreebuf(spc);
return;
}
@ -1251,8 +1255,8 @@ spserver(void *arg)
break;
default:
send_error_resp(spc,
spc->spc_hdr.rsp_reqno,
ENOENT);
spc->spc_hdr.rsp_reqno,
RUMPSP_ERR_MALFORMED_REQUEST);
spcfreebuf(spc);
break;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: sp_common.c,v 1.32 2012/07/27 09:09:05 pooka Exp $ */
/* $NetBSD: sp_common.c,v 1.33 2012/09/21 14:33:03 pooka Exp $ */
/*
* Copyright (c) 2010, 2011 Antti Kantee. All Rights Reserved.
@ -105,6 +105,39 @@ enum { RUMPSP_HANDSHAKE,
enum { HANDSHAKE_GUEST, HANDSHAKE_AUTH, HANDSHAKE_FORK, HANDSHAKE_EXEC };
/*
* error types used for RUMPSP_ERROR
*/
enum rumpsp_err { RUMPSP_ERR_NONE = 0, RUMPSP_ERR_TRYAGAIN, RUMPSP_ERR_AUTH,
RUMPSP_ERR_INVALID_PREFORK, RUMPSP_ERR_RFORK_FAILED,
RUMPSP_ERR_INEXEC, RUMPSP_ERR_NOMEM, RUMPSP_ERR_MALFORMED_REQUEST };
/*
* The mapping of the above types to errno. They are almost never exposed
* to the client after handshake (except for a server resource shortage
* and the client trying to be funny). This is a function instead of
* an array to catch missing values. Theoretically, the compiled code
* should be the same.
*/
static int
errmap(enum rumpsp_err error)
{
switch (error) {
/* XXX: no EAUTH on Linux */
case RUMPSP_ERR_NONE: return 0;
case RUMPSP_ERR_AUTH: return EPERM;
case RUMPSP_ERR_TRYAGAIN: return EAGAIN;
case RUMPSP_ERR_INVALID_PREFORK: return ESRCH;
case RUMPSP_ERR_RFORK_FAILED: return EIO; /* got a light? */
case RUMPSP_ERR_INEXEC: return EBUSY;
case RUMPSP_ERR_NOMEM: return ENOMEM;
case RUMPSP_ERR_MALFORMED_REQUEST: return EINVAL;
}
return -1;
}
#define AUTHLEN 4 /* 128bit fork auth */
struct rsp_hdr {
@ -402,7 +435,7 @@ kickwaiter(struct spclient *spc)
rw->rw_done = 1;
rw->rw_dlen = (size_t)(spc->spc_off - HDRSZ);
if (spc->spc_hdr.rsp_class == RUMPSP_ERROR) {
error = rw->rw_error = spc->spc_hdr.rsp_error;
error = rw->rw_error = errmap(spc->spc_hdr.rsp_error);
}
pthread_cond_signal(&rw->rw_cv);
pthread_mutex_unlock(&spc->spc_mtx);