From 3c38ba1e7b4959602f945112a26b8aee904fefaa Mon Sep 17 00:00:00 2001 From: Kaushal M Date: Thu, 14 Nov 2013 12:15:53 +0530 Subject: glusterd: Start rebalance only where required Gluster was starting rebalance processes on peers where it wasn't required in two cases. - For a normal rebalance command on a volume, rebalance processes were started on all peers instead of just the peers which contain bricks of the volume - For rebalance process being restarted by a volume sync, caused by a new peer being probed or a peer restarting, rebalance processes were started on all peers, for both a normal rebalance and for remove-brick needing rebalance. This patch adds a new check before starting rebalance process in the above two cases. - For rebalance process required by a rebalance command, each peer will check if it contains atleast one brick of the volume - For rebalance process required by a remove-brick command, each peer will check if it contains atleast one of the bricks being removed Change-Id: I512da16994f0d5482889c3a009c46dc20a8a15bb BUG: 1031887 Signed-off-by: Kaushal M Reviewed-on: http://review.gluster.org/6301 Tested-by: Gluster Build System Reviewed-by: Krutika Dhananjay Reviewed-by: Anand Avati --- xlators/mgmt/glusterd/src/glusterd-rebalance.c | 4 +- xlators/mgmt/glusterd/src/glusterd-utils.c | 65 ++++++++++++++++++++++++++ xlators/mgmt/glusterd/src/glusterd-utils.h | 3 ++ 3 files changed, 71 insertions(+), 1 deletion(-) diff --git a/xlators/mgmt/glusterd/src/glusterd-rebalance.c b/xlators/mgmt/glusterd/src/glusterd-rebalance.c index 031de2c9b0e..214f40c668a 100644 --- a/xlators/mgmt/glusterd/src/glusterd-rebalance.c +++ b/xlators/mgmt/glusterd/src/glusterd-rebalance.c @@ -665,9 +665,11 @@ glusterd_op_rebalance (dict_t *dict, char **op_errstr, dict_t *rsp_dict) uuid_parse (task_id_str, volinfo->rebal.rebalance_id) ; volinfo->rebal.op = GD_OP_REBALANCE; } + if (!gd_should_i_start_rebalance (volinfo)) + break; ret = glusterd_handle_defrag_start (volinfo, msg, sizeof (msg), cmd, NULL, GD_OP_REBALANCE); - break; + break; case GF_DEFRAG_CMD_STOP: /* Clear task-id only on explicitly stopping rebalance. * Also clear the stored operation, so it doesn't cause trouble diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c index 9e8b7c5b650..e93b88ecfdc 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.c +++ b/xlators/mgmt/glusterd/src/glusterd-utils.c @@ -6233,6 +6233,8 @@ glusterd_restart_rebalance (glusterd_conf_t *conf) list_for_each_entry (volinfo, &conf->volumes, vol_list) { if (!volinfo->rebal.defrag_cmd) continue; + if (!gd_should_i_start_rebalance (volinfo)) + continue; glusterd_volume_defrag_restart (volinfo, op_errstr, 256, volinfo->rebal.defrag_cmd, NULL); } @@ -7999,3 +8001,66 @@ glusterd_is_status_tasks_op (glusterd_op_t op, dict_t *dict) out: return is_status_tasks; } + +/* Tells if rebalance needs to be started for the given volume on the peer + * + * Rebalance should be started on a peer only if an involved brick is present on + * the peer. + * + * For a normal rebalance, if any one brick of the given volume is present on + * the peer, the rebalance process should be started. + * + * For a rebalance as part of a remove-brick operation, the rebalance process + * should be started only if one of the bricks being removed is present on the + * peer + */ +gf_boolean_t +gd_should_i_start_rebalance (glusterd_volinfo_t *volinfo) { + gf_boolean_t retval = _gf_false; + int ret = -1; + glusterd_brickinfo_t *brick = NULL; + int count = 0; + int i = 0; + char key[1023] = {0,}; + char *brickname = NULL; + + + switch (volinfo->rebal.op) { + case GD_OP_REBALANCE: + list_for_each_entry (brick, &volinfo->bricks, brick_list) { + if (uuid_compare (MY_UUID, brick->uuid) == 0) { + retval = _gf_true; + break; + } + } + break; + case GD_OP_REMOVE_BRICK: + ret = dict_get_int32 (volinfo->rebal.dict, "count", &count); + if (ret) { + goto out; + } + for (i = 1; i <= count; i++) { + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "brick%d", i); + ret = dict_get_str (volinfo->rebal.dict, key, + &brickname); + if (ret) + goto out; + ret = glusterd_volume_brickinfo_get_by_brick (brickname, + volinfo, + &brick); + if (ret) + goto out; + if (uuid_compare (MY_UUID, brick->uuid) == 0) { + retval = _gf_true; + break; + } + } + break; + default: + break; + } + +out: + return retval; +} diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.h b/xlators/mgmt/glusterd/src/glusterd-utils.h index 57120fe3942..5b0cfca7b55 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.h +++ b/xlators/mgmt/glusterd/src/glusterd-utils.h @@ -573,4 +573,7 @@ glusterd_check_gsync_running_local (char *master, char *slave, gf_boolean_t glusterd_is_status_tasks_op (glusterd_op_t op, dict_t *dict); + +gf_boolean_t +gd_should_i_start_rebalance (glusterd_volinfo_t *volinfo); #endif -- cgit