From c85998fec484a0060c2a7cbcbf7ed42a109c6478 Mon Sep 17 00:00:00 2001 From: Amar Tumballi Date: Wed, 7 Jul 2010 08:05:58 +0000 Subject: make DUMP as another program * on server side, make it a rpc program. * on client its another program at protocol Signed-off-by: Amar Tumballi Signed-off-by: Anand V. Avati BUG: 875 (Implement a new protocol to provide proper backward/forward compatibility) URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=875 --- rpc/rpc-lib/src/Makefile.am | 3 +- rpc/rpc-lib/src/rpc-clnt.c | 6 +-- rpc/rpc-lib/src/rpc-common.c | 115 +++++++++++++++++++++++++++++++++++++++++++ rpc/rpc-lib/src/rpcsvc.c | 108 ++++++++++++++++++++++++++++++++++++++++ rpc/rpc-lib/src/xdr-common.h | 45 ++++++++++++++++- 5 files changed, 272 insertions(+), 5 deletions(-) create mode 100644 rpc/rpc-lib/src/rpc-common.c (limited to 'rpc') diff --git a/rpc/rpc-lib/src/Makefile.am b/rpc/rpc-lib/src/Makefile.am index 4df8888a08d..986eb95cebc 100644 --- a/rpc/rpc-lib/src/Makefile.am +++ b/rpc/rpc-lib/src/Makefile.am @@ -2,7 +2,8 @@ lib_LTLIBRARIES = libgfrpc.la libgfrpc_la_LDFLAGS = -module -avoidversion libgfrpc_la_SOURCES = auth-unix.c rpcsvc-auth.c rpcsvc.c auth-null.c \ - rpc-transport.c xdr-rpc.c xdr-rpcclnt.c rpc-clnt.c auth-glusterfs.c + rpc-transport.c xdr-rpc.c xdr-rpcclnt.c rpc-clnt.c auth-glusterfs.c \ + rpc-common.c libgfrpc_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la noinst_HEADERS = rpcsvc.h rpc-transport.h xdr-common.h xdr-rpc.h xdr-rpcclnt.h \ diff --git a/rpc/rpc-lib/src/rpc-clnt.c b/rpc/rpc-lib/src/rpc-clnt.c index 84fdb9bb55f..b41275c2c8a 100644 --- a/rpc/rpc-lib/src/rpc-clnt.c +++ b/rpc/rpc-lib/src/rpc-clnt.c @@ -1202,9 +1202,9 @@ rpc_clnt_submit (struct rpc_clnt *rpc, rpc_clnt_prog_t *prog, if (conn->connected || /* FIXME: hack!! hack!! find a neater way to do this */ - ((prog->prognum == GLUSTER_HNDSK_PROGRAM) && - ((procnum == GF_HNDSK_SETVOLUME) || - (procnum == GF_HNDSK_DUMP_VERSION)))) { + (((prog->prognum == GLUSTER_HNDSK_PROGRAM) && + (procnum == GF_HNDSK_SETVOLUME)) || + (prog->prognum == GLUSTER_DUMP_PROGRAM))) { if (proghdr) { proglen += iov_length (proghdr, proghdrcount); } diff --git a/rpc/rpc-lib/src/rpc-common.c b/rpc/rpc-lib/src/rpc-common.c new file mode 100644 index 00000000000..ffd0c8d2837 --- /dev/null +++ b/rpc/rpc-lib/src/rpc-common.c @@ -0,0 +1,115 @@ + +#include "xdr-common.h" + +ssize_t +xdr_serialize_generic (struct iovec outmsg, void *res, xdrproc_t proc) +{ + ssize_t ret = -1; + XDR xdr; + + if ((!outmsg.iov_base) || (!res) || (!proc)) + return -1; + + xdrmem_create (&xdr, outmsg.iov_base, (unsigned int)outmsg.iov_len, + XDR_ENCODE); + + if (!proc (&xdr, res)) { + ret = -1; + goto ret; + } + + ret = xdr_encoded_length (xdr); + +ret: + return ret; +} + + +ssize_t +xdr_to_generic (struct iovec inmsg, void *args, xdrproc_t proc) +{ + XDR xdr; + ssize_t ret = -1; + + if ((!inmsg.iov_base) || (!args) || (!proc)) + return -1; + + xdrmem_create (&xdr, inmsg.iov_base, (unsigned int)inmsg.iov_len, + XDR_DECODE); + + if (!proc (&xdr, args)) { + ret = -1; + goto ret; + } + + ret = xdr_decoded_length (xdr); +ret: + return ret; +} + + +bool_t +xdr_gf_dump_req (XDR *xdrs, gf_dump_req *objp) +{ + if (!xdr_u_quad_t (xdrs, &objp->gfs_id)) + return FALSE; + return TRUE; +} + +bool_t +xdr_gf_prog_detail (XDR *xdrs, gf_prog_detail *objp) +{ + if (!xdr_string (xdrs, &objp->progname, ~0)) + return FALSE; + if (!xdr_u_quad_t (xdrs, &objp->prognum)) + return FALSE; + if (!xdr_u_quad_t (xdrs, &objp->progver)) + return FALSE; + if (!xdr_pointer (xdrs, (char **)&objp->next, sizeof (gf_prog_detail), (xdrproc_t) xdr_gf_prog_detail)) + return FALSE; + return TRUE; +} + +bool_t +xdr_gf_dump_rsp (XDR *xdrs, gf_dump_rsp *objp) +{ + if (!xdr_u_quad_t (xdrs, &objp->gfs_id)) + return FALSE; + if (!xdr_int (xdrs, &objp->op_ret)) + return FALSE; + if (!xdr_int (xdrs, &objp->op_errno)) + return FALSE; + if (!xdr_pointer (xdrs, (char **)&objp->prog, sizeof (gf_prog_detail), (xdrproc_t) xdr_gf_prog_detail)) + return FALSE; + return TRUE; +} + + +ssize_t +xdr_serialize_dump_rsp (struct iovec outmsg, void *rsp) +{ + return xdr_serialize_generic (outmsg, (void *)rsp, + (xdrproc_t)xdr_gf_dump_rsp); +} + +ssize_t +xdr_to_dump_req (struct iovec inmsg, void *args) +{ + return xdr_to_generic (inmsg, (void *)args, + (xdrproc_t)xdr_gf_dump_req); +} + + +ssize_t +xdr_from_dump_req (struct iovec outmsg, void *rsp) +{ + return xdr_serialize_generic (outmsg, (void *)rsp, + (xdrproc_t)xdr_gf_dump_req); +} + +ssize_t +xdr_to_dump_rsp (struct iovec inmsg, void *args) +{ + return xdr_to_generic (inmsg, (void *)args, + (xdrproc_t)xdr_gf_dump_rsp); +} diff --git a/rpc/rpc-lib/src/rpcsvc.c b/rpc/rpc-lib/src/rpcsvc.c index c39a880886d..bb4e37ef8b0 100644 --- a/rpc/rpc-lib/src/rpcsvc.c +++ b/rpc/rpc-lib/src/rpcsvc.c @@ -33,6 +33,7 @@ #include "xdr-rpc.h" #include "iobuf.h" #include "globals.h" +#include "xdr-common.h" #include #include @@ -45,6 +46,8 @@ #include #include +struct rpcsvc_program gluster_dump_prog; + #define rpcsvc_alloc_request(con, request) \ do { \ @@ -1931,6 +1934,89 @@ free_prog: return ret; } +static void +free_prog_details (gf_dump_rsp *rsp) +{ + gf_prog_detail *prev = NULL; + gf_prog_detail *trav = NULL; + + trav = rsp->prog; + while (trav) { + prev = trav; + trav = trav->next; + GF_FREE (prev); + } +} + +static int +build_prog_details (rpcsvc_request_t *req, gf_dump_rsp *rsp) +{ + int ret = -1; + rpcsvc_program_t *program = NULL; + gf_prog_detail *prog = NULL; + gf_prog_detail *prev = NULL; + + if (!req || !req->conn || !req->conn->svc) + goto out; + + list_for_each_entry (program, &req->conn->svc->programs, program) { + prog = GF_CALLOC (1, sizeof (*prog), 0); + if (!prog) + goto out; + prog->progname = program->progname; + prog->prognum = program->prognum; + prog->progver = program->progver; + if (!rsp->prog) + rsp->prog = prog; + if (prev) + prev->next = prog; + prev = prog; + } + if (prev) + ret = 0; +out: + return ret; +} + +static int +rpcsvc_dump (rpcsvc_request_t *req) +{ + char rsp_buf[8 * 1024] = {0,}; + gf_dump_rsp rsp = {0,}; + struct iovec iov = {0,}; + int op_errno = EINVAL; + int ret = -1; + + if (!req) + goto fail; + + ret = build_prog_details (req, &rsp); + if (ret < 0) { + op_errno = -ret; + goto fail; + } + +fail: + rsp.op_errno = gf_errno_to_error (op_errno); + rsp.op_ret = ret; + + iov.iov_base = rsp_buf; + iov.iov_len = (8 * 1024); + + ret = xdr_serialize_dump_rsp (iov, &rsp); + if (ret < 0) { + req->rpc_err = GARBAGE_ARGS; + op_errno = EINVAL; + goto fail; + } + + ret = rpcsvc_submit_generic (req, &iov, 1, NULL, 0, + NULL); + + free_prog_details (&rsp); + + return 0; +} int rpcsvc_init_options (rpcsvc_t *svc, dict_t *options) @@ -2004,6 +2090,12 @@ rpcsvc_init (glusterfs_ctx_t *ctx, dict_t *options) svc->listener = listener; + ret = rpcsvc_program_register (svc, gluster_dump_prog); + if (ret) { + gf_log (GF_RPCSVC, GF_LOG_ERROR, + "failed to register DUMP program"); + goto free_svc; + } ret = 0; free_svc: if (ret == -1) { @@ -2013,3 +2105,19 @@ free_svc: return svc; } + + +rpcsvc_actor_t gluster_dump_actors[] = { + [GF_DUMP_NULL] = {"NULL", GF_DUMP_NULL, NULL, NULL, NULL }, + [GF_DUMP_DUMP] = {"DUMP", GF_DUMP_DUMP, rpcsvc_dump, NULL, NULL }, + [GF_DUMP_MAXVALUE] = {"MAXVALUE", GF_DUMP_MAXVALUE, NULL, NULL, NULL }, +}; + + +struct rpcsvc_program gluster_dump_prog = { + .progname = "GF-DUMP", + .prognum = GLUSTER_DUMP_PROGRAM, + .progver = GLUSTER_DUMP_VERSION, + .actors = gluster_dump_actors, + .numactors = 2, +}; diff --git a/rpc/rpc-lib/src/xdr-common.h b/rpc/rpc-lib/src/xdr-common.h index 0c9ffb2f827..7ba1372529c 100644 --- a/rpc/rpc-lib/src/xdr-common.h +++ b/rpc/rpc-lib/src/xdr-common.h @@ -27,6 +27,16 @@ #include +enum { + GF_DUMP_NULL, + GF_DUMP_DUMP, + GF_DUMP_MAXVALUE, +} gf_dump_procnum_t; + +#define GLUSTER_DUMP_PROGRAM 123451501 /* Completely random */ +#define GLUSTER_DUMP_VERSION 1 + + #if GF_DARWIN_HOST_OS #define xdr_u_quad_t xdr_u_int64_t #define xdr_quad_t xdr_int64_t @@ -43,8 +53,41 @@ struct auth_glusterfs_parms { }; typedef struct auth_glusterfs_parms auth_glusterfs_parms; -bool_t +struct gf_dump_req { + u_quad_t gfs_id; +}; +typedef struct gf_dump_req gf_dump_req; + +struct gf_prog_detail { + char *progname; + u_quad_t prognum; + u_quad_t progver; + struct gf_prog_detail *next; +}; +typedef struct gf_prog_detail gf_prog_detail; + +struct gf_dump_rsp { + u_quad_t gfs_id; + int op_ret; + int op_errno; + struct gf_prog_detail *prog; +}; +typedef struct gf_dump_rsp gf_dump_rsp; + +extern bool_t xdr_auth_glusterfs_parms (XDR *xdrs, auth_glusterfs_parms *objp); +extern bool_t xdr_gf_dump_req (XDR *, gf_dump_req*); +extern bool_t xdr_gf_prog_detail (XDR *, gf_prog_detail*); +extern bool_t xdr_gf_dump_rsp (XDR *, gf_dump_rsp*); + +ssize_t +xdr_serialize_dump_rsp (struct iovec outmsg, void *rsp); +ssize_t +xdr_to_dump_req (struct iovec inmsg, void *args); +ssize_t +xdr_from_dump_req (struct iovec outmsg, void *rsp); +ssize_t +xdr_to_dump_rsp (struct iovec inmsg, void *args); #define XDR_BYTES_PER_UNIT 4 -- cgit