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

Reply via email to