From 7510d8edf4e7bea50e0c1f041202f063a5d138af Mon Sep 17 00:00:00 2001 From: Pranith Kumar K Date: Mon, 29 Dec 2014 15:32:28 +0530 Subject: mgmt/glusterd: Implement Volume heal enable/disable For volumes with replicate, disperse xlators, self-heal daemon should do healing. This patch provides enable/disable functionality for the xlators to be part of self-heal-daemon. Replicate already had this functionality with 'gluster volume set cluster.self-heal-daemon on/off'. But this patch makes it uniform for both types of volumes. Internally it still does 'volume set' based on the volume type. Change-Id: Ie0f3799b74c2afef9ac658ef3d50dce3e8072b29 BUG: 1177601 Signed-off-by: Pranith Kumar K Reviewed-on: http://review.gluster.org/9358 Reviewed-by: Krishnan Parthasarathi Tested-by: Gluster Build System Reviewed-by: Xavier Hernandez Tested-by: Krishnan Parthasarathi --- xlators/mgmt/glusterd/src/glusterd-volume-ops.c | 70 ++++++++++++++++++++++++- 1 file changed, 69 insertions(+), 1 deletion(-) (limited to 'xlators/mgmt/glusterd/src/glusterd-volume-ops.c') diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c index 9ac489d5070..0535fedd753 100644 --- a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c +++ b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c @@ -638,6 +638,59 @@ glusterd_handle_cli_delete_volume (rpcsvc_request_t *req) __glusterd_handle_cli_delete_volume); } +static int +glusterd_handle_heal_enable_disable (rpcsvc_request_t *req, dict_t *dict, + glusterd_volinfo_t *volinfo) +{ + gf_xl_afr_op_t heal_op = GF_AFR_OP_INVALID; + int ret = 0; + xlator_t *this = THIS; + char *key = NULL; + char *value = NULL; + + ret = dict_get_int32 (dict, "heal-op", (int32_t *)&heal_op); + if (ret || (heal_op == GF_AFR_OP_INVALID)) { + ret = -1; + goto out; + } + + if ((heal_op != GF_AFR_OP_HEAL_ENABLE) && + (heal_op != GF_AFR_OP_HEAL_DISABLE)) { + ret = -EINVAL; + goto out; + } + + key = volgen_get_shd_key (volinfo); + if (!key) { + ret = -1; + goto out; + } + + /* Convert this command to volume-set command based on volume type */ + ret = dict_set_str (dict, "key1", key); + if (ret) + goto out; + + if (heal_op == GF_AFR_OP_HEAL_ENABLE) { + value = "enable"; + } else if (heal_op == GF_AFR_OP_HEAL_DISABLE) { + value = "disable"; + } + + ret = dict_set_str (dict, "value1", value); + if (ret) + goto out; + + ret = dict_set_int32 (dict, "count", 1); + if (ret) + goto out; + + ret = glusterd_op_begin_synctask (req, GD_OP_SET_VOLUME, dict); + +out: + return ret; +} + int __glusterd_handle_cli_heal_volume (rpcsvc_request_t *req) { @@ -696,7 +749,21 @@ __glusterd_handle_cli_heal_volume (rpcsvc_request_t *req) if (ret) { snprintf (op_errstr, sizeof (op_errstr), "Volume %s does not exist", volname); - gf_log (this->name, GF_LOG_ERROR, "%s", op_errstr); + goto out; + } + + ret = glusterd_handle_heal_enable_disable (req, dict, volinfo); + if (ret == -EINVAL) { + ret = 0; + } else { + /* + * If the return value is -ve but not -EINVAL then the command + * failed. If the return value is 0 then the synctask for the + * op has begun, so in both cases just 'goto out'. If there was + * a failure it will respond with an error, otherwise the + * synctask will take the responsibility of sending the + * response. + */ goto out; } @@ -715,6 +782,7 @@ out: if (op_errstr[0] == '\0') snprintf (op_errstr, sizeof (op_errstr), "operation failed"); + gf_log (this->name, GF_LOG_ERROR, "%s", op_errstr); ret = glusterd_op_send_cli_response (cli_op, ret, 0, req, dict, op_errstr); } -- cgit