This is a preparation patch

Signed-off-by: Liu Yuan <[email protected]>
---
 sheep/Makefile.am |   2 +-
 sheep/nfs/mount.c |  42 +++++++++++++++++++
 sheep/nfs/nfs.h   |  99 ++++++++++++++++++++++++++++++++++++++++++++
 sheep/nfs/nfsd.c  |  75 +++++++++++++++++++++++++++++----
 sheep/nfs/xdr.c   | 122 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 330 insertions(+), 10 deletions(-)
 create mode 100644 sheep/nfs/mount.c

diff --git a/sheep/Makefile.am b/sheep/Makefile.am
index b964f5f..82e3af9 100644
--- a/sheep/Makefile.am
+++ b/sheep/Makefile.am
@@ -35,7 +35,7 @@ sheep_SOURCES         += http/http.c http/kv.c http/s3.c 
http/swift.c \
 endif
 
 if BUILD_NFS
-sheep_SOURCES          += nfs/nfsd.c nfs/nfs.c nfs/xdr.c
+sheep_SOURCES          += nfs/nfsd.c nfs/nfs.c nfs/xdr.c nfs/mount.c
 endif
 
 if BUILD_COROSYNC
diff --git a/sheep/nfs/mount.c b/sheep/nfs/mount.c
new file mode 100644
index 0000000..8f454cf
--- /dev/null
+++ b/sheep/nfs/mount.c
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2014 Taobao Inc.
+ *
+ * Liu Yuan <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <nfs://www.gnu.org/licenses/>.
+ */
+
+#include "sheep_priv.h"
+#include "nfs.h"
+
+void *mount3_null(struct svc_req *req, struct nfs_arg *arg)
+{
+       return NULL;
+}
+
+void *mount3_mnt(struct svc_req *req, struct nfs_arg *arg)
+{
+       return NULL;
+}
+
+void *mount3_dump(struct svc_req *req, struct nfs_arg *arg)
+{
+       return NULL;
+}
+void *mount3_umnt(struct svc_req *req, struct nfs_arg *arg)
+{
+       return NULL;
+}
+void *mount3_umntall(struct svc_req *req, struct nfs_arg *arg)
+{
+       return NULL;
+}
+void *mount3_export(struct svc_req *req, struct nfs_arg *arg)
+{
+       return NULL;
+}
diff --git a/sheep/nfs/nfs.h b/sheep/nfs/nfs.h
index c4bc703..1a0e501 100644
--- a/sheep/nfs/nfs.h
+++ b/sheep/nfs/nfs.h
@@ -946,6 +946,8 @@ typedef struct COMMIT3res COMMIT3res;
 #define NFSPROC3_PATHCONF 20
 #define NFSPROC3_COMMIT 21
 
