From 4f76b8d11a93cfb74667f6b3051186b86c1ec55b Mon Sep 17 00:00:00 2001 From: Anuradha Date: Fri, 5 Jun 2015 16:46:39 +0530 Subject: glusterd/ afr : set afr pending xattrs on replace brick This patch is part one change to prevent data loss in a replicate volume on doing a replace-brick commit force operation. Problem: After doing replace-brick commit force, there is a chance that self heal happens from the replaced (sink) brick rather than the source brick leading to data loss. Solution: During the commit phase of replace brick, after old brick is brought down, create a temporary mount and perform setfattr operation (on virtual xattr) indicating AFR to mark the replaced brick as sink. As a part of this change replace-brick command is being changed to use mgmt_v3 framework rather than op-state-machine framework. Many thanks to Krishnan Parthasarathi for helping me out on this. Change-Id: If0d51b5b3cef5b34d5672d46ea12eaa9d35fd894 BUG: 1207829 Signed-off-by: Anuradha Reviewed-on: http://review.gluster.org/10076 Tested-by: NetBSD Build System Reviewed-by: Ravishankar N Reviewed-by: Pranith Kumar Karampuri --- xlators/mgmt/glusterd/src/glusterd-mgmt.c | 52 +++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) (limited to 'xlators/mgmt/glusterd/src/glusterd-mgmt.c') diff --git a/xlators/mgmt/glusterd/src/glusterd-mgmt.c b/xlators/mgmt/glusterd/src/glusterd-mgmt.c index 41e639118f0..607d2c57014 100644 --- a/xlators/mgmt/glusterd/src/glusterd-mgmt.c +++ b/xlators/mgmt/glusterd/src/glusterd-mgmt.c @@ -169,6 +169,16 @@ gd_mgmt_v3_pre_validate_fn (glusterd_op_t op, dict_t *dict, break; + case GD_OP_REPLACE_BRICK: + ret = glusterd_op_stage_replace_brick (dict, op_errstr, + rsp_dict); + if (ret) { + gf_log (this->name, GF_LOG_WARNING, + "Replace-brick prevalidation failed."); + goto out; + } + break; + default: break; } @@ -242,6 +252,17 @@ gd_mgmt_v3_commit_fn (glusterd_op_t op, dict_t *dict, } break; } + case GD_OP_REPLACE_BRICK: + { + ret = glusterd_op_replace_brick (dict, rsp_dict); + if (ret) { + gf_msg (this->name, GF_LOG_ERROR, 0, + GD_MSG_COMMIT_OP_FAIL, + "Replace-brick commit failed."); + goto out; + } + break; + } default: break; } @@ -527,6 +548,16 @@ glusterd_pre_validate_aggr_rsp_dict (glusterd_op_t op, goto out; } break; + case GD_OP_REPLACE_BRICK: + ret = glusterd_rb_use_rsp_dict (aggr, rsp); + if (ret) { + gf_msg (this->name, GF_LOG_ERROR, 0, + GD_MSG_PRE_VALIDATION_FAIL, + "Failed to aggregate prevalidate " + "response dictionaries."); + goto out; + } + break; default: ret = -1; gf_msg (this->name, GF_LOG_ERROR, EINVAL, @@ -809,6 +840,7 @@ glusterd_mgmt_v3_build_payload (dict_t **req, char **op_errstr, dict_t *dict, int32_t ret = -1; dict_t *req_dict = NULL; xlator_t *this = NULL; + char *volname = NULL; this = THIS; GF_ASSERT (this); @@ -824,6 +856,26 @@ glusterd_mgmt_v3_build_payload (dict_t **req, char **op_errstr, dict_t *dict, case GD_OP_SNAP: dict_copy (dict, req_dict); break; + case GD_OP_REPLACE_BRICK: + { + ret = dict_get_str (dict, "volname", &volname); + if (ret) { + gf_log (this->name, GF_LOG_CRITICAL, + "volname is not present in " + "operation ctx"); + goto out; + } + + if (strcasecmp (volname, "all")) { + ret = glusterd_dict_set_volid (dict, + volname, + op_errstr); + if (ret) + goto out; + } + dict_copy (dict, req_dict); + } + break; default: break; } -- cgit