summaryrefslogtreecommitdiffstats
path: root/xlators/nfs/server/src/mount3udp_svc.c
diff options
context:
space:
mode:
authorSantosh Kumar Pradhan <spradhan@redhat.com>2014-07-22 16:56:57 +0530
committerNiels de Vos <ndevos@redhat.com>2014-10-07 00:51:29 -0700
commitddb31110db8e1b5995d392ced988f34d2f9145d2 (patch)
tree196f7271492c76a673e3a330cb22c3e4685b0e48 /xlators/nfs/server/src/mount3udp_svc.c
parent1642ee54cf78bb2d117f7ffb2a180acf12c54ab6 (diff)
gNFS: Subdir mount does not work on UDP proto
After enabling nfs.mount-udp, mounting a subdir on a volume over NFS fails. Because mountudpproc3_mnt_3_svc() invokes nfs3_rootfh() which internally calls mnt3_mntpath_to_export() to resolve the mount path. mnt3_mntpath_to_export() just works if the mount path requested is volume itself. It is not able to resolve, if the path is a subdir inside the volume. MOUNT over TCP uses mnt3_find_export() to resolve subdir path but UDP can't use this routine because mnt3_find_export() needs the req data (of type rpcsvc_request_t) and it's available only for TCP version of RPC. FIX: (1) Use syncop_lookup() framework to resolve the MOUNT PATH by breaking it into components and resolve component-by-component. i.e. glfs_resolve_at () API from libgfapi shared object. (2) If MOUNT PATH is subdir, then make sure subdir export is not disabled. (3) Add auth mechanism to respect nfs.rpc-auth-allow/reject and subdir auth i.e. nfs.export-dir (4) Enhanced error handling for MOUNT over UDP Change-Id: I42ee69415d064b98af4f49773026562824f684d1 BUG: 1118311 Signed-off-by: Santosh Kumar Pradhan <spradhan@redhat.com> Reviewed-on: http://review.gluster.org/8346 Reviewed-by: soumya k <skoduri@redhat.com> Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Niels de Vos <ndevos@redhat.com>
Diffstat (limited to 'xlators/nfs/server/src/mount3udp_svc.c')
-rw-r--r--xlators/nfs/server/src/mount3udp_svc.c74
1 files changed, 50 insertions, 24 deletions
diff --git a/xlators/nfs/server/src/mount3udp_svc.c b/xlators/nfs/server/src/mount3udp_svc.c
index 70aead67edb..4ad8e11ad49 100644
--- a/xlators/nfs/server/src/mount3udp_svc.c
+++ b/xlators/nfs/server/src/mount3udp_svc.c
@@ -23,49 +23,73 @@
#include <netinet/in.h>
-extern struct nfs3_fh* nfs3_rootfh (char *dp);
-extern mountres3 mnt3svc_set_mountres3 (mountstat3 stat, struct nfs3_fh *fh,
- int *authflavor, u_int aflen);
+extern struct nfs3_fh*
+nfs3_rootfh (struct svc_req *req, xlator_t *nfsx, char *dp, char *expname);
+
+extern mountres3
+mnt3svc_set_mountres3 (mountstat3 stat, struct nfs3_fh *fh,
+ int *authflavor, u_int aflen);
extern int
-mount3udp_add_mountlist (char *host, dirpath *expname);
+mount3udp_add_mountlist (xlator_t *nfsx, char *host, char *expname);
extern int
-mount3udp_delete_mountlist (char *host, dirpath *expname);
+mount3udp_delete_mountlist (xlator_t *nfsx, char *host, char *expname);
+
+extern mountstat3
+mnt3svc_errno_to_mnterr (int32_t errnum);
/* only this thread will use this, no locking needed */
char mnthost[INET_ADDRSTRLEN+1];
+#define MNT3UDP_AUTH_LEN 1 /* Only AUTH_UNIX for now */
+
mountres3 *
mountudpproc3_mnt_3_svc(dirpath **dpp, struct svc_req *req)
{
struct mountres3 *res = NULL;
int *autharr = NULL;
struct nfs3_fh *fh = NULL;
- char *tmp = NULL;
+ char *mpath = NULL;
+ xlator_t *nfsx = THIS;
+ char expname[PATH_MAX] = {0, };
+ mountstat3 stat = MNT3ERR_SERVERFAULT;
- tmp = (char *)*dpp;
- while (*tmp == '/')
- tmp++;
- fh = nfs3_rootfh (tmp);
- if (fh == NULL) {
- gf_log (GF_MNT, GF_LOG_DEBUG, "unable to get fh for %s", tmp);
- goto err;
- }
+ errno = 0; /* RESET errno */
+
+ mpath = (char *)*dpp;
+ while (*mpath == '/')
+ mpath++;
res = GF_CALLOC (1, sizeof(*res), gf_nfs_mt_mountres3);
if (res == NULL) {
- gf_log (GF_MNT, GF_LOG_ERROR, "unable to allocate memory");
+ gf_log (GF_MNT, GF_LOG_ERROR, "Unable to allocate memory");
goto err;
}
- autharr = GF_CALLOC (1, sizeof(*autharr), gf_nfs_mt_int);
+ autharr = GF_CALLOC (MNT3UDP_AUTH_LEN, sizeof(int), gf_nfs_mt_int);
if (autharr == NULL) {
- gf_log (GF_MNT, GF_LOG_ERROR, "unable to allocate memory");
+ gf_log (GF_MNT, GF_LOG_ERROR, "Unable to allocate memory");
goto err;
}
+
autharr[0] = AUTH_UNIX;
- *res = mnt3svc_set_mountres3 (MNT3_OK, fh, autharr, 1);
- mount3udp_add_mountlist (mnthost, *dpp);
+
+ fh = nfs3_rootfh (req, nfsx, mpath, (char *)expname);
+
+ /* FAILURE: No FH */
+ if (fh == NULL) {
+ gf_log (GF_MNT, GF_LOG_ERROR, "Unable to get fh for %s", mpath);
+ if (errno)
+ stat = mnt3svc_errno_to_mnterr (errno);
+ *res = mnt3svc_set_mountres3 (stat, NULL /* fh */,
+ autharr, MNT3UDP_AUTH_LEN);
+ return res;
+ }
+
+ /* SUCCESS */
+ stat = MNT3_OK;
+ *res = mnt3svc_set_mountres3 (stat, fh, autharr, MNT3UDP_AUTH_LEN);
+ (void) mount3udp_add_mountlist (nfsx, mnthost, (char *) expname);
return res;
err:
@@ -79,14 +103,16 @@ mountstat3 *
mountudpproc3_umnt_3_svc(dirpath **dp, struct svc_req *req)
{
mountstat3 *stat = NULL;
+ char *mpath = (char *) *dp;
+ xlator_t *nfsx = THIS;
stat = GF_CALLOC (1, sizeof(mountstat3), gf_nfs_mt_mountstat3);
if (stat == NULL) {
- gf_log (GF_MNT, GF_LOG_ERROR, "unable to allocate memory");
+ gf_log (GF_MNT, GF_LOG_ERROR, "Unable to allocate memory");
return NULL;
}
*stat = MNT3_OK;
- mount3udp_delete_mountlist (mnthost, *dp);
+ (void) mount3udp_delete_mountlist (nfsx, mnthost, mpath);
return stat;
}
@@ -147,7 +173,7 @@ mountudp_program_3(struct svc_req *rqstp, register SVCXPRT *transp)
}
if (!svc_freeargs (transp, (xdrproc_t) _xdr_argument,
(caddr_t) &argument)) {
- gf_log (GF_MNT, GF_LOG_ERROR, "unable to free arguments");
+ gf_log (GF_MNT, GF_LOG_ERROR, "Unable to free arguments");
}
if (result == NULL)
return;
@@ -176,8 +202,8 @@ mount3udp_thread (void *argv)
GF_ASSERT (nfsx);
if (glusterfs_this_set(nfsx)) {
- gf_log (GF_MNT, GF_LOG_ERROR, "failed to set xlator, "
- "nfs.mount-udp will not work");
+ gf_log (GF_MNT, GF_LOG_ERROR,
+ "Failed to set xlator, nfs.mount-udp will not work");
return NULL;
}