[rtems-libbsd commit] nfsclient: Port to LibBSD

Sebastian Huber sebh at rtems.org
Fri Jun 10 12:15:35 UTC 2016


Module:    rtems-libbsd
Branch:    master
Commit:    58c4e1c59278acd4e87f5f4372ac6eb3ad0bafb5
Changeset: http://git.rtems.org/rtems-libbsd/commit/?id=58c4e1c59278acd4e87f5f4372ac6eb3ad0bafb5

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Fri Jun 10 14:11:40 2016 +0200

nfsclient: Port to LibBSD

---

 libbsd.py                   |   5 ++
 libbsd_waf.py               |  14 ++++
 rtemsbsd/nfsclient/nfs.c    |   6 +-
 rtemsbsd/nfsclient/rpcio.c  | 161 +++++++++++++++++++++++---------------------
 testsuite/nfs01/test_main.c |  69 +++++++++++++++++++
 5 files changed, 177 insertions(+), 78 deletions(-)

diff --git a/libbsd.py b/libbsd.py
index e7c7d06..d2659c4 100755
--- a/libbsd.py
+++ b/libbsd.py
@@ -110,6 +110,10 @@ def rtems(mm):
             'ftpfs/ftpfs.c',
             'mdns/mdns.c',
             'mdns/mdns-hostname-default.c',
+            'nfsclient/mount_prot_xdr.c',
+            'nfsclient/nfs.c',
+            'nfsclient/nfs_prot_xdr.c',
+            'nfsclient/rpcio.c',
             'pppd/auth.c',
             'pppd/ccp.c',
             'pppd/chap.c',
@@ -2496,6 +2500,7 @@ def in_cksum(mm):
 #
 def tests(mm):
     mod = builder.Module('tests')
