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 --- cli/src/cli-cmd-volume.c | 45 +++++++++++++++++++++++++ cli/src/cli-rpc-ops.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++- cli/src/cli.h | 4 +++ 3 files changed, 136 insertions(+), 1 deletion(-) (limited to 'cli') diff --git a/cli/src/cli-cmd-volume.c b/cli/src/cli-cmd-volume.c index de3166e8d..a2ec50863 100644 --- a/cli/src/cli-cmd-volume.c +++ b/cli/src/cli-cmd-volume.c @@ -1469,6 +1469,47 @@ cli_print_brick_status (char *brick, int port, int online, int pid) return 0; } +int +cli_cmd_volume_heal_cbk (struct cli_state *state, struct cli_cmd_word *word, + const char **words, int wordcount) +{ + int ret = -1; + rpc_clnt_procedure_t *proc = NULL; + call_frame_t *frame = NULL; + gf1_cli_heal_vol_req req = {0,}; + int sent = 0; + int parse_error = 0; + + frame = create_frame (THIS, THIS->ctx->pool); + if (!frame) + goto out; + + if (wordcount != 3) { + cli_usage_out (word->pattern); + parse_error = 1; + goto out; + } + + req.volname = (char *)words[2]; + if (!req.volname) + goto out; + + proc = &cli_rpc_prog->proctable[GLUSTER_CLI_HEAL_VOLUME]; + + if (proc->fn) { + ret = proc->fn (frame, THIS, &req); + } + +out: + if (ret) { + cli_cmd_sent_status_get (&sent); + if ((sent == 0) && (parse_error == 0)) + cli_out ("Volume heal failed"); + } + + return ret; +} + struct cli_cmd volume_cmds[] = { { "volume info [all|]", cli_cmd_volume_info_cbk, @@ -1571,6 +1612,10 @@ struct cli_cmd volume_cmds[] = { cli_cmd_volume_status_cbk, "display status of specified volume"}, + { "volume heal ", + cli_cmd_volume_heal_cbk, + "Start healing of volume specified by "}, + { NULL, NULL, NULL } }; diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c index ccd76d570..78d27b624 100644 --- a/cli/src/cli-rpc-ops.c +++ b/cli/src/cli-rpc-ops.c @@ -3912,6 +3912,91 @@ gf_cli3_1_umount (call_frame_t *frame, xlator_t *this, void *data) return ret; } +int +gf_cli3_1_heal_volume_cbk (struct rpc_req *req, struct iovec *iov, + int count, void *myframe) +{ + gf1_cli_heal_vol_rsp rsp = {0,}; + int ret = 0; + cli_local_t *local = NULL; + char *volname = NULL; + call_frame_t *frame = NULL; + + if (-1 == req->rpc_status) { + goto out; + } + + ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf1_cli_heal_vol_rsp); + if (ret < 0) { + gf_log ("", GF_LOG_ERROR, "error"); + goto out; + } + + frame = myframe; + + if (frame) { + local = frame->local; + frame->local = NULL; + } + + if (local) + volname = local->u.heal_vol.volname; + + gf_log ("cli", GF_LOG_INFO, "Received resp to heal volume"); + + if (rsp.op_ret && strcmp (rsp.op_errstr, "")) + cli_out ("%s", rsp.op_errstr); + else + cli_out ("Starting heal on volume %s has been %s", volname, + (rsp.op_ret) ? "unsuccessful": "successful"); + + ret = rsp.op_ret; + +out: + cli_cmd_broadcast_response (ret); + if (local) + cli_local_wipe (local); + if (rsp.volname) + free (rsp.volname); + if (rsp.op_errstr) + free (rsp.op_errstr); + return ret; +} + +int32_t +gf_cli3_1_heal_volume (call_frame_t *frame, xlator_t *this, + void *data) +{ + gf1_cli_heal_vol_req *req = NULL; + int ret = 0; + cli_local_t *local = NULL; + + if (!frame || !this || !data) { + ret = -1; + goto out; + } + + req = data; + local = cli_local_get (); + + if (local) { + local->u.heal_vol.volname = req->volname; + frame->local = local; + } + + ret = cli_cmd_submit (req, frame, cli_rpc_prog, + GLUSTER_CLI_HEAL_VOLUME, NULL, + this, gf_cli3_1_heal_volume_cbk, + (xdrproc_t) xdr_gf1_cli_heal_vol_req); + +out: + gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret); + + return ret; +} + + + struct rpc_clnt_procedure gluster_cli_actors[GLUSTER_CLI_MAXVALUE] = { [GLUSTER_CLI_NULL] = {"NULL", NULL }, [GLUSTER_CLI_PROBE] = {"PROBE_QUERY", gf_cli3_1_probe}, @@ -3945,7 +4030,8 @@ struct rpc_clnt_procedure gluster_cli_actors[GLUSTER_CLI_MAXVALUE] = { [GLUSTER_CLI_GETWD] = {"GETWD", gf_cli3_1_getwd}, [GLUSTER_CLI_STATUS_VOLUME] = {"STATUS_VOLUME", gf_cli3_1_status_volume}, [GLUSTER_CLI_MOUNT] = {"MOUNT", gf_cli3_1_mount}, - [GLUSTER_CLI_UMOUNT] = {"UMOUNT", gf_cli3_1_umount} + [GLUSTER_CLI_UMOUNT] = {"UMOUNT", gf_cli3_1_umount}, + [GLUSTER_CLI_HEAL_VOLUME] = {"HEAL_VOLUME", gf_cli3_1_heal_volume} }; struct rpc_clnt_program cli_prog = { diff --git a/cli/src/cli.h b/cli/src/cli.h index bf3437827..4ef1dbe06 100644 --- a/cli/src/cli.h +++ b/cli/src/cli.h @@ -149,6 +149,10 @@ struct cli_local { char *volname; int flags; } get_vol; + + struct { + char *volname; + }heal_vol; } u; }; -- cgit