An RPC test dispatch library for vice
authorMatt Benjamin <matt@linuxbox.com>
Thu, 24 Jun 2010 13:07:36 +0000 (09:07 -0400)
committerDerrick Brashear <shadow@dementia.org>
Mon, 12 Jul 2010 18:24:14 +0000 (11:24 -0700)
A library framework for remote testing against file servers,
with the ability to establish multiple call/callback channel
pairs within a single test process and dispatch requests
arbitrarily on each.  Thanks to Derrick for design and debugging
help.  Additional callback processing intelligence will follow
in a future changeset.  This version builds on Windows NT (but
might need further adjustment).

Change-Id: Ibea39e912b2a23ebf58e9e0931114572eccf6e78
Reviewed-on: http://gerrit.openafs.org/2229
Reviewed-by: Derrick Brashear <shadow@dementia.org>
Tested-by: Derrick Brashear <shadow@dementia.org>

Makefile.in
NTMakefile
configure.in
src/config/NTMakefile
tests/rpctestlib/Makefile.in [new file with mode: 0644]
tests/rpctestlib/NTMakefile [new file with mode: 0644]
tests/rpctestlib/rpc_test_cb_procs.c [new file with mode: 0644]
tests/rpctestlib/rpc_test_main.c [new file with mode: 0644]
tests/rpctestlib/rpc_test_procs.c [new file with mode: 0644]
tests/rpctestlib/rpc_test_procs.h [new file with mode: 0644]

index 5f9d6b2..21bcee3 100644 (file)
@@ -554,7 +554,7 @@ xstat: cmd comerr fsint viced
 afsmonitor: cmd comerr gtx xstat
        +${COMPILE_PART1} afsmonitor ${COMPILE_PART2}
 
-tests: rxtests ubiktests
+tests: rxtests ubiktests rpctestlib
 
 # pthread based user space RX library
 libafsrpc: rx rxkad des
@@ -900,6 +900,7 @@ distclean: clean
        src/volser/Makefile \
        src/xstat/Makefile  \
        tests/Makefile \
+       tests/rpctestlib/Makefile \
        tests/tap/Makefile \
        src/helper-splint.sh
        if test -d doc/man-pages ; then \
index 54c818b..409063f 100644 (file)
@@ -19,6 +19,7 @@
 # These three macros define the source, object, and destination folders
 SRC=$(AFSROOT)\src
 DOC=$(AFSROOT)\doc
+TESTS=$(AFSROOT)\tests
 
 #If AFS_OBJDIR is not defined then use obj as relative obj folder
 !IFNDEF AFS_OBJDIR
@@ -619,7 +620,14 @@ netidmgr_plugin: xstat
        $(NTMAKE)
        $(CD) ..\..\..
 
-extra: netidmgr_plugin
+rpctestlib: fsint libafsrpc
+     @echo ***** $@
+       $(DOCD) $(TESTS)\$@
+       $(CD) $(TESTS)\$@
+       $(NTMAKE)
+       $(CD) ..\..
+
+extra: netidmgr_plugin rpctestlib
 !      IF EXIST($(SRC)\WINNT\extra) && EXIST($(SRC)\WINNT\extra\NTMakefile)
      @echo ***** $@
     $(DOCD) $(SRC)\WINNT\$@
index 9aa231f..49c0f65 100644 (file)
@@ -227,6 +227,7 @@ src/volser/Makefile \
 src/xstat/Makefile \
 src/helper-splint.sh \
 tests/Makefile \
+tests/rpctestlib/Makefile \
 tests/tap/Makefile \
 tests/util/Makefile,
 
index a32708c..b458230 100644 (file)
@@ -108,6 +108,12 @@ idirs: doclink
 !      IF (!EXIST($(OJT)\libacl))
                $(MKDIR) $(OJT)\libacl
 !      ENDIF
+!      IF (!EXIST($(OJT)\tests))
+               $(MKDIR) $(OJT)\tests
+!      ENDIF
+!      IF (!EXIST($(OJT)\tests\rpctestlib))
+               $(MKDIR) $(OJT)\tests\rpctestlib
+!      ENDIF
 !      IF (!EXIST($(OJT)\libadmin))
                $(MKDIR) $(OJT)\libadmin
 !      ENDIF
