summaryrefslogtreecommitdiffstats
path: root/xlators/mgmt/glusterd/src/glusterd-pmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/mgmt/glusterd/src/glusterd-pmap.c')
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-pmap.c336
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,
+};