+    mod.addTest(mm.generator['test']('nfs01', ['test_main'], netTest = True))
     mod.addTest(mm.generator['test']('foobarclient', ['test_main'],
                                      runTest = False, netTest = True))
     mod.addTest(mm.generator['test']('foobarserver', ['test_main'],
diff --git a/libbsd_waf.py b/libbsd_waf.py
index b751c9f..25a979c 100644
--- a/libbsd_waf.py
+++ b/libbsd_waf.py
@@ -1018,6 +1018,10 @@ def build(bld):
               'rtemsbsd/local/usb_if.c',
               'rtemsbsd/mdns/mdns-hostname-default.c',
               'rtemsbsd/mdns/mdns.c',
+              'rtemsbsd/nfsclient/mount_prot_xdr.c',
+              'rtemsbsd/nfsclient/nfs.c',
+              'rtemsbsd/nfsclient/nfs_prot_xdr.c',
+              'rtemsbsd/nfsclient/rpcio.c',
               'rtemsbsd/pppd/auth.c',
               'rtemsbsd/pppd/ccp.c',
               'rtemsbsd/pppd/chap.c',
@@ -1337,6 +1341,16 @@ def build(bld):
                 lib = ["m", "z"],
                 install_path = None)
 
+    test_nfs01 = ['testsuite/nfs01/test_main.c']
+    bld.program(target = "nfs01.exe",
+                features = "cprogram",
+                cflags = cflags,
+                includes = includes,
+                source = test_nfs01,
+                use = ["bsd"],
+                lib = ["m", "z"],
+                install_path = None)
+
     test_ping01 = ['testsuite/ping01/test_main.c']
     bld.program(target = "ping01.exe",
                 features = "cprogram",
diff --git a/rtemsbsd/nfsclient/nfs.c b/rtemsbsd/nfsclient/nfs.c
index 17a726d..fae79b8 100644
--- a/rtemsbsd/nfsclient/nfs.c
+++ b/rtemsbsd/nfsclient/nfs.c
@@ -79,11 +79,11 @@
 #include <netinet/in.h>
 #include <arpa/inet.h>
 
-#include <nfs_prot.h>
-#include <mount_prot.h>
+#include "nfs_prot.h"
+#include "mount_prot.h"
 
 #include "rpcio.h"
-#include "librtemsNfs.h"
+#include <librtemsNfs.h>
 
 /* Configurable parameters */
 
diff --git a/rtemsbsd/nfsclient/rpcio.c b/rtemsbsd/nfsclient/rpcio.c
index 2848225..6bc1aad 100644
--- a/rtemsbsd/nfsclient/rpcio.c
+++ b/rtemsbsd/nfsclient/rpcio.c
@@ -71,7 +71,7 @@
 
 #include <rtems.h>
 #include <rtems/error.h>
-#include <rtems/rtems_bsdnet.h>
+#include <rtems/bsd/bsd.h>
 #include <stdlib.h>
 #include <time.h>
 #include <rpc/rpc.h>
@@ -85,6 +85,7 @@
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <sys/cpuset.h>
+#include <sys/event.h>
 
 #include "rpcio.h"
 #include "nfsclient-private.h"
@@ -93,14 +94,14 @@
 /* CONFIGURABLE PARAMETERS                                      */
 /****************************************************************/
 
-#define MBUF_RX			/* If defined: use mbuf XDR stream for
+#undef MBUF_RX			/* If defined: use mbuf XDR stream for
 						 *  decoding directly out of mbufs
 						 *  Otherwise, the regular 'recvfrom()'
 						 *  interface will be used involving an
 						 *  extra buffer allocation + copy step.
 						 */
 
-#define MBUF_TX			/* If defined: avoid copying data when
+#undef MBUF_TX			/* If defined: avoid copying data when
 						 *  sending. Instead, use a wrapper to
 						 *  'sosend()' which will point an MBUF
 						 *  directly to our buffer space.
@@ -121,8 +122,7 @@
 						 */
 
 /* daemon task parameters */
-#define RPCIOD_STACK		10000
-#define RPCIOD_PRIO			100	/* *fallback* priority */
+#define RPCIOD_NAME		"RPCD"
 
 /* depth of the message queue for sending
  * RPC requests to the daemon
@@ -149,9 +149,10 @@ static struct timeval _rpc_default_timeout = { 10 /* secs */, 0 /* usecs */ };
 											 * RPC IO will receive this - hence it is
 											 * RESERVED
 											 */
-#define RPCIOD_RX_EVENT		RTEMS_EVENT_1	/* Events the RPCIOD is using/waiting for */
-#define RPCIOD_TX_EVENT		RTEMS_EVENT_2
-#define RPCIOD_KILL_EVENT	RTEMS_EVENT_3	/* send to the daemon to kill it          */
+#define RPCIOD_KQ_IDENT		0xeb
+#define RPCIOD_RX_EVENT		0x1	/* Events the RPCIOD is using/waiting for */
+#define RPCIOD_TX_EVENT		0x2
+#define RPCIOD_KILL_EVENT	0x4	/* send to the daemon to kill it          */
 
 #define LD_XACT_HASH		8				/* ld of the size of the transaction hash table  */
 
@@ -393,6 +394,7 @@ static RpcUdpServer		rpcUdpServers = 0;	/* linked list of all servers; protected
 
 static int				ourSock = -1;		/* the socket we are using for communication */
 static rtems_id			rpciod  = 0;		/* task id of the RPC daemon                 */
+static int	  		rpcKq = -1;		/* the kqueue of the RPC daemon */
 static rtems_id			msgQ    = 0;		/* message queue where the daemon picks up
 											 * requests
 											 */
@@ -407,12 +409,6 @@ static rtems_interval	ticksPerSec;		/* cached system clock rate (WHO IS ASSUMED
 											 * TO CHANGE)
 											 */
 
-rtems_task_priority		rpciodPriority = 0;
-#ifdef RTEMS_SMP
-const cpu_set_t			*rpciodCpuset = 0;
-size_t				rpciodCpusetSize = 0;
-#endif
-
 #if (DEBUG) & DEBUG_MALLOC
 /* malloc wrappers for debugging */
 static int nibufs = 0;
@@ -481,15 +477,34 @@ bool_t rval;
 }
 
 static inline bool_t
-locked_refresh(RpcUdpServer s)
+locked_refresh(RpcUdpServer s, struct rpc_msg *msg)
 {
 bool_t rval;
 	MU_LOCK(s->authlock);
-	rval = AUTH_REFRESH(s->auth);
+	rval = AUTH_REFRESH(s->auth, msg);
 	MU_UNLOCK(s->authlock);
 	return rval;
 }
 
+static void
+sendEventToRpcServer(u_int events)
+{
+struct kevent	trigger;
+int		s;
+
+	EV_SET(
+		&trigger,
+		RPCIOD_KQ_IDENT,
+		EVFILT_USER,
+		0,
+		NOTE_TRIGGER | NOTE_FFOR | events,
+		0,
+		0);
+
+	s = kevent(rpcKq, &trigger, 1, NULL, 0, NULL);
+	assert(s == 0);
+}
+
 /* Create a server object
  *
  */
@@ -507,7 +522,7 @@ RpcUdpServer	rval;
 u_short			port;
 char			hname[MAX_MACHINE_NAME + 1];
 int				theuid, thegid;
-int				thegids[NGRPS];
+u_int				thegids[NGRPS];
 gid_t			gids[NGROUPS];
 int				len,i;
 AUTH			*auth;
@@ -828,7 +843,7 @@ va_list			ap;
 		return RPC_CANTSEND;
 	}
 	/* wakeup the rpciod */
-	ASSERT( RTEMS_SUCCESSFUL==rtems_event_send(rpciod, RPCIOD_TX_EVENT) );
+	sendEventToRpcServer(RPCIOD_TX_EVENT);
 
 	return RPC_SUCCESS;
 }
