"Fossies" - the Fresh Open Source Software Archive

Member "glusterfs-8.2/xlators/nfs/server/src/mount3udp_svc.c" (16 Sep 2020, 6976 Bytes) of package /linux/misc/glusterfs-8.2.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "mount3udp_svc.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2   Copyright (c) 2012 Gluster, Inc. <http://www.gluster.com>
    3   This file is part of GlusterFS.
    4 
    5   This file is licensed to you under your choice of the GNU Lesser
    6   General Public License, version 3 or any later version (LGPLv3 or
    7   later), or the GNU General Public License, version 2 (GPLv2), in all
    8   cases as published by the Free Software Foundation.
    9 */
   10 
   11 #include "xdr-nfs3.h"
   12 #include <glusterfs/logging.h>
   13 #include <glusterfs/mem-pool.h>
   14 #include "nfs-mem-types.h"
   15 #include "nfs-messages.h"
   16 #include "mount3.h"
   17 #include <stdio.h>
   18 #include <stdlib.h>
   19 #include <rpc/pmap_clnt.h>
   20 #include <string.h>
   21 #include <memory.h>
   22 #include <sys/socket.h>
   23 #include <netinet/in.h>
   24 
   25 extern struct nfs3_fh *
   26 nfs3_rootfh(struct svc_req *req, xlator_t *nfsx, char *dp, char *expname);
   27 
   28 extern mountres3
   29 mnt3svc_set_mountres3(mountstat3 stat, struct nfs3_fh *fh, int *authflavor,
   30                       u_int aflen);
   31 extern int
   32 mount3udp_add_mountlist(xlator_t *nfsx, char *host, char *expname);
   33 
   34 extern int
   35 mount3udp_delete_mountlist(xlator_t *nfsx, char *host, char *expname);
   36 
   37 extern mountstat3
   38 mnt3svc_errno_to_mnterr(int32_t errnum);
   39 
   40 /* only this thread will use this, no locking needed */
   41 char mnthost[INET_ADDRSTRLEN + 1];
   42 
   43 #define MNT3UDP_AUTH_LEN 1 /* Only AUTH_UNIX for now */
   44 
   45 mountres3 *
   46 mountudpproc3_mnt_3_svc(dirpath **dpp, struct svc_req *req)
   47 {
   48     struct mountres3 *res = NULL;
   49     int *autharr = NULL;
   50     struct nfs3_fh *fh = NULL;
   51     char *mpath = NULL;
   52     xlator_t *nfsx = THIS;
   53     char expname[PATH_MAX] = {
   54         0,
   55     };
   56     mountstat3 stat = MNT3ERR_SERVERFAULT;
   57 
   58     errno = 0; /* RESET errno */
   59 
   60     mpath = (char *)*dpp;
   61     while (*mpath == '/')
   62         mpath++;
   63 
   64     res = GF_CALLOC(1, sizeof(*res), gf_nfs_mt_mountres3);
   65     if (res == NULL) {
   66         gf_msg(GF_MNT, GF_LOG_ERROR, ENOMEM, NFS_MSG_NO_MEMORY,
   67                "Unable to allocate memory");
   68         goto err;
   69     }
   70     autharr = GF_CALLOC(MNT3UDP_AUTH_LEN, sizeof(int), gf_nfs_mt_int);
   71     if (autharr == NULL) {
   72         gf_msg(GF_MNT, GF_LOG_ERROR, ENOMEM, NFS_MSG_NO_MEMORY,
   73                "Unable to allocate memory");
   74         goto err;
   75     }
   76 
   77     autharr[0] = AUTH_UNIX;
   78 
   79     fh = nfs3_rootfh(req, nfsx, mpath, (char *)expname);
   80 
   81     /* FAILURE: No FH */
   82     if (fh == NULL) {
   83         gf_msg(GF_MNT, GF_LOG_ERROR, errno, NFS_MSG_GET_FH_FAIL,
   84                "Unable to get fh for %s", mpath);
   85         if (errno)
   86             stat = mnt3svc_errno_to_mnterr(errno);
   87         *res = mnt3svc_set_mountres3(stat, NULL /* fh */, autharr,
   88                                      MNT3UDP_AUTH_LEN);
   89         return res;
   90     }
   91 
   92     /* SUCCESS */
   93     stat = MNT3_OK;
   94     *res = mnt3svc_set_mountres3(stat, fh, autharr, MNT3UDP_AUTH_LEN);
   95     (void)mount3udp_add_mountlist(nfsx, mnthost, (char *)expname);
   96     return res;
   97 
   98 err:
   99     GF_FREE(fh);
  100     GF_FREE(res);
  101     GF_FREE(autharr);
  102     return NULL;
  103 }
  104 
  105 mountstat3 *
  106 mountudpproc3_umnt_3_svc(dirpath **dp, struct svc_req *req)
  107 {
  108     mountstat3 *stat = NULL;
  109     char *mpath = (char *)*dp;
  110     xlator_t *nfsx = THIS;
  111 
  112     stat = GF_MALLOC(sizeof(mountstat3), gf_nfs_mt_mountstat3);
  113     if (stat == NULL) {
  114         gf_msg(GF_MNT, GF_LOG_ERROR, ENOMEM, NFS_MSG_NO_MEMORY,
  115                "Unable to allocate memory");
  116         return NULL;
  117     }
  118     *stat = MNT3_OK;
  119     (void)mount3udp_delete_mountlist(nfsx, mnthost, mpath);
  120     return stat;
  121 }
  122 
  123 static void
  124 mountudp_program_3(struct svc_req *rqstp, register SVCXPRT *transp)
  125 {
  126     union {
  127         dirpath mountudpproc3_mnt_3_arg;
  128     } argument;
  129     char *result = NULL;
  130     xdrproc_t _xdr_argument = NULL, _xdr_result = NULL;
  131     char *(*local)(char *, struct svc_req *) = NULL;
  132     mountres3 *res = NULL;
  133     struct sockaddr_in *sin = NULL;
  134 
  135 #if !defined(_TIRPC_SVC_H)
  136     sin = svc_getcaller(transp);
  137 #else
  138     sin = (struct sockaddr_in *)svc_getcaller(transp);
  139     /* TIRPC's svc_getcaller() returns a pointer to a sockaddr_in6, even
  140      * though it might actually be an IPv4 address. It ought return a
  141      * struct sockaddr and make the caller upcast it to the proper
  142      * address family. Sigh.
  143      */
  144 #endif
  145     /* And let's make sure that it's actually an IPv4 address. */
  146     GF_ASSERT(sin->sin_family == AF_INET);
  147 
  148     inet_ntop(AF_INET, &sin->sin_addr, mnthost, INET_ADDRSTRLEN + 1);
  149 
  150     switch (rqstp->rq_proc) {
  151         case NULLPROC:
  152             (void)svc_sendreply(transp, (xdrproc_t)xdr_void, (char *)NULL);
  153             return;
  154 
  155         case MOUNT3_MNT:
  156             _xdr_argument = (xdrproc_t)xdr_dirpath;
  157             _xdr_result = (xdrproc_t)xdr_mountres3;
  158             local = (char *(*)(char *,
  159                                struct svc_req *))mountudpproc3_mnt_3_svc;
  160             break;
  161 
  162         case MOUNT3_UMNT:
  163             _xdr_argument = (xdrproc_t)xdr_dirpath;
  164             _xdr_result = (xdrproc_t)xdr_mountstat3;
  165             local = (char *(*)(char *,
  166                                struct svc_req *))mountudpproc3_umnt_3_svc;
  167             break;
  168 
  169         default:
  170             svcerr_noproc(transp);
  171             return;
  172     }
  173     memset((char *)&argument, 0, sizeof(argument));
  174     if (!svc_getargs(transp, (xdrproc_t)_xdr_argument, (caddr_t)&argument)) {
  175         svcerr_decode(transp);
  176         return;
  177     }
  178     result = (*local)((char *)&argument, rqstp);
  179     if (result == NULL) {
  180         gf_msg_debug(GF_MNT, 0, "PROC returned error");
  181         svcerr_systemerr(transp);
  182     }
  183     if (result != NULL &&
  184         !svc_sendreply(transp, (xdrproc_t)_xdr_result, result)) {
  185         gf_msg(GF_MNT, GF_LOG_ERROR, 0, NFS_MSG_SVC_ERROR,
  186                "svc_sendreply returned error");
  187         svcerr_systemerr(transp);
  188     }
  189     if (!svc_freeargs(transp, (xdrproc_t)_xdr_argument, (caddr_t)&argument)) {
  190         gf_msg(GF_MNT, GF_LOG_ERROR, 0, NFS_MSG_ARG_FREE_FAIL,
  191                "Unable to free arguments");
  192     }
  193     if (result == NULL)
  194         return;
  195     /* free the result */
  196     switch (rqstp->rq_proc) {
  197         case MOUNT3_MNT:
  198             res = (mountres3 *)result;
  199             GF_FREE(res->mountres3_u.mountinfo.fhandle.fhandle3_val);
  200             GF_FREE(res->mountres3_u.mountinfo.auth_flavors.auth_flavors_val);
  201             GF_FREE(res);
  202             break;
  203 
  204         case MOUNT3_UMNT:
  205             GF_FREE(result);
  206             break;
  207     }
  208     return;
  209 }
  210 
  211 void *
  212 mount3udp_thread(void *argv)
  213 {
  214     xlator_t *nfsx = argv;
  215     register SVCXPRT *transp = NULL;
  216 
  217     GF_ASSERT(nfsx);
  218 
  219     glusterfs_this_set(nfsx);
  220 
  221     transp = svcudp_create(RPC_ANYSOCK);
  222     if (transp == NULL) {
  223         gf_msg(GF_MNT, GF_LOG_ERROR, 0, NFS_MSG_SVC_ERROR,
  224                "svcudp_create error");
  225         return NULL;
  226     }
  227     if (!svc_register(transp, MOUNT_PROGRAM, MOUNT_V3, mountudp_program_3,
  228                       IPPROTO_UDP)) {
  229         gf_msg(GF_MNT, GF_LOG_ERROR, 0, NFS_MSG_SVC_ERROR,
  230                "svc_register error");
  231         return NULL;
  232     }
  233 
  234     svc_run();
  235     gf_msg(GF_MNT, GF_LOG_ERROR, 0, NFS_MSG_SVC_RUN_RETURNED,
  236            "svc_run returned");
  237     return NULL;
  238 }