Module Name:    src
Committed By:   pooka
Date:           Fri Aug  3 11:31:34 UTC 2012

Modified Files:
        src/lib/librumpclient: rumpclient.c rumpclient.h
        src/sys/kern: makesyscalls.sh

Log Message:
Make librumpclient compile and work on Linux.  This is accomplished by:

1) avoid "NetBSD'isms" in the rumpclient sources
2) do not require the knowledge of unnecessary weird_t's in syscallargs.h
   for rumpclient


To generate a diff of this commit:
cvs rdiff -u -r1.48 -r1.49 src/lib/librumpclient/rumpclient.c
cvs rdiff -u -r1.11 -r1.12 src/lib/librumpclient/rumpclient.h
cvs rdiff -u -r1.123 -r1.124 src/sys/kern/makesyscalls.sh

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.48 src/lib/librumpclient/rumpclient.c:1.49
--- src/lib/librumpclient/rumpclient.c:1.48	Wed Mar 21 10:10:37 2012
+++ src/lib/librumpclient/rumpclient.c	Fri Aug  3 11:31:34 2012
@@ -1,4 +1,4 @@
-/*      $NetBSD: rumpclient.c,v 1.48 2012/03/21 10:10:37 matt Exp $	*/
+/*      $NetBSD: rumpclient.c,v 1.49 2012/08/03 11:31:34 pooka Exp $	*/
 
 /*
  * Copyright (c) 2010, 2011 Antti Kantee.  All Rights Reserved.
@@ -29,13 +29,36 @@
  * Client side routines for rump syscall proxy.
  */
 
+#include "rumpuser_port.h"
+
+/*
+ * We use kqueue on NetBSD, poll elsewhere.  Theoretically we could
+ * use kqueue on other BSD's too, but I haven't tested those.  We
+ * want to use kqueue because it will give us the ability to get signal
+ * notifications but defer their handling to a stage where we do not
+ * hold the communication lock.  Taking a signal while holding on to
+ * that lock may cause a deadlock.  Therefore, block signals throughout
+ * the RPC when using poll.  This unfortunately means that the normal
+ * SIGINT way of stopping a process while it is undergoing rump kernel
+ * RPC will not work.  If anyone know which Linux system call handles
+ * the above scenario correctly, I'm all ears.
+ */
+
+#ifdef __NetBSD__
+#define USE_KQUEUE
+#endif
+
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: rumpclient.c,v 1.48 2012/03/21 10:10:37 matt Exp $");
+__RCSID("$NetBSD: rumpclient.c,v 1.49 2012/08/03 11:31:34 pooka Exp $");
 
 #include <sys/param.h>
-#include <sys/event.h>
 #include <sys/mman.h>
 #include <sys/socket.h>
+#include <sys/time.h>
+
+#ifdef USE_KQUEUE
+#include <sys/event.h>
+#endif
 
 #include <arpa/inet.h>
 #include <netinet/in.h>
