current transport for later use.
The problem with this is the context of the RPC message is kept in
the transport and if any RPC message arrives before nfs_quick_reply()
is called that context will be corrupted.
So add a function get_nfs_xprt() to replace the current transport
with a new one returning the passed in transort so nfs_quick_reply()
can use it later.
A function put_nfs_xprt() is also added (although not really needed
since it just destroys the now unused transport) for completeness.
From: Ian Kent
#include <am_defs.h>
#include <amu.h>
+static int soNFS = RPC_ANYSOCK;
/*
* find the IP address that can be used to connect to the local host
return 3;
}
+ soNFS = *soNFSp;
+
return 0; /* all is well */
}
+/*
+ * Get a pointer to the current NFS SVCXPRT and replace it
+ * with a new one.
+ */
+SVCXPRT *
+get_nfs_xprt(SVCXPRT *nfs_xprt)
+{
+ SVCXPRT *newxprt;
+ int newfd;
+
+ if (!nfs_xprt || soNFS == RPC_ANYSOCK)
+ return NULL;
+
+ newfd = dup(soNFS);
+ if (newfd < 0)
+ return NULL;
+
+ xprt_unregister(nfs_xprt);
+ newxprt = svcudp_create(newfd);
+ if (!newxprt) {
+ plog(XLOG_FATAL, "Can't swicth to new transpot");
+ xprt_register(nfs_xprt);
+ close(newfd);
+ return NULL;
+ }
+
+ soNFS = newfd;
+
+ return nfs_xprt;
+}
+
+/*
+ * Destroy a transport previously obtained by get_nfs_xprt().
+ */
+void put_nfs_xprt(SVCXPRT *nfs_xprt)
+{
+ if (!nfs_xprt || soNFS == RPC_ANYSOCK)
+ return;
+
+ svc_destroy(nfs_xprt);
+}
/*
* Create the amq service for amd (both TCP and UDP)
#include <am_defs.h>
#include <amu.h>
-struct netconfig *nfsncp;
+struct netconfig *nfsncp = NULL;
+static int soNFS = RPC_ANYSOCK;
/*
return 1;
}
+ soNFS = *soNFSp;
+
return 0; /* all is well */
}
+/*
+ * Get a pointer to the current NFS SVCXPRT and replace it
+ * with a new one.
+ */
+SVCXPRT *
+get_nfs_xprt(SVCXPRT *nfs_xprt)
+{
+ SVCXPRT *newxprt;
+ int newfd;
+
+ if (!nfs_xprt || soNFS == RPC_ANYSOCK)
+ return NULL;
+
+ newfd = dup(soNFS);
+ if (newfd < 0)
+ return NULL;
+
+ xprt_unregister(nfs_xprt);
+ newxprt = svc_tli_create(newfd, nfsncp, NULL, 0, 0);
+ if (!newxprt) {
+ plog(XLOG_FATAL, "Can't swicth to new transpot");
+ xprt_register(nfs_xprt);
+ close(newfd);
+ return NULL;
+ }
+
+ soNFS = newfd;
+
+ return nfs_xprt;
+}
+
+/*
+ * Destroy a transport previously obtained by get_nfs_xprt().
+ */
+void put_nfs_xprt(SVCXPRT *nfs_xprt)
+{
+ if (!nfs_xprt || soNFS == RPC_ANYSOCK)
+ return;
+
+ svc_destroy(nfs_xprt);
+}
/*
* Bind to preferred AMQ port.
extern void destroy_nfs_args(void *nap, u_long nfs_version);
extern int create_amq_service(int *udp_soAMQp, SVCXPRT **udp_amqpp, struct netconfig **udp_amqncpp, int *tcp_soAMQp, SVCXPRT **tcp_amqpp, struct netconfig **tcp_amqncpp, u_short preferred_amq_port);
extern int create_nfs_service(int *soNFSp, u_short *nfs_portp, SVCXPRT **nfs_xprtp, void (*dispatch_fxn)(struct svc_req *rqstp, SVCXPRT *transp), u_long nfs_version);
+extern SVCXPRT *get_nfs_xprt(SVCXPRT *nfs_xprt);
+extern void put_nfs_xprt(SVCXPRT *nfs_xprt);
extern int amu_svc_register(SVCXPRT *, u_long, u_long, void (*)(struct svc_req *, SVCXPRT *), u_long, struct netconfig *);
#ifdef HAVE_TRANSPORT_TYPE_TLI