nfsclient: Port to LibBSD

This commit is contained in:
Sebastian Huber 2016-06-10 14:11:40 +02:00
parent 4464594567
commit 58c4e1c592
5 changed files with 177 additions and 78 deletions

View File

@ -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'],

View File

@ -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",

View File

@ -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 */

View File

@ -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

View File

@ -0,0 +1,69 @@
/*
* Copyright (c) 2016 embedded brains GmbH. All rights reserved.
*
* embedded brains GmbH
* Dornierstr. 4
* 82178 Puchheim
* Germany
* <rtems@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>