diff options
Diffstat (limited to 'xlators/nfs/server/src/mount3udp_svc.c')
| -rw-r--r-- | xlators/nfs/server/src/mount3udp_svc.c | 326 |
1 files changed, 183 insertions, 143 deletions
diff --git a/xlators/nfs/server/src/mount3udp_svc.c b/xlators/nfs/server/src/mount3udp_svc.c index aa38b1cc40e..1a2b0f85453 100644 --- a/xlators/nfs/server/src/mount3udp_svc.c +++ b/xlators/nfs/server/src/mount3udp_svc.c @@ -2,26 +2,17 @@ Copyright (c) 2012 Gluster, Inc. <http://www.gluster.com> This file is part of GlusterFS. - GlusterFS is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - GlusterFS is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see - <http://www.gnu.org/licenses/>. + This file is licensed to you under your choice of the GNU Lesser + General Public License, version 3 or any later version (LGPLv3 or + later), or the GNU General Public License, version 2 (GPLv2), in all + cases as published by the Free Software Foundation. */ - #include "xdr-nfs3.h" -#include "logging.h" -#include "mem-pool.h" +#include <glusterfs/logging.h> +#include <glusterfs/mem-pool.h> #include "nfs-mem-types.h" +#include "nfs-messages.h" #include "mount3.h" #include <stdio.h> #include <stdlib.h> @@ -31,168 +22,217 @@ #include <sys/socket.h> #include <netinet/in.h> +extern struct nfs3_fh * +nfs3_rootfh(struct svc_req *req, xlator_t *nfsx, char *dp, char *expname); -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 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]; +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; - - 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; - } - - res = GF_CALLOC (1, sizeof(*res), gf_nfs_mt_mountres3); - if (res == NULL) { - gf_log (GF_MNT, GF_LOG_ERROR, "unable to allocate memory"); - goto err; - } - autharr = GF_CALLOC (1, sizeof(*autharr), gf_nfs_mt_int); - if (autharr == NULL) { - 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); + struct mountres3 *res = NULL; + int *autharr = NULL; + struct nfs3_fh *fh = NULL; + char *mpath = NULL; + xlator_t *nfsx = THIS; + char expname[PATH_MAX] = { + 0, + }; + mountstat3 stat = MNT3ERR_SERVERFAULT; + + errno = 0; /* RESET errno */ + + mpath = (char *)*dpp; + while (*mpath == '/') + mpath++; + + res = GF_CALLOC(1, sizeof(*res), gf_nfs_mt_mountres3); + if (res == NULL) { + gf_msg(GF_MNT, GF_LOG_ERROR, ENOMEM, NFS_MSG_NO_MEMORY, + "Unable to allocate memory"); + goto err; + } + autharr = GF_CALLOC(MNT3UDP_AUTH_LEN, sizeof(int), gf_nfs_mt_int); + if (autharr == NULL) { + gf_msg(GF_MNT, GF_LOG_ERROR, ENOMEM, NFS_MSG_NO_MEMORY, + "Unable to allocate memory"); + goto err; + } + + autharr[0] = AUTH_UNIX; + + fh = nfs3_rootfh(req, nfsx, mpath, (char *)expname); + + /* FAILURE: No FH */ + if (fh == NULL) { + gf_msg(GF_MNT, GF_LOG_ERROR, errno, NFS_MSG_GET_FH_FAIL, + "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; - - err: - GF_FREE (fh); - GF_FREE (res); - GF_FREE (autharr); - return NULL; + } + + /* 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: + GF_FREE(fh); + GF_FREE(res); + GF_FREE(autharr); + return NULL; } mountstat3 * mountudpproc3_umnt_3_svc(dirpath **dp, struct svc_req *req) { - mountstat3 *stat = NULL; - - stat = GF_CALLOC (1, sizeof(mountstat3), gf_nfs_mt_mountstat3); - if (stat == NULL) { - gf_log (GF_MNT, GF_LOG_ERROR, "unable to allocate memory"); - return NULL; - } - *stat = MNT3_OK; - mount3udp_delete_mountlist (mnthost, *dp); - return stat; + mountstat3 *stat = NULL; + char *mpath = (char *)*dp; + xlator_t *nfsx = THIS; + + stat = GF_MALLOC(sizeof(mountstat3), gf_nfs_mt_mountstat3); + if (stat == NULL) { + gf_msg(GF_MNT, GF_LOG_ERROR, ENOMEM, NFS_MSG_NO_MEMORY, + "Unable to allocate memory"); + return NULL; + } + *stat = MNT3_OK; + (void)mount3udp_delete_mountlist(nfsx, mnthost, mpath); + return stat; } static void mountudp_program_3(struct svc_req *rqstp, register SVCXPRT *transp) { - union { - dirpath mountudpproc3_mnt_3_arg; - } argument; - char *result = NULL; - xdrproc_t _xdr_argument = NULL, _xdr_result = NULL; - char *(*local)(char *, struct svc_req *) = NULL; - mountres3 *res = NULL; - struct sockaddr_in *sin = NULL; - - sin = svc_getcaller (transp); - inet_ntop (AF_INET, &sin->sin_addr, mnthost, INET_ADDRSTRLEN+1); - - switch (rqstp->rq_proc) { + union { + dirpath mountudpproc3_mnt_3_arg; + } argument; + char *result = NULL; + xdrproc_t _xdr_argument = NULL, _xdr_result = NULL; + char *(*local)(char *, struct svc_req *) = NULL; + mountres3 *res = NULL; + struct sockaddr_in *sin = NULL; + +#if !defined(_TIRPC_SVC_H) + sin = svc_getcaller(transp); +#else + sin = (struct sockaddr_in *)svc_getcaller(transp); + /* TIRPC's svc_getcaller() returns a pointer to a sockaddr_in6, even + * though it might actually be an IPv4 address. It ought return a + * struct sockaddr and make the caller upcast it to the proper + * address family. Sigh. + */ +#endif + /* And let's make sure that it's actually an IPv4 address. */ + GF_ASSERT(sin->sin_family == AF_INET); + + inet_ntop(AF_INET, &sin->sin_addr, mnthost, INET_ADDRSTRLEN + 1); + + switch (rqstp->rq_proc) { case NULLPROC: - (void) svc_sendreply (transp, (xdrproc_t) xdr_void, - (char *)NULL); - return; + (void)svc_sendreply(transp, (xdrproc_t)xdr_void, (char *)NULL); + return; case MOUNT3_MNT: - _xdr_argument = (xdrproc_t) xdr_dirpath; - _xdr_result = (xdrproc_t) xdr_mountres3; - local = (char *(*)(char *, - struct svc_req *)) mountudpproc3_mnt_3_svc; - break; + _xdr_argument = (xdrproc_t)xdr_dirpath; + _xdr_result = (xdrproc_t)xdr_mountres3; + local = (char *(*)(char *, + struct svc_req *))mountudpproc3_mnt_3_svc; + break; case MOUNT3_UMNT: - _xdr_argument = (xdrproc_t) xdr_dirpath; - _xdr_result = (xdrproc_t) xdr_mountstat3; - local = (char *(*)(char *, - struct svc_req *)) mountudpproc3_umnt_3_svc; - break; + _xdr_argument = (xdrproc_t)xdr_dirpath; + _xdr_result = (xdrproc_t)xdr_mountstat3; + local = (char *(*)(char *, + struct svc_req *))mountudpproc3_umnt_3_svc; + break; default: - svcerr_noproc (transp); - return; - } - memset ((char *)&argument, 0, sizeof (argument)); - if (!svc_getargs (transp, (xdrproc_t) _xdr_argument, - (caddr_t) &argument)) { - svcerr_decode (transp); - return; - } - result = (*local)((char *)&argument, rqstp); - if (result == NULL) { - gf_log (GF_MNT, GF_LOG_DEBUG, "PROC returned error"); - svcerr_systemerr (transp); - } - if (result != NULL && !svc_sendreply(transp, (xdrproc_t) _xdr_result, - result)) { - gf_log (GF_MNT, GF_LOG_ERROR, "svc_sendreply returned error"); - svcerr_systemerr (transp); - } - if (!svc_freeargs (transp, (xdrproc_t) _xdr_argument, - (caddr_t) &argument)) { - gf_log (GF_MNT, GF_LOG_ERROR, "unable to free arguments"); - } - if (result == NULL) - return; - /* free the result */ - switch (rqstp->rq_proc) { + svcerr_noproc(transp); + return; + } + memset((char *)&argument, 0, sizeof(argument)); + if (!svc_getargs(transp, (xdrproc_t)_xdr_argument, (caddr_t)&argument)) { + svcerr_decode(transp); + return; + } + result = (*local)((char *)&argument, rqstp); + if (result == NULL) { + gf_msg_debug(GF_MNT, 0, "PROC returned error"); + svcerr_systemerr(transp); + } + if (result != NULL && + !svc_sendreply(transp, (xdrproc_t)_xdr_result, result)) { + gf_msg(GF_MNT, GF_LOG_ERROR, 0, NFS_MSG_SVC_ERROR, + "svc_sendreply returned error"); + svcerr_systemerr(transp); + } + if (!svc_freeargs(transp, (xdrproc_t)_xdr_argument, (caddr_t)&argument)) { + gf_msg(GF_MNT, GF_LOG_ERROR, 0, NFS_MSG_ARG_FREE_FAIL, + "Unable to free arguments"); + } + if (result == NULL) + return; + /* free the result */ + switch (rqstp->rq_proc) { case MOUNT3_MNT: - res = (mountres3 *) result; - GF_FREE (res->mountres3_u.mountinfo.fhandle.fhandle3_val); - GF_FREE (res->mountres3_u.mountinfo.auth_flavors.auth_flavors_val); - GF_FREE (res); - break; + res = (mountres3 *)result; + GF_FREE(res->mountres3_u.mountinfo.fhandle.fhandle3_val); + GF_FREE(res->mountres3_u.mountinfo.auth_flavors.auth_flavors_val); + GF_FREE(res); + break; case MOUNT3_UMNT: - GF_FREE (result); - break; - } - return; + GF_FREE(result); + break; + } + return; } void * -mount3udp_thread (void *argv) +mount3udp_thread(void *argv) { - register SVCXPRT *transp = NULL; - - transp = svcudp_create(RPC_ANYSOCK); - if (transp == NULL) { - gf_log (GF_MNT, GF_LOG_ERROR, "svcudp_create error"); - return NULL; - } - if (!svc_register(transp, MOUNT_PROGRAM, MOUNT_V3, - mountudp_program_3, IPPROTO_UDP)) { - gf_log (GF_MNT, GF_LOG_ERROR, "svc_register error"); - return NULL; - } - - svc_run (); - gf_log (GF_MNT, GF_LOG_ERROR, "svc_run returned"); + xlator_t *nfsx = argv; + register SVCXPRT *transp = NULL; + + GF_ASSERT(nfsx); + + THIS = nfsx; + + transp = svcudp_create(RPC_ANYSOCK); + if (transp == NULL) { + gf_msg(GF_MNT, GF_LOG_ERROR, 0, NFS_MSG_SVC_ERROR, + "svcudp_create error"); + return NULL; + } + if (!svc_register(transp, MOUNT_PROGRAM, MOUNT_V3, mountudp_program_3, + IPPROTO_UDP)) { + gf_msg(GF_MNT, GF_LOG_ERROR, 0, NFS_MSG_SVC_ERROR, + "svc_register error"); return NULL; + } + + svc_run(); + gf_msg(GF_MNT, GF_LOG_ERROR, 0, NFS_MSG_SVC_RUN_RETURNED, + "svc_run returned"); + return NULL; } |
