From 4765dd1a1c51c67ab86687fbd871c89156680c34 Mon Sep 17 00:00:00 2001 From: Krishnan Parthasarathi Date: Fri, 16 Sep 2011 10:40:32 +0530 Subject: glusterd: Implemented cmd to trigger self-heal on a replicate volume. This cmd is used in the context of proactive self-heal for replicated volumes. User invokes the following cmd when (s)he suspects that self-heal needs to be done on a particular volume, gluster volume heal . Change-Id: I3954353b53488c28b70406e261808239b44997f3 BUG: 3602 Reviewed-on: http://review.gluster.com/454 Tested-by: Gluster Build System Reviewed-by: Vijay Bellur --- glusterfsd/src/glusterfsd-mgmt.c | 127 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 126 insertions(+), 1 deletion(-) (limited to 'glusterfsd/src/glusterfsd-mgmt.c') diff --git a/glusterfsd/src/glusterfsd-mgmt.c b/glusterfsd/src/glusterfsd-mgmt.c index 43d49b3f4e8..adce060a6d2 100644 --- a/glusterfsd/src/glusterfsd-mgmt.c +++ b/glusterfsd/src/glusterfsd-mgmt.c @@ -315,6 +315,41 @@ out: return ret; } +int +glusterfs_translator_heal_response_send (rpcsvc_request_t *req, int op_ret, + char *msg, dict_t *output) +{ + gd1_mgmt_brick_op_rsp rsp = {0,}; + int ret = -1; + GF_ASSERT (msg); + GF_ASSERT (req); + GF_ASSERT (output); + + rsp.op_ret = op_ret; + rsp.op_errno = 0; + if (ret && msg[0]) + rsp.op_errstr = msg; + else + rsp.op_errstr = ""; + + ret = dict_allocate_and_serialize (output, &rsp.output.output_val, + (size_t *)&rsp.output.output_len); + if (ret) { + gf_log (THIS->name, GF_LOG_ERROR, "Couldn't serialize " + "output dict."); + goto out; + } + + ret = glusterfs_submit_reply (req, &rsp, NULL, 0, NULL, + (xdrproc_t)xdr_gd1_mgmt_brick_op_rsp); + +out: + if (rsp.output.output_val) + GF_FREE (rsp.output.output_val); + + return ret; +} + int glusterfs_handle_translator_info_get (rpcsvc_request_t *req) { @@ -614,6 +649,92 @@ out: return NULL; } +int +glusterfs_handle_translator_heal (rpcsvc_request_t *req) +{ + int32_t ret = -1; + gd1_mgmt_brick_op_req xlator_req = {0,}; + dict_t *dict = NULL; + xlator_t *xlator = NULL; + xlator_t *any = NULL; + dict_t *output = NULL; + char msg[2048] = {0}; + char key[2048] = {0}; + char *xname = NULL; + glusterfs_ctx_t *ctx = NULL; + glusterfs_graph_t *active = NULL; + xlator_t *this = NULL; + int i = 0; + int count = 0; + + GF_ASSERT (req); + this = THIS; + GF_ASSERT (this); + + ctx = glusterfs_ctx_get (); + GF_ASSERT (ctx); + + active = ctx->active; + any = active->first; + if (!xdr_to_generic (req->msg[0], &xlator_req, + (xdrproc_t)xdr_gd1_mgmt_brick_op_req)) { + //failed to decode msg; + req->rpc_err = GARBAGE_ARGS; + goto out; + } + dict = dict_new (); + + ret = dict_unserialize (xlator_req.input.input_val, + xlator_req.input.input_len, + &dict); + if (ret < 0) { + gf_log (this->name, GF_LOG_ERROR, + "failed to " + "unserialize req-buffer to dictionary"); + goto out; + } + + ret = dict_get_int32 (dict, "count", &count); + i = 0; + while (i < count) { + snprintf (key, sizeof (key), "heal-%d", i); + ret = dict_get_str (dict, key, &xname); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Couldn't get " + "replicate xlator %s to trigger " + "self-heal", xname); + goto out; + } + xlator = xlator_search_by_name (any, xname); + if (!xlator) { + snprintf (msg, sizeof (msg), "xlator %s is not loaded", + xlator_req.name); + ret = -1; + goto out; + } + + ret = xlator_notify (xlator, GF_EVENT_TRIGGER_HEAL, dict, NULL); + i++; + } + output = dict_new (); + if (!output) + goto out; + + /* output dict is not used currently, could be used later. */ + ret = glusterfs_translator_heal_response_send (req, ret, msg, output); +out: + if (dict) + dict_unref (dict); + if (xlator_req.input.input_val) + free (xlator_req.input.input_val); // malloced by xdr + if (output) + dict_unref (output); + if (xlator_req.name) + free (xlator_req.name); //malloced by xdr + + return ret; +} + int glusterfs_handle_rpc_msg (rpcsvc_request_t *req) { @@ -627,6 +748,9 @@ glusterfs_handle_rpc_msg (rpcsvc_request_t *req) case GF_BRICK_XLATOR_INFO: ret = glusterfs_handle_translator_info_get (req); break; + case GF_BRICK_XLATOR_HEAL: + ret = glusterfs_handle_translator_heal (req); + break; default: break; } @@ -681,7 +805,8 @@ rpc_clnt_prog_t clnt_handshake_prog = { rpcsvc_actor_t glusterfs_actors[] = { [GF_BRICK_NULL] = { "NULL", GF_BRICK_NULL, glusterfs_handle_rpc_msg, NULL, NULL}, [GF_BRICK_TERMINATE] = { "TERMINATE", GF_BRICK_TERMINATE, glusterfs_handle_rpc_msg, NULL, NULL}, - [GF_BRICK_XLATOR_INFO] = { "TRANSLATOR INFO", GF_BRICK_XLATOR_INFO, glusterfs_handle_rpc_msg, NULL, NULL} + [GF_BRICK_XLATOR_INFO] = { "TRANSLATOR INFO", GF_BRICK_XLATOR_INFO, glusterfs_handle_rpc_msg, NULL, NULL}, + [GF_BRICK_XLATOR_HEAL] = { "TRANSLATOR HEAL", GF_BRICK_XLATOR_HEAL, glusterfs_handle_rpc_msg, NULL, NULL} }; struct rpcsvc_program glusterfs_mop_prog = { -- cgit