- fix unusual NFS kernel client problem and add several fixes.
This commit is contained in:
parent
c3388d3bdd
commit
eb3e266891
241
am-utils-6.2-add-NFSv3-nfs_quick_reply-functionality.patch
Normal file
241
am-utils-6.2-add-NFSv3-nfs_quick_reply-functionality.patch
Normal file
@ -0,0 +1,241 @@
|
||||
am-utils-6.2 - add NFSv3 nfs_quick_reply() functionality
|
||||
|
||||
From: Ian Kent <raven@themaw.net>
|
||||
|
||||
The implementation of the NFS v3 server does not use the hack needed
|
||||
by the nfs_quick_reply() function.
|
||||
|
||||
Now that saving the current transort for later use by nfs_quick_reply()
|
||||
avoids concurrency races it should be ok to use it.
|
||||
|
||||
Signed-off-by: Ian Kent <raven@themaw.net>
|
||||
---
|
||||
amd/nfs_prot_svc.c | 13 +++++
|
||||
amd/nfs_subr.c | 137 +++++++++++++++++++++++++++++++++++++++++-----------
|
||||
2 files changed, 120 insertions(+), 30 deletions(-)
|
||||
|
||||
diff --git a/amd/nfs_prot_svc.c b/amd/nfs_prot_svc.c
|
||||
index cbde172..29b7551 100644
|
||||
--- a/amd/nfs_prot_svc.c
|
||||
+++ b/amd/nfs_prot_svc.c
|
||||
@@ -180,7 +180,7 @@ nfs_program_2(struct svc_req *rqstp, SVCXPRT *transp)
|
||||
xdr_result = (xdrproc_t) xdr_diropres;
|
||||
local = (nfssvcproc_t) nfsproc_lookup_2_svc;
|
||||
/*
|
||||
- * Cheap way to pass transp down to amfs_auto_lookuppn so it can
|
||||
+ * Cheap way to pass transp down to amfs_auto_lookup so it can
|
||||
* be stored in the am_node structure and later used for
|
||||
* quick_reply().
|
||||
*/
|
||||
@@ -327,6 +327,8 @@ nfs_program_3(struct svc_req *rqstp, register SVCXPRT *transp)
|
||||
xdrproc_t _xdr_argument, _xdr_result;
|
||||
nfssvcproc_t local;
|
||||
|
||||
+ current_transp = NULL;
|
||||
+
|
||||
switch (rqstp->rq_proc) {
|
||||
case AM_NFS3_NULL:
|
||||
_xdr_argument = (xdrproc_t) xdr_void;
|
||||
@@ -350,6 +352,12 @@ nfs_program_3(struct svc_req *rqstp, register SVCXPRT *transp)
|
||||
_xdr_argument = (xdrproc_t) xdr_am_LOOKUP3args;
|
||||
_xdr_result = (xdrproc_t) xdr_am_LOOKUP3res;
|
||||
local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_lookup_3_svc;
|
||||
+ /*
|
||||
+ * Cheap way to pass transp down to amfs_auto_lookup so it can
|
||||
+ * be stored in the am_node structure and later used for
|
||||
+ * quick_reply().
|
||||
+ */
|
||||
+ current_transp = transp;
|
||||
break;
|
||||
|
||||
case AM_NFS3_ACCESS:
|
||||
@@ -476,6 +484,9 @@ nfs_program_3(struct svc_req *rqstp, register SVCXPRT *transp)
|
||||
}
|
||||
|
||||
result = (*local) (&argument, rqstp);
|
||||
+
|
||||
+ current_transp = NULL;
|
||||
+
|
||||
if (result != NULL && !svc_sendreply(transp, (xdrproc_t) _xdr_result, result)) {
|
||||
svcerr_systemerr (transp);
|
||||
}
|
||||
diff --git a/amd/nfs_subr.c b/amd/nfs_subr.c
|
||||
index 07d960d..a383618 100644
|
||||
--- a/amd/nfs_subr.c
|
||||
+++ b/amd/nfs_subr.c
|
||||
@@ -87,6 +87,9 @@ struct am_fh3 {
|
||||
};
|
||||
|
||||
/* forward declarations */
|
||||
+static int nfs_quick_reply2(am_node *mp, int error);
|
||||
+static int nfs_quick_reply3(am_node *mp, int error);
|
||||
+
|
||||
/* converting am-filehandles to mount-points */
|
||||
static am_node *fh_to_mp3(am_nfs_fh *fhp, int *rp, int vop);
|
||||
static am_node *fh_to_mp(am_nfs_fh *fhp);
|
||||
@@ -255,46 +258,65 @@ nfsproc_lookup_2_svc(nfsdiropargs *argp, struct svc_req *rqstp)
|
||||
return &res;
|
||||
}
|
||||
|
||||
-
|
||||
void
|
||||
nfs_quick_reply(am_node *mp, int error)
|
||||
{
|
||||
- SVCXPRT *transp = mp->am_transp;
|
||||
- nfsdiropres res;
|
||||
- xdrproc_t xdr_result = (xdrproc_t) xdr_diropres;
|
||||
+ int ret;
|
||||
|
||||
/*
|
||||
- * If there's a transp structure then we can reply to the client's
|
||||
- * nfs lookup request.
|
||||
+ * If there's no transp structure then we can't reply to the
|
||||
+ * client's nfs lookup request.
|
||||
*/
|
||||
- if (transp) {
|
||||
- if (error == 0) {
|
||||
- /*
|
||||
- * Construct a valid reply to a lookup request. Same
|
||||
- * code as in nfsproc_lookup_2_svc() above.
|
||||
- */
|
||||
- mp_to_fh(mp, &res.dr_u.dr_drok_u.drok_fhandle);
|
||||
- res.dr_u.dr_drok_u.drok_attributes = mp->am_fattr;
|
||||
- res.dr_status = NFS_OK;
|
||||
- } else
|
||||
- /*
|
||||
- * Return the error that was passed to us.
|
||||
- */
|
||||
- res.dr_status = nfs_error(error);
|
||||
+ if (!mp->am_transp)
|
||||
+ return;
|
||||
+
|
||||
+ if (nfs_dispatcher == nfs_program_2)
|
||||
+ ret = nfs_quick_reply2(mp, error);
|
||||
+ else
|
||||
+ ret = nfs_quick_reply3(mp, error);
|
||||
+
|
||||
+ if (!ret)
|
||||
+ svcerr_systemerr(mp->am_transp);
|
||||
+
|
||||
+ /*
|
||||
+ * Free up transp. It's only used for one reply.
|
||||
+ */
|
||||
+ put_nfs_xprt(mp->am_transp);
|
||||
+ mp->am_transp = NULL;
|
||||
+ dlog("Quick reply sent for %s", mp->am_al->al_mnt->mf_mount);
|
||||
+}
|
||||
|
||||
+
|
||||
+static int
|
||||
+nfs_quick_reply2(am_node *mp, int error)
|
||||
+{
|
||||
+ SVCXPRT *transp = mp->am_transp;
|
||||
+ nfsdiropres res;
|
||||
+ xdrproc_t xdr_result = (xdrproc_t) xdr_diropres;
|
||||
+ int ret;
|
||||
+
|
||||
+ if (error == 0) {
|
||||
/*
|
||||
- * Send off our reply
|
||||
+ * Construct a valid reply to a lookup request. Same
|
||||
+ * code as in nfsproc_lookup_2_svc() above.
|
||||
*/
|
||||
- if (!svc_sendreply(transp, (XDRPROC_T_TYPE) xdr_result, (SVC_IN_ARG_TYPE) & res))
|
||||
- svcerr_systemerr(transp);
|
||||
-
|
||||
+ mp_to_fh(mp, &res.dr_u.dr_drok_u.drok_fhandle);
|
||||
+ res.dr_u.dr_drok_u.drok_attributes = mp->am_fattr;
|
||||
+ res.dr_status = NFS_OK;
|
||||
+ } else
|
||||
/*
|
||||
- * Free up transp. It's only used for one reply.
|
||||
+ * Return the error that was passed to us.
|
||||
*/
|
||||
- put_nfs_xprt(mp->am_transp);
|
||||
- mp->am_transp = NULL;
|
||||
- dlog("Quick reply sent for %s", mp->am_al->al_mnt->mf_mount);
|
||||
- }
|
||||
+ res.dr_status = nfs_error(error);
|
||||
+
|
||||
+ /*
|
||||
+ * Send off our reply
|
||||
+ */
|
||||
+ ret = svc_sendreply(transp,
|
||||
+ (XDRPROC_T_TYPE) xdr_result,
|
||||
+ (SVC_IN_ARG_TYPE) & res);
|
||||
+
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -890,6 +912,8 @@ mp_to_fh(am_node *mp, am_nfs_fh *fhp)
|
||||
/* dlog("mp_to_fh: old filehandle: %d", fp->u.s.fhh_id); */
|
||||
}
|
||||
}
|
||||
+
|
||||
+
|
||||
void
|
||||
mp_to_fh3(am_node *mp, am_nfs_fh3 *fhp)
|
||||
{
|
||||
@@ -1257,6 +1281,61 @@ am_nfs3_lookup_3_svc(am_LOOKUP3args *argp, struct svc_req *rqstp)
|
||||
return &result;
|
||||
}
|
||||
|
||||
+
|
||||
+static int
|
||||
+nfs_quick_reply3(am_node *mp, int error)
|
||||
+{
|
||||
+ SVCXPRT *transp = mp->am_transp;
|
||||
+ xdrproc_t xdr_result = (xdrproc_t) xdr_am_LOOKUP3res;
|
||||
+ am_LOOKUP3res result;
|
||||
+ am_post_op_attr *post_op_dir;
|
||||
+ am_post_op_attr *post_op_obj;
|
||||
+ int ret;
|
||||
+
|
||||
+ if (error) {
|
||||
+ /*
|
||||
+ * Return the error that was passed to us.
|
||||
+ */
|
||||
+ post_op_dir->attributes_follow = 0;
|
||||
+ result.status = nfs_error(error);
|
||||
+ } else {
|
||||
+ post_op_dir = &result.res_u.ok.dir_attributes;
|
||||
+ post_op_obj = &result.res_u.ok.obj_attributes;
|
||||
+ am_fattr3 *fattr3;
|
||||
+ nfsfattr *fattr;
|
||||
+
|
||||
+ /*
|
||||
+ * Construct a valid reply to a lookup request. Same
|
||||
+ * code as in am_nfs3_lookup_3_svc() above.
|
||||
+ */
|
||||
+
|
||||
+ /* dir attributes */
|
||||
+ post_op_dir->attributes_follow = 1;
|
||||
+ fattr3 = &post_op_dir->am_post_op_attr_u.attributes;
|
||||
+ parent_fattr_to_fattr3(mp, fattr3);
|
||||
+
|
||||
+ mp_to_fh3(mp, &result.res_u.ok.object);
|
||||
+
|
||||
+ /* mount attributes */
|
||||
+ post_op_obj->attributes_follow = 1;
|
||||
+ fattr = &mp->am_fattr;
|
||||
+ fattr3 = &post_op_obj->am_post_op_attr_u.attributes;
|
||||
+ fattr_to_fattr3(fattr, fattr3);
|
||||
+
|
||||
+ result.status = AM_NFS3_OK;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * Send off our reply
|
||||
+ */
|
||||
+ ret = svc_sendreply(transp,
|
||||
+ (XDRPROC_T_TYPE) xdr_result,
|
||||
+ (SVC_IN_ARG_TYPE) &result);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+
|
||||
am_ACCESS3res *
|
||||
am_nfs3_access_3_svc(am_ACCESS3args *argp, struct svc_req *rqstp)
|
||||
{
|
127
am-utils-6.2-add-NFSv3-rpc-request-validation.patch
Normal file
127
am-utils-6.2-add-NFSv3-rpc-request-validation.patch
Normal file
@ -0,0 +1,127 @@
|
||||
am-utils-6.2 - add NFSv3 rpc request validation
|
||||
|
||||
From: Ian Kent <raven@themaw.net>
|
||||
|
||||
The NFS v2 internal server uses several validation checks for each
|
||||
RPC request it receives, also add this validation for the NFS v3
|
||||
internal server.
|
||||
|
||||
Signed-off-by: Ian Kent <raven@themaw.net>
|
||||
---
|
||||
amd/nfs_prot_svc.c | 65 +++++++++++++++++++++++++++++++---------------------
|
||||
1 file changed, 39 insertions(+), 26 deletions(-)
|
||||
|
||||
diff --git a/amd/nfs_prot_svc.c b/amd/nfs_prot_svc.c
|
||||
index 29b7551..cae12d4 100644
|
||||
--- a/amd/nfs_prot_svc.c
|
||||
+++ b/amd/nfs_prot_svc.c
|
||||
@@ -71,30 +71,9 @@ dispatcher_t nfs_dispatcher = nfs_program_2;
|
||||
typedef char *(*nfssvcproc_t)(voidp, struct svc_req *);
|
||||
|
||||
|
||||
-void
|
||||
-nfs_program_2(struct svc_req *rqstp, SVCXPRT *transp)
|
||||
+static int
|
||||
+validate_rpc_request(struct svc_req *rqstp, SVCXPRT *transp)
|
||||
{
|
||||
- union {
|
||||
- am_nfs_fh nfsproc_getattr_2_arg;
|
||||
- nfssattrargs nfsproc_setattr_2_arg;
|
||||
- nfsdiropargs nfsproc_lookup_2_arg;
|
||||
- am_nfs_fh nfsproc_readlink_2_arg;
|
||||
- nfsreadargs nfsproc_read_2_arg;
|
||||
- nfswriteargs nfsproc_write_2_arg;
|
||||
- nfscreateargs nfsproc_create_2_arg;
|
||||
- nfsdiropargs nfsproc_remove_2_arg;
|
||||
- nfsrenameargs nfsproc_rename_2_arg;
|
||||
- nfslinkargs nfsproc_link_2_arg;
|
||||
- nfssymlinkargs nfsproc_symlink_2_arg;
|
||||
- nfscreateargs nfsproc_mkdir_2_arg;
|
||||
- nfsdiropargs fsproc_rmdir_2_arg;
|
||||
- nfsreaddirargs nfsproc_readdir_2_arg;
|
||||
- am_nfs_fh nfsproc_statfs_2_arg;
|
||||
- } argument;
|
||||
- char *result;
|
||||
- xdrproc_t xdr_argument, xdr_result;
|
||||
- nfssvcproc_t local;
|
||||
-
|
||||
#ifdef HAVE_TRANSPORT_TYPE_TLI
|
||||
/*
|
||||
* On TLI systems we don't use an INET network type, but a "ticlts" (see
|
||||
@@ -109,7 +88,7 @@ nfs_program_2(struct svc_req *rqstp, SVCXPRT *transp)
|
||||
extern int __rpc_get_local_uid(SVCXPRT *transp, uid_t *uid);
|
||||
if (__rpc_get_local_uid(transp, &u) >= 0 && u != 0) {
|
||||
plog(XLOG_WARNING, "ignoring request from UID %ld, must be 0", (long) u);
|
||||
- return;
|
||||
+ return 0;
|
||||
}
|
||||
# else /* not HAVE___RPC_GET_LOCAL_UID */
|
||||
dlog("cannot verify local uid for rpc request");
|
||||
@@ -126,7 +105,7 @@ nfs_program_2(struct svc_req *rqstp, SVCXPRT *transp)
|
||||
plog(XLOG_WARNING, "ignoring request from %s:%u, port not reserved",
|
||||
inet_dquad(dq, sizeof(dq), sinp->sin_addr.s_addr),
|
||||
ntohs(sinp->sin_port));
|
||||
- return;
|
||||
+ return 0;
|
||||
}
|
||||
# endif /* MNT2_NFS_OPT_RESVPORT */
|
||||
/* if the address does not match, ignore the request */
|
||||
@@ -136,16 +115,47 @@ nfs_program_2(struct svc_req *rqstp, SVCXPRT *transp)
|
||||
plog(XLOG_WARNING, "ignoring request from %s:%u, not a local interface",
|
||||
inet_dquad(dq, sizeof(dq), sinp->sin_addr.s_addr),
|
||||
ntohs(sinp->sin_port));
|
||||
+ return 0;
|
||||
}
|
||||
} else {
|
||||
plog(XLOG_WARNING, "ignoring request from %s:%u, expected %s",
|
||||
inet_dquad(dq, sizeof(dq), sinp->sin_addr.s_addr),
|
||||
ntohs(sinp->sin_port),
|
||||
inet_dquad(dq2, sizeof(dq2), myipaddr.s_addr));
|
||||
- return;
|
||||
+ return 0;
|
||||
}
|
||||
}
|
||||
#endif /* not HAVE_TRANPORT_TYPE_TLI */
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+void
|
||||
+nfs_program_2(struct svc_req *rqstp, SVCXPRT *transp)
|
||||
+{
|
||||
+ union {
|
||||
+ am_nfs_fh nfsproc_getattr_2_arg;
|
||||
+ nfssattrargs nfsproc_setattr_2_arg;
|
||||
+ nfsdiropargs nfsproc_lookup_2_arg;
|
||||
+ am_nfs_fh nfsproc_readlink_2_arg;
|
||||
+ nfsreadargs nfsproc_read_2_arg;
|
||||
+ nfswriteargs nfsproc_write_2_arg;
|
||||
+ nfscreateargs nfsproc_create_2_arg;
|
||||
+ nfsdiropargs nfsproc_remove_2_arg;
|
||||
+ nfsrenameargs nfsproc_rename_2_arg;
|
||||
+ nfslinkargs nfsproc_link_2_arg;
|
||||
+ nfssymlinkargs nfsproc_symlink_2_arg;
|
||||
+ nfscreateargs nfsproc_mkdir_2_arg;
|
||||
+ nfsdiropargs fsproc_rmdir_2_arg;
|
||||
+ nfsreaddirargs nfsproc_readdir_2_arg;
|
||||
+ am_nfs_fh nfsproc_statfs_2_arg;
|
||||
+ } argument;
|
||||
+ char *result;
|
||||
+ xdrproc_t xdr_argument, xdr_result;
|
||||
+ nfssvcproc_t local;
|
||||
+
|
||||
+ if (!validate_rpc_request(rqstp, transp))
|
||||
+ return;
|
||||
|
||||
current_transp = NULL;
|
||||
|
||||
@@ -327,6 +337,9 @@ nfs_program_3(struct svc_req *rqstp, register SVCXPRT *transp)
|
||||
xdrproc_t _xdr_argument, _xdr_result;
|
||||
nfssvcproc_t local;
|
||||
|
||||
+ if (!validate_rpc_request(rqstp, transp))
|
||||
+ return;
|
||||
+
|
||||
current_transp = NULL;
|
||||
|
||||
switch (rqstp->rq_proc) {
|
170
am-utils-6.2-add-get_nfs_xprt-and-put_nfs_xprt-functions.patch
Normal file
170
am-utils-6.2-add-get_nfs_xprt-and-put_nfs_xprt-functions.patch
Normal file
@ -0,0 +1,170 @@
|
||||
am-utils-6.2 - add get_nfs_xprt() and put_nfs_xprt() functions
|
||||
|
||||
From: Ian Kent <raven@themaw.net>
|
||||
|
||||
The nfs_quick_reply() functionality relies on taking a copy of the
|
||||
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.
|
||||
|
||||
Signed-off-by: Ian Kent <raven@themaw.net>
|
||||
---
|
||||
conf/transp/transp_sockets.c | 44 ++++++++++++++++++++++++++++++++++++++++
|
||||
conf/transp/transp_tli.c | 46 +++++++++++++++++++++++++++++++++++++++++-
|
||||
include/am_utils.h | 2 ++
|
||||
3 files changed, 91 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/conf/transp/transp_sockets.c b/conf/transp/transp_sockets.c
|
||||
index 6326007..98f79c8 100644
|
||||
--- a/conf/transp/transp_sockets.c
|
||||
+++ b/conf/transp/transp_sockets.c
|
||||
@@ -45,6 +45,7 @@
|
||||
#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
|
||||
@@ -273,9 +274,52 @@ create_nfs_service(int *soNFSp, u_short *nfs_portp, SVCXPRT **nfs_xprtp, void (*
|
||||
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 switch to new transport");
|
||||
+ 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)
|
||||
diff --git a/conf/transp/transp_tli.c b/conf/transp/transp_tli.c
|
||||
index d26a511..ea565cc 100644
|
||||
--- a/conf/transp/transp_tli.c
|
||||
+++ b/conf/transp/transp_tli.c
|
||||
@@ -45,7 +45,8 @@
|
||||
#include <am_defs.h>
|
||||
#include <amu.h>
|
||||
|
||||
-struct netconfig *nfsncp;
|
||||
+struct netconfig *nfsncp = NULL;
|
||||
+static int soNFS = RPC_ANYSOCK;
|
||||
|
||||
|
||||
/*
|
||||
@@ -456,9 +457,52 @@ create_nfs_service(int *soNFSp, u_short *nfs_portp, SVCXPRT **nfs_xprtp, void (*
|
||||
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 switch to new transport");
|
||||
+ 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.
|
||||
diff --git a/include/am_utils.h b/include/am_utils.h
|
||||
index 0de881a..ff13c26 100644
|
||||
--- a/include/am_utils.h
|
||||
+++ b/include/am_utils.h
|
||||
@@ -378,6 +378,8 @@ extern void compute_nfs_args(void *nap, mntent_t *mntp, int genflags, struct net
|
||||
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
|
52
am-utils-6.2-fix-wcc-attr-usage-in-unlink3_or_rmdir3.patch
Normal file
52
am-utils-6.2-fix-wcc-attr-usage-in-unlink3_or_rmdir3.patch
Normal file
@ -0,0 +1,52 @@
|
||||
am-utils-6.2 - fix wcc attr usage in unlink3_or_rmdir3()
|
||||
|
||||
From: Ian Kent <raven@themaw.net>
|
||||
|
||||
The definition of the wcc post op attributes should be am_fattr3 not
|
||||
am_wcc_attr in unlink3_or_rmdir3().
|
||||
|
||||
Signed-off-by: Ian Kent <raven@themaw.net>
|
||||
---
|
||||
amd/nfs_subr.c | 9 +++++----
|
||||
1 file changed, 5 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/amd/nfs_subr.c b/amd/nfs_subr.c
|
||||
index a383618..b88a40c 100644
|
||||
--- a/amd/nfs_subr.c
|
||||
+++ b/amd/nfs_subr.c
|
||||
@@ -1058,7 +1058,8 @@ static am_nfsstat3 unlink3_or_rmdir3(am_diropargs3 *argp,
|
||||
am_pre_op_attr *pre_op_dir = &wcc_data->before;
|
||||
am_post_op_attr *post_op_dir = &wcc_data->after;
|
||||
nfsfattr *fattr;
|
||||
- am_wcc_attr *pre_op_wcc_attr, *post_op_wcc_attr;
|
||||
+ am_wcc_attr *pre_op_wcc_attr;
|
||||
+ am_fattr3 *post_op_wcc_attr;
|
||||
am_node *mp, *ap;
|
||||
int retry;
|
||||
|
||||
@@ -1085,7 +1086,7 @@ static am_nfsstat3 unlink3_or_rmdir3(am_diropargs3 *argp,
|
||||
fattr_to_wcc_attr(fattr, pre_op_wcc_attr);
|
||||
|
||||
if (mp->am_fattr.na_type != NFDIR) {
|
||||
- fattr_to_wcc_attr(fattr, post_op_wcc_attr);
|
||||
+ fattr_to_fattr3(fattr, post_op_wcc_attr);
|
||||
res = nfs_error(ENOTDIR);
|
||||
goto out;
|
||||
}
|
||||
@@ -1105,14 +1106,14 @@ static am_nfsstat3 unlink3_or_rmdir3(am_diropargs3 *argp,
|
||||
*/
|
||||
else if (retry == ENOENT)
|
||||
retry = 0;
|
||||
- fattr_to_wcc_attr(fattr, post_op_wcc_attr);
|
||||
+ fattr_to_fattr3(fattr, post_op_wcc_attr);
|
||||
res = nfs_error(retry);
|
||||
} else {
|
||||
forcibly_timeout_mp(mp);
|
||||
/* we can't wait for the expire so use the attributes as
|
||||
* they are now for the post op wcc attributes.
|
||||
*/
|
||||
- fattr_to_wcc_attr(fattr, post_op_wcc_attr);
|
||||
+ fattr_to_fattr3(fattr, post_op_wcc_attr);
|
||||
res = AM_NFS3_OK;
|
||||
}
|
||||
|
93
am-utils-6.2-use-linux-libtirpc-if-present.patch
Normal file
93
am-utils-6.2-use-linux-libtirpc-if-present.patch
Normal file
@ -0,0 +1,93 @@
|
||||
am-utils-6.2 - use Linux libtirpc if present
|
||||
|
||||
From: Ian Kent <raven@themaw.net>
|
||||
|
||||
For Linux systems, if the header files and shared libraries of libtirpc
|
||||
are present use them instead of the glibc RPC implementation.
|
||||
|
||||
Signed-off-by: Ian Kent <raven@themaw.net>
|
||||
---
|
||||
Makefile.am | 3 ++-
|
||||
configure.ac | 4 ++++
|
||||
include/am_compat.h | 8 ++++++--
|
||||
m4/macros/check_linux_libtirpc.m4 | 13 +++++++++++++
|
||||
4 files changed, 25 insertions(+), 3 deletions(-)
|
||||
create mode 100644 m4/macros/check_linux_libtirpc.m4
|
||||
|
||||
diff --git a/Makefile.am b/Makefile.am
|
||||
index bae4615..e094e95 100644
|
||||
--- a/Makefile.am
|
||||
+++ b/Makefile.am
|
||||
@@ -146,7 +146,8 @@ EXTRA_DIST_M4 = \
|
||||
m4/macros/type_xdrproc_t.m4 \
|
||||
m4/macros/type_xfs_args.m4 \
|
||||
m4/macros/type_yp_order_outorder.m4 \
|
||||
- m4/macros/with_addon.m4
|
||||
+ m4/macros/with_addon.m4 \
|
||||
+ m4/macros/check_linux_libtirpc.m4
|
||||
|
||||
EXTRA_DIST_CONF = \
|
||||
conf/autofs/autofs_default.h \
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index ce61925..98b444d 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -222,6 +222,9 @@ dnl lots of code. So I am forced to use a special purpose macro that sets
|
||||
dnl the libraries based on the OS. Sigh. -Erez.
|
||||
AMU_CHECK_OS_LIBS
|
||||
|
||||
+dnl use Linux libtirpc if possible
|
||||
+AMU_CHECK_LIBTIRPC
|
||||
+
|
||||
dnl librpc and librpcsvc are needed on Solaris
|
||||
AC_CHECK_LIB(rpc, clnt_sperrno)
|
||||
AC_CHECK_LIB(rpcsvc, xdr_fhandle)
|
||||
@@ -433,6 +436,7 @@ AC_CHECK_HEADERS( \
|
||||
arpa/nameser.h \
|
||||
arpa/inet.h \
|
||||
bsd/rpc/rpc.h \
|
||||
+ tirpc/netconfig.h \
|
||||
cdfs/cdfsmount.h \
|
||||
cdfs/cdfs_mount.h \
|
||||
fs/udf/udf_mount.h \
|
||||
diff --git a/include/am_compat.h b/include/am_compat.h
|
||||
index 3463f3f..d6826fc 100644
|
||||
--- a/include/am_compat.h
|
||||
+++ b/include/am_compat.h
|
||||
@@ -454,11 +454,15 @@ struct hsfs_args {
|
||||
/*
|
||||
* Define a dummy struct netconfig for non-TLI systems
|
||||
*/
|
||||
-#if !defined(HAVE_NETCONFIG_H) && !defined(HAVE_SYS_NETCONFIG_H)
|
||||
+#if !defined(HAVE_NETCONFIG_H)
|
||||
+# if !defined(HAVE_SYS_NETCONFIG_H)
|
||||
+# if !defined(HAVE_TIRPC_NETCONFIG_H)
|
||||
struct netconfig {
|
||||
int dummy;
|
||||
};
|
||||
-#endif /* not HAVE_NETCONFIG_H and not HAVE_SYS_NETCONFIG_H */
|
||||
+# endif /* not HAVE_TIRPC_NETCONFIG_H */
|
||||
+# endif /* not HAVE_SYS_NETCONFIG_H */
|
||||
+#endif /* not HAVE_NETCONFIG_H */
|
||||
|
||||
/* some OSs don't define INADDR_NONE and assume it's unsigned -1 */
|
||||
#ifndef INADDR_NONE
|
||||
diff --git a/m4/macros/check_linux_libtirpc.m4 b/m4/macros/check_linux_libtirpc.m4
|
||||
new file mode 100644
|
||||
index 0000000..918423c
|
||||
--- /dev/null
|
||||
+++ b/m4/macros/check_linux_libtirpc.m4
|
||||
@@ -0,0 +1,13 @@
|
||||
+dnl ######################################################################
|
||||
+dnl Check for Linux libtirpc library
|
||||
+AC_DEFUN([AMU_CHECK_LIBTIRPC],[
|
||||
+TIRPC_CPPFLAGS=""
|
||||
+TIRPC_LIBS=""
|
||||
+
|
||||
+AC_CHECK_HEADER(tirpc/netconfig.h,[
|
||||
+ TIRPC_CPPFLAGS="-I/usr/include/tirpc"
|
||||
+ AC_DEFINE(HAVE_LIBTIRPC, 1, [Define to 1 if you have libtirpc headers installed])
|
||||
+ AC_CHECK_LIB(tirpc, clnt_tli_create, [TIRPC_LIBS="-ltirpc"], [TIRPC_CPPFLAGS=""])])
|
||||
+ AMU_CFLAGS="$ANU_CFLAGS $TIRPC_CPPFLAGS"
|
||||
+ LIBS="$LIBS $TIRPC_LIBS"
|
||||
+])
|
@ -0,0 +1,60 @@
|
||||
am-utils-6.2 - use new get_nfs_xprt() and put_nfs_xprt() functions
|
||||
|
||||
From: Ian Kent <raven@themaw.net>
|
||||
|
||||
The nfs_quick_reply() function needs to know the current RPC transport
|
||||
outside of the NFS LOOKUP method call. It needs this to reply to the
|
||||
NFS LOOKUP call that initiated the mount.
|
||||
|
||||
Now there are functions that avoid transport corruption if another
|
||||
request comes in during the backgroud mount make nfs_quick_reply()
|
||||
use them.
|
||||
|
||||
Signed-off-by: Ian Kent <raven@themaw.net>
|
||||
---
|
||||
amd/amfs_generic.c | 3 +--
|
||||
amd/map.c | 2 +-
|
||||
amd/nfs_subr.c | 3 ++-
|
||||
3 files changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/amd/amfs_generic.c b/amd/amfs_generic.c
|
||||
index c352a32..86d0ab7 100644
|
||||
--- a/amd/amfs_generic.c
|
||||
+++ b/amd/amfs_generic.c
|
||||
@@ -1129,8 +1129,7 @@ amfs_generic_mount_child(am_node *new_mp, int *error_return)
|
||||
*/
|
||||
if (current_transp && !new_mp->am_transp) {
|
||||
dlog("Saving RPC transport for %s", new_mp->am_path);
|
||||
- new_mp->am_transp = (SVCXPRT *) xmalloc(sizeof(SVCXPRT));
|
||||
- *(new_mp->am_transp) = *current_transp;
|
||||
+ new_mp->am_transp = get_nfs_xprt(current_transp);
|
||||
}
|
||||
if (error && new_mp->am_al && new_mp->am_al->al_mnt &&
|
||||
(new_mp->am_al->al_mnt->mf_ops == &amfs_error_ops))
|
||||
diff --git a/amd/map.c b/amd/map.c
|
||||
index 0d404cf..bcb2156 100644
|
||||
--- a/amd/map.c
|
||||
+++ b/amd/map.c
|
||||
@@ -471,7 +471,7 @@ free_map(am_node *mp)
|
||||
XFREE(mp->am_name);
|
||||
XFREE(mp->am_path);
|
||||
XFREE(mp->am_pref);
|
||||
- XFREE(mp->am_transp);
|
||||
+ put_nfs_xprt(mp->am_transp);
|
||||
|
||||
if (mp->am_al)
|
||||
free_loc(mp->am_al);
|
||||
diff --git a/amd/nfs_subr.c b/amd/nfs_subr.c
|
||||
index 0a43b98..07d960d 100644
|
||||
--- a/amd/nfs_subr.c
|
||||
+++ b/amd/nfs_subr.c
|
||||
@@ -291,7 +291,8 @@ nfs_quick_reply(am_node *mp, int error)
|
||||
/*
|
||||
* Free up transp. It's only used for one reply.
|
||||
*/
|
||||
- XFREE(mp->am_transp);
|
||||
+ put_nfs_xprt(mp->am_transp);
|
||||
+ mp->am_transp = NULL;
|
||||
dlog("Quick reply sent for %s", mp->am_al->al_mnt->mf_mount);
|
||||
}
|
||||
}
|
@ -2,7 +2,7 @@ Summary: Automount utilities including an updated version of Amd
|
||||
Name: am-utils
|
||||
Version: 6.2.0
|
||||
%define upstream_version 6.2
|
||||
Release: 11%{?dist}
|
||||
Release: 12%{?dist}
|
||||
License: BSD
|
||||
Epoch: 5
|
||||
Group: System Environment/Daemons
|
||||
@ -27,11 +27,13 @@ BuildRequires: systemd-units
|
||||
BuildRequires: texinfo
|
||||
BuildRequires: gcc
|
||||
BuildRequires: m4
|
||||
BuildRequires: libtirpc-devel
|
||||
|
||||
Requires: rpcbind
|
||||
Requires: grep
|
||||
Requires: gawk
|
||||
Requires: findutils
|
||||
Requires: libtirpc
|
||||
|
||||
Requires(pre): /bin/grep
|
||||
Requires(post): /sbin/install-info
|
||||
@ -51,6 +53,12 @@ Patch5: am-utils-6.2-fix-NFSv3-readdir-post_op_dir-attributes-return.patch
|
||||
Patch6: am-utils-6.2-fix-NFSv3-unlink3_or_rmdir3-post_op-attributes-return.patch
|
||||
|
||||
Patch7: am-utils-6.2-fix-Linux-NFS-recognition-of-umounts.patch
|
||||
Patch8: am-utils-6.2-add-get_nfs_xprt-and-put_nfs_xprt-functions.patch
|
||||
Patch9: am-utils-6.2-use-new-get_nfs_xprt-and-put_nfs_xprt-functions.patch
|
||||
Patch10: am-utils-6.2-add-NFSv3-nfs_quick_reply-functionality.patch
|
||||
Patch11: am-utils-6.2-add-NFSv3-rpc-request-validation.patch
|
||||
Patch12: am-utils-6.2-fix-wcc-attr-usage-in-unlink3_or_rmdir3.patch
|
||||
Patch13: am-utils-6.2-use-linux-libtirpc-if-present.patch
|
||||
|
||||
# Not needed since autoreconf/libtool appear to do this automatically
|
||||
# Leaving it set doesn't appear to be a problem so leave it set in
|
||||
@ -82,6 +90,12 @@ mounting and unmounting filesystems.
|
||||
%patch5 -p1
|
||||
%patch6 -p1
|
||||
%patch7 -p1
|
||||
%patch8 -p1
|
||||
%patch9 -p1
|
||||
%patch10 -p1
|
||||
%patch11 -p1
|
||||
%patch12 -p1
|
||||
%patch13 -p1
|
||||
|
||||
./bootstrap
|
||||
|
||||
@ -193,6 +207,15 @@ fi
|
||||
%{_libdir}/libamu.so*
|
||||
|
||||
%changelog
|
||||
* Wed Mar 2 2016 Ian Kent <ikent@redhat.com> - 5:6.2.0-12
|
||||
- add get_nfs_xprt() and put_nfs_xprt() functions.
|
||||
- use new get_nfs_xprt() and put_nfs_xprt() functions.
|
||||
- add NFSv3 nfs_quick_reply() functionality.
|
||||
- use libtirpc instead of glibc RPC.
|
||||
- add NFSv3 rpc request validation.
|
||||
- fix wcc attr usage in unlink3_or_rmdir3().
|
||||
- use Linux libtirpc if present.
|
||||
|
||||
* Mon Feb 29 2016 Ian Kent <ikent@redhat.com> - 5:6.2.0-11
|
||||
- fix Linux NFS recognition of umounts.
|
||||
- add systemd dependency on nfs-lock.service.
|
||||
|
Loading…
x
Reference in New Issue
Block a user