diff options
Diffstat (limited to 'xlators/mgmt/glusterd/src/glusterd-pmap.c')
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-pmap.c | 336 |
1 files changed, 336 insertions, 0 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-pmap.c b/xlators/mgmt/glusterd/src/glusterd-pmap.c new file mode 100644 index 000000000..76ad72987 --- /dev/null +++ b/xlators/mgmt/glusterd/src/glusterd-pmap.c @@ -0,0 +1,336 @@ +/* + Copyright (c) 2010 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/>. +*/ + + +#ifndef _CONFIG_H +#define _CONFIG_H +#include "config.h" +#endif + +#include "xlator.h" +#include "glusterfs.h" +#include "compat-errno.h" + +#include "glusterd.h" +#include "glusterd-utils.h" + +#include "portmap.h" +#include "protocol-common.h" +#include "rpcsvc.h" + +#include <sys/socket.h> +#include <sys/types.h> +#include <netinet/in.h> + + +int +pmap_port_isfree (int port) +{ + struct sockaddr_in sin; + int sock = -1; + int ret = 0; + + memset (&sin, 0, sizeof (sin)); + sin.sin_family = PF_INET; + sin.sin_port = hton16 (port); + + sock = socket (PF_INET, SOCK_STREAM, 0); + if (sock == -1) + return -1; + + ret = bind (sock, (struct sockaddr *)&sin, sizeof (sin)); + close (sock); + + return ret == 0 ? 1 : 0; +} + + +struct pmap_registry * +pmap_registry_new (void) +{ + struct pmap_registry *pmap = NULL; + int i = 0; + + pmap = CALLOC (sizeof (*pmap), 1); + if (!pmap) + return NULL; + + for (i = 0; i < 65536; i++) { + if (!pmap_port_isfree (i)) + pmap->ports[i].used = 1; + } + + pmap->base_port = 6969; + pmap->last_alloc = 6969; + + return pmap; +} + + +struct pmap_registry * +pmap_registry_get (xlator_t *this) +{ + glusterd_conf_t *priv = NULL; + struct pmap_registry *pmap = NULL; + + priv = this->private; + + pmap = priv->pmap; + if (!pmap) { + pmap = pmap_registry_new (); + if (!pmap) + return NULL; + priv->pmap = pmap; + } + + return pmap; +} + + +int +pmap_registry_search (xlator_t *this, const char *brickname) +{ + glusterd_conf_t *priv = NULL; + struct pmap_registry *pmap = NULL; + int p = 0; + int port = 0; + + priv = this->private; + + pmap = priv->pmap; + + for (p = pmap->base_port; p < 65535; p++) { + if (strcmp (pmap->ports[p].brickname, brickname) == 0) { + port = p; + break; + } + } + + return port; +} + + +int +pmap_registry_alloc (xlator_t *this) +{ + glusterd_conf_t *priv = NULL; + struct pmap_registry *pmap = NULL; + int p = 0; + int port = 0; + + priv = this->private; + + pmap = priv->pmap; + + for (p = pmap->base_port; p < 65535; p++) { + if (pmap->ports[p].used) + continue; + + if (pmap_port_isfree (p)) { + pmap->ports[p].used = 1; + port = p; + break; + } + } + + return port; +} + + + +int +pmap_registry_bind (xlator_t *this, int port, const char *brickname) +{ + glusterd_conf_t *priv = NULL; + struct pmap_registry *pmap = NULL; + int p = 0; + + + priv = this->private; + + pmap = priv->pmap; + + pmap->ports[p].used = 1; + if (pmap->ports[p].brickname) + free (pmap->ports[p].brickname); + pmap->ports[p].brickname = strdup (brickname); + + return 0; +} + + +typedef ssize_t (*gfs_serialize_t) (struct iovec outmsg, void *data); + + +static int +xdr_to_glusterfs_req (rpcsvc_request_t *req, void *arg, gfs_serialize_t sfunc) +{ + int ret = -1; + + if (!req) + return -1; + + ret = sfunc (req->msg[0], arg); + + if (ret > 0) + ret = 0; + + return ret; +} + + +int +gluster_pmap_portbybrick (rpcsvc_request_t *req) +{ + pmap_port_by_brick_req args = {0,}; + pmap_port_by_brick_rsp rsp = {0,}; + char *brick = NULL; + int port = 0; + + + if (xdr_to_glusterfs_req (req, &args, xdr_to_pmap_port_by_brick_req)) { + req->rpc_err = GARBAGE_ARGS; + goto fail; + } + + brick = args.brick; + + port = pmap_registry_search (THIS, brick); + + rsp.op_ret = 0; + rsp.port = port; + +fail: + glusterd_submit_reply (req, &rsp, NULL, 0, NULL, + (gd_serialize_t)xdr_from_pmap_port_by_brick_rsp); + + return 0; +} + + +int +gluster_pmap_brickbyport (rpcsvc_request_t *req) +{ + pmap_brick_by_port_req args = {0,}; + pmap_brick_by_port_rsp rsp = {0,}; + + + if (xdr_to_glusterfs_req (req, &args, xdr_to_pmap_brick_by_port_req)) { + req->rpc_err = GARBAGE_ARGS; + goto fail; + } + + +fail: + + glusterd_submit_reply (req, &rsp, NULL, 0, NULL, + (gd_serialize_t)xdr_from_pmap_brick_by_port_rsp); + + return 0; +} + + + +int +gluster_pmap_signup (rpcsvc_request_t *req) +{ + pmap_signup_req args = {0,}; + pmap_signup_rsp rsp = {0,}; + + + if (xdr_to_glusterfs_req (req, &args, xdr_to_pmap_signup_req)) { + req->rpc_err = GARBAGE_ARGS; + goto fail; + } + + +fail: + glusterd_submit_reply (req, &rsp, NULL, 0, NULL, + (gd_serialize_t)xdr_from_pmap_signup_rsp); + + return 0; +} + + +int +gluster_pmap_signin (rpcsvc_request_t *req) +{ + pmap_signin_req args = {0,}; + pmap_signin_rsp rsp = {0,}; + + + if (xdr_to_glusterfs_req (req, &args, xdr_to_pmap_signin_req)) { + req->rpc_err = GARBAGE_ARGS; + goto fail; + } + + +fail: + glusterd_submit_reply (req, &rsp, NULL, 0, NULL, + (gd_serialize_t)xdr_from_pmap_signin_rsp); + + return 0; +} + + + +int +gluster_pmap_signout (rpcsvc_request_t *req) +{ + pmap_signout_req args = {0,}; + pmap_signout_rsp rsp = {0,}; + + + if (xdr_to_glusterfs_req (req, &args, xdr_to_pmap_signout_req)) { + //failed to decode msg; + req->rpc_err = GARBAGE_ARGS; + goto fail; + } + + +fail: + glusterd_submit_reply (req, &rsp, NULL, 0, NULL, + (gd_serialize_t)xdr_from_pmap_signout_rsp); + + return 0; +} + + +rpcsvc_actor_t gluster_pmap_actors[] = { + [GF_PMAP_NULL] = {"NULL", GF_HNDSK_NULL, NULL, NULL, NULL }, + [GF_PMAP_PORTBYBRICK] = {"PORTBYBRICK", GF_PMAP_PORTBYBRICK, + gluster_pmap_portbybrick, NULL, NULL }, + [GF_PMAP_BRICKBYPORT] = {"BRICKBYPORT", GF_PMAP_BRICKBYPORT, + gluster_pmap_brickbyport, NULL, NULL }, + [GF_PMAP_SIGNIN] = {"SIGNIN", GF_PMAP_SIGNIN, + gluster_pmap_signin, NULL, NULL }, + [GF_PMAP_SIGNOUT] = {"SIGNOUT", GF_PMAP_SIGNOUT, + gluster_pmap_signout, NULL, NULL }, + [GF_PMAP_SIGNUP] = {"SIGNUP", GF_PMAP_SIGNUP, + gluster_pmap_signup, NULL, NULL }, +}; + + +struct rpcsvc_program gluster_pmap_prog = { + .progname = "Gluster Portmap", + .prognum = GLUSTER_PMAP_PROGRAM, + .progver = GLUSTER_PMAP_VERSION, + .actors = gluster_pmap_actors, + .numactors = GF_PMAP_MAXVALUE, +}; |