@@ -70,9 +93,11 @@ ssize_t (*host_sendmsg)(int, const struc
 int	(*host_setsockopt)(int, int, int, const void *, socklen_t);
 int	(*host_dup)(int);
 
+#ifdef USE_KQUEUE
 int	(*host_kqueue)(void);
 int	(*host_kevent)(int, const struct kevent *, size_t,
 		       struct kevent *, size_t, const struct timespec *);
+#endif
 
 int	(*host_execve)(const char *, char *const[], char *const[]);
 
@@ -197,14 +222,17 @@ cliwaitresp(struct spclient *spc, struct
 
 		/* are we free to receive? */
 		if (spc->spc_istatus == SPCSTATUS_FREE) {
-			struct kevent kev[8];
-			int gotresp, dosig, rv, i;
+			int gotresp, dosig, rv;
 
 			spc->spc_istatus = SPCSTATUS_BUSY;
 			pthread_mutex_unlock(&spc->spc_mtx);
 
 			dosig = 0;
 			for (gotresp = 0; !gotresp; ) {
+#ifdef USE_KQUEUE
+				struct kevent kev[8];
+				int i;
+
 				/*
 				 * typically we don't have a frame waiting
 				 * when we come in here, so call kevent now
@@ -239,6 +267,15 @@ cliwaitresp(struct spclient *spc, struct
 				 * determine what happens next.
 				 */
  activity:
+#else /* USE_KQUEUE */
+				struct pollfd pfd;
+
+				pfd.fd = clispc.spc_fd;
+				pfd.events = POLLIN;
+
+				rv = host_poll(&pfd, 1, -1);
+#endif /* !USE_KQUEUE */
+
 				switch (readframe(spc)) {
 				case 0:
 					continue;
@@ -343,7 +380,29 @@ handshake_req(struct spclient *spc, int 
 	if (type == HANDSHAKE_FORK) {
 		bonus = sizeof(rf);
 	} else {
+#ifdef __NetBSD__
+		/* would procfs work on NetBSD too? */
 		myprogname = getprogname();
+#else
+		int fd = open("/proc/self/comm", O_RDONLY);
+		if (fd == -1) {
+			myprogname = "???";
+		} else {
+			static char commname[128];
+
+			if (read(fd, commname, sizeof(commname)) > 0) {
+				char *n;
+
+				n = strrchr(commname, '\n');
+				if (n)
+					*n = '\0';
+				myprogname = commname;
+			} else {
+				myprogname = "???";
+			}
+			close(fd);
+		}
+#endif
 		bonus = strlen(myprogname)+1;
 	}
 
@@ -620,10 +679,9 @@ doconnect(void)
 {
 	struct respwait rw;
 	struct rsp_hdr rhdr;
-	struct kevent kev[NSIG+1];
 	char banner[MAXBANNER];
 	struct pollfd pfd;
-	int s, error, flags, i;
+	int s, error, flags;
 	ssize_t n;
 
 	if (kq != -1)
@@ -668,7 +726,7 @@ doconnect(void)
 
 	pfd.fd = s;
 	pfd.events = POLLIN;
-	while (host_connect(s, serv_sa, (socklen_t)serv_sa->sa_len) == -1) {
+	while (host_connect(s, serv_sa, parsetab[ptab_idx].slen) == -1) {
 		if (errno == EINTR)
 			continue;
 		ERRLOG(("rump_sp: client connect failed: %s\n",
@@ -702,6 +760,11 @@ doconnect(void)
 	clispc.spc_state = SPCSTATE_RUNNING;
 	clispc.spc_reconnecting = 0;
 
+#ifdef USE_KQUEUE
+{
+	struct kevent kev[NSIG+1];
+	int i;
+
 	/* setup kqueue, we want all signals and the fd */
 	if ((kq = dupgood(host_kqueue(), 0)) == -1) {
 		ERRLOG(("rump_sp: cannot setup kqueue"));
@@ -717,6 +780,8 @@ doconnect(void)
 		ERRLOG(("rump_sp: kevent() failed"));
 		return -1;
 	}
+}
+#endif /* USE_KQUEUE */
 
 	return 0;
 }
@@ -733,14 +798,14 @@ doinit(void)
 }
 
 void *rumpclient__dlsym(void *, const char *);
-void *rumphijack_dlsym(void *, const char *) __attribute__((__weak__));
 void *
 rumpclient__dlsym(void *handle, const char *symbol)
 {
 
 	return dlsym(handle, symbol);
 }
-__weak_alias(rumphijack_dlsym,rumpclient__dlsym)
+void *rumphijack_dlsym(void *, const char *)
+    __attribute__((__weak__, alias("rumpclient__dlsym")));
 
 static pid_t init_done = 0;
 
@@ -771,7 +836,7 @@ rumpclient_init(void)
 	sigfillset(&fullset);
 
 	/*
-	 * sag mir, wo die symbol sind.  zogen fort, der krieg beginnt.
+	 * sag mir, wo die symbols sind.  zogen fort, der krieg beginnt.
 	 * wann wird man je verstehen?  wann wird man je verstehen?
 	 */
 #define FINDSYM2(_name_,_syscall_)					\
@@ -784,7 +849,12 @@ rumpclient_init(void)
 			    dlerror());					\
 	}
 #define FINDSYM(_name_) FINDSYM2(_name_,_name_)
+#ifdef __NetBSD__
 	FINDSYM2(socket,__socket30)
+#else
+	FINDSYM(socket)
+#endif
+
 	FINDSYM(close)
 	FINDSYM(connect)
 	FINDSYM(fcntl)
@@ -793,13 +863,17 @@ rumpclient_init(void)
 	FINDSYM(sendmsg)
 	FINDSYM(setsockopt)
 	FINDSYM(dup)
-	FINDSYM(kqueue)
 	FINDSYM(execve)
+
+#ifdef USE_KQUEUE
+	FINDSYM(kqueue)
 #if !__NetBSD_Prereq__(5,99,7)
 	FINDSYM(kevent)
 #else
 	FINDSYM2(kevent,_sys___kevent50)
 #endif
+#endif /* USE_KQUEUE */
+
 #undef	FINDSYM
 #undef	FINDSY2
 
@@ -960,11 +1034,14 @@ rumpclient__closenotify(int *fdp, enum r
 	case RUMPCLIENT_CLOSE_CLOSE:
 	case RUMPCLIENT_CLOSE_DUP2:
 		if (fd == clispc.spc_fd) {
-			struct kevent kev[2];
-
 			newfd = dupgood(clispc.spc_fd, 1);
 			if (newfd == -1)
 				return -1;
+
+#ifdef USE_KQUEUE
+			{
+			struct kevent kev[2];
+
 			/*
 			 * now, we have a new socket number, so change
 			 * the file descriptor that kqueue is
@@ -981,12 +1058,16 @@ rumpclient__closenotify(int *fdp, enum r
 				return -1;
 			}
 			clispc.spc_fd = newfd;
+			}
 		}
 		if (fd == kq) {
 			newfd = dupgood(kq, 1);
 			if (newfd == -1)
 				return -1;
 			kq = newfd;
+#else /* USE_KQUEUE */
+			clispc.spc_fd = newfd;
+#endif /* !USE_KQUEUE */
 		}
 		break;
 	}

Index: src/lib/librumpclient/rumpclient.h
diff -u src/lib/librumpclient/rumpclient.h:1.11 src/lib/librumpclient/rumpclient.h:1.12
--- src/lib/librumpclient/rumpclient.h:1.11	Fri Dec 16 23:19:28 2011
+++ src/lib/librumpclient/rumpclient.h	Fri Aug  3 11:31:34 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: rumpclient.h,v 1.11 2011/12/16 23:19:28 joerg Exp $	*/
+/*	$NetBSD: rumpclient.h,v 1.12 2012/08/03 11:31:34 pooka Exp $	*/
 
 /*-
  * Copyright (c) 2010 Antti Kantee.  All Rights Reserved.
@@ -29,7 +29,14 @@
 #define _RUMP_RUMPCLIENT_H_
 
 #include <sys/types.h>
-#include <sys/null.h>
+
+#if !defined(__returns_twice)
+#ifdef __GNUC__
+#define __returns_twice __attribute__((__returns_twice__))
+#else /* __GNUC__ */
+#define __returns_twice
+#endif /* !__GNUC__ */
+#endif /* !__returns_twice */
 
 struct rumpclient_fork;
 
@@ -61,6 +68,7 @@ enum rumpclient_closevariant {
 };
 int rumpclient__closenotify(int *, enum rumpclient_closevariant);
 
+
 /*
  * vfork needs to be implemented as an inline to make everything
  * run in the caller's stackframe.
@@ -72,7 +80,7 @@ rumpclient__dofork(pid_t (*forkfn)(void)
 	pid_t pid;
 	int childran = 0;
 
-	if ((rf = rumpclient_prefork()) == NULL)
+	if (!(rf = rumpclient_prefork()))
 		return -1;
                 
 	switch ((pid = forkfn())) {

Index: src/sys/kern/makesyscalls.sh
diff -u src/sys/kern/makesyscalls.sh:1.123 src/sys/kern/makesyscalls.sh:1.124
--- src/sys/kern/makesyscalls.sh:1.123	Fri Jul 20 18:19:09 2012
+++ src/sys/kern/makesyscalls.sh	Fri Aug  3 11:31:33 2012
@@ -1,4 +1,4 @@
-#	$NetBSD: makesyscalls.sh,v 1.123 2012/07/20 18:19:09 pooka Exp $
+#	$NetBSD: makesyscalls.sh,v 1.124 2012/08/03 11:31:33 pooka Exp $
 #
 # Copyright (c) 1994, 1996, 2000 Christopher G. Demetriou
 # All rights reserved.
@@ -162,6 +162,9 @@ BEGIN {
 	compatopts = \"$compatopts\"
 	"'
 
+	if (rumpcalls != "/dev/null")
+		haverumpcalls = 1
+
 	printf "/* %s */\n\n", tag > sysdcl
 	printf "/*\n * System call switch table.\n *\n" > sysdcl
 	printf " * DO NOT EDIT-- this file is automatically generated.\n" > sysdcl
@@ -188,6 +191,8 @@ BEGIN {
 	printf " * DO NOT EDIT-- this file is automatically generated.\n" > sysnames
 
 	printf "\n/*\n * System call prototypes.\n */\n\n" > sysprotos
+	if (haverumpcalls)
+		printf("#ifndef RUMP_CLIENT\n") > sysprotos
 
 	printf "/* %s */\n\n", tag > sysnumhdr
 	printf "/*\n * System call numbers.\n *\n" > sysnumhdr
@@ -214,15 +219,19 @@ NR == 1 {
 	printf "#include <sys/cdefs.h>\n__KERNEL_RCSID(0, \"%s\");\n\n", tag > sysnames
 
 	printf " * created from%s\n */\n\n", $0 > rumpcalls
+	printf "#include <sys/param.h>\n\n" > rumpcalls
+	printf "#ifdef __NetBSD__\n" > rumpcalls
 	printf "#include <sys/cdefs.h>\n__KERNEL_RCSID(0, \"%s\");\n\n", tag > rumpcalls
 
-	printf "#include <sys/param.h>\n" > rumpcalls
 	printf "#include <sys/fstypes.h>\n" > rumpcalls
 	printf "#include <sys/proc.h>\n" > rumpcalls
+	printf "#endif /* __NetBSD__ */\n\n" > rumpcalls
 	printf "#ifdef RUMP_CLIENT\n" > rumpcalls
+	printf "#include <errno.h>\n" > rumpcalls
+	printf "#include <stdint.h>\n" > rumpcalls
+	printf "#include <stdlib.h>\n\n" > rumpcalls
 	printf "#include <srcsys/syscall.h>\n" > rumpcalls
 	printf "#include <srcsys/syscallargs.h>\n\n" > rumpcalls
-	printf "#include <errno.h>\n" > rumpcalls
 	printf "#include <rump/rumpclient.h>\n\n" > rumpcalls
 	printf "#define rsys_syscall(num, data, dlen, retval)\t\\\n" > rumpcalls
 	printf "    rumpclient_syscall(num, data, dlen, retval)\n" > rumpcalls
@@ -732,7 +741,10 @@ function putent(type, compatwrap) {
 
 	# output syscall argument structure, if it has arguments
 	if (argc != 0) {
-		printf("\nstruct %s%s_args", compatwrap_, funcname) > sysarghdr
+		printf("\n") > sysarghdr
+		if (haverumpcalls && !rumpable)
+			printf("#ifndef RUMP_CLIENT\n") > sysarghdr
+		printf("struct %s%s_args", compatwrap_, funcname) > sysarghdr
 		if (type != "NOARGS") {
 			print " {" >sysarghdr;
 			for (i = 1; i <= argc; i++)
@@ -745,6 +757,8 @@ function putent(type, compatwrap) {
 			printf("check_syscall_args(%s%s)\n", compatwrap_,
 			    funcname) >sysarghdr
 		}
+		if (haverumpcalls && !rumpable)
+			printf("#endif /* !RUMP_CLIENT */\n") > sysarghdr
 	}
 
 	if (!rumpable) {
@@ -943,6 +957,8 @@ END {
 	printf("};\n") > rumpsysent
 	printf("CTASSERT(__arraycount(rump_sysent) == SYS_NSYSENT);\n") > rumpsysent
 	printf("#endif /* RUMP_CLIENT */\n") > rumpsysent
+	if (haverumpcalls)
+		printf("#endif /* !RUMP_CLIENT */\n") > sysprotos
 	printf("};\n") > sysnamesbottom
 	printf("#define\t%sMAXSYSCALL\t%d\n", constprefix, maxsyscall) > sysnumhdr
 	if (nsysent)

Reply via email to