diff options
Diffstat (limited to 'xlators')
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-volgen.c | 1 | ||||
| -rw-r--r-- | xlators/nfs/server/src/Makefile.am | 2 | ||||
| -rw-r--r-- | xlators/nfs/server/src/mount3.c | 91 | ||||
| -rw-r--r-- | xlators/nfs/server/src/mount3udp_svc.c | 201 | ||||
| -rw-r--r-- | xlators/nfs/server/src/nfs-mem-types.h | 10 | ||||
| -rw-r--r-- | xlators/nfs/server/src/nfs.c | 26 | ||||
| -rw-r--r-- | xlators/nfs/server/src/nfs.h | 1 | ||||
| -rw-r--r-- | xlators/nfs/server/src/nfs3-fh.c | 12 | ||||
| -rw-r--r-- | xlators/nfs/server/src/nfs3-fh.h | 4 | 
9 files changed, 342 insertions, 6 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-volgen.c b/xlators/mgmt/glusterd/src/glusterd-volgen.c index 0d82f1624b5..ae38d5b14a5 100644 --- a/xlators/mgmt/glusterd/src/glusterd-volgen.c +++ b/xlators/mgmt/glusterd/src/glusterd-volgen.c @@ -217,6 +217,7 @@ static struct volopt_map_entry glusterd_volopt_map[] = {          {"nfs.export-dir",                       "nfs/server",                "!nfs3.*.export-dir", NULL, DOC, 0},          {"nfs.disable",                          "nfs/server",                "!nfs-disable", NULL, DOC, 0},          {"nfs.nlm",                              "nfs/server",                "nfs.nlm", NULL, GLOBAL_DOC, 0}, +        {"nfs.mount-udp",                        "nfs/server",                "nfs.mount-udp", NULL, GLOBAL_DOC, 0},          {VKEY_FEATURES_QUOTA,                    "features/marker",           "quota", "off", NO_DOC, OPT_FLAG_FORCE},          {VKEY_FEATURES_LIMIT_USAGE,              "features/quota",            "limit-set", NULL, NO_DOC, 0}, diff --git a/xlators/nfs/server/src/Makefile.am b/xlators/nfs/server/src/Makefile.am index b5fd8586dbd..ef3b672975d 100644 --- a/xlators/nfs/server/src/Makefile.am +++ b/xlators/nfs/server/src/Makefile.am @@ -4,7 +4,7 @@ nfsrpclibdir = $(top_srcdir)/rpc/rpc-lib/src  server_la_LDFLAGS = -module -avoidversion  server_la_SOURCES = nfs.c nfs-common.c nfs-fops.c nfs-inodes.c \  	nfs-generics.c mount3.c nfs3-fh.c nfs3.c nfs3-helpers.c nlm4.c \ -	nlmcbk_svc.c +	nlmcbk_svc.c mount3udp_svc.c  server_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la  noinst_HEADERS = nfs.h nfs-common.h nfs-fops.h nfs-inodes.h nfs-generics.h \ diff --git a/xlators/nfs/server/src/mount3.c b/xlators/nfs/server/src/mount3.c index d088b3c53ca..93b0864767a 100644 --- a/xlators/nfs/server/src/mount3.c +++ b/xlators/nfs/server/src/mount3.c @@ -47,6 +47,9 @@  typedef ssize_t (*mnt3_serializer) (struct iovec outmsg, void *args); +extern void * +mount3udp_thread (void *argv); +  /* Generic reply function for MOUNTv3 specific replies. */  int @@ -1406,6 +1409,87 @@ err:          return ret;  } +/* just declaring, definition is way down below */ +rpcsvc_program_t        mnt3prog; + +/* nfs3_rootfh used by mount3udp thread needs to access mount3prog.private + * directly as we don't have nfs xlator pointer to dereference it. But thats OK + */ + +struct nfs3_fh * +nfs3_rootfh (char* path) +{ +        struct mount3_state     *ms = NULL; +        struct nfs3_fh          *fh = NULL; +        struct mnt3_export      *exp = NULL; +        inode_t                 *inode = NULL; +        char                    *tmp = NULL; + +        ms = mnt3prog.private; +        exp = mnt3_mntpath_to_export (ms, path); +        if (exp == NULL) +                goto err; + +        tmp = (char *)path; +        tmp = strchr (tmp, '/'); +        if (tmp == NULL) +                tmp = "/"; + +        inode = inode_from_path (exp->vol->itable, tmp); +        if (inode == NULL) +                goto err; + +        fh = GF_CALLOC (1, sizeof(*fh), gf_nfs_mt_nfs3_fh); +        if (fh == NULL) +                goto err; +        nfs3_build_fh (inode, exp->volumeid, fh); + +err: +        if (inode) +                inode_unref (inode); +        return fh; +} + +int +mount3udp_add_mountlist (char *host, dirpath *expname) +{ +        struct mountentry       *me = NULL; +        struct mount3_state     *ms = NULL; +        char                    *export = NULL; + +        ms = mnt3prog.private; +        me = GF_CALLOC (1, sizeof (*me), gf_nfs_mt_mountentry); +        if (!me) +                return -1; +        export = (char *)expname; +        while (*export == '/') +                export++; + +        strcpy (me->exname, export); +        strcpy (me->hostname, host); +        INIT_LIST_HEAD (&me->mlist); +        LOCK (&ms->mountlock); +        { +                list_add_tail (&me->mlist, &ms->mountlist); +        } +        UNLOCK (&ms->mountlock); +        return 0; +} + +int +mount3udp_delete_mountlist (char *hostname, dirpath *expname) +{ +        struct mount3_state     *ms = NULL; +        char                    *export = NULL; + +        ms = mnt3prog.private; +        export = (char *)expname; +        while (*export == '/') +                export++; +        __mnt3svc_umount (ms, export, hostname); +        return 0; +} +  struct mnt3_export *  mnt3_init_export_ent (struct mount3_state *ms, xlator_t *xl, char *exportpath, @@ -1785,6 +1869,7 @@ rpcsvc_program_t        mnt3prog = {  }; +  rpcsvc_program_t *  mnt3svc_init (xlator_t *nfsx)  { @@ -1793,6 +1878,7 @@ mnt3svc_init (xlator_t *nfsx)          dict_t                  *options = NULL;          char                    *portstr = NULL;          int                      ret = -1; +        pthread_t                udp_thread;          if (!nfsx || !nfsx->private)                  return NULL; @@ -1842,6 +1928,9 @@ mnt3svc_init (xlator_t *nfsx)                  goto err;          } +        if (nfs->mount_udp) { +                pthread_create (&udp_thread, NULL, mount3udp_thread, NULL); +        }          return &mnt3prog;  err:          return NULL; @@ -1930,5 +2019,3 @@ mnt1svc_init (xlator_t *nfsx)  err:          return NULL;  } - - diff --git a/xlators/nfs/server/src/mount3udp_svc.c b/xlators/nfs/server/src/mount3udp_svc.c new file mode 100644 index 00000000000..2c370a74a96 --- /dev/null +++ b/xlators/nfs/server/src/mount3udp_svc.c @@ -0,0 +1,201 @@ +/* +  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/>. +*/ + + +#include "xdr-nfs3.h" +#include "logging.h" +#include "mem-pool.h" +#include "nfs-mem-types.h" +#include "mount3.h" +#include <stdio.h> +#include <stdlib.h> +#include <rpc/pmap_clnt.h> +#include <string.h> +#include <memory.h> +#include <sys/socket.h> +#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 int +mount3udp_add_mountlist (char *host, dirpath *expname); + +extern int +mount3udp_delete_mountlist (char *host, dirpath *expname); + + +/* only this thread will use this, no locking needed */ +char mnthost[INET_ADDRSTRLEN+1]; + +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); +        return res; + + err: +        if (fh) +                GF_FREE (fh); +        if (res) +                GF_FREE (res); +        if (autharr) +                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; +} + +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) { +        case NULLPROC: +                (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; + +        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; + +        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) { +        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; + +        case MOUNT3_UMNT: +                GF_FREE (result); +                break; +        } +        return; +} + +void * +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"); +        return NULL; +} diff --git a/xlators/nfs/server/src/nfs-mem-types.h b/xlators/nfs/server/src/nfs-mem-types.h index 1a3b25281ba..d9edc95b90c 100644 --- a/xlators/nfs/server/src/nfs-mem-types.h +++ b/xlators/nfs/server/src/nfs-mem-types.h @@ -37,15 +37,19 @@ enum gf_nfs_mem_types_ {          gf_nfs_mt_entry3,          gf_nfs_mt_entryp3,          gf_nfs_mt_nfs3_fd_entry, +        gf_nfs_mt_nfs3_fh,          gf_nfs_mt_nfs_initer_list,          gf_nfs_mt_xlator_t,          gf_nfs_mt_list_head,          gf_nfs_mt_mnt3_resolve,          gf_nfs_mt_mnt3_export, +        gf_nfs_mt_int, +        gf_nfs_mt_mountres3, +        gf_nfs_mt_mountstat3,          gf_nfs_mt_inode_q, -	gf_nfs_mt_nlm4_state, -	gf_nfs_mt_nlm4_cm, -	gf_nfs_mt_nlm4_fde, +        gf_nfs_mt_nlm4_state, +        gf_nfs_mt_nlm4_cm, +        gf_nfs_mt_nlm4_fde,          gf_nfs_mt_nlm4_nlmclnt,          gf_nfs_mt_nlm4_share,          gf_nfs_mt_end diff --git a/xlators/nfs/server/src/nfs.c b/xlators/nfs/server/src/nfs.c index a48e114999a..6e9a274d980 100644 --- a/xlators/nfs/server/src/nfs.c +++ b/xlators/nfs/server/src/nfs.c @@ -651,6 +651,25 @@ nfs_init_state (xlator_t *this)                  }          } +        nfs->mount_udp = 0; +        if (dict_get(this->options, "nfs.mount-udp")) { +                ret = dict_get_str (this->options, "nfs.mount-udp", &optstr); +                if (ret == -1) { +                        gf_log (GF_NFS, GF_LOG_ERROR, "Failed to parse dict"); +                        goto free_foppool; +                } + +                ret = gf_string2boolean (optstr, &boolt); +                if (ret < 0) { +                        gf_log (GF_NFS, GF_LOG_ERROR, "Failed to parse bool " +                                "string"); +                        goto free_foppool; +                } + +                if (boolt == _gf_true) +                        nfs->mount_udp = 1; +        } +          /* support both options rpc-auth.ports.insecure and           * rpc-auth-allow-insecure for backward compatibility           */ @@ -1187,6 +1206,13 @@ struct volume_options options[] = {                           " Set it to 'on' to re-enable it. Default value: 'on'"          }, +        { .key = {"nfs.mount-udp"}, +          .type = GF_OPTION_TYPE_BOOL, +          .description = "set the option to 'on' to enable mountd on UDP. " +                         "Needed by Solaris NFS clients if NLM support is" +                         "needed" +        }, +          { .key  = {NULL} },  }; diff --git a/xlators/nfs/server/src/nfs.h b/xlators/nfs/server/src/nfs.h index 0c9721244c6..4c6d039f8d2 100644 --- a/xlators/nfs/server/src/nfs.h +++ b/xlators/nfs/server/src/nfs.h @@ -86,6 +86,7 @@ struct nfs_state {          unsigned int            override_portnum;          int                     allow_insecure;          int                     enable_nlm; +        int                     mount_udp;          struct rpc_clnt         *rpc_clnt;  }; diff --git a/xlators/nfs/server/src/nfs3-fh.c b/xlators/nfs/server/src/nfs3-fh.c index 9aea881379e..f41c3f2f1e8 100644 --- a/xlators/nfs/server/src/nfs3-fh.c +++ b/xlators/nfs/server/src/nfs3-fh.c @@ -229,6 +229,18 @@ done:          return 0;  } +int +nfs3_build_fh (inode_t *inode, uuid_t exportid, struct nfs3_fh *newfh) +{ +        if (!newfh || !inode) +                return -1; + +        newfh->ident[0] = GF_NFSFH_IDENT0; +        newfh->ident[1] = GF_NFSFH_IDENT1; +        uuid_copy (newfh->gfid, inode->gfid); +        uuid_copy (newfh->exportid, exportid); +        return 0; +}  int  nfs3_fh_build_child_fh (struct nfs3_fh *parent, struct iatt *newstat, diff --git a/xlators/nfs/server/src/nfs3-fh.h b/xlators/nfs/server/src/nfs3-fh.h index e7c0625ee16..3be043ed3c9 100644 --- a/xlators/nfs/server/src/nfs3-fh.h +++ b/xlators/nfs/server/src/nfs3-fh.h @@ -115,4 +115,8 @@ nfs3_fh_build_parent_fh (struct nfs3_fh *child, struct iatt *newstat,  extern struct nfs3_fh  nfs3_fh_build_uuid_root_fh (uuid_t volumeid); + +extern int +nfs3_build_fh (inode_t *inode, uuid_t exportid, struct nfs3_fh *newfh); +  #endif  | 