@@ -911,14 +926,14 @@ rtems_event_set		gotEvents;
 	xact->ibufsize = 0;
 #endif
 
-	if (refresh && locked_refresh(xact->server)) {
+	if (refresh && locked_refresh(xact->server, &reply_msg)) {
 		rtems_task_ident(RTEMS_SELF, RTEMS_WHO_AM_I, &xact->requestor);
 		if ( rtems_message_queue_send(msgQ, &xact, sizeof(xact)) ) {
 			return RPC_CANTSEND;
 		}
 		/* wakeup the rpciod */
 		fprintf(stderr,"RPCIO INFO: refreshing my AUTH\n");
-		ASSERT( RTEMS_SUCCESSFUL==rtems_event_send(rpciod, RPCIOD_TX_EVENT) );
+		sendEventToRpcServer(RPCIOD_TX_EVENT);
 	}
 
 	} while ( 0 &&  refresh-- > 0 );
@@ -926,17 +941,6 @@ rtems_event_set		gotEvents;
 	return xact->status.re_status;
 }
 
-
-/* On RTEMS, I'm told to avoid select(); this seems to
- * be more efficient
- */
-static void
-rxWakeupCB(struct socket *sock, void *arg)
-{
-  rtems_id *rpciod = (rtems_id*) arg;
-  rtems_event_send(*rpciod, RPCIOD_RX_EVENT);
-}
-
 void
 rpcSetXIDs(uint32_t xid)
 {
@@ -955,7 +959,7 @@ rpcUdpInit(void)
 int			s;
 rtems_status_code	status;
 int			noblock = 1;
-struct sockwakeup	wkup;
+struct kevent		change;
 
 	if (ourSock < 0) {
     fprintf(stderr,"RTEMS-RPCIOD $Release$, " \
@@ -972,34 +976,41 @@ struct sockwakeup	wkup;
 			MU_CREAT( &hlock );
 			MU_CREAT( &llock );
 
-			if ( !rpciodPriority ) {
-				/* use configured networking priority */
-				if ( ! (rpciodPriority = rtems_bsdnet_config.network_task_priority) )
-					rpciodPriority = RPCIOD_PRIO;	/* fallback value */
-			}
+			rpcKq = kqueue();
+			assert( rpcKq >= 0 );
+
+			EV_SET(
+				&change,
+				RPCIOD_KQ_IDENT,
+				EVFILT_USER, EV_ADD | EV_ENABLE | EV_CLEAR,
+				NOTE_FFNOP,
+				0,
+				0);
+
+			s = kevent( rpcKq, &change, 1, NULL, 0, NULL );
+			assert( s == 0 );
+
+			EV_SET(
+				&change,
+				ourSock,
+				EVFILT_READ, EV_ADD | EV_ENABLE,
+				0,
+				0,
+				0);
+
+			s = kevent( rpcKq, &change, 1, NULL, 0, NULL );
+			assert( s == 0 );
 
 			status = rtems_task_create(
 											rtems_build_name('R','P','C','d'),
-											rpciodPriority,
-											RPCIOD_STACK,
+											rtems_bsd_get_task_priority(RPCIOD_NAME),
+											rtems_bsd_get_task_stack_size(RPCIOD_NAME),
 											RTEMS_DEFAULT_MODES,
 											/* fprintf saves/restores FP registers on PPC :-( */
 											RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT,
 											&rpciod);
 			assert( status == RTEMS_SUCCESSFUL );
 
-#ifdef RTEMS_SMP
-			if ( rpciodCpuset == 0 ) {
-				rpciodCpuset = rtems_bsdnet_config.network_task_cpuset;
-				rpciodCpusetSize = rtems_bsdnet_config.network_task_cpuset_size;
-			}
-			if ( rpciodCpuset != 0 )
-				rtems_task_set_affinity( rpciod, rpciodCpusetSize, rpciodCpuset );
-#endif
-
-			wkup.sw_pfn = rxWakeupCB;
-			wkup.sw_arg = &rpciod;
-			assert( 0==setsockopt(ourSock, SOL_SOCKET, SO_RCVWAKEUP, &wkup, sizeof(wkup)) );
 			status = rtems_message_queue_create(
 											rtems_build_name('R','P','C','q'),
 											RPCIOD_QDEPTH,
@@ -1026,7 +1037,7 @@ rpcUdpCleanup(void)
 			RTEMS_DEFAULT_ATTRIBUTES,
 			0,
 			&fini);
-	rtems_event_send(rpciod, RPCIOD_KILL_EVENT);
+	sendEventToRpcServer(RPCIOD_KILL_EVENT);
 	/* synchronize with daemon */
 	rtems_semaphore_obtain(fini, RTEMS_WAIT, 5*ticksPerSec);
 	/* if the message queue is still there, something went wrong */
@@ -1175,12 +1186,11 @@ nodeAppend(ListNode l, ListNode n)
 static void
 rpcio_daemon(rtems_task_argument arg)
 {
-rtems_status_code stat;
 RpcUdpXact        xact;
 RpcUdpServer      srv;
 rtems_interval    next_retrans, then, unow;
 long			  			now;	/* need to do signed comparison with age! */
-rtems_event_set   events;
+u_int             events;
 ListNode          newList;
 size_t            size;
 rtems_id          q          =  0;
@@ -1193,15 +1203,27 @@ rtems_status_code	status;
         then = rtems_clock_get_ticks_since_boot();
 
 	for (next_retrans = epoch;;) {
+		{
+			struct timespec timeout = {
+				.tv_sec = (next_retrans + ticksPerSec - 1) / ticksPerSec,
+				.tv_nsec = 0
+			};
+			struct kevent event[2];
+			int i;
+			int n;
+
+			n = kevent(rpcKq, NULL, 0, &event[0], 2, &timeout);
+			assert(n >= 0);
 
-		if ( RTEMS_SUCCESSFUL !=
-			 (stat = rtems_event_receive(
-						RPCIOD_RX_EVENT | RPCIOD_TX_EVENT | RPCIOD_KILL_EVENT,
-						RTEMS_WAIT | RTEMS_EVENT_ANY,
-						next_retrans,
-						&events)) ) {
-			ASSERT( RTEMS_TIMEOUT == stat );
 			events = 0;
+
+			for (i = 0; i < n; ++i) {
+				if (event[i].filter == EVFILT_USER) {
+					events |= event[i].fflags;
+				} else {
+					events |= RPCIOD_RX_EVENT;
+				}
+			}
 		}
 
 		if (events & RPCIOD_KILL_EVENT) {
@@ -1498,6 +1520,7 @@ rtems_status_code	status;
 	}
 	/* close our socket; shut down the receiver */
 	close(ourSock);
+	close(rpcKq);
 
 #if 0 /* if we get here, no transactions exist, hence there can be none
 	   * in the queue whatsoever
@@ -1625,7 +1648,7 @@ RpcUdpXactPool pool;
  *             the RTEMS/BSDNET headers redefine those :-(
  */
 
-#define _KERNEL
+#include <machine/rtems-bsd-kernel-space.h>
 #include <sys/mbuf.h>
 
 static void
@@ -1687,7 +1710,7 @@ union {
 	struct sockaddr_in	sin;
 	struct sockaddr     sa;
 }					fromAddr;
-int					fromLen  = sizeof(fromAddr.sin);
+socklen_t				fromLen  = sizeof(fromAddr.sin);
 RxBuf				ibuf     = 0;
 RpcUdpXact			xact     = 0;
 
@@ -1800,15 +1823,3 @@ cleanup:
 
 	return 0;
 }
-
-
-#include <rtems/rtems_bsdnet_internal.h>
-/* double check the event configuration; should probably globally
- * manage system events!!
- * We do this at the end of the file for the same reason we had
- * included mbuf.h only a couple of lines above - see comment up
- * there...
- */
-#if RTEMS_RPC_EVENT & SOSLEEP_EVENT & SBWAIT_EVENT & NETISR_EVENTS
-#error ILLEGAL EVENT CONFIGURATION
-#endif
diff --git a/testsuite/nfs01/test_main.c b/testsuite/nfs01/test_main.c
new file mode 100644
index 0000000..37d48ac
--- /dev/null
+++ b/testsuite/nfs01/test_main.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2016 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Dornierstr. 4
+ *  82178 Puchheim
+ *  Germany
+ *  <rtems at embedded-brains.de>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <assert.h>
+#include <unistd.h>
+
+#include <rtems.h>
+#include <rtems/libio.h>
+
+#include <librtemsNfs.h>
+
+#include <rtems/bsd/test/network-config.h>
+
+#define TEST_NAME "LIBBSD NFS 1"
+
+static void
+test_main(void)
+{
+	static const char remote_target[] =
+	    "1000.100@" NET_CFG_PEER_IP " :/srv/nfs";
+	int rv;
+
+	do {
+		sleep(1);
+
+		rv = mount_and_make_target_path(&remote_target[0], "/nfs",
+		    RTEMS_FILESYSTEM_TYPE_NFS, RTEMS_FILESYSTEM_READ_WRITE,
+		    NULL);
+	} while (rv != 0);
+
+	rtems_task_delete(RTEMS_SELF);
+	assert(0);
+}
+
+#define DEFAULT_NETWORK_SHELL
+
+#define CONFIGURE_FILESYSTEM_NFS
+
+#define CONFIGURE_MAXIMUM_DRIVERS 32
+
+#include <rtems/bsd/test/default-network-init.h>



More information about the vc mailing list