diff options
Diffstat (limited to 'xlators/mgmt/glusterd/src/glusterd-handler.c')
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-handler.c | 517 |
1 files changed, 310 insertions, 207 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c index 0db5992fc2c..7635f15546c 100644 --- a/xlators/mgmt/glusterd/src/glusterd-handler.c +++ b/xlators/mgmt/glusterd/src/glusterd-handler.c @@ -398,6 +398,37 @@ out: return ret; } +int32_t +glusterd_op_txn_begin () +{ + int32_t ret = -1; + glusterd_conf_t *priv = NULL; + int32_t locked = 0; + + priv = THIS->private; + GF_ASSERT (priv); + + ret = glusterd_lock (priv->uuid); + + if (ret) { + gf_log ("glusterd", GF_LOG_ERROR, + "Unable to acquire local lock, ret: %d", ret); + goto out; + } + + locked = 1; + gf_log ("glusterd", GF_LOG_NORMAL, "Acquired local lock"); + + ret = glusterd_op_sm_inject_event (GD_OP_EVENT_START_LOCK, NULL); + + gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret); + +out: + if (locked && ret) + glusterd_unlock (priv->uuid); + return ret; +} + int glusterd_handle_cluster_lock (rpcsvc_request_t *req) { @@ -439,147 +470,137 @@ out: } int -glusterd_handle_stage_op (rpcsvc_request_t *req) +glusterd_req_ctx_create (rpcsvc_request_t *rpc_req, + glusterd_op_t op, uuid_t uuid, + char *buf_val, size_t buf_len, + gf_gld_mem_types_t mem_type, + glusterd_req_ctx_t **req_ctx_out) { - int32_t ret = -1; - gd1_mgmt_stage_op_req stage_req = {{0,}}; - glusterd_op_stage_ctx_t *ctx = NULL; + int ret = -1; + glusterd_req_ctx_t *req_ctx = NULL; + char str[50] = {0,}; + dict_t *dict = NULL; char volname[GLUSTERD_MAX_VOLUME_NAME] = {0}; char *dup_volname = NULL; - GF_ASSERT (req); - - if (!gd_xdr_to_mgmt_stage_op_req (req->msg[0], &stage_req)) { - //failed to decode msg; - req->rpc_err = GARBAGE_ARGS; - goto out; - } - + uuid_unparse (uuid, str); gf_log ("glusterd", GF_LOG_NORMAL, - "Received stage op from uuid: %s", uuid_utoa (stage_req.uuid)); - - ctx = GF_CALLOC (1, sizeof (*ctx), gf_gld_mt_op_stage_ctx_t); - if (!ctx) { - //respond here - goto err; - } - - ctx->dict = dict_new(); - if (!ctx->dict) - goto err; + "Received op from uuid: %s", str); - uuid_copy (ctx->uuid, stage_req.uuid); - ctx->op = stage_req.op; - ctx->req = req; + dict = dict_new (); + if (!dict) + goto out; + req_ctx = GF_CALLOC (1, sizeof (*req_ctx), mem_type); - if (!stage_req.buf.buf_val) + if (!req_ctx) { goto out; + } - if (GD_OP_DELETE_VOLUME == stage_req.op) { - strncpy (volname, stage_req.buf.buf_val, stage_req.buf.buf_len); + uuid_copy (req_ctx->uuid, uuid); + req_ctx->op = op; + if (GD_OP_DELETE_VOLUME == op) { + strncpy (volname, buf_val, buf_len); dup_volname = gf_strdup (volname); if (dup_volname) { - ret = dict_set_dynstr (ctx->dict, "volname", dup_volname); - if (ret) + ret = dict_set_dynstr (dict, "volname", dup_volname); + if (ret) { gf_log ("", GF_LOG_WARNING, - "failed to set volume name from payload"); + "failed to set volume name from payload"); + goto out; + } + } else { + ret = -1; + goto out; } - } else { - ret = dict_unserialize (stage_req.buf.buf_val, - stage_req.buf.buf_len, - &ctx->dict); + ret = dict_unserialize (buf_val, buf_len, &dict); - if (ret) + if (ret) { gf_log ("", GF_LOG_WARNING, - "failed to unserialize the dictionary"); + "failed to unserialize the dictionary"); + goto out; + } } - ret = glusterd_op_sm_inject_event (GD_OP_EVENT_STAGE_OP, ctx); - + req_ctx->dict = dict; + req_ctx->req = rpc_req; + *req_ctx_out = req_ctx; + ret = 0; out: - if (stage_req.buf.buf_val) - free (stage_req.buf.buf_val);//malloced by xdr - - glusterd_friend_sm (); - glusterd_op_sm (); -err: + if (ret) { + if (dict) + dict_unref (dict); + if (req_ctx) + GF_FREE (req_ctx); + } return ret; } int -glusterd_handle_commit_op (rpcsvc_request_t *req) +glusterd_handle_stage_op (rpcsvc_request_t *req) { int32_t ret = -1; - gd1_mgmt_commit_op_req commit_req = {{0},}; - glusterd_op_commit_ctx_t *ctx = NULL; - char volname[GLUSTERD_MAX_VOLUME_NAME] = {0}; - char *dup_volname = NULL; + glusterd_req_ctx_t *req_ctx = NULL; + gd1_mgmt_stage_op_req op_req = {{0},}; GF_ASSERT (req); - - if (!gd_xdr_to_mgmt_commit_op_req (req->msg[0], &commit_req)) { + if (!gd_xdr_to_mgmt_stage_op_req (req->msg[0], &op_req)) { //failed to decode msg; req->rpc_err = GARBAGE_ARGS; goto out; } + ret = glusterd_req_ctx_create (req, op_req.op, op_req.uuid, + op_req.buf.buf_val, op_req.buf.buf_len, + gf_gld_mt_op_stage_ctx_t, &req_ctx); + if (ret) + goto out; - gf_log ("glusterd", GF_LOG_NORMAL, - "Received commit op from uuid: %s", uuid_utoa (commit_req.uuid)); - - ctx = GF_CALLOC (1, sizeof (*ctx), gf_gld_mt_op_commit_ctx_t); - - if (!ctx) { - //respond here - goto err; - } + ret = glusterd_op_sm_inject_event (GD_OP_EVENT_STAGE_OP, req_ctx); - ctx->req = req; + out: + if (op_req.buf.buf_val) + free (op_req.buf.buf_val);//malloced by xdr + glusterd_friend_sm (); + glusterd_op_sm (); + return ret; +} - uuid_copy (ctx->uuid, commit_req.uuid); - ctx->op = commit_req.op; +int +glusterd_handle_commit_op (rpcsvc_request_t *req) +{ + int32_t ret = -1; + glusterd_req_ctx_t *req_ctx = NULL; + gd1_mgmt_commit_op_req op_req = {{0},}; - ctx->dict = dict_new(); - if (!ctx->dict) - goto err; + GF_ASSERT (req); - if (!commit_req.buf.buf_val) + if (!gd_xdr_to_mgmt_commit_op_req (req->msg[0], &op_req)) { + //failed to decode msg; + req->rpc_err = GARBAGE_ARGS; goto out; - - if (GD_OP_DELETE_VOLUME == commit_req.op) { - strncpy (volname, commit_req.buf.buf_val, commit_req.buf.buf_len); - dup_volname = gf_strdup (volname); - if (dup_volname) { - ret = dict_set_dynstr (ctx->dict, "volname", dup_volname); - if (ret) - gf_log ("", GF_LOG_WARNING, - "failed to set volume name from payload"); - } - - } else { - ret = dict_unserialize (commit_req.buf.buf_val, - commit_req.buf.buf_len, - &ctx->dict); - - if (ret) - gf_log ("", GF_LOG_WARNING, - "failed to unserialize the dictionary"); } - ret = glusterd_op_sm_inject_event (GD_OP_EVENT_COMMIT_OP, ctx); + //the structures should always be equal + GF_ASSERT (sizeof (gd1_mgmt_commit_op_req) == sizeof (gd1_mgmt_stage_op_req)); + ret = glusterd_req_ctx_create (req, op_req.op, op_req.uuid, + op_req.buf.buf_val, op_req.buf.buf_len, + gf_gld_mt_op_commit_ctx_t, &req_ctx); + if (ret) + goto out; -out: - if (commit_req.buf.buf_val) - free (commit_req.buf.buf_val);//malloced by xdr + ret = glusterd_op_sm_inject_event (GD_OP_EVENT_COMMIT_OP, req_ctx); + if (ret) + goto out; + ret = glusterd_op_init_ctx (op_req.op); +out: + if (op_req.buf.buf_val) + free (op_req.buf.buf_val);//malloced by xdr glusterd_friend_sm (); glusterd_op_sm (); - -err: return ret; } - int glusterd_handle_cli_probe (rpcsvc_request_t *req) { @@ -804,37 +825,6 @@ out: } int32_t -glusterd_op_txn_begin () -{ - int32_t ret = -1; - glusterd_conf_t *priv = NULL; - int32_t locked = 0; - - priv = THIS->private; - GF_ASSERT (priv); - - ret = glusterd_lock (priv->uuid); - - if (ret) { - gf_log ("glusterd", GF_LOG_ERROR, - "Unable to acquire local lock, ret: %d", ret); - goto out; - } - - locked = 1; - gf_log ("glusterd", GF_LOG_NORMAL, "Acquired local lock"); - - ret = glusterd_op_sm_inject_event (GD_OP_EVENT_START_LOCK, NULL); - - gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret); - -out: - if (locked && ret) - glusterd_unlock (priv->uuid); - return ret; -} - -int32_t glusterd_op_begin (rpcsvc_request_t *req, glusterd_op_t op, void *ctx, gf_boolean_t is_ctx_free) { @@ -2924,6 +2914,77 @@ out: } int +glusterd_handle_cli_profile_volume (rpcsvc_request_t *req) +{ + int32_t ret = -1; + gf1_cli_stats_volume_req cli_req = {0,}; + dict_t *dict = NULL; + char msg[2048] = {0,}; + gf_boolean_t free_volname = _gf_true; + int lock_fail = 0; + glusterd_op_t cli_op = GD_OP_PROFILE_VOLUME; + + + GF_ASSERT (req); + + ret = glusterd_op_set_cli_op (cli_op); + if (ret) { + gf_log ("", GF_LOG_ERROR, "Unable to set cli op: %d", + ret); + lock_fail = 1; + goto out; + } + + ret = -1; + if (!gf_xdr_to_cli_stats_volume_req (req->msg[0], &cli_req)) { + //failed to decode msg; + req->rpc_err = GARBAGE_ARGS; + goto out; + } + + gf_log ("glusterd", GF_LOG_NORMAL, "Received volume profile req " + "for volume %s", cli_req.volname); + + dict = dict_new (); + if (!dict) + goto out; + ret = dict_set_dynmstr (dict, "volname", cli_req.volname); + if (ret) { + gf_log ("", GF_LOG_ERROR, "volume name set failed"); + snprintf (msg, sizeof (msg), "volume name set failed"); + goto out; + } else { + free_volname = _gf_false; + } + + ret = dict_set_int32 (dict, "op", cli_req.op); + if (ret) { + gf_log ("", GF_LOG_ERROR, "op set failed"); + goto out; + } + + ret = glusterd_op_begin (req, cli_op, dict, _gf_true); + +out: + glusterd_friend_sm (); + glusterd_op_sm (); + if (ret) + dict_unref (dict); + if (free_volname) + free (cli_req.volname); // malloced by xdr + if (ret) { + ret = glusterd_op_send_cli_response (cli_op, ret, 0, req, + NULL, "operation failed"); + if (!lock_fail) + (void) glusterd_opinfo_unlock (); + + } + + gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret); + return ret; +} + +int glusterd_friend_remove (uuid_t uuid, char *hostname) { int ret = 0; @@ -2940,96 +3001,83 @@ out: } int -glusterd_friend_rpc_create (struct rpc_clnt **rpc, - const char *hoststr, int port, - glusterd_peerctx_t *peerctx) +glusterd_rpc_create (struct rpc_clnt **rpc, + dict_t *options, + rpc_clnt_notify_t notify_fn, + void *notify_data) { struct rpc_clnt *new_rpc = NULL; - dict_t *options = NULL; - struct rpc_clnt_config rpc_cfg = {0,}; int ret = -1; - char *hostname = NULL; - int32_t intvl = 0; xlator_t *this = NULL; - GF_ASSERT (hoststr); this = THIS; GF_ASSERT (this); - options = dict_new (); - if (!options) + GF_ASSERT (options); + new_rpc = rpc_clnt_new (options, this->ctx, this->name); + + if (!new_rpc) goto out; - ret = dict_get_int32 (this->options, - "transport.socket.keepalive-interval", - &intvl); - if (!ret) { - ret = dict_set_int32 (options, - "transport.socket.keepalive-interval", intvl); - if (ret) - goto out; + ret = rpc_clnt_register_notify (new_rpc, notify_fn, notify_data); + *rpc = new_rpc; + if (ret) + goto out; + ret = rpc_clnt_start (new_rpc); +out: + if (ret) { + if (new_rpc) { + (void) rpc_clnt_unref (new_rpc); + } } + gf_log ("", GF_LOG_DEBUG, "returning %d", ret); + return ret; +} + +int +glusterd_transport_keepalive_options_get (int *interval, int *time) +{ + int ret = 0; + xlator_t *this = NULL; + + this = THIS; + GF_ASSERT (this); + + ret = dict_get_int32 (this->options, + "transport.socket.keepalive-interval", + interval); ret = dict_get_int32 (this->options, "transport.socket.keepalive-time", - &intvl); - if (!ret) { - ret = dict_set_int32 (options, - "transport.socket.keepalive-time", intvl); - if (ret) - goto out; - } + time); + return 0; +} - hostname = gf_strdup((char*)hoststr); - if (!hostname) { - ret = -1; - goto out; - } +int +glusterd_transport_inet_keepalive_options_build (dict_t **options, + const char *hostname, int port) +{ + dict_t *dict = NULL; + int32_t interval = -1; + int32_t time = -1; + int ret = 0; - ret = dict_set_dynstr (options, "remote-host", hostname); - if (ret) - goto out; + GF_ASSERT (options); + GF_ASSERT (hostname); if (!port) port = GLUSTERD_DEFAULT_PORT; - - rpc_cfg.remote_host = (char *)hoststr; - rpc_cfg.remote_port = port; - - ret = dict_set_int32 (options, "remote-port", port); - if (ret) - goto out; - - ret = dict_set_str (options, "transport.address-family", "inet"); + ret = rpc_transport_inet_options_build (&dict, hostname, port); if (ret) goto out; - new_rpc = rpc_clnt_new (options, this->ctx, this->name); + glusterd_transport_keepalive_options_get (&interval, &time); - if (!new_rpc) { - gf_log ("glusterd", GF_LOG_ERROR, - "new_rpc init failed for peer: %s!", hoststr); - ret = -1; - goto out; - } - - ret = rpc_clnt_register_notify (new_rpc, glusterd_rpc_notify, - peerctx); - if (ret) - goto out; - *rpc = new_rpc; - rpc_clnt_start (new_rpc); + if ((interval > 0) || (time > 0)) + ret = rpc_transport_keepalive_options_set (dict, interval, time); + *options = dict; out: - if (ret) { - if (new_rpc) { - (void) rpc_clnt_unref (new_rpc); - } - if (options) - dict_unref (options); - *rpc = NULL; - } - - gf_log ("", GF_LOG_DEBUG, "returning %d", ret); + gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret); return ret; } @@ -3042,14 +3090,16 @@ glusterd_friend_add (const char *hoststr, int port, gf_boolean_t restore, glusterd_peerctx_args_t *args) { - int ret = 0; - glusterd_conf_t *conf = NULL; - glusterd_peerinfo_t *peerinfo = NULL; + int ret = 0; + glusterd_conf_t *conf = NULL; + glusterd_peerinfo_t *peerinfo = NULL; glusterd_peerctx_t *peerctx = NULL; - gf_boolean_t is_allocated = _gf_false; + gf_boolean_t is_allocated = _gf_false; + dict_t *options = NULL; conf = THIS->private; GF_ASSERT (conf) + GF_ASSERT (hoststr); peerctx = GF_CALLOC (1, sizeof (*peerctx), gf_gld_mt_peerctx_t); if (!peerctx) { @@ -3067,17 +3117,24 @@ glusterd_friend_add (const char *hoststr, int port, if (friend) *friend = peerinfo; - if (hoststr) { - if (!rpc) { - ret = glusterd_friend_rpc_create (&rpc, hoststr, port, - peerctx); - if (ret) - goto out; - is_allocated = _gf_true; + if (!rpc) { + ret = glusterd_transport_inet_keepalive_options_build (&options, + hoststr, port); + if (ret) + goto out; + ret = glusterd_rpc_create (&rpc, options, + glusterd_peer_rpc_notify, + peerctx); + if (ret) { + gf_log ("glusterd", GF_LOG_ERROR, "failed to create rpc for" + " peer %s", (char*)hoststr); + goto out; } - peerinfo->rpc = rpc; + is_allocated = _gf_true; } + peerinfo->rpc = rpc; + if (!restore) ret = glusterd_store_update_peerinfo (peerinfo); @@ -3482,14 +3539,58 @@ out: } int -glusterd_rpc_notify (struct rpc_clnt *rpc, void *mydata, rpc_clnt_event_t event, - void *data) +glusterd_brick_rpc_notify (struct rpc_clnt *rpc, void *mydata, + rpc_clnt_event_t event, + void *data) +{ + xlator_t *this = NULL; + glusterd_conf_t *conf = NULL; + int ret = 0; + glusterd_brickinfo_t *brickinfo = NULL; + + brickinfo = mydata; + if (!brickinfo) + return 0; + + this = THIS; + GF_ASSERT (this); + conf = this->private; + GF_ASSERT (conf); + + switch (event) { + case RPC_CLNT_CONNECT: + gf_log (this->name, GF_LOG_DEBUG, "got RPC_CLNT_CONNECT"); + glusterd_set_brick_status (brickinfo, GF_BRICK_STARTED); + ret = default_notify (this, GF_EVENT_CHILD_UP, NULL); + + break; + + case RPC_CLNT_DISCONNECT: + gf_log (this->name, GF_LOG_DEBUG, "got RPC_CLNT_DISCONNECT"); + glusterd_set_brick_status (brickinfo, GF_BRICK_STOPPED); + if (brickinfo->timer && brickinfo->timer->callbk) + brickinfo->timer->callbk (brickinfo->timer->data); + break; + + default: + gf_log (this->name, GF_LOG_TRACE, + "got some other RPC event %d", event); + break; + } + + return ret; +} + +int +glusterd_peer_rpc_notify (struct rpc_clnt *rpc, void *mydata, + rpc_clnt_event_t event, + void *data) { xlator_t *this = NULL; glusterd_conf_t *conf = NULL; int ret = 0; glusterd_peerinfo_t *peerinfo = NULL; - glusterd_peerctx_t *peerctx = NULL; + glusterd_peerctx_t *peerctx = NULL; peerctx = mydata; if (!peerctx) @@ -3579,6 +3680,7 @@ rpcsvc_actor_t gd_svc_cli_actors[] = { [GLUSTER_CLI_RESET_VOLUME] = { "RESET_VOLUME", GLUSTER_CLI_RESET_VOLUME, glusterd_handle_reset_volume, NULL, NULL}, [GLUSTER_CLI_FSM_LOG] = { "FSM_LOG", GLUSTER_CLI_FSM_LOG, glusterd_handle_fsm_log, NULL, NULL}, [GLUSTER_CLI_GSYNC_SET] = { "GSYNC_SET", GLUSTER_CLI_GSYNC_SET, glusterd_handle_gsync_set, NULL, NULL}, + [GLUSTER_CLI_PROFILE_VOLUME] = { "STATS_VOLUME", GLUSTER_CLI_PROFILE_VOLUME, glusterd_handle_cli_profile_volume, NULL, NULL} }; struct rpcsvc_program gd_svc_cli_prog = { @@ -3621,6 +3723,7 @@ rpcsvc_actor_t glusterd1_mgmt_actors[] = { [GD_MGMT_CLI_RESET_VOLUME] = { "RESET_VOLUME", GD_MGMT_CLI_RESET_VOLUME, glusterd_handle_reset_volume, NULL, NULL}, [GD_MGMT_CLI_FSM_LOG] = { "FSM_LOG", GD_MGMT_CLI_FSM_LOG, glusterd_handle_fsm_log, NULL, NULL}, [GD_MGMT_CLI_GSYNC_SET] = {"GSYNC_SET", GD_MGMT_CLI_GSYNC_SET, glusterd_handle_gsync_set, NULL, NULL}, + [GD_MGMT_CLI_PROFILE_VOLUME] = { "STATS_VOLUME", GD_MGMT_CLI_PROFILE_VOLUME, glusterd_handle_cli_profile_volume, NULL, NULL} }; struct rpcsvc_program glusterd1_mop_prog = { |