diff --git a/tests/rpctestlib/Makefile.in b/tests/rpctestlib/Makefile.in
new file mode 100644 (file)
index 0000000..934825e
--- /dev/null
@@ -0,0 +1,99 @@
+# Copyright 2000, International Business Machines Corporation and others.
+# All Rights Reserved.
+#
+# This software has been released under the terms of the IBM Public
+# License.  For details, see the LICENSE file in the top-level source
+# directory or online at http://www.openafs.org/dl/license10.html
+#
+# Portions Copyright (c) 2003 Apple Computer, Inc.
+
+srcdir=@srcdir@
+include @TOP_OBJDIR@/src/config/Makefile.config
+
+# impermanent build glue
+#@ENABLE_XCB@include @TOP_OBJDIR@/src/mcas/Makefile.osi
+
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+
+RTL=@TOP_OBJDIR@/tests/rpctestlib
+RX=@TOP_OBJDIR@/src/rx
+VICED=@TOP_OBJDIR@/src/viced
+UTIL=@TOP_OBJDIR@/src/util
+FSINT=@TOP_OBJDIR@/src/fsint
+MCAS=@TOP_OBJDIR@/src/mcas
+OSI=@TOP_OBJDIR@/src/osi
+
+CC=${MT_CC}
+CFLAGS=${COMMON_CFLAGS} -DNINTERFACE ${MT_CFLAGS} -DRXDEBUG \
+       -DFSSYNC_BUILD_SERVER -DSALVSYNC_BUILD_CLIENT \
+       -I${TOP_SRCDIR} -I${RX} -I${MCAS} ${OSI_XCFLAGS} ${MCAS_CFLAGS} \
+       -DSUBSYS_LOG_MACRO=RTLLog
+
+CCRULE=${CC} ${CFLAGS} -c $?
+CCRULE2=${CC} ${CFLAGS} -c $? -o $@
+
+headers= ${RTL}/rpc_test_procs.h
+
+RTLOBJS= rpc_test_procs.o rpc_test_cb_procs.o
+
+FSINTOBJS= afsaux.o afscbint.ss.o afsint.cs.o afscbint.xdr.o \
+       afsint.xdr.o
+
+RXOBJS = rx_pthread.o
+
+LIBOBJS= ${RTLOBJS} ${FSINTOBJS} ${RXOBJS}
+
+LIBS=${TOP_LIBDIR}/libafsauthent.a ${TOP_LIBDIR}/libafsrpc.a ${TOP_LIBDIR}/util.a
+
+all: xmpl_driver
+
+rx_pthread.o: ${RX}/rx_pthread.c
+       ${CCRULE} -DDPF_FSLOG
+
+rpc_test_main.o: ${RTL}/rpc_test_main.c ${headers}
+       ${CCRULE}
+
+rpc_test_procs.o: ${RTL}/rpc_test_procs.c ${headers}
+       ${CCRULE}
+
+rpc_test_cb_procs.o: ${RTL}/rpc_test_cb_procs.c ${headers}
+       ${CCRULE}
+
+afsaux.o: ${FSINT}/afsaux.c
+       ${CCRULE} -I{FSINT}
+
+afscbint.ss.o: ${FSINT}/afscbint.ss.c
+       ${CCRULE}
+
+afsint.cs.o: ${FSINT}/afsint.cs.c
+       ${CCRULE}
+
+afsint.ss.o: ${FSINT}/afsint.ss.c
+       ${CCRULE}
+
+afsint.xdr.o: ${FSINT}/afsint.xdr.c
+       ${CCRULE}
+
+afscbint.xdr.o: ${FSINT}/afscbint.xdr.c
+       ${CCRULE}
+
+xmpl_driver: librpc_test_lib.a rpc_test_main.o ${LIBS}
+       ${CC} ${LDFLAGS} -o $@ rpc_test_main.o \
+       librpc_test_lib.a ${LIBS} ${MT_LIBS} ${XLIBS}
+
+librpc_test_lib.a: ${LIBOBJS}
+       $(RM) -f $@
+       $(AR) crv $@ ${LIBOBJS}
+       $(RANLIB) $@
+
+install:
+
+dest:
+
+clean:
+       $(RM) -f *.o *.a *.gch xmpl_driver core
+
+include @TOP_OBJDIR@/src/config/Makefile.version
diff --git a/tests/rpctestlib/NTMakefile b/tests/rpctestlib/NTMakefile
new file mode 100644 (file)
index 0000000..7d69d6b
--- /dev/null
@@ -0,0 +1,82 @@
+# Copyright 2000, International Business Machines Corporation and others.
+# All Rights Reserved.
+#
+# This software has been released under the terms of the IBM Public
+# License.  For details, see the LICENSE file in the top-level source
+# directory or online at http://www.openafs.org/dl/license10.html
+
+AFSDEV_AUXCDEFINES = -DAFS_PTHREAD_ENV -DRXDEBUG
+
+RELDIR=tests\rpctestlib
+!INCLUDE $(AFSROOT)\src\config\NTMakefile.$(SYS_NAME)
+!INCLUDE $(AFSROOT)\src\config\NTMakefile.version
+
+SRC_DIR = .
+
+############################################################################
+# Build rpc_test.lib and xmpl_driver.exe
+
+EXEFILE = $(OUT)\xmpl_driver.exe
+LIBFILE = $(OUT)\rpc_test.lib
+
+RTL = $(AFSROOT)\tests\rpctestlib
+RX = $(AFSROOT)\src\rx
+VICED = $(AFSROOT)\src\viced
+UTIL = $(AFSROOT)\src\util
+FSINT = $(AFSROOT)\src\fsint
+
+HEADERS =  $(RTL)\rpc_test_procs.h
+
+RXOBJS = $(OUT)\xdr_int64.obj \
+         $(OUT)\xdr_int32.obj
+
+RTLOBJS= $(OUT)\rpc_test_procs.obj $(OUT)\rpc_test_cb_procs.obj
+
+FSINTOBJS = $(OUT)\afsaux.obj $(OUT)\afscbint.ss.obj $(OUT)\afsint.cs.obj \
+       $(OUT)\afscbint.xdr.obj $(OUT)\afsint.xdr.obj
+
+LIBOBJS = $(RTLOBJS) $(FSINTOBJS) $(RXOBJS)
+
+EXEOBJS = $(OUT)\rpc_test_main.obj
+
+all: $(EXEFILE)
+
+$(RTLOBJS) $(OUT)\rpc_test_main.obj: $(RTL)\$$(@B).c $(HEADERS)
+       $(C2OBJ) -I$(RTL) $**
+
+$(RXOBJS): $(RX)\$$(@B).c
+       $(C2OBJ) -I$(RX) $**
+
+$(FSINTOBJS): $(FSINT)\$$(@B).C
+       $(C2OBJ) -I$(FSINT) $**
+
+$(LIBFILE): $(LIBOBJS)
+       $(LIBARCH)
+
+EXELIBS = \
+       $(DESTDIR)\lib\afsauthent.lib \
+       $(DESTDIR)\lib\afsrpc.lib \
+       $(DESTDIR)\lib\afs\afscmd.lib \
+       $(DESTDIR)\lib\afs\afsaudit.lib \
+       $(DESTDIR)\lib\afs\afscom_err.lib \
+       $(DESTDIR)\lib\afs\afsreg.lib \
+       $(DESTDIR)\lib\afs\afsprocmgmt.lib \
+       $(DESTDIR)\lib\afs\afseventlog.lib \
+       $(DESTDIR)\lib\afs\mtafsutil.lib \
+        $(DESTDIR)\lib\afs\mtafsvol.lib \
+        $(DESTDIR)\lib\afs\mtafsvldb.lib \
+       $(DESTDIR)\lib\afspthread.lib
+
+$(EXEFILE): $(EXEOBJS) $(EXELIBS) $(LIBFILE)
+       $(EXECONLINK)
+        $(_VC_MANIFEST_EMBED_EXE)
+       $(EXEPREP)
+        $(CODESIGN_USERLAND)
+        $(SYMSTORE_IMPORT)
+
+install:  $(EXEFILE)
+
+mkdir:
+       $(ECHO) "(mkdir: no target)"
+clean::
+       -$(DEL) $(EXEFILE) $(LIBFILE) $(LIBOBJS) $(EXEOBJS)
diff --git a/tests/rpctestlib/rpc_test_cb_procs.c b/tests/rpctestlib/rpc_test_cb_procs.c
new file mode 100644 (file)
index 0000000..e7b4943
--- /dev/null
@@ -0,0 +1,279 @@
+/*
+ * Copyright (c) 2010, Linux Box Corporation.
+ * All Rights Reserved.
+ *
+ * Portions Copyright (c) 2007, Hartmut Reuter,
+ * RZG, Max-Planck-Institut f. Plasmaphysik.
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED ``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
+ * 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 <afsconfig.h>
+#include <afs/param.h>
+#include <afs/stds.h>
+
+#include "rpc_test_procs.h"
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <signal.h>
+#include <afs/vice.h>
+#include <afs/cmd.h>
+#include <afs/auth.h>
+#include <afs/cellconfig.h>
+
+#include <afs/com_err.h>
+#ifdef HAVE_DIRENT_H
+#include <dirent.h>
+#endif
+#ifdef HAVE_DIRECT_H
+#include <direct.h>
+#endif
+#ifdef AFS_DARWIN_ENV
+#include <sys/malloc.h>
+#else
+#include <malloc.h>
+#endif
+#include <afs/errors.h>
+#include <afs/sys_prototypes.h>
+#include <rx_prototypes.h>
+#ifdef AFS_PTHREAD_ENV
+#include <assert.h>
+#endif
+
+extern const char *prog;
+extern pthread_key_t ctx_key;
+
+#if defined(AFS_EXTENDED_CALLBACK)
+#define RPC_TEST_EXTENDED_CALLBACK  1
+
+afs_int32 SRXAFSCB_ExtendedCallBack(
+    /*IN */ struct rx_call *a_call,
+    /*IN */ HostIdentifier * Server,
+    /*IN */ AFSXCBInvocationSeq * Invocations_Array,
+    /*OUT*/ AFSExtendedCallBackRSeq * CallBack_Result_Array)
+{
+    rpc_test_request_ctx *ctx;
+
+    ctx = CTX_FOR_RXCALL(a_call);
+
+    printf("%s: SRXAFSCB_ExtendedCallBack: enter (%s)\n", prog,
+        ctx->cb_svc_name);
+
+    return (0);
+};
+#endif /* AFS_EXTENDED_CALLBACK */
+
+#if defined(AFS_BYTE_RANGE_FLOCKS)
+afs_int32 SRXAFSCB_AsyncIssueByteRangeLock(
+       /*IN */ struct rx_call *a_call,
+       /*IN */ HostIdentifier * Server,
+       /*IN */ AFSByteRangeLockSeq Locks_Array)
+{
+    rpc_test_request_ctx *ctx = CTX_FOR_RXCALL(a_call);
+
+    printf("%s: SRXAFSCB_AsyncIssueByteRangeLock: enter (%s)\n", prog,
+        ctx->cb_svc_name);
+
+    return (0);
+}
+#endif /* AFS_BYTE_RANGE_FLOCKS */
+
+afs_int32
+SRXAFSCB_CallBack(struct rx_call *a_call, AFSCBFids *Fids_Array,
+                 AFSCBs *CallBack_Array)
+{
+    rpc_test_request_ctx *ctx = CTX_FOR_RXCALL(a_call);
+
+    printf("%s: SRXAFSCB_CallBack: enter (%s)\n", prog,
+        ctx->cb_svc_name);
+
+    return (0);
+}
+
+
+afs_int32
+SRXAFSCB_InitCallBackState(struct rx_call *a_call)
+{
+    return (0);
+}
+
+
+afs_int32
+SRXAFSCB_Probe(struct rx_call *a_call)
+{
+    return (0);
+}
+
+
+afs_int32
+SRXAFSCB_GetCE(struct rx_call *a_call,
+              afs_int32 index,
+              AFSDBCacheEntry * ce)
+{
+    return(0);
+}
+
+
+afs_int32
+SRXAFSCB_GetLock(struct rx_call *a_call,
+                afs_int32 index,
+                AFSDBLock * lock)
+{
+    return(0);
+}
+
+
+afs_int32
+SRXAFSCB_XStatsVersion(struct rx_call *a_call,
+                      afs_int32 * versionNumberP)
+{
+    return(0);
+}
+
+
+afs_int32
+SRXAFSCB_GetXStats(struct rx_call *a_call,
+                  afs_int32 clientVersionNumber,
+                  afs_int32 collectionNumber,
+                  afs_int32 * srvVersionNumberP,
+                  afs_int32 * timeP,
+                  AFSCB_CollData * dataP)
+{
+    return(0);
+}
+
+afs_int32
+SRXAFSCB_ProbeUuid(struct rx_call *a_call, afsUUID *a_uuid)
+{
+    rpc_test_request_ctx *ctx = CTX_FOR_RXCALL(a_call);
+    if ( !afs_uuid_equal(&ctx->cb_listen_addr.uuid, a_uuid) )
+        return (1);
+    else
+        return (0);
+}
+
+
+afs_int32
+SRXAFSCB_WhoAreYou(struct rx_call *a_call, struct interfaceAddr *addr)
+{
+    return SRXAFSCB_TellMeAboutYourself(a_call, addr, NULL);
+}
+
+
+afs_int32
+SRXAFSCB_InitCallBackState2(struct rx_call *a_call, struct interfaceAddr *
+                           addr)
+{
+    return RXGEN_OPCODE;
+}
+
+
+afs_int32
+SRXAFSCB_InitCallBackState3(struct rx_call *a_call, afsUUID *a_uuid)
+{
+    return (0);
+}
+
+
+afs_int32
+SRXAFSCB_GetCacheConfig(struct rx_call *a_call, afs_uint32 callerVersion,
+                       afs_uint32 *serverVersion, afs_uint32 *configCount,
+                       cacheConfig *config)
+{
+    return RXGEN_OPCODE;
+}
+
+afs_int32
+SRXAFSCB_GetLocalCell(struct rx_call *a_call, char **a_name)
+{
+    return RXGEN_OPCODE;
+}
+
+
+afs_int32
+SRXAFSCB_GetCellServDB(struct rx_call *a_call, afs_int32 a_index,
+                      char **a_name, serverList *a_hosts)
+{
+    return RXGEN_OPCODE;
+}
+
+
+afs_int32
+SRXAFSCB_GetServerPrefs(struct rx_call *a_call, afs_int32 a_index,
+                       afs_int32 *a_srvr_addr, afs_int32 *a_srvr_rank)
+{
+    return RXGEN_OPCODE;
+}
+
+
+afs_int32
+SRXAFSCB_TellMeAboutYourself(struct rx_call *a_call, struct interfaceAddr *
+                            addr, Capabilities *capabilities)
+{
+    afs_int32 code;
+    rpc_test_request_ctx *ctx = CTX_FOR_RXCALL(a_call);
+
+    printf("%s: SRXAFSCB_TellMeAboutYourself: enter (%s)\n", prog,
+        ctx->cb_svc_name);
+
+    addr->numberOfInterfaces = ctx->cb_listen_addr.numberOfInterfaces;
+    addr->uuid = ctx->cb_listen_addr.uuid;
+
+    if (capabilities) {
+        afs_uint32 *dataBuffP;
+        afs_int32 dataBytes;
+
+        dataBytes = 1 * sizeof(afs_uint32);
+        dataBuffP = (afs_uint32 *) xdr_alloc(dataBytes);
+        dataBuffP[0] = CLIENT_CAPABILITY_ERRORTRANS;
+#if defined(AFS_EXTENDED_CALLBACK)
+        if (ctx->flags & RPC_TEST_REQ_CTX_FLAG_XCB)
+            dataBuffP[0] |= CLIENT_CAPABILITY_EXT_CALLBACK;
+#endif /* AFS_EXTENDED_CALLBACK */
+        capabilities->Capabilities_len = dataBytes / sizeof(afs_uint32);
+        capabilities->Capabilities_val = dataBuffP;
+    }
+
+    return (0);
+
+}        /* SRXAFSCB_TellMeAboutYourself */
+
+
+afs_int32
+SRXAFSCB_GetCellByNum(struct rx_call *a_call, afs_int32 a_cellnum,
+                     char **a_name, serverList *a_hosts)
+{
+    return RXGEN_OPCODE;
+}
+
+
+afs_int32
+SRXAFSCB_GetCE64(struct rx_call *a_call, afs_int32 a_index,
+                struct AFSDBCacheEntry64 *a_result)
+{
+    return RXGEN_OPCODE;
+}
diff --git a/tests/rpctestlib/rpc_test_main.c b/tests/rpctestlib/rpc_test_main.c
new file mode 100644 (file)
index 0000000..d440530
--- /dev/null
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 2010, Linux Box Corporation.
+ * All Rights Reserved.
+ *
+ * Portions Copyright (c) 2007, Hartmut Reuter,
+ * RZG, Max-Planck-Institut f. Plasmaphysik.
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED ``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
+ * 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 <afsconfig.h>
+#include <afs/param.h>
+#include <afs/stds.h>
+
+#include "rpc_test_procs.h"
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <signal.h>
+#include <afs/vice.h>
+#include <afs/cmd.h>
+#include <afs/auth.h>
+#include <afs/cellconfig.h>
+#include <afs/com_err.h>
+#ifdef HAVE_DIRENT_H
+#include <dirent.h>
+#endif
+#ifdef HAVE_DIRECT_H
+#include <direct.h>
+#endif
+#ifdef AFS_DARWIN_ENV
+#include <sys/malloc.h>
+#else
+#include <malloc.h>
+#endif
+#include <afs/errors.h>
+#include <afs/sys_prototypes.h>
+#include <rx_prototypes.h>
+#ifdef AFS_PTHREAD_ENV
+#include <assert.h>
+#endif
+
+const char *prog = "lockharness";
+
+#ifndef AFS_PTHREAD_ENV
+#error compilation without pthreads is not supported
+#endif
+
+
+int
+main(int argc, char **argv)
+{
+    int i, code;
+    rpc_test_request_ctx *c1, *c2;
+    AFSFetchStatus outstatus;
+
+    printf("%s: start\n", prog);
+
+    code = rpc_test_PkgInit();
+
+    /* replace with appropriate test addresses */
+    code = init_fs_channel(&c1, "eth0", "10.1.1.213", "24",
+                           "10.1.1.81", /* fs */ RPC_TEST_REQ_CTX_FLAG_NONE);
+    code = init_fs_channel(&c2, "eth0", "10.1.1.213", "24",
+                           "10.1.1.81" /* fs */, RPC_TEST_REQ_CTX_FLAG_XCB);
+
+    printf("%s: channels initialized\n", prog);
+
+    i = 0;
+repeat:
+    {
+        /* XXXX fid members should be...dynamic */
+        AFSFid fid = { 536870915, 12, 4016};
+        code = rpc_test_afs_fetch_status(c1, &fid, &outstatus);
+        printf("%s: c1 call returned %d\n", prog, code);
+    }
+
+    {
+        /* XXXX fid members should be...dynamic */
+        AFSFid fid = { 536870915, 12, 4016};
+        code = rpc_test_afs_fetch_status(c2, &fid, &outstatus);
+        printf("%s: c2 call returned %d\n", prog, code);
+    }
+
+    /* force bcb at c1 */
+    {
+        AFSFid fid = { 536870915, 12, 4016};
+        AFSStoreStatus instatus;
+        instatus.Mask = 0;
+        instatus.SegSize = 0;
+        instatus.Owner = outstatus.Owner;
+        instatus.Group = outstatus.Group;
+        instatus.UnixModeBits = outstatus.UnixModeBits;
+        instatus.ClientModTime = time(NULL);
+        code = rpc_test_afs_store_status(c2, &fid, &instatus, &outstatus);
+        printf("%s: c2 store status returned %d\n", prog, code);
+    }
+
+    /* force bcb at c2 */
+    {
+        AFSFid fid = { 536870915, 12, 4016};
+        AFSStoreStatus instatus;
+        instatus.Mask = 0;
+        instatus.SegSize = 0;
+        instatus.Owner = outstatus.Owner;
+        instatus.Group = outstatus.Group;
+        instatus.UnixModeBits = outstatus.UnixModeBits;
+        instatus.ClientModTime = time(NULL);
+        code = rpc_test_afs_store_status(c1, &fid, &instatus, &outstatus);
+        printf("%s: c1 store status returned %d\n", prog, code);
+    }
+    i++;
+    if (i < 10)
+        goto repeat;
+
+#if defined(AFS_BYTE_RANGE_FLOCKS)
+    /* set a lock on c1 */
+    {
+        AFSFid fid = { 536870915, 12, 4016};
+        AFSByteRangeLock lock;
+        memset(&lock, 0, sizeof(AFSByteRangeLock));
+        lock.Fid = fid;
+        lock.Type = LockWrite;
+        lock.Flags = 0;
+        lock.Owner = 1001;
+        lock.Uniq = 1;
+        lock.Offset = 50;
+        lock.Length = 100;
+        code = rpc_test_afs_set_byterangelock(c1, &lock);
+        printf("%s: c1 set lock returned %d\n", prog, code);
+    }
+
+    /* try to set the same lock in c2 (should FAIL) */
+    {
+        AFSFid fid = { 536870915, 12, 4016};
+        AFSByteRangeLock lock;
+        memset(&lock, 0, sizeof(AFSByteRangeLock));
+        lock.Fid = fid;
+        lock.Type = LockWrite;
+        lock.Flags = 0;
+        lock.Owner = 1002;
+        lock.Uniq = 2;
+        lock.Offset = 50;
+        lock.Length = 100;
+        code = rpc_test_afs_set_byterangelock(c2, &lock);
+        printf("%s: c2 set lock returned %d\n", prog, code);
+    }
+
+    /* release lock on c1 */
+    {
+        AFSFid fid = { 536870915, 12, 4016};
+        AFSByteRangeLock lock;
+        memset(&lock, 0, sizeof(AFSByteRangeLock));
+        lock.Fid = fid;
+        lock.Type = LockWrite;
+        lock.Flags = 0;
+        lock.Owner = 1001;
+        lock.Uniq = 1;
+        lock.Offset = 50;
+        lock.Length = 100;
+        code = rpc_test_afs_release_byterangelock(c1, &lock);
+        printf("%s: c1 set lock returned %d\n", prog, code);
+    }
+#endif /* AFS_BYTE_RANGE_FLOCKS */
+
+    printf("%s: wait %d sec for processing\n", prog, 5);
+    sleep(5);
+
+    code = destroy_fs_channel(c1);
+    code = destroy_fs_channel(c2);
+
+    rpc_test_PkgShutdown();
+
+    printf("%s: finish\n", prog);
+
+    exit (0);
+
+}        /* main */
diff --git a/tests/rpctestlib/rpc_test_procs.c b/tests/rpctestlib/rpc_test_procs.c
new file mode 100644 (file)
index 0000000..9a99cd1
--- /dev/null
@@ -0,0 +1,420 @@
+/*
+ * Copyright (c) 2010, Linux Box Corporation.
+ * All Rights Reserved.
+ *
+ * Portions Copyright (c) 2007, Hartmut Reuter,
+ * RZG, Max-Planck-Institut f. Plasmaphysik.
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED ``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
+ * 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 <afsconfig.h>
+#include <afs/param.h>
+#include <afs/stds.h>
+
+#include "rpc_test_procs.h"
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <string.h>
+
+#ifdef AFS_NT40_ENV
+#else
+#include <sys/param.h>
+#include <sys/file.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#endif
+
+#include <string.h>
+#include <fcntl.h>
+#ifdef AFS_NT40_ENV
+#include <io.h>
+#include <windows.h>
+#include <WINNT/afsevent.h>
+#else
+#include <pwd.h>
+#include <afs/venus.h>
+#include <sys/time.h>
+#include <netdb.h>
+#endif
+#include <afs/afsint.h>
+#define FSINT_COMMON_XG 1
+#include <sys/stat.h>
+#include <errno.h>
+#include <signal.h>
+#include <afs/vice.h>
+#include <afs/cmd.h>
+#include <afs/auth.h>
+#include <afs/cellconfig.h>
+
+#include <afs/com_err.h>
+#ifdef HAVE_DIRENT_H
+#include <dirent.h>
+#endif
+#ifdef HAVE_DIRECT_H
+#include <direct.h>
+#endif
+#ifdef AFS_DARWIN_ENV
+#include <sys/malloc.h>
+#else
+#include <malloc.h>
+#endif
+#include <afs/errors.h>
+#include <afs/sys_prototypes.h>
+#include <rx_prototypes.h>
+#ifdef AFS_PTHREAD_ENV
+#include <assert.h>
+#endif
+
+extern const char *prog;
+const int ctx_key = 1;
+
+#if 1
+#define RPC_TEST_GLOBAL_RX_INIT 1
+#else
+#undef RPC_TEST_GLOBAL_RX_INIT
+#endif
+
+const afs_uint32 fs_port = 7000;
+
+typedef struct rpc_test_pkg_params {
+    pthread_mutex_t mtx;
+    pthread_mutexattr_t mtx_attrs;
+    afs_uint32 cb_next_port;
+    afs_uint32 next_cno;
+} rpc_test_pkg_params;
+static rpc_test_pkg_params rpc_test_params;
+
+afs_int32 rpc_test_PkgInit()
+{
+    afs_int32 code = 0;
+    static afs_uint32 rpc_test_initialized = 0; /* once */
+
+    if (!rpc_test_initialized) {
+        rpc_test_initialized = 1;
+    } else {
+        printf("%s: rpc_test_PkgInit: package already initialized\n");
+        exit(1);
+    }
+
+#ifndef AFS_NT40_ENV
+    code = pthread_mutexattr_init(&rpc_test_params.mtx_attrs);
+    if (code) {
+        printf("%s: rpc_test_PkgInit: pthread_mutexattr_init failed\n", prog);
+        exit(1);
+    }
+    code = pthread_mutex_init(&rpc_test_params.mtx, &rpc_test_params.mtx_attrs);
+    if (code) {
+        printf("%s: rpc_test_PkgInit: pthread_mutex_init failed\n", prog);
+        exit(1);
+    }
+#endif
+
+    /* start connection sequence */
+    rpc_test_params.next_cno = 1;
+
+    /* set the starting port in sequence */
+    rpc_test_params.cb_next_port = 7105;
+
+#if defined(RPC_TEST_GLOBAL_RX_INIT)
+    rx_Init(0);
+#endif
+
+    return (code);
+
+}        /* rpc_test_PkgInit */
+
+static void *
+init_callback_service_lwp(void *arg)
+{
+    struct rx_securityClass *sc;
+    struct rx_service *svc;
+    afs_int32 code = 0;
+
+    rpc_test_request_ctx *ctx = (rpc_test_request_ctx *) arg;
+
+    printf("%s: init_callback_service_lwp: listen_addr: %s "
+          "(%d) cb_port: %d\n",
+          prog, ctx->cb_listen_addr_s, ctx->cb_listen_addr.addr_in[0],
+          ctx->cb_port);
+
+    sc = (struct rx_securityClass *) rxnull_NewServerSecurityObject();
+    if (!sc) {
+       fprintf(stderr,"rxnull_NewServerSecurityObject failed for callback "
+                "service\n");
+       exit(1);
+    }
+
+#if defined(RPC_TEST_GLOBAL_RX_INIT)
+    svc = rx_NewServiceHost(htonl(INADDR_ANY), htons(ctx->cb_port), 1,
+                            ctx->cb_svc_name, &sc, 1, RXAFSCB_ExecuteRequest);
+#else
+    svc = rx_NewService(0, 1, ctx->cb_svc_name, &sc, 1, RXAFSCB_ExecuteRequest);
+#endif
+    /* stash context */
+    rx_SetServiceSpecific(svc, ctx_key, ctx);
+
+    if (!svc) {
+       fprintf(stderr,"rx_NewServiceHost failed for callback service\n");
+       exit(1);
+    }
+
+    /* XXX stash service so we can hijack its rx_socket when inititiating
+     * RPC calls */
+    ctx->svc = svc;
+
+    /* release pkg mutex before entering rx processing loop */
+    pthread_mutex_unlock(&rpc_test_params.mtx);
+
+    rx_StartServer(1);
+
+    printf("%s: init_callback_service_lwp: finished");
+
+    return (NULL);
+
+}        /* callback_service_lwp */
+
+afs_int32 init_callback_service(rpc_test_request_ctx *ctx)
+{
+    pthread_t tid;
+    pthread_attr_t tattr;
+    afs_int32 code = 0;
+
+    afs_uuid_create(&(ctx->cb_listen_addr.uuid));
+
+#if !defined(RPC_TEST_GLOBAL_RX_INIT)
+#if 0
+    code = rx_InitHost(ctx->cb_listen_addr.addr_in[0],
+                       (int) htons(ctx->cb_port));
+#else
+    code = rx_Init((int) htons(ctx->cb_port));
+#endif
+#endif /* RPC_TEST_GLOBAL_RX_INIT */
+
+    assert(pthread_attr_init(&tattr) == 0);
+    assert(pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED) == 0);
+    assert(pthread_create(&tid, &tattr, init_callback_service_lwp, ctx) == 0);
+
+    return (code);
+
+}        /* init_callback_service */
+
+afs_int32 init_fs_channel(rpc_test_request_ctx **octx, char *cb_if,
+                          char *listen_addr_s, char *prefix, char *fs_addr_s,
+                          afs_uint32 flags)
+{
+    char cmd[512];
+    rpc_test_request_ctx *ctx;
+    afs_int32 code = 0;
+#ifdef AFS_NT40_ENV
+    afs_int32 sslen = sizeof(struct sockaddr);
+#endif
+
+    ctx = *octx = (rpc_test_request_ctx *) malloc(sizeof(rpc_test_request_ctx));
+    memset(ctx, 0, sizeof(rpc_test_request_ctx));
+
+    /* initialize a local mutex */
+    code = pthread_mutex_init(&ctx->mtx, &rpc_test_params.mtx_attrs);
+
+    /* lock package before rx setup--which has global deps, atm */
+    pthread_mutex_lock(&rpc_test_params.mtx);
+
+    ctx->cno = rpc_test_params.next_cno++;
+    ctx->flags = flags;
+
+    /* afscbint (server) */
+    sprintf(ctx->cb_svc_name, "cb_%d", ctx->cno);
+    sprintf(ctx->cb_if_s, cb_if);
+    sprintf(ctx->cb_listen_addr_s, listen_addr_s);
+    sprintf(ctx->cb_prefix_s, prefix);
+    sprintf(ctx->fs_addr_s, fs_addr_s);
+
+#if defined(RPC_TEST_ADD_ADDRESSES)
+#if defined(AFS_LINUX26_ENV)
+    sprintf(cmd, "ip addr add %s/%s dev %s label %s", listen_addr_s, prefix,
+            cb_if, cb_if);
+    code = system(cmd);
+#endif
+#endif /* RPC_TEST_ADD_ADDRESSES */
+
+    /* lock this */
+    pthread_mutex_lock(&ctx->mtx);
+
+    /* set up rx */
+    ctx->cb_port = rpc_test_params.cb_next_port++;
+    ctx->cb_listen_addr.numberOfInterfaces = 1;
+
+#ifdef AFS_NT40_ENV
+    code = WSAStringToAddressA(listen_addr_s, AF_INET, NULL,
+              (struct sockaddr*) &(ctx->cb_listen_addr), &sslen);
+#else
+    code = inet_pton(AF_INET, listen_addr_s,
+                     (void*) &(ctx->cb_listen_addr.addr_in[0]));
+#endif
+
+    code = init_callback_service(ctx /* LOCKED, && rpc_test_params->mtx LOCKED */);
+
+    /* fsint (client) */
+
+#ifdef AFS_NT40_ENV
+    code = WSAStringToAddressA(fs_addr_s, AF_INET, NULL,
+              (struct sockaddr*) &(ctx->fs_addr.addr_in[0]), &sslen);
+#else
+    code = inet_pton(AF_INET, fs_addr_s, (void*) &(ctx->fs_addr.addr_in[0]));
+#endif
+    ctx->sc = rxnull_NewClientSecurityObject();
+    ctx->sc_index = RX_SECIDX_NULL;
+    ctx->conn = rx_NewConnection(ctx->fs_addr.addr_in[0], (int) htons(fs_port),
+                                 1, ctx->sc, ctx->sc_index);
+
+    /* unlock this */
+    pthread_mutex_unlock(&ctx->mtx);
+
+out:
+    return (code);
+
+}        /* init_fs_channel */
+
+/* XXX use the pkg lock to protect the state of rx_socket for
+ * the duration of the call, switching it out for the stashed
+ * rx_socket created by rx_NewService for this channel */
+#define RXCALL_WITH_SOCK(code, ctx, call) \
+    do { \
+        osi_socket prev_rx_socket; \
+        pthread_mutex_lock(&rpc_test_params.mtx); \
+        prev_rx_socket = rx_socket; \
+        rx_socket = ctx->svc->socket; \
+        code = call; \
+        rx_socket = prev_rx_socket; \
+        pthread_mutex_unlock(&rpc_test_params.mtx); \
+} while(0);
+
+afs_int32
+rpc_test_afs_fetch_status(rpc_test_request_ctx *ctx, AFSFid *fid,
+                              AFSFetchStatus *outstatus)
+{
+    struct rx_call *tcall;
+    struct AFSVolSync tsync;
+    struct AFSCallBack tcb;
+    afs_int32 code = 0;
+
+    RXCALL_WITH_SOCK(code, ctx,
+       (RXAFS_FetchStatus(ctx->conn, fid, outstatus, &tcb, &tsync)));
+
+    return (code);
+
+}        /* rpc_test_afs_fetch_status */
+
+afs_int32
+rpc_test_afs_store_status(rpc_test_request_ctx *ctx, AFSFid *fid,
+                    AFSStoreStatus *instatus, AFSFetchStatus *outstatus)
+{
+    struct rx_call *tcall;
+    struct AFSVolSync tsync;
+    afs_int32 code = 0;
+
+    RXCALL_WITH_SOCK(code, ctx,
+       (RXAFS_StoreStatus(ctx->conn, fid, instatus, outstatus, &tsync)));
+
+    return (code);
+
+}        /* rpc_test_afs_fetch_status */
+
+#if defined(AFS_BYTE_RANGE_FLOCKS)
+afs_int32 rpc_test_afs_set_byterangelock(rpc_test_request_ctx *ctx,
+    AFSByteRangeLock * lock)
+{
+    struct rx_call *tcall;
+    afs_int32 code = 0;
+
+    RXCALL_WITH_SOCK(code, ctx,
+       (RXAFS_SetByteRangeLock(ctx->conn, lock)));
+
+    return (code);
+
+}        /* rpc_test_afs_set_byterangelock */
+
+afs_int32 rpc_test_afs_release_byterangelock(rpc_test_request_ctx *ctx,
+    AFSByteRangeLock * lock)
+{
+    struct rx_call *tcall;
+    afs_int32 code = 0;
+
+    RXCALL_WITH_SOCK(code, ctx,
+       (RXAFS_ReleaseByteRangeLock(ctx->conn, lock)));
+
+    return (code);
+
+}        /* rpc_test_afs_release_byterangelock */
+
+afs_int32 rpc_test_afs_upgrade_byterangelock(rpc_test_request_ctx *ctx,
+    AFSByteRangeLock * lock)
+{
+    afs_int32 code = 0;
+
+    /* TODO:  implement */
+
+    return (code);
+
+}        /* rpc_test_afs_upgrade_byterangelock */
+
+afs_int32 rpc_test_afs_downgrade_byterangelock(rpc_test_request_ctx *ctx,
+    AFSByteRangeLock * Lock)
+{
+    afs_int32 code = 0;
+
+    /* TODO:  implement */
+
+    return (code);
+
+}        /* rpc_test_afs_downgrade_byterangelock */
+#endif /* AFS_BYTE_RANGE_FLOCKS */
+
+afs_int32
+destroy_fs_channel(rpc_test_request_ctx *ctx)
+{
+    char cmd[512];
+    afs_int32 code = 0;
+#if defined(RPC_TEST_ADD_ADDRESSES)
+#if defined(AFS_LINUX26_ENV)
+    sprintf(cmd, "ip addr del %s/%s dev %s label %s", ctx->cb_listen_addr_s,
+            ctx->cb_prefix_s, ctx->cb_if_s, ctx->cb_if_s);
+    code = system(cmd);
+#endif
+#endif /* RPC_TEST_ADD_ADDRESSES */
+    assert(ctx);
+    free(ctx);
+    return (code);
+
+}        /* destroy_fs_channel */
+
+void
+rpc_test_PkgShutdown()
+{
+    afs_int32 code = 0;
+
+}        /* rpc_test_PkgShutdown */
diff --git a/tests/rpctestlib/rpc_test_procs.h b/tests/rpctestlib/rpc_test_procs.h
new file mode 100644 (file)
index 0000000..fa5e439
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2010, Linux Box Corporation.
+ * All Rights Reserved.
+ *
+ * Portions Copyright (c) 2007, Hartmut Reuter,
+ * RZG, Max-Planck-Institut f. Plasmaphysik.
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED ``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
+ * 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.
+ */
+
+#ifndef _RPC_TEST_PROCS_H
+#define _RPC_TEST_PROCS_H
+
+#include <afsconfig.h>
+#include <afs/param.h>
+#include <afs/stds.h>
+
+#include <afs/afsutil.h>
+#include <rx/rx.h>
+#include <rx/xdr.h>
+#include <afs/afs_consts.h>
+#include <afs/afsint.h>
+#define FSINT_COMMON_XG 1
+#include <afs/afscbint.h>
+#include <pthread.h>
+
+#define RPC_TEST_REQ_CTX_FLAG_NONE         0x0000
+#define RPC_TEST_REQ_CTX_FLAG_XCB          0x0001
+
+typedef struct rpc_test_request_ctx {
+    afs_uint32 flags;
+    /* sync */
+    pthread_mutex_t mtx;
+    /* local address */
+    char cb_svc_name[256];
+    char cb_if_s[256];
+    char cb_listen_addr_s[256];
+    char cb_prefix_s[256];
+    char fs_addr_s[256];
+    interfaceAddr cb_listen_addr;
+    interfaceAddr fs_addr;
+    /* rx connection */
+    afs_uint32 cno;
+    afs_uint32 cb_port;
+    struct rx_connection *conn;
+    struct rx_securityClass *sc;
+    struct rx_service *svc; /* until rx fixes client socket mgmt */
+    afs_int32 sc_index;
+    /* stats */
+    afs_uint32 calls;
+} rpc_test_request_ctx;
+
+
+#define CTX_FOR_RXCALL(call) \
+    (rx_GetServiceSpecific((rx_ConnectionOf(call))->service, ctx_key))
+
+afs_int32 rpc_test_PkgInit();
+void rpc_test_PkgShutdown();
+
+/* call channel, callback RPC server multiplexing */
+afs_int32 init_fs_channel(rpc_test_request_ctx **ctx /* out */, char *cb_if,
+    char *listen_addr_s, char *prefix, char *fs_addr_s, afs_uint32 flags);
+afs_int32 destroy_fs_channel(rpc_test_request_ctx *ctx);
+
+/* test proc wrappers */
+afs_int32 rpc_test_fetch_status();
+afs_int32 rpc_test_afs_fetch_status(rpc_test_request_ctx *ctx, AFSFid *fid,
+                              AFSFetchStatus *outstatus);
+#if defined(AFS_BYTE_RANGE_FLOCKS) /* when will then be now?  soon. */
+afs_int32 rpc_test_afs_set_byterangelock(rpc_test_request_ctx *ctx,
+    AFSByteRangeLock * Lock);
+afs_int32 rpc_test_afs_release_byterangelock(rpc_test_request_ctx *ctx,
+    AFSByteRangeLock * Lock);
+afs_int32 rpc_test_afs_upgrade_byterangelock(rpc_test_request_ctx *ctx,
+    AFSByteRangeLock * Lock);
+afs_int32 rpc_test_afs_downgrade_byterangelock(rpc_test_request_ctx *ctx,
+    AFSByteRangeLock * Lock);
+#endif /* AFS_BYTE_RANGE_FLOCKS */
+
+afs_int32 rpc_test_afs_store_status(rpc_test_request_ctx *ctx, AFSFid *fid,
+    AFSStoreStatus *instatus, AFSFetchStatus *outstatus);
+afs_int32 rpc_test_afs_storedata_range(rpc_test_request_ctx *ctx, AFSFid *fid,
+    void *stuff);
+
+#endif /* _RPC_TEST_PROCS_H */