summaryrefslogtreecommitdiffstats
path: root/xlators/mgmt/glusterd/src/glusterd-handler.c
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/mgmt/glusterd/src/glusterd-handler.c')
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-handler.c188
1 files changed, 126 insertions, 62 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c
index ef39f76d2e7..55c01e975dc 100644
--- a/xlators/mgmt/glusterd/src/glusterd-handler.c
+++ b/xlators/mgmt/glusterd/src/glusterd-handler.c
@@ -182,15 +182,28 @@ glusterd_handle_friend_req (rpcsvc_request_t *req, uuid_t uuid,
glusterd_peerinfo_t *peerinfo = NULL;
glusterd_friend_sm_event_t *event = NULL;
glusterd_friend_req_ctx_t *ctx = NULL;
+ glusterd_peerctx_args_t args = {0};
+ char rhost[UNIX_PATH_MAX + 1] = {0};
+ uuid_t friend_uuid = {0};
+ char uuid_str[50] = {0,};
+ uuid_unparse (uuid, uuid_str);
+ uuid_parse (uuid_str, friend_uuid);
if (!port)
port = 6969; // TODO: use define values.
- ret = glusterd_friend_find (uuid, hostname, &peerinfo);
+ ret = glusterd_remote_hostname_get (req, rhost, sizeof (rhost));
+ ret = glusterd_friend_find (uuid, rhost, &peerinfo);
if (ret) {
gf_log ("glusterd", GF_LOG_NORMAL,
- "Unable to find peer");
+ " for host: %s (%d)", rhost, port);
+ args.mode = GD_MODE_SWITCH_ON;
+ args.req = NULL;
+ ret = glusterd_friend_add (rhost, port,
+ GD_FRIEND_STATE_DEFAULT,
+ &friend_uuid, NULL, &peerinfo, 0,
+ &args);
}
@@ -240,6 +253,8 @@ out:
GF_FREE (ctx);
}
+ if (0 == peerinfo->connected)
+ ret = GLUSTERD_CONNECTION_AWAITED;
return ret;
}
@@ -2396,8 +2411,10 @@ glusterd_handle_incoming_friend_req (rpcsvc_request_t *req)
dict);
out:
- if (ret && dict)
- dict_unref (dict);
+ if (GLUSTERD_CONNECTION_AWAITED != ret) {
+ if (ret && dict)
+ dict_unref (dict);
+ }
if (friend_req.hostname)
free (friend_req.hostname);//malloced by xdr
@@ -2451,6 +2468,7 @@ glusterd_handle_friend_update (rpcsvc_request_t *req)
int i = 1;
int count = 0;
uuid_t uuid = {0,};
+ glusterd_peerctx_args_t args = {0};
GF_ASSERT (req);
@@ -2490,6 +2508,7 @@ glusterd_handle_friend_update (rpcsvc_request_t *req)
if (ret)
goto out;
+ args.mode = GD_MODE_SWITCH_ON;
while ( i <= count) {
snprintf (key, sizeof (key), "friend%d.uuid", i);
ret = dict_get_str (dict, key, &uuid_buf);
@@ -2519,7 +2538,7 @@ glusterd_handle_friend_update (rpcsvc_request_t *req)
ret = glusterd_friend_add (hostname, friend_req.port,
GD_FRIEND_STATE_BEFRIENDED,
- &uuid, NULL, &peerinfo, 0);
+ &uuid, NULL, &peerinfo, 0, &args);
i++;
}
@@ -2542,7 +2561,6 @@ glusterd_handle_probe_query (rpcsvc_request_t *req)
glusterd_conf_t *conf = NULL;
gd1_mgmt_probe_req probe_req = {{0},};
gd1_mgmt_probe_rsp rsp = {{0},};
- glusterd_peer_hostname_t *name = NULL;
glusterd_peerinfo_t *peerinfo = NULL;
char remote_hostname[UNIX_PATH_MAX + 1] = {0,};
@@ -2570,16 +2588,7 @@ glusterd_handle_probe_query (rpcsvc_request_t *req)
goto out;
}
ret = glusterd_friend_find (probe_req.uuid, remote_hostname, &peerinfo);
- if ((ret == 0 ) || list_empty (&conf->peers)) {
- ret = glusterd_peer_hostname_new (probe_req.hostname, &name);
-
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to get new peer_hostname");
- } else {
- list_add_tail (&name->hostname_list, &conf->hostnames);
- }
-
- } else {
+ if ((ret != 0 ) && (!list_empty (&conf->peers))) {
rsp.op_ret = -1;
rsp.op_errno = GF_PROBE_ANOTHER_CLUSTER;
}
@@ -2623,7 +2632,8 @@ glusterd_friend_add (const char *hoststr, int port,
uuid_t *uuid,
struct rpc_clnt *rpc,
glusterd_peerinfo_t **friend,
- gf_boolean_t restore)
+ gf_boolean_t restore,
+ glusterd_peerctx_args_t *args)
{
int ret = 0;
glusterd_conf_t *priv = NULL;
@@ -2632,14 +2642,25 @@ glusterd_friend_add (const char *hoststr, int port,
struct rpc_clnt_config rpc_cfg = {0,};
glusterd_peer_hostname_t *name = NULL;
char *hostname = NULL;
+ glusterd_peerctx_t *peerctx = NULL;
priv = THIS->private;
- peerinfo = GF_CALLOC (1, sizeof(*peerinfo), gf_gld_mt_peerinfo_t);
+ peerctx = GF_CALLOC (1, sizeof (*peerctx), gf_gld_mt_peerctx_t);
+ if (!peerctx) {
+ ret = -1;
+ goto out;
+ }
+ peerinfo = GF_CALLOC (1, sizeof (*peerinfo), gf_gld_mt_peerinfo_t);
- if (!peerinfo)
- return -1;
+ if (!peerinfo) {
+ ret = -1;
+ goto out;
+ }
+ if (args)
+ peerctx->args = *args;
+ peerctx->peerinfo = peerinfo;
if (friend)
*friend = peerinfo;
@@ -2650,7 +2671,7 @@ glusterd_friend_add (const char *hoststr, int port,
if (ret)
goto out;
list_add_tail (&peerinfo->hostnames, &name->hostname_list);
- rpc_cfg.remote_host = gf_strdup (hoststr);
+ rpc_cfg.remote_host = (char *)hoststr;
peerinfo->hostname = gf_strdup (hoststr);
}
INIT_LIST_HEAD (&peerinfo->uuid_list);
@@ -2664,8 +2685,10 @@ glusterd_friend_add (const char *hoststr, int port,
if (hoststr) {
options = dict_new ();
- if (!options)
- return -1;
+ if (!options) {
+ ret = -1;
+ goto out;
+ }
hostname = gf_strdup((char*)hoststr);
if (!hostname) {
@@ -2701,7 +2724,7 @@ glusterd_friend_add (const char *hoststr, int port,
}
ret = rpc_clnt_register_notify (rpc, glusterd_rpc_notify,
- peerinfo);
+ peerctx);
peerinfo->rpc = rpc;
@@ -2712,9 +2735,21 @@ glusterd_friend_add (const char *hoststr, int port,
out:
+ if (ret) {
+ if (peerctx)
+ GF_FREE (peerctx);
+ if (rpc) {
+ (void) rpc_clnt_unref (rpc);
+ }
+ if (peerinfo) {
+ peerinfo->rpc = NULL;
+ (void) glusterd_friend_cleanup (peerinfo);
+ }
+ if (options)
+ dict_unref (options);
+ }
+
gf_log ("glusterd", GF_LOG_NORMAL, "connect returned %d", ret);
- if (rpc_cfg.remote_host)
- GF_FREE (rpc_cfg.remote_host);
return ret;
}
@@ -2725,8 +2760,7 @@ glusterd_probe_begin (rpcsvc_request_t *req, const char *hoststr, int port)
{
int ret = -1;
glusterd_peerinfo_t *peerinfo = NULL;
- glusterd_friend_sm_event_t *event = NULL;
- glusterd_probe_ctx_t *ctx = NULL;
+ glusterd_peerctx_args_t args = {0};
GF_ASSERT (hoststr);
@@ -2735,38 +2769,11 @@ glusterd_probe_begin (rpcsvc_request_t *req, const char *hoststr, int port)
if (ret) {
gf_log ("glusterd", GF_LOG_NORMAL, "Unable to find peerinfo"
" for host: %s (%d)", hoststr, port);
+ args.mode = GD_MODE_ON;
+ args.req = req;
ret = glusterd_friend_add ((char *)hoststr, port,
GD_FRIEND_STATE_DEFAULT,
- NULL, NULL, &peerinfo, 0);
- }
-
- ret = glusterd_friend_sm_new_event
- (GD_FRIEND_EVENT_PROBE, &event);
-
- if (ret) {
- gf_log ("glusterd", GF_LOG_ERROR, "Unable to get new event");
- return ret;
- }
-
- ctx = GF_CALLOC (1, sizeof(*ctx), gf_gld_mt_probe_ctx_t);
-
- if (!ctx) {
- return ret;
- }
-
- ctx->hostname = gf_strdup (hoststr);
- ctx->port = port;
- ctx->req = req;
-
- event->peerinfo = peerinfo;
- event->ctx = ctx;
-
- ret = glusterd_friend_sm_inject_event (event);
-
- if (ret) {
- gf_log ("glusterd", GF_LOG_ERROR, "Unable to inject event %d, "
- "ret = %d", event->event, ret);
- return ret;
+ NULL, NULL, &peerinfo, 0, &args);
}
if (!peerinfo->connected) {
@@ -3420,6 +3427,54 @@ out:
return ret;
}
+static int
+glusterd_event_connected_inject (glusterd_peerctx_t *peerctx)
+{
+ GF_ASSERT (peerctx);
+
+ glusterd_friend_sm_event_t *event = NULL;
+ glusterd_probe_ctx_t *ctx = NULL;
+ int ret = -1;
+ glusterd_peerinfo_t *peerinfo = NULL;
+
+
+ ret = glusterd_friend_sm_new_event
+ (GD_FRIEND_EVENT_CONNECTED, &event);
+
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to get new event");
+ goto out;
+ }
+
+ ctx = GF_CALLOC (1, sizeof(*ctx), gf_gld_mt_probe_ctx_t);
+
+ if (!ctx) {
+ ret = -1;
+ gf_log ("", GF_LOG_ERROR, "Memory not available");
+ goto out;
+ }
+
+ peerinfo = peerctx->peerinfo;
+ ctx->hostname = gf_strdup (peerinfo->hostname);
+ ctx->port = peerinfo->port;
+ ctx->req = peerctx->args.req;
+
+ event->peerinfo = peerinfo;
+ event->ctx = ctx;
+
+ ret = glusterd_friend_sm_inject_event (event);
+
+ if (ret) {
+ gf_log ("glusterd", GF_LOG_ERROR, "Unable to inject "
+ "EVENT_CONNECTED ret = %d", ret);
+ goto out;
+ }
+
+out:
+ gf_log ("", GF_LOG_DEBUG, "returning %d", ret);
+ return ret;
+}
+
int
glusterd_rpc_notify (struct rpc_clnt *rpc, void *mydata, rpc_clnt_event_t event,
void *data)
@@ -3429,8 +3484,10 @@ glusterd_rpc_notify (struct rpc_clnt *rpc, void *mydata, rpc_clnt_event_t event,
glusterd_conf_t *conf = NULL;
int ret = 0;
glusterd_peerinfo_t *peerinfo = NULL;
+ glusterd_peerctx_t *peerctx = NULL;
- peerinfo = mydata;
+ peerctx = mydata;
+ peerinfo = peerctx->peerinfo;
this = THIS;
conf = this->private;
@@ -3438,11 +3495,8 @@ glusterd_rpc_notify (struct rpc_clnt *rpc, void *mydata, rpc_clnt_event_t event,
switch (event) {
case RPC_CLNT_CONNECT:
{
-
gf_log (this->name, GF_LOG_DEBUG, "got RPC_CLNT_CONNECT");
peerinfo->connected = 1;
- glusterd_friend_sm ();
- glusterd_op_sm ();
if ((ret < 0) || (strcasecmp (handshake, "on"))) {
//ret = glusterd_handshake (this, peerinfo->rpc);
@@ -3451,6 +3505,16 @@ glusterd_rpc_notify (struct rpc_clnt *rpc, void *mydata, rpc_clnt_event_t event,
//conf->rpc->connected = 1;
ret = default_notify (this, GF_EVENT_CHILD_UP, NULL);
}
+
+ if (GD_MODE_ON == peerctx->args.mode) {
+ ret = glusterd_event_connected_inject (peerctx);
+ peerctx->args.req = NULL;
+ } else if (GD_MODE_SWITCH_ON == peerctx->args.mode) {
+ peerctx->args.mode = GD_MODE_ON;
+ }
+
+ glusterd_friend_sm ();
+ glusterd_op_sm ();
break;
}