This commit was generated by cvs2svn to compensate for changes in r15677,

which included commits to RCS files with non-trunk default branches.
This commit is contained in:
Ralf Corsepius
2007-07-25 05:22:23 +00:00
25 changed files with 13055 additions and 0 deletions
+112
View File
@@ -0,0 +1,112 @@
Changes since RTEMS-NFS 1.4:
LICENSE:
- changed license terms; RTEMS-NFS is now released under the more liberal
'SLAC license'.
NFS:
- silenced compiler warnings (follow handler declaration changes in libio.h
by using 'size_t' instead of 'uint32_t' etc.).
Changes since RTEMS-NFS 1.3:
RPCIOD:
- round timeout to next system clock tick and ensure it is at least
1 tick.
- cap retransmission timeout to transaction lifetime.
- BUGFIX (reported by Steven Johnson, 12/5/06): we must change the XID
before sending a timed-out transaction back to the requestor to prevent
a late reply from being accepted.
- Made task priority run-time configurable (and read from rtems_bsdnet_config
by default).
NFS:
- added nfsGetTimeout() and nfsSetTimeout() to retrieve and modify,
respectively the (global) timeout for NFS/MOUNT operations.
- Minor mod. to fix 'type-punned pointer' warning (can avoid pointer cast).
- Added global variable 'nfsStBlksize' (defaults to 8k) which is now
used to report the file system's 'preferred' blocksize (stat(2)/st_blksize).
The old behavior (server's fattr.st_blksize is passed through) can be
obtained by setting nfsStBlksize=0.
The new feature lets stdio use 8k buffers (only if newlib was built with
HAVE_BLKSIZE defined). This enhances NFS (buffered) read performance quite
a bit. Thanks to Steven Johnson <sjohnson@sakuraindustries.com> for helping
with this.
- Updated README (performance section).
- Added simple performance test: nfsTest.c
Changes since RTEMS-NFS 1.3_pre2:
RPCIOD:
- fix a problem with NFS server clusters (reply comes from an IP address
different from the destination of the request) by relaxing paranoia checks.
Changes since RTEMS-NFS 1.2:
NFS:
- replaced inet_aton -> inet_pton
- replaced unsigned32 -> uint32_t
- added _KERNEL definition for 4.7 compilation
- silenced compiler warnings (4.7)
- added -Wno-unused-variable in 'proto' -- rpcgen produces a lot of them.
- new locking scheme. The 'in-use' counters cannot be protected by a mutex
because files might be closed when a thread is deleted from a dispatch-disabled
section where mutexes must not be locked. The counters are now protected by
disabling interrupts.
The only critical race-condition I can see ATM is while the NFS is being
unmounted and the mount point is crossed by another thread. It should be the
generic FS code's responsibility to handle that (but AFAIK, it doesn't) --
it's out of our scope...
- ftruncate didn't work. The functionality is achieved by nfs_sattr()
setting the file size to 0. However, nfs_sattr() always tried to set
all attributes (re-applying the current values to fields we didn't
want to change) which failed (EPERM) if we were not the owner.
Now, we restrict modifications to the requested fields (in case of
ftruncate this is *only* the size), adhering to rfc1094 (which states
that unused fields shall be set to -1).
- lseek(SEEK_END) didn't work. The underlying RTEMS filesystem code
uses an internal file 'size' field to compute the offset whence SEEK_END.
Instead of painfully maintaining 'size' across all system calls, we
just tweak the offset for SEEK_END and leave 'size' unused.
- fix: O_APPEND wasn't honoured. Note that there is no NFS 'append' call -
the client simply uses the currently available idea of the file size
to set the write offset. This obviously is subject to race conditions
if multiple clients are writing the same file.
dirutils:
- replaced read/write calls by stdio; In case of copying to stdout, I
experienced occasional crashes when write(fileno(stdout),...) -- according
to the standard, mixing low-level i/o with stdio might produce undefined
results; there we go...
Changes since RTEMS-NFS 1.1:
NFS:
- unlink() didnt work. The underlying RTEMS filesystem code evaluates
a '..' path on a non-directory node to find out the file's parent
directory. Workaround to this semantically inelegant RTEMS feature
was implemented.
Changes since RTEMS-NFS 1.0.beta3:
NFS:
- fixed possible string overrun in nfsMount
- nfs_read_dir() must reset the 'eofreached' flag if it skipped
dirents present in the xdr but not fitting into the user buffer.
- nfsMountsShow() released the wrong lock!
RPCIO:
- cannot delete locked binary semaphore (authlock) -- must unlock
first (authlock was never deleted and hence effectively leaked)
- added ASSERT paranoia around mutex primitives
- Relaxed paranoia check / ASSERTion failure:
paranoia_free() is called more than once on an ext_buf - it must
undo calls to paranoia_refcnt() - hence the 0 == --refcnt check
is too strict.
- Added a DEBUG flag to introduce random packet losses for testing
retransmission.
xdr_mbuf:
- make sure we do a signed comparison
Changes since rtemsNFS-1.0.beta2:
- moved 'tar' command to the 'config' area; use
predefined 'make-tar' in individual Makefiles
- use INSTALL_CHANGE for headers, not INSTALL_VARIANT (probably doesn't
matter, though)
- use LD not LD_FOR_TARGET (to get absolute path)
- fixed assertion failure print format
- print requestor id if send_event fails - had just experienced this :-(
- hint about fprintf using FP registers is probably PPC specific
- provided implementation for xdrmbuf_getlong_aligned(). i386-rtems
seems to use it.
+44
View File
@@ -0,0 +1,44 @@
/*
* Authorship
* ----------
* This software (NFS-2 client implementation for RTEMS) was created by
* Till Straumann <strauman@slac.stanford.edu>, 2002-2007,
* Stanford Linear Accelerator Center, Stanford University.
*
* Acknowledgement of sponsorship
* ------------------------------
* The NFS-2 client implementation for RTEMS was produced by
* the Stanford Linear Accelerator Center, Stanford University,
* under Contract DE-AC03-76SFO0515 with the Department of Energy.
*
* Government disclaimer of liability
* ----------------------------------
* Neither the United States nor the United States Department of Energy,
* nor any of their employees, makes any warranty, express or implied, or
* assumes any legal liability or responsibility for the accuracy,
* completeness, or usefulness of any data, apparatus, product, or process
* disclosed, or represents that its use would not infringe privately owned
* rights.
*
* Stanford disclaimer of liability
* --------------------------------
* Stanford University makes no representations or warranties, express or
* implied, nor assumes any liability for the use of this software.
*
* Stanford disclaimer of copyright
* --------------------------------
* Stanford University, owner of the copyright, hereby disclaims its
* copyright and all other rights in this software. Hence, anyone may
* freely use it for any purpose without restriction.
*
* Maintenance of notices
* ----------------------
* In the interest of clarity regarding the origin and status of this
* SLAC software, this and all the preceding Stanford University notices
* are to remain affixed to any copy or derivative of this software made
* or distributed by the recipient and are to be affixed to any copy of
* software made or distributed by the recipient that contains a copy or
* derivative of this software.
*
* ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
*/
+16
View File
@@ -0,0 +1,16 @@
#
# $Id$
#
include $(RTEMS_MAKEFILE_PATH)/Makefile.inc
include $(RTEMS_CUSTOM)
include $(RTEMS_ROOT)/make/directory.cfg
SUBDIRS=proto src
REVISION=$(filter-out $$%,$$Name$$)
tar: tar-recursive
@$(make-tar)
File diff suppressed because it is too large Load Diff
+76
View File
@@ -0,0 +1,76 @@
#
# $Id$
#
# Templates/Makefile.lib
# Template library Makefile
#
LIBNAME=libnfsprot.a # xxx- your library names goes here
LIB=${ARCH}/${LIBNAME}
# C and C++ source names, if any, go here -- minus the .c or .cc
C_PIECES=nfs_prot_xdr mount_prot_xdr
C_FILES=$(C_PIECES:%=%.c)
C_O_FILES=$(C_PIECES:%=${ARCH}/%.o)
CC_PIECES=
CC_FILES=$(CC_PIECES:%=%.cc)
CC_O_FILES=$(CC_PIECES:%=${ARCH}/%.o)
H_FILES=
XFILES = $(wildcard *.x)
# Assembly source names, if any, go here -- minus the .S
S_PIECES=
S_FILES=$(S_PIECES:%=%.S)
S_O_FILES=$(S_FILES:%.S=${ARCH}/%.o)
SRCS=$(C_FILES) $(CC_FILES) $(H_FILES) $(S_FILES)
OBJS=$(C_O_FILES) $(CC_O_FILES) $(S_O_FILES)
include $(RTEMS_MAKEFILE_PATH)/Makefile.inc
include $(RTEMS_CUSTOM)
include $(RTEMS_ROOT)/make/lib.cfg
#
# Add local stuff here using +=
#
DEFINES +=
CPPFLAGS +=
# inline declarations require -O
# rpcgen produces unused variables
CFLAGS += -O2 -Winline -Wno-unused-variable
#
# Add your list of files to delete here. The config files
# already know how to delete some stuff, so you may want
# to just run 'make clean' first to see what gets missed.
# 'make clobber' already includes 'make clean'
#
CLEAN_ADDITIONS +=
CLOBBER_ADDITIONS += $(XFILES:%.x=%*.c) $(XFILES:%.x=%*.h)
all: ${ARCH} $(SRCS) $(LIB)
$(LIB): ${OBJS}
$(make-library)
%_xdr.c: %.x %.h
rpcgen -c -C $< > $@
%.h: %.x
rpcgen -h -C $< > $@
.PRECIOUS: $(XFILES:%.x=%.h) $(XFILES:%.x=%_xdr.c)
tar: $(XFILES:%.x=%.h) $(XFILES:%.x=%_xdr.c)
distclean: clean
# DONT install this library.
install: all
+144
View File
@@ -0,0 +1,144 @@
/*
* Please do not edit this file.
* It was generated using rpcgen.
*/
#ifndef _MOUNT_PROT_H_RPCGEN
#define _MOUNT_PROT_H_RPCGEN
#include <rpc/rpc.h>
#ifdef __cplusplus
extern "C" {
#endif
#define MNTPATHLEN 1024
#define MNTNAMLEN 255
#define FHSIZE 32
typedef char fhandle[FHSIZE];
struct fhstatus {
u_int fhs_status;
union {
fhandle fhs_fhandle;
} fhstatus_u;
};
typedef struct fhstatus fhstatus;
typedef char *dirpath;
typedef char *name;
typedef struct mountbody *mountlist;
struct mountbody {
name ml_hostname;
dirpath ml_directory;
mountlist ml_next;
};
typedef struct mountbody mountbody;
typedef struct groupnode *groups;
struct groupnode {
name gr_name;
groups gr_next;
};
typedef struct groupnode groupnode;
typedef struct exportnode *exports;
struct exportnode {
dirpath ex_dir;
groups ex_groups;
exports ex_next;
};
typedef struct exportnode exportnode;
#define MOUNTPROG 100005
#define MOUNTVERS 1
#if defined(__STDC__) || defined(__cplusplus)
#define MOUNTPROC_NULL 0
extern void * mountproc_null_1(void *, CLIENT *);
extern void * mountproc_null_1_svc(void *, struct svc_req *);
#define MOUNTPROC_MNT 1
extern fhstatus * mountproc_mnt_1(dirpath *, CLIENT *);
extern fhstatus * mountproc_mnt_1_svc(dirpath *, struct svc_req *);
#define MOUNTPROC_DUMP 2
extern mountlist * mountproc_dump_1(void *, CLIENT *);
extern mountlist * mountproc_dump_1_svc(void *, struct svc_req *);
#define MOUNTPROC_UMNT 3
extern void * mountproc_umnt_1(dirpath *, CLIENT *);
extern void * mountproc_umnt_1_svc(dirpath *, struct svc_req *);
#define MOUNTPROC_UMNTALL 4
extern void * mountproc_umntall_1(void *, CLIENT *);
extern void * mountproc_umntall_1_svc(void *, struct svc_req *);
#define MOUNTPROC_EXPORT 5
extern exports * mountproc_export_1(void *, CLIENT *);
extern exports * mountproc_export_1_svc(void *, struct svc_req *);
#define MOUNTPROC_EXPORTALL 6
extern exports * mountproc_exportall_1(void *, CLIENT *);
extern exports * mountproc_exportall_1_svc(void *, struct svc_req *);
extern int mountprog_1_freeresult (SVCXPRT *, xdrproc_t, caddr_t);
#else /* K&R C */
#define MOUNTPROC_NULL 0
extern void * mountproc_null_1();
extern void * mountproc_null_1_svc();
#define MOUNTPROC_MNT 1
extern fhstatus * mountproc_mnt_1();
extern fhstatus * mountproc_mnt_1_svc();
#define MOUNTPROC_DUMP 2
extern mountlist * mountproc_dump_1();
extern mountlist * mountproc_dump_1_svc();
#define MOUNTPROC_UMNT 3
extern void * mountproc_umnt_1();
extern void * mountproc_umnt_1_svc();
#define MOUNTPROC_UMNTALL 4
extern void * mountproc_umntall_1();
extern void * mountproc_umntall_1_svc();
#define MOUNTPROC_EXPORT 5
extern exports * mountproc_export_1();
extern exports * mountproc_export_1_svc();
#define MOUNTPROC_EXPORTALL 6
extern exports * mountproc_exportall_1();
extern exports * mountproc_exportall_1_svc();
extern int mountprog_1_freeresult ();
#endif /* K&R C */
/* the xdr functions */
#if defined(__STDC__) || defined(__cplusplus)
extern bool_t xdr_fhandle (XDR *, fhandle);
extern bool_t xdr_fhstatus (XDR *, fhstatus*);
extern bool_t xdr_dirpath (XDR *, dirpath*);
extern bool_t xdr_name (XDR *, name*);
extern bool_t xdr_mountlist (XDR *, mountlist*);
extern bool_t xdr_mountbody (XDR *, mountbody*);
extern bool_t xdr_groups (XDR *, groups*);
extern bool_t xdr_groupnode (XDR *, groupnode*);
extern bool_t xdr_exports (XDR *, exports*);
extern bool_t xdr_exportnode (XDR *, exportnode*);
#else /* K&R C */
extern bool_t xdr_fhandle ();
extern bool_t xdr_fhstatus ();
extern bool_t xdr_dirpath ();
extern bool_t xdr_name ();
extern bool_t xdr_mountlist ();
extern bool_t xdr_mountbody ();
extern bool_t xdr_groups ();
extern bool_t xdr_groupnode ();
extern bool_t xdr_exports ();
extern bool_t xdr_exportnode ();
#endif /* K&R C */
#ifdef __cplusplus
}
#endif
#endif /* !_MOUNT_PROT_H_RPCGEN */
+161
View File
@@ -0,0 +1,161 @@
/* @(#)mount.x 2.1 88/08/01 4.0 RPCSRC */
/* @(#)mount.x 1.2 87/09/18 Copyr 1987 Sun Micro */
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
* media and as a part of the software program in whole or part. Users
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
/*
* Protocol description for the mount program
*/
const MNTPATHLEN = 1024; /* maximum bytes in a pathname argument */
const MNTNAMLEN = 255; /* maximum bytes in a name argument */
const FHSIZE = 32; /* size in bytes of a file handle */
/*
* The fhandle is the file handle that the server passes to the client.
* All file operations are done using the file handles to refer to a file
* or a directory. The file handle can contain whatever information the
* server needs to distinguish an individual file.
*/
typedef opaque fhandle[FHSIZE];
/*
* If a status of zero is returned, the call completed successfully, and
* a file handle for the directory follows. A non-zero status indicates
* some sort of error. The status corresponds with UNIX error numbers.
*/
union fhstatus switch (unsigned fhs_status) {
case 0:
fhandle fhs_fhandle;
default:
void;
};
/*
* The type dirpath is the pathname of a directory
*/
typedef string dirpath<MNTPATHLEN>;
/*
* The type name is used for arbitrary names (hostnames, groupnames)
*/
typedef string name<MNTNAMLEN>;
/*
* A list of who has what mounted
*/
typedef struct mountbody *mountlist;
struct mountbody {
name ml_hostname;
dirpath ml_directory;
mountlist ml_next;
};
/*
* A list of netgroups
*/
typedef struct groupnode *groups;
struct groupnode {
name gr_name;
groups gr_next;
};
/*
* A list of what is exported and to whom
*/
typedef struct exportnode *exports;
struct exportnode {
dirpath ex_dir;
groups ex_groups;
exports ex_next;
};
program MOUNTPROG {
/*
* Version one of the mount protocol communicates with version two
* of the NFS protocol. The only connecting point is the fhandle
* structure, which is the same for both protocols.
*/
version MOUNTVERS {
/*
* Does no work. It is made available in all RPC services
* to allow server reponse testing and timing
*/
void
MOUNTPROC_NULL(void) = 0;
/*
* If fhs_status is 0, then fhs_fhandle contains the
* file handle for the directory. This file handle may
* be used in the NFS protocol. This procedure also adds
* a new entry to the mount list for this client mounting
* the directory.
* Unix authentication required.
*/
fhstatus
MOUNTPROC_MNT(dirpath) = 1;
/*
* Returns the list of remotely mounted filesystems. The
* mountlist contains one entry for each hostname and
* directory pair.
*/
mountlist
MOUNTPROC_DUMP(void) = 2;
/*
* Removes the mount list entry for the directory
* Unix authentication required.
*/
void
MOUNTPROC_UMNT(dirpath) = 3;
/*
* Removes all of the mount list entries for this client
* Unix authentication required.
*/
void
MOUNTPROC_UMNTALL(void) = 4;
/*
* Returns a list of all the exported filesystems, and which
* machines are allowed to import it.
*/
exports
MOUNTPROC_EXPORT(void) = 5;
/*
* Identical to MOUNTPROC_EXPORT above
*/
exports
MOUNTPROC_EXPORTALL(void) = 6;
} = 1;
} = 100005;
+124
View File
@@ -0,0 +1,124 @@
/*
* Please do not edit this file.
* It was generated using rpcgen.
*/
#include "mount_prot.h"
bool_t
xdr_fhandle (XDR *xdrs, fhandle objp)
{
register int32_t *buf;
if (!xdr_opaque (xdrs, objp, FHSIZE))
return FALSE;
return TRUE;
}
bool_t
xdr_fhstatus (XDR *xdrs, fhstatus *objp)
{
register int32_t *buf;
if (!xdr_u_int (xdrs, &objp->fhs_status))
return FALSE;
switch (objp->fhs_status) {
case 0:
if (!xdr_fhandle (xdrs, objp->fhstatus_u.fhs_fhandle))
return FALSE;
break;
default:
break;
}
return TRUE;
}
bool_t
xdr_dirpath (XDR *xdrs, dirpath *objp)
{
register int32_t *buf;
if (!xdr_string (xdrs, objp, MNTPATHLEN))
return FALSE;
return TRUE;
}
bool_t
xdr_name (XDR *xdrs, name *objp)
{
register int32_t *buf;
if (!xdr_string (xdrs, objp, MNTNAMLEN))
return FALSE;
return TRUE;
}
bool_t
xdr_mountlist (XDR *xdrs, mountlist *objp)
{
register int32_t *buf;
if (!xdr_pointer (xdrs, (char **)objp, sizeof (struct mountbody), (xdrproc_t) xdr_mountbody))
return FALSE;
return TRUE;
}
bool_t
xdr_mountbody (XDR *xdrs, mountbody *objp)
{
register int32_t *buf;
if (!xdr_name (xdrs, &objp->ml_hostname))
return FALSE;
if (!xdr_dirpath (xdrs, &objp->ml_directory))
return FALSE;
if (!xdr_mountlist (xdrs, &objp->ml_next))
return FALSE;
return TRUE;
}
bool_t
xdr_groups (XDR *xdrs, groups *objp)
{
register int32_t *buf;
if (!xdr_pointer (xdrs, (char **)objp, sizeof (struct groupnode), (xdrproc_t) xdr_groupnode))
return FALSE;
return TRUE;
}
bool_t
xdr_groupnode (XDR *xdrs, groupnode *objp)
{
register int32_t *buf;
if (!xdr_name (xdrs, &objp->gr_name))
return FALSE;
if (!xdr_groups (xdrs, &objp->gr_next))
return FALSE;
return TRUE;
}
bool_t
xdr_exports (XDR *xdrs, exports *objp)
{
register int32_t *buf;
if (!xdr_pointer (xdrs, (char **)objp, sizeof (struct exportnode), (xdrproc_t) xdr_exportnode))
return FALSE;
return TRUE;
}
bool_t
xdr_exportnode (XDR *xdrs, exportnode *objp)
{
register int32_t *buf;
if (!xdr_dirpath (xdrs, &objp->ex_dir))
return FALSE;
if (!xdr_groups (xdrs, &objp->ex_groups))
return FALSE;
if (!xdr_exports (xdrs, &objp->ex_next))
return FALSE;
return TRUE;
}
+453
View File
@@ -0,0 +1,453 @@
/*
* Please do not edit this file.
* It was generated using rpcgen.
*/
#ifndef _NFS_PROT_H_RPCGEN
#define _NFS_PROT_H_RPCGEN
#include <rpc/rpc.h>
#ifdef __cplusplus
extern "C" {
#endif
#define NFS_PORT 2049
#define NFS_MAXDATA 8192
#define NFS_MAXPATHLEN 1024
#define NFS_MAXNAMLEN 255
#define NFS_FHSIZE 32
#define NFS_COOKIESIZE 4
#define NFS_FIFO_DEV -1
#define NFSMODE_FMT 0170000
#define NFSMODE_DIR 0040000
#define NFSMODE_CHR 0020000
#define NFSMODE_BLK 0060000
#define NFSMODE_REG 0100000
#define NFSMODE_LNK 0120000
#define NFSMODE_SOCK 0140000
#define NFSMODE_FIFO 0010000
enum nfsstat {
NFS_OK = 0,
NFSERR_PERM = 1,
NFSERR_NOENT = 2,
NFSERR_IO = 5,
NFSERR_NXIO = 6,
NFSERR_ACCES = 13,
NFSERR_EXIST = 17,
NFSERR_NODEV = 19,
NFSERR_NOTDIR = 20,
NFSERR_ISDIR = 21,
NFSERR_FBIG = 27,
NFSERR_NOSPC = 28,
NFSERR_ROFS = 30,
NFSERR_NAMETOOLONG = 63,
NFSERR_NOTEMPTY = 66,
NFSERR_DQUOT = 69,
NFSERR_STALE = 70,
NFSERR_WFLUSH = 99,
};
typedef enum nfsstat nfsstat;
enum ftype {
NFNON = 0,
NFREG = 1,
NFDIR = 2,
NFBLK = 3,
NFCHR = 4,
NFLNK = 5,
NFSOCK = 6,
NFBAD = 7,
NFFIFO = 8,
};
typedef enum ftype ftype;
struct nfs_fh {
char data[NFS_FHSIZE];
};
typedef struct nfs_fh nfs_fh;
struct nfstime {
u_int seconds;
u_int useconds;
};
typedef struct nfstime nfstime;
struct fattr {
ftype type;
u_int mode;
u_int nlink;
u_int uid;
u_int gid;
u_int size;
u_int blocksize;
u_int rdev;
u_int blocks;
u_int fsid;
u_int fileid;
nfstime atime;
nfstime mtime;
nfstime ctime;
};
typedef struct fattr fattr;
struct sattr {
u_int mode;
u_int uid;
u_int gid;
u_int size;
nfstime atime;
nfstime mtime;
};
typedef struct sattr sattr;
typedef char *filename;
typedef char *nfspath;
struct attrstat {
nfsstat status;
union {
fattr attributes;
} attrstat_u;
};
typedef struct attrstat attrstat;
struct sattrargs {
nfs_fh file;
sattr attributes;
};
typedef struct sattrargs sattrargs;
struct diropargs {
nfs_fh dir;
filename name;
};
typedef struct diropargs diropargs;
struct diropokres {
nfs_fh file;
fattr attributes;
};
typedef struct diropokres diropokres;
struct diropres {
nfsstat status;
union {
diropokres diropres;
} diropres_u;
};
typedef struct diropres diropres;
struct readlinkres {
nfsstat status;
union {
nfspath data;
} readlinkres_u;
};
typedef struct readlinkres readlinkres;
struct readargs {
nfs_fh file;
u_int offset;
u_int count;
u_int totalcount;
};
typedef struct readargs readargs;
struct readokres {
fattr attributes;
struct {
u_int data_len;
char *data_val;
} data;
};
typedef struct readokres readokres;
struct readres {
nfsstat status;
union {
readokres reply;
} readres_u;
};
typedef struct readres readres;
struct writeargs {
nfs_fh file;
u_int beginoffset;
u_int offset;
u_int totalcount;
struct {
u_int data_len;
char *data_val;
} data;
};
typedef struct writeargs writeargs;
struct createargs {
diropargs where;
sattr attributes;
};
typedef struct createargs createargs;
struct renameargs {
diropargs from;
diropargs to;
};
typedef struct renameargs renameargs;
struct linkargs {
nfs_fh from;
diropargs to;
};
typedef struct linkargs linkargs;
struct symlinkargs {
diropargs from;
nfspath to;
sattr attributes;
};
typedef struct symlinkargs symlinkargs;
struct nfscookie {
char data[NFS_COOKIESIZE];
};
typedef struct nfscookie nfscookie;
struct readdirargs {
nfs_fh dir;
nfscookie cookie;
u_int count;
};
typedef struct readdirargs readdirargs;
struct entry {
u_int fileid;
filename name;
nfscookie cookie;
struct entry *nextentry;
};
typedef struct entry entry;
struct dirlist {
entry *entries;
bool_t eof;
};
typedef struct dirlist dirlist;
struct readdirres {
nfsstat status;
union {
dirlist reply;
} readdirres_u;
};
typedef struct readdirres readdirres;
struct statfsokres {
u_int tsize;
u_int bsize;
u_int blocks;
u_int bfree;
u_int bavail;
};
typedef struct statfsokres statfsokres;
struct statfsres {
nfsstat status;
union {
statfsokres reply;
} statfsres_u;
};
typedef struct statfsres statfsres;
#define NFS_PROGRAM 100003
#define NFS_VERSION 2
#if defined(__STDC__) || defined(__cplusplus)
#define NFSPROC_NULL 0
extern void * nfsproc_null_2(void *, CLIENT *);
extern void * nfsproc_null_2_svc(void *, struct svc_req *);
#define NFSPROC_GETATTR 1
extern attrstat * nfsproc_getattr_2(nfs_fh *, CLIENT *);
extern attrstat * nfsproc_getattr_2_svc(nfs_fh *, struct svc_req *);
#define NFSPROC_SETATTR 2
extern attrstat * nfsproc_setattr_2(sattrargs *, CLIENT *);
extern attrstat * nfsproc_setattr_2_svc(sattrargs *, struct svc_req *);
#define NFSPROC_ROOT 3
extern void * nfsproc_root_2(void *, CLIENT *);
extern void * nfsproc_root_2_svc(void *, struct svc_req *);
#define NFSPROC_LOOKUP 4
extern diropres * nfsproc_lookup_2(diropargs *, CLIENT *);
extern diropres * nfsproc_lookup_2_svc(diropargs *, struct svc_req *);
#define NFSPROC_READLINK 5
extern readlinkres * nfsproc_readlink_2(nfs_fh *, CLIENT *);
extern readlinkres * nfsproc_readlink_2_svc(nfs_fh *, struct svc_req *);
#define NFSPROC_READ 6
extern readres * nfsproc_read_2(readargs *, CLIENT *);
extern readres * nfsproc_read_2_svc(readargs *, struct svc_req *);
#define NFSPROC_WRITECACHE 7
extern void * nfsproc_writecache_2(void *, CLIENT *);
extern void * nfsproc_writecache_2_svc(void *, struct svc_req *);
#define NFSPROC_WRITE 8
extern attrstat * nfsproc_write_2(writeargs *, CLIENT *);
extern attrstat * nfsproc_write_2_svc(writeargs *, struct svc_req *);
#define NFSPROC_CREATE 9
extern diropres * nfsproc_create_2(createargs *, CLIENT *);
extern diropres * nfsproc_create_2_svc(createargs *, struct svc_req *);
#define NFSPROC_REMOVE 10
extern nfsstat * nfsproc_remove_2(diropargs *, CLIENT *);
extern nfsstat * nfsproc_remove_2_svc(diropargs *, struct svc_req *);
#define NFSPROC_RENAME 11
extern nfsstat * nfsproc_rename_2(renameargs *, CLIENT *);
extern nfsstat * nfsproc_rename_2_svc(renameargs *, struct svc_req *);
#define NFSPROC_LINK 12
extern nfsstat * nfsproc_link_2(linkargs *, CLIENT *);
extern nfsstat * nfsproc_link_2_svc(linkargs *, struct svc_req *);
#define NFSPROC_SYMLINK 13
extern nfsstat * nfsproc_symlink_2(symlinkargs *, CLIENT *);
extern nfsstat * nfsproc_symlink_2_svc(symlinkargs *, struct svc_req *);
#define NFSPROC_MKDIR 14
extern diropres * nfsproc_mkdir_2(createargs *, CLIENT *);
extern diropres * nfsproc_mkdir_2_svc(createargs *, struct svc_req *);
#define NFSPROC_RMDIR 15
extern nfsstat * nfsproc_rmdir_2(diropargs *, CLIENT *);
extern nfsstat * nfsproc_rmdir_2_svc(diropargs *, struct svc_req *);
#define NFSPROC_READDIR 16
extern readdirres * nfsproc_readdir_2(readdirargs *, CLIENT *);
extern readdirres * nfsproc_readdir_2_svc(readdirargs *, struct svc_req *);
#define NFSPROC_STATFS 17
extern statfsres * nfsproc_statfs_2(nfs_fh *, CLIENT *);
extern statfsres * nfsproc_statfs_2_svc(nfs_fh *, struct svc_req *);
extern int nfs_program_2_freeresult (SVCXPRT *, xdrproc_t, caddr_t);
#else /* K&R C */
#define NFSPROC_NULL 0
extern void * nfsproc_null_2();
extern void * nfsproc_null_2_svc();
#define NFSPROC_GETATTR 1
extern attrstat * nfsproc_getattr_2();
extern attrstat * nfsproc_getattr_2_svc();
#define NFSPROC_SETATTR 2
extern attrstat * nfsproc_setattr_2();
extern attrstat * nfsproc_setattr_2_svc();
#define NFSPROC_ROOT 3
extern void * nfsproc_root_2();
extern void * nfsproc_root_2_svc();
#define NFSPROC_LOOKUP 4
extern diropres * nfsproc_lookup_2();
extern diropres * nfsproc_lookup_2_svc();
#define NFSPROC_READLINK 5
extern readlinkres * nfsproc_readlink_2();
extern readlinkres * nfsproc_readlink_2_svc();
#define NFSPROC_READ 6
extern readres * nfsproc_read_2();
extern readres * nfsproc_read_2_svc();
#define NFSPROC_WRITECACHE 7
extern void * nfsproc_writecache_2();
extern void * nfsproc_writecache_2_svc();
#define NFSPROC_WRITE 8
extern attrstat * nfsproc_write_2();
extern attrstat * nfsproc_write_2_svc();
#define NFSPROC_CREATE 9
extern diropres * nfsproc_create_2();
extern diropres * nfsproc_create_2_svc();
#define NFSPROC_REMOVE 10
extern nfsstat * nfsproc_remove_2();
extern nfsstat * nfsproc_remove_2_svc();
#define NFSPROC_RENAME 11
extern nfsstat * nfsproc_rename_2();
extern nfsstat * nfsproc_rename_2_svc();
#define NFSPROC_LINK 12
extern nfsstat * nfsproc_link_2();
extern nfsstat * nfsproc_link_2_svc();
#define NFSPROC_SYMLINK 13
extern nfsstat * nfsproc_symlink_2();
extern nfsstat * nfsproc_symlink_2_svc();
#define NFSPROC_MKDIR 14
extern diropres * nfsproc_mkdir_2();
extern diropres * nfsproc_mkdir_2_svc();
#define NFSPROC_RMDIR 15
extern nfsstat * nfsproc_rmdir_2();
extern nfsstat * nfsproc_rmdir_2_svc();
#define NFSPROC_READDIR 16
extern readdirres * nfsproc_readdir_2();
extern readdirres * nfsproc_readdir_2_svc();
#define NFSPROC_STATFS 17
extern statfsres * nfsproc_statfs_2();
extern statfsres * nfsproc_statfs_2_svc();
extern int nfs_program_2_freeresult ();
#endif /* K&R C */
/* the xdr functions */
#if defined(__STDC__) || defined(__cplusplus)
extern bool_t xdr_nfsstat (XDR *, nfsstat*);
extern bool_t xdr_ftype (XDR *, ftype*);
extern bool_t xdr_nfs_fh (XDR *, nfs_fh*);
extern bool_t xdr_nfstime (XDR *, nfstime*);
extern bool_t xdr_fattr (XDR *, fattr*);
extern bool_t xdr_sattr (XDR *, sattr*);
extern bool_t xdr_filename (XDR *, filename*);
extern bool_t xdr_nfspath (XDR *, nfspath*);
extern bool_t xdr_attrstat (XDR *, attrstat*);
extern bool_t xdr_sattrargs (XDR *, sattrargs*);
extern bool_t xdr_diropargs (XDR *, diropargs*);
extern bool_t xdr_diropokres (XDR *, diropokres*);
extern bool_t xdr_diropres (XDR *, diropres*);
extern bool_t xdr_readlinkres (XDR *, readlinkres*);
extern bool_t xdr_readargs (XDR *, readargs*);
extern bool_t xdr_readokres (XDR *, readokres*);
extern bool_t xdr_readres (XDR *, readres*);
extern bool_t xdr_writeargs (XDR *, writeargs*);
extern bool_t xdr_createargs (XDR *, createargs*);
extern bool_t xdr_renameargs (XDR *, renameargs*);
extern bool_t xdr_linkargs (XDR *, linkargs*);
extern bool_t xdr_symlinkargs (XDR *, symlinkargs*);
extern bool_t xdr_nfscookie (XDR *, nfscookie*);
extern bool_t xdr_readdirargs (XDR *, readdirargs*);
extern bool_t xdr_entry (XDR *, entry*);
extern bool_t xdr_dirlist (XDR *, dirlist*);
extern bool_t xdr_readdirres (XDR *, readdirres*);
extern bool_t xdr_statfsokres (XDR *, statfsokres*);
extern bool_t xdr_statfsres (XDR *, statfsres*);
#else /* K&R C */
extern bool_t xdr_nfsstat ();
extern bool_t xdr_ftype ();
extern bool_t xdr_nfs_fh ();
extern bool_t xdr_nfstime ();
extern bool_t xdr_fattr ();
extern bool_t xdr_sattr ();
extern bool_t xdr_filename ();
extern bool_t xdr_nfspath ();
extern bool_t xdr_attrstat ();
extern bool_t xdr_sattrargs ();
extern bool_t xdr_diropargs ();
extern bool_t xdr_diropokres ();
extern bool_t xdr_diropres ();
extern bool_t xdr_readlinkres ();
extern bool_t xdr_readargs ();
extern bool_t xdr_readokres ();
extern bool_t xdr_readres ();
extern bool_t xdr_writeargs ();
extern bool_t xdr_createargs ();
extern bool_t xdr_renameargs ();
extern bool_t xdr_linkargs ();
extern bool_t xdr_symlinkargs ();
extern bool_t xdr_nfscookie ();
extern bool_t xdr_readdirargs ();
extern bool_t xdr_entry ();
extern bool_t xdr_dirlist ();
extern bool_t xdr_readdirres ();
extern bool_t xdr_statfsokres ();
extern bool_t xdr_statfsres ();
#endif /* K&R C */
#ifdef __cplusplus
}
#endif
#endif /* !_NFS_PROT_H_RPCGEN */
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+104
View File
@@ -0,0 +1,104 @@
#
# $Id$
#
# Templates/Makefile.leaf
# Template leaf node Makefile
#
# if you have CEXP set this variable to 'YES'
# and some "help" info will be compiled in.
HAVE_CEXP=YES
# C source names, if any, go here -- minus the .c
C_PIECES_YES=rpcio nfs sock_mbuf xdr_mbuf dirutils rpcio.modini nfs.modini cexphelp
C_PIECES_NO=rpcio nfs sock_mbuf xdr_mbuf
C_PIECES=$(C_PIECES_$(HAVE_CEXP))
C_FILES=$(C_PIECES:%=%.c)
C_O_FILES=$(C_PIECES:%=${ARCH}/%.o)
# C++ source names, if any, go here -- minus the .cc
CC_PIECES=
CC_FILES=$(CC_PIECES:%=%.cc)
CC_O_FILES=$(CC_PIECES:%=${ARCH}/%.o)
H_FILES=librtemsNfs.h rpcio.h
INST_HEADERS=librtemsNfs.h
# Assembly source names, if any, go here -- minus the .S
S_PIECES=
S_FILES=$(S_PIECES:%=%.S)
S_O_FILES=$(S_FILES:%.S=${ARCH}/%.o)
SRCS=$(C_FILES) $(CC_FILES) $(H_FILES) $(S_FILES)
OBJS=$(C_O_FILES) $(CC_O_FILES) $(S_O_FILES) $(wildcard ../proto/$(ARCH)/*.o)
PGMS=${ARCH}/nfs.obj ${ARCH}/rpcio.obj ${ARCH}/dirutils.obj
LIBNAME=librtemsNfs.a
LIB=$(ARCH)/$(LIBNAME)
include $(RTEMS_MAKEFILE_PATH)/Makefile.inc
include $(RTEMS_CUSTOM)
include $(RTEMS_ROOT)/make/lib.cfg
#
# (OPTIONAL) Add local stuff here using +=
#
DEFS_CEXP_YES=-DHAVE_CEXP
DEFINES += $(DEFS_CEXP_$(HAVE_CEXP))
CPPFLAGS += -I. -I../proto
CFLAGS +=
#
# CFLAGS_DEBUG_V are used when the `make debug' target is built.
# To link your application with the non-optimized RTEMS routines,
# uncomment the following line:
# CFLAGS_DEBUG_V += -qrtems_debug
#
LDFLAGS +=
#
# Add your list of files to delete here. The config files
# already know how to delete some stuff, so you may want
# to just run 'make clean' first to see what gets missed.
# 'make clobber' already includes 'make clean'
#
#CLEAN_ADDITIONS += xxx-your-debris-goes-here
CLOBBER_ADDITIONS +=
ifndef RTEMS_SITE_INSTALLDIR
RTEMS_SITE_INSTALLDIR = $(PROJECT_RELEASE)
endif
%nfs.obj: %nfs.o %nfs.modini.o
$(LD) -r -o $@ $^ -L../proto/$(ARCH) -lnfsprot
%rpcio.obj: %rpcio.o %sock_mbuf.o %xdr_mbuf.o %rpcio.modini.o
$(LD) -r -o $@ $^
%dirutils.obj: %dirutils.o
$(LD) -r -o $@ $^
$(LIB): $(OBJS)
$(make-library)
all: ${ARCH} $(SRCS) $(PGMS) $(LIB)
tar:
echo not implemented
# Install the program(s), appending _g or _p as appropriate.
# for include files, just use $(INSTALL_CHANGE)
install: all
$(INSTALL_VARIANT) -m 555 ${PGMS} ${RTEMS_SITE_INSTALLDIR}/bin
$(INSTALL_VARIANT) -m 555 ${LIB} ${RTEMS_SITE_INSTALLDIR}/lib
$(INSTALL_CHANGE) -m 444 ${INST_HEADERS} ${RTEMS_SITE_INSTALLDIR}/include
+16
View File
@@ -0,0 +1,16 @@
#include <librtemsNfs.h>
#include <cexpHelp.h>
CEXP_HELP_TAB_BEGIN(rtemsNfs)
HELP(
"Mount a remote filesystem (NFS). The mount point (must not be a NFS dir)\n"
"is created on the fly if not existing already.\n"
"uid/gid to use may be specified:\n"
" hostspec: [uid.gid@]hostname_or_ipaddr\n"
, int, nfsMount, (char *hostspec, char *exportdir, char *mntpoint)
),
HELP(
"Print all currently mounted NFS directories to open file handle.\n"
"Pass f = 0 to print to stdout\n"
, int, nfsMountsShow, (FILE *f)
),
CEXP_HELP_TAB_END
+362
View File
@@ -0,0 +1,362 @@
/* $Id$ */
/* very crude and basic fs utilities for testing the NFS */
/* Till Straumann, <strauman@slac.stanford.edu>, 10/2002 */
/*
* Authorship
* ----------
* This software (NFS-2 client implementation for RTEMS) was created by
* Till Straumann <strauman@slac.stanford.edu>, 2002-2007,
* Stanford Linear Accelerator Center, Stanford University.
*
* Acknowledgement of sponsorship
* ------------------------------
* The NFS-2 client implementation for RTEMS was produced by
* the Stanford Linear Accelerator Center, Stanford University,
* under Contract DE-AC03-76SFO0515 with the Department of Energy.
*
* Government disclaimer of liability
* ----------------------------------
* Neither the United States nor the United States Department of Energy,
* nor any of their employees, makes any warranty, express or implied, or
* assumes any legal liability or responsibility for the accuracy,
* completeness, or usefulness of any data, apparatus, product, or process
* disclosed, or represents that its use would not infringe privately owned
* rights.
*
* Stanford disclaimer of liability
* --------------------------------
* Stanford University makes no representations or warranties, express or
* implied, nor assumes any liability for the use of this software.
*
* Stanford disclaimer of copyright
* --------------------------------
* Stanford University, owner of the copyright, hereby disclaims its
* copyright and all other rights in this software. Hence, anyone may
* freely use it for any purpose without restriction.
*
* Maintenance of notices
* ----------------------
* In the interest of clarity regarding the origin and status of this
* SLAC software, this and all the preceding Stanford University notices
* are to remain affixed to any copy or derivative of this software made
* or distributed by the recipient and are to be affixed to any copy of
* software made or distributed by the recipient that contains a copy or
* derivative of this software.
*
* ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
*/
#ifdef __vxworks
#include <vxWorks.h>
#endif
#include <stdio.h>
#include <dirent.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <errno.h>
#include <stdlib.h>
#ifdef HAVE_CEXP
#include <cexpHelp.h>
#endif
#ifndef __vxworks
int
pwd(void)
{
char buf[MAXPATHLEN];
if ( !getcwd(buf,MAXPATHLEN)) {
perror("getcwd");
return -1;
} else {
printf("%s\n",buf);
}
return 0;
}
static int
ls_r(char *path, char *chpt, char *name, struct stat *buf)
{
char *t;
sprintf(chpt, "/%s", name);
if (lstat(path,buf)) {
fprintf(stderr,"stat(%s): %s\n", path, strerror(errno));
return -1;
}
switch ( buf->st_mode & S_IFMT ) {
case S_IFSOCK:
case S_IFIFO: t = "|"; break;
default:
case S_IFREG:
case S_IFBLK:
case S_IFCHR:
t = ""; break;
case S_IFDIR:
t = "/"; break;
case S_IFLNK:
t = "@"; break;
}
printf("%10li, %10lib, %5i.%-5i 0%04o %s%s\n",
buf->st_ino,
buf->st_size,
buf->st_uid,
buf->st_gid,
buf->st_mode & ~S_IFMT,
name,
t);
*chpt = 0;
return 0;
}
int
ls(char *dir, char *opts)
{
struct dirent *de;
char path[MAXPATHLEN+1];
char *chpt;
DIR *dp = 0;
int rval = -1;
struct stat buf;
if ( !dir )
dir = ".";
strncpy(path, dir, MAXPATHLEN);
path[MAXPATHLEN] = 0;
chpt = path+strlen(path);
if ( !(dp=opendir(dir)) ) {
perror("opendir");
goto cleanup;
}
while ( (de = readdir(dp)) ) {
ls_r(path, chpt, de->d_name, &buf);
}
rval = 0;
cleanup:
if (dp)
closedir(dp);
return rval;
}
#endif
#if 0
fprintf(stderr, "usage: cp(""from"",[""to""[,""-f""]]\n");
fprintf(stderr, " ""to""==NULL -> stdout\n");
fprintf(stderr, " ""-f"" -> overwrite existing file\n");
#endif
int
cp(char *from, char *to, char *opts)
{
struct stat st;
int rval = -1;
int fd = -1;
FILE *fst = 0;
FILE *tst = 0;
int flags = O_CREAT | O_WRONLY | O_TRUNC | O_EXCL;
if (from) {
if ((fd=open(from,O_RDONLY,0)) < 0) {
fprintf(stderr,
"Opening %s for reading: %s\n",
from,
strerror(errno));
goto cleanup;
}
if (fstat(fd, &st)) {
fprintf(stderr,
"rstat(%s): %s\n",
from,
strerror(errno));
goto cleanup;
}
if (!S_ISREG(st.st_mode)) {
fprintf(stderr,"Refuse to copy a non-regular file\n");
errno = EINVAL;
goto cleanup;
}
/* Now create a stream -- I experienced occasional weirdness
* when circumventing the streams attached to fildno(stdin)
* by reading/writing to the underlying fd's directly ->
* for now we always go through buffered I/O...
*/
if ( !(fst=fdopen(fd,"r")) ) {
fprintf(stderr,
"Opening input stream [fdopen()] failed: %s\n",
strerror(errno));
goto cleanup;
}
/* at this point, we have a stream and don't need 'fd' anymore */
fd = -1;
} else {
fst = stdin;
st.st_mode = 0644;
}
if (opts && strchr(opts,'f'))
flags &= ~ O_EXCL;
if (to) {
if ( (fd=open(to,flags,st.st_mode)) < 0 ) {
fprintf(stderr,
"Opening %s for writing: %s\n",
to,
strerror(errno));
goto cleanup;
}
if ( !(tst=fdopen(fd, "w")) ) {
fprintf(stderr,
"Opening output stream [fdopen()] failed: %s\n",
strerror(errno));
goto cleanup;
}
/* at this point we have a stream and don't need 'fd' anymore */
fd = -1;
} else {
tst = stdout;
}
/* clear old errors */
clearerr(fst);
clearerr(tst);
/* use macro versions on register vars; stdio is already buffered,
* there's nothing to be gained by reading/writing blocks into
* a secondary buffer...
*/
{
register int ch;
register FILE *f = fst;
register FILE *t = tst;
while ( EOF != (ch = getc(f)) && EOF != putc(ch, t) )
/* nothing else */;
}
if ( ferror(fst) ) {
fprintf(stderr,"Read error: %s\n",strerror(errno));
goto cleanup;
}
if ( ferror(tst) ) {
fprintf(stderr,"Write error: %s\n",strerror(errno));
goto cleanup;
}
rval = 0;
cleanup:
if ( fd >= 0 )
close(fd);
if ( fst ) {
if ( from )
fclose(fst);
else
clearerr(fst);
}
if ( tst ) {
if ( to )
fclose(tst);
else {
/* flush stdout */
fflush(tst);
clearerr(tst);
}
}
return rval;
}
int
ln(char *to, char *name, char *opts)
{
if (!to) {
fprintf(stderr,"ln: need 'to' argument\n");
return -1;
}
if (!name) {
if ( !(name = strrchr(to,'/')) ) {
fprintf(stderr,
"ln: 'unable to link %s to %s\n",
to,to);
return -1;
}
name++;
}
if (opts || strchr(opts,'s')) {
if (symlink(name,to)) {
fprintf(stderr,"symlink: %s\n",strerror(errno));
return -1;
}
} else {
if (link(name,to)) {
fprintf(stderr,"hardlink: %s\n",strerror(errno));
return -1;
}
}
return 0;
}
int
rm(char *path)
{
return unlink(path);
}
int
cd(char *path)
{
return chdir(path);
}
#ifdef HAVE_CEXP
static CexpHelpTabRec _cexpHelpTabDirutils[] __attribute__((unused)) = {
HELP(
"copy a file: cp(""from"",[""to""[,""-f""]])\n\
from = NULL <-- stdin\n\
to = NULL --> stdout\n\
option -f: overwrite existing file\n",
int,
cp, (char *from, char *to, char *options)
),
HELP(
"list a directory: ls([""dir""])\n",
int,
ls, (char *dir)
),
HELP(
"remove a file\n",
int,
rm, (char *path)
),
HELP(
"change the working directory\n",
int,
cd, (char *path)
),
HELP(
"create a link: ln(""to"",""name"",""[-s]""\n\
-s creates a symlink\n",
int,
ln, (char *to, char *name, char *options)
),
HELP("",,0,)
};
#endif
+182
View File
@@ -0,0 +1,182 @@
#ifndef LIB_RTEMS_NFS_CLIENT_H
#define LIB_RTEMS_NFS_CLIENT_H
/* $Id$ */
/* public interface to the NFS client library for RTEMS */
/* Author: Till Straumann <strauman@slac.stanford.edu> 2002-2003 */
/*
* Authorship
* ----------
* This software (NFS-2 client implementation for RTEMS) was created by
* Till Straumann <strauman@slac.stanford.edu>, 2002-2007,
* Stanford Linear Accelerator Center, Stanford University.
*
* Acknowledgement of sponsorship
* ------------------------------
* The NFS-2 client implementation for RTEMS was produced by
* the Stanford Linear Accelerator Center, Stanford University,
* under Contract DE-AC03-76SFO0515 with the Department of Energy.
*
* Government disclaimer of liability
* ----------------------------------
* Neither the United States nor the United States Department of Energy,
* nor any of their employees, makes any warranty, express or implied, or
* assumes any legal liability or responsibility for the accuracy,
* completeness, or usefulness of any data, apparatus, product, or process
* disclosed, or represents that its use would not infringe privately owned
* rights.
*
* Stanford disclaimer of liability
* --------------------------------
* Stanford University makes no representations or warranties, express or
* implied, nor assumes any liability for the use of this software.
*
* Stanford disclaimer of copyright
* --------------------------------
* Stanford University, owner of the copyright, hereby disclaims its
* copyright and all other rights in this software. Hence, anyone may
* freely use it for any purpose without restriction.
*
* Maintenance of notices
* ----------------------
* In the interest of clarity regarding the origin and status of this
* SLAC software, this and all the preceding Stanford University notices
* are to remain affixed to any copy or derivative of this software made
* or distributed by the recipient and are to be affixed to any copy of
* software made or distributed by the recipient that contains a copy or
* derivative of this software.
*
* ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <rtems.h>
#include <rtems/libio.h>
#include <rtems/libio_.h>
#include <rtems/seterr.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <sys/stat.h>
#include <dirent.h>
#include <netdb.h>
#include <ctype.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#ifdef HAVE_CEXP_H
#include <cexpHelp.h>
#endif
/* RPCIO driver interface.
* If you need RPCIO for other purposes than NFS
* you may want to include <rpcio.h>
#include "rpcio.h"
*/
/* Priority of daemon; may be setup prior to calling rpcUdpInit();
* otherwise the network task priority from the rtems_bsdnet_config
* is used...
*/
extern rtems_task_priority rpciodPriority;
/* Initialize the driver
*
* RETURNS: 0 on success, -1 on failure
*/
int
rpcUdpInit(void);
/* Cleanup/Stop
*
* RETURNS: 0 on success, nonzero if still in use
*/
int
rpcUdpCleanup(void);
/* NFS driver interface */
/* Initialize the NFS driver.
*
* NOTE: The RPCIO driver must have been initialized prior to
* calling this.
*
* ARGS: depth of the small and big
* transaction pools, i.e. how
* many transactions (buffers)
* should always be kept around.
*
* (If more transactions are needed,
* they are created and destroyed
* on the fly).
*
* Supply zero values to have the
* driver chose reasonable defaults.
*/
int
nfsInit(int smallPoolDepth, int bigPoolDepth);
/* Driver cleanup code
*
* RETURNS: 0 on success, nonzero if still in use
*/
int
nfsCleanup(void);
/* Dump a list of the currently mounted NFS to a file
* (stdout is used in case f==NULL)
*/
int
nfsMountsShow(FILE *f);
/* convenience wrapper
*
* NOTE: this routine calls NON-REENTRANT
* gethostbyname() if the host is
* not in 'dot' notation.
*/
int
nfsMount(char *uidhost, char *path, char *mntpoint);
/* Alternatively, a pointer to the filesystem operations
* table can be supplied to the native RTEMS (NON-POSIX!)
* 'mount()' call.
* Supply a "<host.in.ip.dot.notation>:<path>" string
* for 'device' argument to 'mount()'.
*/
extern struct _rtems_filesystem_operations_table nfs_fs_ops;
/* A utility routine to find the path leading to a
* rtems_filesystem_location_info_t node.
*
* This should really be present in libcsupport...
*
* INPUT: 'loc' and a buffer 'buf' (length 'len') to hold the
* path.
* OUTPUT: path copied into 'buf'
*
* RETURNS: 0 on success, RTEMS error code on error.
*/
rtems_status_code
rtems_filesystem_resolve_location(char *buf, int len, rtems_filesystem_location_info_t *loc);
/* Set the timeout (initial default: 10s) for NFS and mount calls.
*
* RETURNS 0 on success, nonzero if the requested timeout is less than
* a clock tick or if the system clock rate cannot be determined.
*/
int
nfsSetTimeout(uint32_t timeout_ms);
/* Read current timeout (in milliseconds) */
uint32_t
nfsGetTimeout();
#endif
File diff suppressed because it is too large Load Diff
+27
View File
@@ -0,0 +1,27 @@
#include "librtemsNfs.h"
/* CEXP dynamic loader support */
void
_cexpModuleInitialize(void *mod)
{
#if defined(DEBUG)
/* print load address (in case we crash while initializing) */
unsigned lr;
__asm__ __volatile__(
" bl thisis_loaded_at \n"
"thisis_loaded_at: \n"
" mflr %0 \n"
: "=r"(lr) ::"lr");
printf("thisis_loaded_at: 0x%08x\n",lr);
#endif
nfsInit(0,0);
}
int
_cexpModuleFinalize(void *mod)
{
return nfsCleanup();
}
+377
View File
@@ -0,0 +1,377 @@
/* $Id$ */
/* Test program for evaluating NFS read throughput */
/* Author: Till Straumann <strauman@slac.stanford.edu>, 2006 */
/* This test code allows for evaluating NFS read performance
* under various scenarios:
* - synchronous reads with various buffer sizes (select
* 'num_readers' == 0, see below).
* - pseudo 'read-ahead' using multiple threads that issue
* NFS reads from the same file (but from different offsets)
* in parallel.
* Rationale: each NFS read request is synchronous, i.e., the
* caller sends a request to the server and waits for the
* reply to come back. Performance enhancement can be expected
* by requesting multiple blocks in parallel rather than
* sequentially.
*
* rtems_interval
* nfsTestRead(char *file_name, int chunk_size, int num_readers);
*
* 1) creates 'num_readers' threads, each opening 'file_name' for
* reading on a separate file descriptor.
* 2) creates message queues for communicating with reader threads
*
* 3) read file using nfsTestReadBigbuf() until EOF is reached
*
* 4) releases resources.
*
* RETURNS: Time elapsed during step 3 in ms. This is measured
* using the system clock so make sure the test file
* is big enough.
*
* nfsTestReadBigbuf() synchronously reads a block of
* 'num_readers * chunk_size' (which may be bigger than
* the UDP limit of 8k) using 'num_reader' threads to
* retrieve the various pieces of the big block in parallel.
* This speeds up things since several RPC calls can
* be in the works at once.
*
* NOTES:
* - if 'num_readers' == 0 this corresponds to an 'ordinary'
* NFS read. 'num_readers' == 1 schedules a single reader
* thread (== ordinary NFS read + message passing overhead).
* - no actual processing on the data is done; they are simply
* thrown away. A real, performance-critical application could
* pipeline 'reader' and 'cruncher' threads.
* - read is not completely asynchronous; synchronization is still
* performed at 'big block' boundaries (num_readers * chunk_size).
*/
/*
* Authorship
* ----------
* This software (NFS-2 client implementation for RTEMS) was created by
* Till Straumann <strauman@slac.stanford.edu>, 2002-2007,
* Stanford Linear Accelerator Center, Stanford University.
*
* Acknowledgement of sponsorship
* ------------------------------
* The NFS-2 client implementation for RTEMS was produced by
* the Stanford Linear Accelerator Center, Stanford University,
* under Contract DE-AC03-76SFO0515 with the Department of Energy.
*
* Government disclaimer of liability
* ----------------------------------
* Neither the United States nor the United States Department of Energy,
* nor any of their employees, makes any warranty, express or implied, or
* assumes any legal liability or responsibility for the accuracy,
* completeness, or usefulness of any data, apparatus, product, or process
* disclosed, or represents that its use would not infringe privately owned
* rights.
*
* Stanford disclaimer of liability
* --------------------------------
* Stanford University makes no representations or warranties, express or
* implied, nor assumes any liability for the use of this software.
*
* Stanford disclaimer of copyright
* --------------------------------
* Stanford University, owner of the copyright, hereby disclaims its
* copyright and all other rights in this software. Hence, anyone may
* freely use it for any purpose without restriction.
*
* Maintenance of notices
* ----------------------
* In the interest of clarity regarding the origin and status of this
* SLAC software, this and all the preceding Stanford University notices
* are to remain affixed to any copy or derivative of this software made
* or distributed by the recipient and are to be affixed to any copy of
* software made or distributed by the recipient that contains a copy or
* derivative of this software.
*
* ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
*/
#include <rtems.h>
#include <rtems/error.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
unsigned nfsTestReaderPri = 80;
struct nfsTestReq_ {
unsigned offset; /* file offset */
int size; /* IN: block size to read (must be < 8192), OUT: bytes actually read */
void *buf; /* data buffer address */
};
/* Queue for sending requests to parallel reader tasks */
rtems_id nfsTestRQ = 0;
/* Queue to pickup replies from parallel reader tasks */
rtems_id nfsTestAQ = 0;
/* Reader task; opens its own file descriptor
* and works on requests:
* - obtain request from request queue.
* - lseek to the requested file offset
* - NFS read into buffer
* - queue reply.
*
* Note that this implementation is very simple
* - no full error checking.
* - file is opened/closed by thread
* it's main purpose is running quick tests.
*/
static rtems_task
nfsTestReader(rtems_task_argument arg)
{
int fd = open((char*)arg,O_RDONLY);
unsigned long s;
struct nfsTestReq_ r;
rtems_status_code sc;
if ( fd < 0 ) {
perror("nfsReader: opening file");
goto cleanup;
}
do {
s = sizeof(r);
sc = rtems_message_queue_receive(nfsTestRQ, &r, &s, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
if ( RTEMS_SUCCESSFUL != sc ) {
rtems_error(sc, "(Error) reading from message queue");
goto cleanup;
}
if ( !r.buf ) {
/* They send a NULL buffer as a shutdown request */
break;
}
#ifdef DEBUG
printf("Reader: reading offset %u, size %i to %p ... ",
r.offset, r.size, r.buf);
#endif
/* seek to requested offset */
lseek(fd, r.offset, SEEK_SET);
r.size = read(fd, r.buf, r.size);
#ifdef DEBUG
printf("got %i\n",r.size);
#endif
rtems_message_queue_send(nfsTestAQ, &r, sizeof(r));
} while (1) ;
cleanup:
if ( fd >= 0 )
close(fd);
rtems_task_delete(RTEMS_SELF);
}
/* helper to create and start a reader task */
static rtems_id
taskSpawn(char *filenm, int inst)
{
rtems_status_code sc;
rtems_id tid;
sc = rtems_task_create(
rtems_build_name('n','t','t','0'+inst),
nfsTestReaderPri,
1400,
RTEMS_DEFAULT_MODES,
RTEMS_DEFAULT_ATTRIBUTES,
&tid);
if ( RTEMS_SUCCESSFUL != sc ) {
rtems_error(sc,"(Error) Creating nfs reader task %i",inst);
return 0;
}
sc = rtems_task_start(tid, nfsTestReader, (rtems_task_argument)filenm);
if ( RTEMS_SUCCESSFUL != sc ) {
rtems_error(sc,"(Error) Staritng nfs reader task %i",inst);
rtems_task_delete(tid);
return 0;
}
return tid;
}
/*
* Read nrd*sz bytes into 'buf' from file offset 'off'
* using 'nrd' parallel reader tasks to do the job.
* This helper routine schedules 'nrd' requests to
* the reader tasks and waits for all requests to
* finish.
*
* RETURNS: number of bytes read or -1 (error).
*
* CAVEATS:
* - assumes read requests always return 'sz' bytes
* unless the end of file is reached.
* THIS ASSUMPTION SHOULD NOT BE MADE WHEN WRITING
* ANY 'REAL' CODE.
*/
static int
nfsTestReadBigbuf(char *buf, int off, int sz, int nrd)
{
int i,rval=0;
struct nfsTestReq_ r;
r.buf = buf;
r.size = sz;
r.offset = off;
/* send out parallel requests */
for (i=0; i<nrd; i++) {
rtems_message_queue_send(nfsTestRQ, &r, sizeof(r));
r.offset += sz;
r.buf += sz;
}
/* wait for answers */
for (i=0; i<nrd; i++) {
unsigned long s = sizeof(r);
rtems_message_queue_receive(nfsTestAQ, &r, &s, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
if ( r.size < 0 ) {
fprintf(stderr,"A reader failed\n");
rval = -1;
} else {
/* FIXME sanity checks:
* - catch case where any-but-last read returns < sz
*/
if ( rval >= 0 ) {
rval += r.size;
}
}
}
return rval;
}
/* Main test routine
*
* Read file 'fname' usint 'nrd' parallel reader tasks,
* each operating on chunks of 'sz' bytes.
*
* RETURNS: time elapsed in milliseconds. This is measured
* using the system clock. Hence, for the result
* to be meaningful, the file must be big enough.
*
*/
rtems_interval
nfsTestRead(char *fnam, int sz, int nrd)
{
int i;
unsigned off;
rtems_interval now=-1, then, tickspsec;
rtems_status_code sc;
int fd=-1;
char *buf=0;
if ( nrd < 0 )
nrd = 0;
if ( sz < 0 || sz > 8192 ) {
fprintf(stderr,"\n");
return -1;
}
nfsTestRQ = nfsTestAQ = 0;
/* Allocate buffer */
if ( ! (buf=malloc(sz*(nrd ? nrd : 1))) ) {
perror("allocating buffer");
goto cleanup;
}
/* Don't bother proceeding if we can't open the file for reading */
if ( (fd=open(fnam,O_RDONLY)) < 0 ) {
perror("opening file");
goto cleanup;
}
if ( nrd ) {
close(fd); fd = -1;
}
/* Create request queue */
if ( nrd ) {
sc = rtems_message_queue_create(
rtems_build_name('n','t','r','q'),
nrd,
sizeof(struct nfsTestReq_),
RTEMS_DEFAULT_ATTRIBUTES,
& nfsTestRQ );
if ( RTEMS_SUCCESSFUL != sc ) {
rtems_error(sc, "(Error) creating request queue");
nfsTestRQ = 0;
goto cleanup;
}
/* Spawn reader tasks */
for ( i=0; i<nrd; i++ ) {
if ( ! taskSpawn(fnam, i) )
goto cleanup;
}
/* Create reply queue */
sc = rtems_message_queue_create(
rtems_build_name('n','t','a','q'),
nrd,
sizeof(struct nfsTestReq_),
RTEMS_DEFAULT_ATTRIBUTES,
& nfsTestAQ );
if ( RTEMS_SUCCESSFUL != sc ) {
rtems_error(sc, "(Error) creating reply queue");
nfsTestAQ = 0;
goto cleanup;
}
}
/* Timed main loop */
rtems_clock_get( RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &then);
if ( nrd ) {
off = 0;
while ((i = nfsTestReadBigbuf(buf, off, sz, nrd)) > 0 ) {
#ifdef DEBUG
printf("bigbuf got %i\n", i);
#endif
off += i;
}
} else {
while ( (i = read(fd, buf, sz)) > 0 )
/* nothing else to do */;
if ( i < 0 ) {
perror("reading");
goto cleanup;
}
}
rtems_clock_get( RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &now);
now = (now-then)*1000;
rtems_clock_get( RTEMS_CLOCK_GET_TICKS_PER_SECOND, &tickspsec);
now /= tickspsec; /* time in ms */
cleanup:
if ( fd >= 0 )
close(fd);
if ( nfsTestRQ ) {
/* request tasks to shutdown by sending NULL buf request */
struct nfsTestReq_ r;
r.buf = 0;
for ( i=0; i<nrd; i++ ) {
rtems_message_queue_send( nfsTestRQ, &r, sizeof(r) );
}
/* cheat: instead of proper synchronization with shutdown we simply
* delay for a second...
*/
rtems_task_wake_after( tickspsec );
rtems_message_queue_delete( nfsTestRQ );
}
if ( nfsTestAQ )
rtems_message_queue_delete( nfsTestAQ );
free(buf);
return now;
}
File diff suppressed because it is too large Load Diff
+209
View File
@@ -0,0 +1,209 @@
#ifndef RPCIO_H
#define RPCIO_H
/* $Id$ */
/* A multihreaded RPC/UDP multiplexor */
/* Author: Till Straumann, <strauman@slac.stanford.edu>, 2002 */
/*
* Authorship
* ----------
* This software (NFS-2 client implementation for RTEMS) was created by
* Till Straumann <strauman@slac.stanford.edu>, 2002-2007,
* Stanford Linear Accelerator Center, Stanford University.
*
* Acknowledgement of sponsorship
* ------------------------------
* The NFS-2 client implementation for RTEMS was produced by
* the Stanford Linear Accelerator Center, Stanford University,
* under Contract DE-AC03-76SFO0515 with the Department of Energy.
*
* Government disclaimer of liability
* ----------------------------------
* Neither the United States nor the United States Department of Energy,
* nor any of their employees, makes any warranty, express or implied, or
* assumes any legal liability or responsibility for the accuracy,
* completeness, or usefulness of any data, apparatus, product, or process
* disclosed, or represents that its use would not infringe privately owned
* rights.
*
* Stanford disclaimer of liability
* --------------------------------
* Stanford University makes no representations or warranties, express or
* implied, nor assumes any liability for the use of this software.
*
* Stanford disclaimer of copyright
* --------------------------------
* Stanford University, owner of the copyright, hereby disclaims its
* copyright and all other rights in this software. Hence, anyone may
* freely use it for any purpose without restriction.
*
* Maintenance of notices
* ----------------------
* In the interest of clarity regarding the origin and status of this
* SLAC software, this and all the preceding Stanford University notices
* are to remain affixed to any copy or derivative of this software made
* or distributed by the recipient and are to be affixed to any copy of
* software made or distributed by the recipient that contains a copy or
* derivative of this software.
*
* ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
*/
#ifdef __rtems
#include <rtems.h>
#endif
#include <rpc/rpc.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <sys/param.h>
#include <stdarg.h>
typedef struct RpcUdpServerRec_ *RpcUdpServer;
typedef struct RpcUdpXactRec_ *RpcUdpXact;
typedef RpcUdpXact RpcUdpClnt;
#define RPCIOD_DEFAULT_ID 0xdef10000
int
rpcUdpInit(void);
enum clnt_stat
rpcUdpServerCreate(
struct sockaddr_in *paddr,
int prog,
int vers,
u_long uid, /* RPCIO_DEFAULT_ID picks default */
u_long gid, /* RPCIO_DEFAULT_ID picks default */
RpcUdpServer *pclnt /* new server is returned here */
);
void
rpcUdpServerDestroy(RpcUdpServer s);
/* Dump statistics to a file (stdout if NULL);
* returns 0 for convenience
*/
int
rpcUdpStats(FILE *f);
enum clnt_stat
rpcUdpClntCreate(
struct sockaddr_in *psaddr,
int prog,
int vers,
u_long uid, /* RPCIO_DEFAULT_ID picks default */
u_long gid, /* RPCIO_DEFAULT_ID picks default */
RpcUdpClnt *pclnt /* new client is returned here */
);
void
RpcUdpClntDestroy(RpcUdpClnt clnt);
/* mute compiler warnings */
typedef void *XdrProcT;
typedef void *CaddrT;
enum clnt_stat
rpcUdpClntCall(
RpcUdpClnt clnt,
u_long proc,
XdrProcT xargs,
CaddrT pargs,
XdrProcT xres,
CaddrT pres,
struct timeval *timeout /* optional timeout; maybe NULL to pick default */
);
RpcUdpXact
rpcUdpXactCreate(
u_long program,
u_long version,
u_long size
);
void
rpcUdpXactDestroy(
RpcUdpXact xact
);
/* send a transaction */
enum clnt_stat
rpcUdpSend(
RpcUdpXact xact,
RpcUdpServer srvr,
struct timeval *timeout, /* maybe NULL to pick default */
u_long proc,
xdrproc_t xres,
caddr_t pres,
xdrproc_t xargs,
caddr_t pargs,
... /* 0 terminated xdrproc/pobj additional argument list */
);
/* wait for a transaction to complete */
enum clnt_stat
rpcUdpRcv(RpcUdpXact xact);
/* a yet simpler interface */
enum clnt_stat
rpcUdpCallRp(
struct sockaddr_in *pserver_addr,
u_long prog,
u_long vers,
u_long proc,
XdrProcT xargs,
CaddrT pargs,
XdrProcT xres,
CaddrT pres,
u_long uid, /* RPCIO_DEFAULT_ID picks default */
u_long gid, /* RPCIO_DEFAULT_ID picks default */
struct timeval *timeout /* NULL picks default */
);
/* manage pools of transactions */
/* A pool of transactions. The idea is not to malloc/free them
* all the time but keep a limited number around in a 'pool'.
* Users who need a XACT may get it from the pool and put it back
* when done.
* The pool is implemented by RTEMS message queues who manage
* the required task synchronization.
* A requestor has different options if the pool is empty:
* - it can wait (block) for a XACT to become available
* - it can get an error status
* - or it can malloc an extra XACT from the heap which
* will eventually be released.
*/
typedef struct RpcUdpXactPoolRec_ *RpcUdpXactPool;
/* NOTE: the pool is empty initially, must get messages (in
* GetCreate mode
*/
RpcUdpXactPool
rpcUdpXactPoolCreate(
int prog, int version,
int xactsize, int poolsize);
void
rpcUdpXactPoolDestroy(RpcUdpXactPool pool);
typedef enum {
XactGetFail, /* call fails if no transaction available */
XactGetWait, /* call blocks until transaction available */
XactGetCreate /* a new transaction is allocated (and freed when put back to the pool */
} XactPoolGetMode;
RpcUdpXact
rpcUdpXactPoolGet(RpcUdpXactPool pool, XactPoolGetMode mode);
void
rpcUdpXactPoolPut(RpcUdpXact xact);
#endif
+15
View File
@@ -0,0 +1,15 @@
#include "librtemsNfs.h"
/* CEXP module support (magic init) */
void
_cexpModuleInitialize(void *mod)
{
rpcUdpInit();
}
int
_cexpModuleFinalize(void *mod)
{
return rpcUdpCleanup();
}
+281
View File
@@ -0,0 +1,281 @@
/*
* $Id$
*
* NOTE:
* This is derived from libnetworking/rtems/rtems_syscall.c
*
* RTEMS/libnetworking LICENSING restrictions may apply
*
* Author (modifications only):
* Copyright: 2002, Stanford University and
* Till Straumann, <strauman@slac.stanford.edu>
* Licensing: 'LICENSE.NET' file in the RTEMS top source directory
* for more information.
*/
/*
The RTEMS TCP/IP stack is a port of the FreeBSD TCP/IP stack. The following
copyright and licensing information applies to this code.
This code is found under the c/src/libnetworking directory but does not
constitute the entire contents of that subdirectory.
=============================================================================
Copyright (c) 1980, 1983, 1988, 1993
The Regents of the University of California. All rights reserved.
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.
3. All advertising materials mentioning features or use of this software
must display the following acknowledgment:
This product includes software developed by the University of
California, Berkeley and its contributors.
4. Neither the name of the University nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
-
Portions Copyright (c) 1993 by Digital Equipment Corporation.
Permission to use, copy, modify, and distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies, and that
the name of Digital Equipment Corporation not be used in advertising or
publicity pertaining to distribution of the document or software without
specific, written prior permission.
THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
SOFTWARE.
=============================================================================
*/
#include <string.h>
#include <stdarg.h>
#include <stdio.h>
#include <rtems.h>
#include <rtems/libio.h>
#include <rtems/error.h>
#define KERNEL
#define _KERNEL
#define __BSD_VISIBLE 1
#include <rtems/rtems_bsdnet.h>
#include <sys/errno.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/protosw.h>
#include <sys/proc.h>
#include <sys/fcntl.h>
#include <sys/filio.h>
#include <net/if.h>
#include <net/route.h>
struct socket *rtems_bsdnet_fdToSocket(int fd);
/*
* Package system call argument into mbuf.
*
* (unfortunately, the original is not public)
*/
static int
sockaddrtombuf (struct mbuf **mp, const struct sockaddr *buf, int buflen)
{
struct mbuf *m;
struct sockaddr *sa;
if ((u_int)buflen > MLEN)
return (EINVAL);
rtems_bsdnet_semaphore_obtain();
m = m_get(M_WAIT, MT_SONAME);
rtems_bsdnet_semaphore_release();
if (m == NULL)
return (ENOBUFS);
m->m_len = buflen;
memcpy (mtod(m, caddr_t), buf, buflen);
*mp = m;
sa = mtod(m, struct sockaddr *);
sa->sa_len = buflen;
return 0;
}
static void
dummyproc(caddr_t ext_buf, u_int ext_size)
{
}
/*
* send data by simply allocating an MBUF packet
* header and pointing it to our data region.
*
* Optionally, the caller may supply 'reference'
* and 'free' procs. (The latter may call the
* user back once the networking stack has
* released the buffer).
*
* The callbacks are provided with the 'closure'
* pointer and the 'buflen' argument.
*/
ssize_t
sendto_nocpy (
int s,
const void *buf, size_t buflen,
int flags,
const struct sockaddr *toaddr, int tolen,
void *closure,
void (*freeproc)(caddr_t, u_int),
void (*refproc)(caddr_t, u_int)
)
{
int error;
struct socket *so;
struct mbuf *to, *m;
int ret = -1;
rtems_bsdnet_semaphore_obtain ();
if ((so = rtems_bsdnet_fdToSocket (s)) == NULL) {
rtems_bsdnet_semaphore_release ();
return -1;
}
error = sockaddrtombuf (&to, toaddr, tolen);
if (error) {
errno = error;
rtems_bsdnet_semaphore_release ();
return -1;
}
MGETHDR(m, M_WAIT, MT_DATA);
m->m_pkthdr.len = 0;
m->m_pkthdr.rcvif = (struct ifnet *) 0;
m->m_flags |= M_EXT;
m->m_ext.ext_buf = closure ? closure : (void*)buf;
m->m_ext.ext_size = buflen;
/* we _must_ supply non-null procs; otherwise,
* the kernel code assumes it's a mbuf cluster
*/
m->m_ext.ext_free = freeproc ? freeproc : dummyproc;
m->m_ext.ext_ref = refproc ? refproc : dummyproc;
m->m_pkthdr.len += buflen;
m->m_len = buflen;
m->m_data = (void*)buf;
error = sosend (so, to, NULL, m, NULL, flags);
if (error) {
if (/*auio.uio_resid != len &&*/ (error == EINTR || error == EWOULDBLOCK))
error = 0;
}
if (error)
errno = error;
else
ret = buflen;
if (to)
m_freem(to);
rtems_bsdnet_semaphore_release ();
return (ret);
}
/*
* receive data in an 'mbuf chain'.
* The chain must be released once the
* data has been extracted:
*
* rtems_bsdnet_semaphore_obtain();
* m_freem(chain);
* rtems_bsdnet_semaphore_release();
*/
ssize_t
recv_mbuf_from(int s, struct mbuf **ppm, long len, struct sockaddr *fromaddr, int *fromlen)
{
int ret = -1;
int error;
struct uio auio;
struct socket *so;
struct mbuf *from = NULL;
memset(&auio, 0, sizeof(auio));
*ppm = 0;
rtems_bsdnet_semaphore_obtain ();
if ((so = rtems_bsdnet_fdToSocket (s)) == NULL) {
rtems_bsdnet_semaphore_release ();
return -1;
}
/* auio.uio_iov = mp->msg_iov;
auio.uio_iovcnt = mp->msg_iovlen;
auio.uio_segflg = UIO_USERSPACE;
auio.uio_rw = UIO_READ;
auio.uio_offset = 0;
*/
auio.uio_resid = len;
error = soreceive (so, &from, &auio, (struct mbuf **) ppm,
(struct mbuf **)NULL,
NULL);
if (error) {
if (auio.uio_resid != len && (error == EINTR || error == EWOULDBLOCK))
error = 0;
}
if (error) {
errno = error;
}
else {
ret = len - auio.uio_resid;
if (fromaddr) {
len = *fromlen;
if ((len <= 0) || (from == NULL)) {
len = 0;
}
else {
if (len > from->m_len)
len = from->m_len;
memcpy (fromaddr, mtod(from, caddr_t), len);
}
*fromlen = len;
}
}
if (from)
m_freem (from);
if (error && *ppm) {
m_freem(*ppm);
*ppm = 0;
}
rtems_bsdnet_semaphore_release ();
return (ret);
}
File diff suppressed because it is too large Load Diff