+typedef char *dirpath;
+
 struct nfs_arg {
        union {
                GETATTR3args getattr;
@@ -969,6 +971,9 @@ struct nfs_arg {
                FSINFO3args fsinfo;
                PATHCONF3args pathconf;
                COMMIT3args commit;
+               /* mount */
+               dirpath mnt;
+               dirpath umnt;
        };
 };
 
@@ -1131,4 +1136,98 @@ extern bool_t xdr_commit_res(XDR *, COMMIT3res*);
 extern bool_t xdr_null_args(XDR *xdrs, void *);
 extern bool_t xdr_null_res(XDR *xdrs, void *);
 
+/* Mount Protocol */
+
+#define MNTPATHLEN 1024
+#define MNTNAMLEN 255
+#define FHSIZE 32
+#define FHSIZE3 64
+
+typedef struct {
+       u_int fhandle3_len;
+       char *fhandle3_val;
+} fhandle3;
+
+enum mountstat3 {
+       MNT3_OK = 0,
+       MNT3ERR_PERM = 1,
+       MNT3ERR_NOENT = 2,
+       MNT3ERR_IO = 5,
+       MNT3ERR_ACCES = 13,
+       MNT3ERR_NOTDIR = 20,
+       MNT3ERR_INVAL = 22,
+       MNT3ERR_NAMETOOLONG = 63,
+       MNT3ERR_NOTSUPP = 10004,
+       MNT3ERR_SERVERFAULT = 10006,
+};
+typedef enum mountstat3 mountstat3;
+
+struct mountres3_ok {
+       fhandle3 fhandle;
+       struct {
+               u_int auth_flavors_len;
+               int *auth_flavors_val;
+       } auth_flavors;
+};
+typedef struct mountres3_ok mountres3_ok;
+
+struct mountres3 {
+       mountstat3 fhs_status;
+       union {
+               mountres3_ok mountinfo;
+       } mountres3_u;
+};
+typedef struct mountres3 mountres3;
+
+typedef struct mountbody *mountlist;
+
+struct mountbody {
+       char *ml_hostname;
+       dirpath ml_directory;
+       mountlist ml_next;
+};
+typedef struct mountbody mountbody;
+
+typedef struct groupnode *groups;
+
+struct groupnode {
+       char *gr_name;
+       groups gr_next;
+};
+typedef struct groupnode groupnode;
+
+typedef struct exportnode *exports;
+
+struct exportnode {
+       dirpath ex_dir;
+       groups ex_groups;
+       exports ex_next;
+};
+typedef struct exportnode exportnode;
+
+#define MOUNT_PROGRAM 100005
+#define MOUNT_V3 3
+
+extern void *mount3_null(struct svc_req *, struct nfs_arg *);
+extern void *mount3_mnt(struct svc_req *, struct nfs_arg *);
+extern void *mount3_dump(struct svc_req *, struct nfs_arg *);
+extern void *mount3_umnt(struct svc_req *, struct nfs_arg *);
+extern void *mount3_umntall(struct svc_req *, struct nfs_arg *);
+extern void *mount3_export(struct svc_req *, struct nfs_arg *);
+
+/* the xdr functions */
+
+extern bool_t xdr_fhandle3(XDR *, fhandle3*);
+extern bool_t xdr_mountstat3(XDR *, mountstat3*);
+extern bool_t xdr_mountres3_ok(XDR *, mountres3_ok*);
+extern bool_t xdr_mountres3(XDR *, mountres3*);
+extern bool_t xdr_dirpath(XDR *, dirpath*);
+extern bool_t xdr_name(XDR *, char **);
+extern bool_t xdr_mountlist(XDR *, mountlist*);
+extern bool_t xdr_mountbody(XDR *, mountbody*);
+extern bool_t xdr_groups(XDR *, groups*);
+extern bool_t xdr_groupnode(XDR *, groupnode*);
+extern bool_t xdr_exports(XDR *, exports*);
+extern bool_t xdr_exportnode(XDR *, exportnode*);
+
 #endif /* !_NFS_H */
diff --git a/sheep/nfs/nfsd.c b/sheep/nfs/nfsd.c
index 11af50a..a1394c5 100644
--- a/sheep/nfs/nfsd.c
+++ b/sheep/nfs/nfsd.c
@@ -22,6 +22,7 @@ struct svc_handler {
        xdrproc_t    decoder; /* XDR decode args */
        xdrproc_t    encoder; /* XDR encode result */
        unsigned int count;      /* call count */
+       const char *name;       /* handler name */
 };
 
 #define NFS_HANDLER(name)                      \
@@ -30,6 +31,7 @@ struct svc_handler {
        (xdrproc_t) xdr_##name##_args,          \
        (xdrproc_t) xdr_##name##_res,           \
        0,                                      \
+       "nfs3."#name,                           \
 }
 
 static struct svc_handler nfs3_handlers[] = {
@@ -57,28 +59,57 @@ static struct svc_handler nfs3_handlers[] = {
        NFS_HANDLER(commit),
 };
 
-static void nfs3_dispatcher(struct svc_req *reg, SVCXPRT *transp)
+#define MOUNT_HANDLER(name, arg, res)          \
+{                                              \
+       (svc_func)  mount3_##name,              \
+       (xdrproc_t) xdr_##arg,                  \
+       (xdrproc_t) xdr_##res,                  \
+       0,                                      \
+       "mount3."#name,                         \
+}
+
+static struct svc_handler mount3_handlers[] = {
+       MOUNT_HANDLER(null, null_args, null_res),
+       MOUNT_HANDLER(mnt, dirpath, mountres3),
+       MOUNT_HANDLER(dump, null_args, mountlist),
+       MOUNT_HANDLER(umnt, dirpath, null_res),
+       MOUNT_HANDLER(umntall, null_args, null_res),
+       MOUNT_HANDLER(export, null_args, exports),
+};
+
+static void svc_dispatcher(struct svc_req *reg, SVCXPRT *transp)
 {
        struct nfs_arg arg = {};
-       int proc = reg->rq_proc;
+       int prog = reg->rq_prog, vers = reg->rq_vers, proc = reg->rq_proc;
+       struct svc_handler *handlers;
        void *result;
 
-       sd_debug("%d", proc);
+       if (prog == NFS_PROGRAM && vers == NFS_V3)
+               handlers = nfs3_handlers;
+       else if (prog == MOUNT_PROGRAM && vers == MOUNT_V3)
+               handlers = mount3_handlers;
+       else {
+               sd_err("invalid protocol %d, version %d", prog, vers);
+               return;
+       }
+
+       sd_debug("%s", handlers[proc].name);
 
-       if (!svc_getargs(transp, nfs3_handlers[proc].decoder, (caddr_t)&arg)) {
+       if (!svc_getargs(transp, handlers[proc].decoder, (caddr_t)&arg)) {
                sd_err("svc_getargs failed");
                svcerr_decode(transp);
                return;
        }
 
-       result = nfs3_handlers[proc].func(reg, &arg);
-       if (result && !svc_sendreply(transp, nfs3_handlers[proc].encoder,
+       handlers[proc].count++;
+       result = handlers[proc].func(reg, &arg);
+       if (result && !svc_sendreply(transp, handlers[proc].encoder,
                                     result)) {
                sd_err("svc_sendreply failed");
                svcerr_systemerr(transp);
        }
 
-       if (!svc_freeargs(transp, nfs3_handlers[proc].decoder, (caddr_t)&arg))
+       if (!svc_freeargs(transp, handlers[proc].decoder, (caddr_t)&arg))
                panic("unable to free arguments");
 
        return;
@@ -89,6 +120,7 @@ static int nfs_init_transport(void)
        SVCXPRT *nfs_trans = NULL;
 
        pmap_unset(NFS_PROGRAM, NFS_V3);
+       pmap_unset(MOUNT_PROGRAM, MOUNT_V3);
 
        nfs_trans = svcudp_create(RPC_ANYSOCK);
        if (!nfs_trans) {
@@ -96,7 +128,7 @@ static int nfs_init_transport(void)
                return -1;
        }
 
-       if (!svc_register(nfs_trans, NFS_PROGRAM, NFS_V3, nfs3_dispatcher,
+       if (!svc_register(nfs_trans, NFS_PROGRAM, NFS_V3, svc_dispatcher,
                          IPPROTO_UDP)) {
                sd_err("svc_register udp, failed");
                return -1;
@@ -109,13 +141,38 @@ static int nfs_init_transport(void)
                return -1;
        }
 
-       if (!svc_register(nfs_trans, NFS_PROGRAM, NFS_V3, nfs3_dispatcher,
+       if (!svc_register(nfs_trans, NFS_PROGRAM, NFS_V3, svc_dispatcher,
                          IPPROTO_TCP)) {
                sd_err("svc_register tcp, failed");
                return -1;
        }
        sd_info("nfs service listen at %d, proto tcp", nfs_trans->xp_port);
 
+       nfs_trans = svcudp_create(RPC_ANYSOCK);
+       if (!nfs_trans) {
+               sd_err("svcudp_create for mount failed");
+               return -1;
+       }
+
+       if (!svc_register(nfs_trans, MOUNT_PROGRAM, MOUNT_V3, svc_dispatcher,
+                         IPPROTO_UDP)) {
+               sd_err("svc_register udp for mount failed");
+               return -1;
+       }
+       sd_info("mount service listen at %d, proto udp", nfs_trans->xp_port);
+
+       nfs_trans = svctcp_create(RPC_ANYSOCK, 0, 0);
+       if (!nfs_trans) {
+               sd_err("svctcp_create for mount failed");
+               return -1;
+       }
+
+       if (!svc_register(nfs_trans, MOUNT_PROGRAM, MOUNT_V3, svc_dispatcher,
+                         IPPROTO_TCP)) {
+               sd_err("svc_register tcp for mount failed");
+               return -1;
+       }
+       sd_info("mount service listen at %d, proto tcp", nfs_trans->xp_port);
        return 0;
 }
 
diff --git a/sheep/nfs/xdr.c b/sheep/nfs/xdr.c
index 15f9902..7f9b0f4 100644
--- a/sheep/nfs/xdr.c
+++ b/sheep/nfs/xdr.c
@@ -1659,3 +1659,125 @@ bool_t xdr_null_res(XDR *xdrs, void *ignore)
 {
        return xdr_void();
 }
+
+bool_t
+xdr_fhandle3(XDR *xdrs, fhandle3 *objp)
+{
+       if (!xdr_bytes(xdrs, (char **)&objp->fhandle3_val,
+                      (u_int *)&objp->fhandle3_len, FHSIZE3))
+               return FALSE;
+       return TRUE;
+}
+
+bool_t
+xdr_mountstat3(XDR *xdrs, mountstat3 *objp)
+{
+       if (!xdr_enum(xdrs, (enum_t *) objp))
+               return FALSE;
+       return TRUE;
+}
+
+bool_t
+xdr_mountres3_ok(XDR *xdrs, mountres3_ok *objp)
+{
+       if (!xdr_fhandle3(xdrs, &objp->fhandle))
+               return FALSE;
+       if (!xdr_array(xdrs, (char **)&objp->auth_flavors.auth_flavors_val,
+                      (u_int *)&objp->auth_flavors.auth_flavors_len, ~0,
+                      sizeof(int), (xdrproc_t) xdr_int))
+               return FALSE;
+       return TRUE;
+}
+
+bool_t
+xdr_mountres3(XDR *xdrs, mountres3 *objp)
+{
+       if (!xdr_mountstat3(xdrs, &objp->fhs_status))
+               return FALSE;
+       switch (objp->fhs_status) {
+       case 0:
+               if (!xdr_mountres3_ok(xdrs, &objp->mountres3_u.mountinfo))
+                       return FALSE;
+               break;
+       default:
+               break;
+       }
+       return TRUE;
+}
+
+bool_t
+xdr_dirpath(XDR *xdrs, dirpath *objp)
+{
+       if (!xdr_string(xdrs, objp, MNTPATHLEN))
+               return FALSE;
+       return TRUE;
+}
+
+bool_t
+xdr_name(XDR *xdrs, char **objp)
+{
+       if (!xdr_string(xdrs, objp, MNTNAMLEN))
+               return FALSE;
+       return TRUE;
+}
+
+bool_t
+xdr_mountlist(XDR *xdrs, mountlist *objp)
+{
+       if (!xdr_pointer(xdrs, (char **)objp, sizeof(struct mountbody),
+                        (xdrproc_t) xdr_mountbody))
+               return FALSE;
+       return TRUE;
+}
+
+bool_t
+xdr_mountbody(XDR *xdrs, mountbody *objp)
+{
+       if (!xdr_name(xdrs, &objp->ml_hostname))
+               return FALSE;
+       if (!xdr_dirpath(xdrs, &objp->ml_directory))
+               return FALSE;
+       if (!xdr_mountlist(xdrs, &objp->ml_next))
+               return FALSE;
+       return TRUE;
+}
+
+bool_t
+xdr_groups(XDR *xdrs, groups *objp)
+{
+       if (!xdr_pointer(xdrs, (char **)objp, sizeof(struct groupnode),
+                        (xdrproc_t) xdr_groupnode))
+               return FALSE;
+       return TRUE;
+}
+
+bool_t
+xdr_groupnode(XDR *xdrs, groupnode *objp)
+{
+       if (!xdr_name(xdrs, &objp->gr_name))
+               return FALSE;
+       if (!xdr_groups(xdrs, &objp->gr_next))
+               return FALSE;
+       return TRUE;
+}
+
+bool_t
+xdr_exports(XDR *xdrs, exports *objp)
+{
+       if (!xdr_pointer(xdrs, (char **)objp, sizeof(struct exportnode),
+                        (xdrproc_t) xdr_exportnode))
+               return FALSE;
+       return TRUE;
+}
+
+bool_t
+xdr_exportnode(XDR *xdrs, exportnode *objp)
+{
+       if (!xdr_dirpath(xdrs, &objp->ex_dir))
+               return FALSE;
+       if (!xdr_groups(xdrs, &objp->ex_groups))
+               return FALSE;
+       if (!xdr_exports(xdrs, &objp->ex_next))
+               return FALSE;
+       return TRUE;
+}
-- 
1.8.1.2

-- 
sheepdog mailing list
[email protected]
http://lists.wpkg.org/mailman/listinfo/sheepdog

Reply via email to