summaryrefslogtreecommitdiffstats
path: root/glusterfsd
diff options
context:
space:
mode:
authorKrishnan Parthasarathi <kp@gluster.com>2011-09-16 10:40:32 +0530
committerVijay Bellur <vijay@gluster.com>2011-09-22 09:43:25 -0700
commit4765dd1a1c51c67ab86687fbd871c89156680c34 (patch)
treed1d3890457cbcb01131d21f66e40ec8a1c537cf1 /glusterfsd
parent53b5da6dfab2e6b11ab2e40119e92ff7d4527b2c (diff)
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 <VOLNAME>. Change-Id: I3954353b53488c28b70406e261808239b44997f3 BUG: 3602 Reviewed-on: http://review.gluster.com/454 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Vijay Bellur <vijay@gluster.com>
Diffstat (limited to 'glusterfsd')
-rw-r--r--glusterfsd/src/glusterfsd-mgmt.c127
1 files changed, 126 insertions, 1 deletions
diff --git a/glusterfsd/src/glusterfsd-mgmt.c b/glusterfsd/src/glusterfsd-mgmt.c
index 43d49b3f4..adce060a6 100644
--- a/glusterfsd/src/glusterfsd-mgmt.c
+++ b/glusterfsd/src/glusterfsd-mgmt.c
@@ -316,6 +316,41 @@ out:
}
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)
{
int32_t ret = -1;
@@ -615,6 +650,92 @@ out:
}
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)
{
int ret = -1;
@@ -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 = {