From c550ae69526ad60b2f288ddc98a59141b9e64dcc Mon Sep 17 00:00:00 2001 From: Ravishankar N Date: Fri, 13 Sep 2013 18:48:38 +0530 Subject: cli/glusterd: improve rebalance fix-layout status reporting Problem: Currenly the CLI rebalance status command output does not indicate the 'type' of rebalance, i.e. whether a full rebalance or only a fix-layout was carried out. Fix: After the rebalance status of all peers is received by the originator glusterd, alter it to reflect the type of rebalance before passing it on to the CLI process. Change-Id: I1940ffda0d36e25e5b33c84a0ea210394cc9e1d3 BUG: 1004744 Signed-off-by: Ravishankar N Reviewed-on: http://review.gluster.org/5826 Reviewed-by: Krishnan Parthasarathi Tested-by: Gluster Build System Reviewed-by: Anand Avati --- cli/src/cli-rpc-ops.c | 12 +++- rpc/xdr/src/cli1-xdr.h | 4 ++ rpc/xdr/src/cli1-xdr.x | 6 +- tests/bugs/bug-1004744.t | 48 +++++++++++++ tests/bugs/bug-853258.t | 4 +- tests/volume.rc | 7 +- xlators/cluster/dht/src/dht-common.h | 4 ++ xlators/cluster/dht/src/dht-rebalance.c | 2 + xlators/mgmt/glusterd/src/glusterd-op-sm.c | 96 ++++++++++++++++++++++++++ xlators/mgmt/glusterd/src/glusterd-rebalance.c | 3 +- 10 files changed, 177 insertions(+), 9 deletions(-) create mode 100644 tests/bugs/bug-1004744.t diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c index c15e0e086..fe3db41b6 100644 --- a/cli/src/cli-rpc-ops.c +++ b/cli/src/cli-rpc-ops.c @@ -67,6 +67,10 @@ char *cli_vol_task_status_str[] = {"not started", "stopped", "completed", "failed", + "fix-layout in progress", + "fix-layout stopped", + "fix-layout completed", + "fix-layout failed", }; int32_t @@ -1334,10 +1338,10 @@ gf_cli_defrag_volume_cbk (struct rpc_req *req, struct iovec *iov, goto out; } - cli_out ("%40s %16s %13s %13s %13s %13s %14s %s", "Node", + cli_out ("%40s %16s %13s %13s %13s %13s %20s %18s", "Node", "Rebalanced-files", "size", "scanned", "failures", "skipped", "status", "run time in secs"); - cli_out ("%40s %16s %13s %13s %13s %13s %14s %16s", "---------", + cli_out ("%40s %16s %13s %13s %13s %13s %20s %18s", "---------", "-----------", "-----------", "-----------", "-----------", "-----------", "------------", "--------------"); do { @@ -1398,7 +1402,7 @@ gf_cli_defrag_volume_cbk (struct rpc_req *req, struct iovec *iov, status = cli_vol_task_status_str[status_rcd]; size_str = gf_uint64_2human_readable(size); cli_out ("%40s %16"PRIu64 " %13s" " %13"PRIu64 " %13"PRIu64 - " %13"PRIu64 " %14s %16.2f", node_uuid, files, + " %13"PRIu64 " %20s %18.2f", node_uuid, files, size_str, lookup, failures, skipped, status, elapsed); GF_FREE(size_str); @@ -1892,6 +1896,8 @@ xml_output: case GF_DEFRAG_STATUS_FAILED: status = "failed"; break; + default: + break; } size_str = gf_uint64_2human_readable(size); diff --git a/rpc/xdr/src/cli1-xdr.h b/rpc/xdr/src/cli1-xdr.h index 20787c494..10453bbb0 100644 --- a/rpc/xdr/src/cli1-xdr.h +++ b/rpc/xdr/src/cli1-xdr.h @@ -48,6 +48,10 @@ enum gf_defrag_status_t { GF_DEFRAG_STATUS_STOPPED = 2, GF_DEFRAG_STATUS_COMPLETE = 3, GF_DEFRAG_STATUS_FAILED = 4, + GF_DEFRAG_STATUS_LAYOUT_FIX_STARTED = 5, + GF_DEFRAG_STATUS_LAYOUT_FIX_STOPPED = 6, + GF_DEFRAG_STATUS_LAYOUT_FIX_COMPLETE = 7, + GF_DEFRAG_STATUS_LAYOUT_FIX_FAILED = 8, }; typedef enum gf_defrag_status_t gf_defrag_status_t; diff --git a/rpc/xdr/src/cli1-xdr.x b/rpc/xdr/src/cli1-xdr.x index d674030ec..8018e3034 100644 --- a/rpc/xdr/src/cli1-xdr.x +++ b/rpc/xdr/src/cli1-xdr.x @@ -11,7 +11,11 @@ GF_DEFRAG_STATUS_STARTED, GF_DEFRAG_STATUS_STOPPED, GF_DEFRAG_STATUS_COMPLETE, - GF_DEFRAG_STATUS_FAILED + GF_DEFRAG_STATUS_FAILED, + GF_DEFRAG_STATUS_LAYOUT_FIX_STARTED, + GF_DEFRAG_STATUS_LAYOUT_FIX_STOPPED, + GF_DEFRAG_STATUS_LAYOUT_FIX_COMPLETE, + GF_DEFRAG_STATUS_LAYOUT_FIX_FAILED } ; enum gf1_cluster_type { diff --git a/tests/bugs/bug-1004744.t b/tests/bugs/bug-1004744.t new file mode 100644 index 000000000..0290119ef --- /dev/null +++ b/tests/bugs/bug-1004744.t @@ -0,0 +1,48 @@ +#!/bin/bash + +#Test case: After a rebalance fix-layout, check if the rebalance status command +#displays the appropriate message at the CLI. + +. $(dirname $0)/../include.rc +. $(dirname $0)/../volume.rc + +cleanup; + +#Basic checks +TEST glusterd +TEST pidof glusterd +TEST $CLI volume info + +#Create a 2x1 distributed volume +TEST $CLI volume create $V0 $H0:$B0/${V0}{1,2}; +TEST $CLI volume start $V0 + +# Mount FUSE and create file/directory +TEST glusterfs -s $H0 --volfile-id $V0 $M0 +for i in `seq 1 10`; +do + mkdir $M0/dir_$i + echo file>$M0/dir_$i/file_$i + for j in `seq 1 100`; + do + mkdir $M0/dir_$i/dir_$j + echo file>$M0/dir_$i/dir_$j/file_$j + done +done + +#add 2 bricks +TEST $CLI volume add-brick $V0 $H0:$B0/${V0}{3,4}; + +#perform rebalance fix-layout +TEST $CLI volume rebalance $V0 fix-layout start + +EXPECT_WITHIN 1 "fix-layout in progress" rebalance_status_field $V0; + +EXPECT_WITHIN 20 "fix-layout completed" rebalance_status_field $V0; + +TEST umount $M0 +TEST $CLI volume stop $V0 +TEST $CLI volume delete $V0; +TEST ! $CLI volume info $V0; + +cleanup; diff --git a/tests/bugs/bug-853258.t b/tests/bugs/bug-853258.t index 79cb88099..0ca995551 100755 --- a/tests/bugs/bug-853258.t +++ b/tests/bugs/bug-853258.t @@ -20,7 +20,7 @@ EXPECT_WITHIN 15 'Started' volinfo_field $V0 'Status'; # Force assignment of initial ranges. TEST $CLI volume rebalance $V0 fix-layout start -EXPECT_WITHIN 15 "completed" rebalance_status_field $V0 +EXPECT_WITHIN 15 "fix-layout completed" rebalance_status_field $V0 # Get the original values. xattrs="" @@ -32,7 +32,7 @@ done TEST $CLI volume add-brick $V0 $H0:$B0/${V0}3 # Force assignment of initial ranges. TEST $CLI volume rebalance $V0 fix-layout start -EXPECT_WITHIN 15 "completed" rebalance_status_field $V0 +EXPECT_WITHIN 15 "fix-layout completed" rebalance_status_field $V0 for i in $(seq 0 3); do xattrs="$xattrs $(dht_get_layout $B0/${V0}$i)" diff --git a/tests/volume.rc b/tests/volume.rc index 470fe9a7c..987122420 100644 --- a/tests/volume.rc +++ b/tests/volume.rc @@ -27,7 +27,12 @@ function volume_option() } function rebalance_status_field { - $CLI volume rebalance $1 status | awk '{print $7}' | sed -n 3p + #The rebalance status can be upto 3 words, (ex:'fix-layout in progress'), hence the awk-print $7 thru $9. + #But if the status is less than 3 words, it also prints the next field i.e the run_time_in_secs.(ex:'completed 3.00'). + #So we trim the numbers out with `tr`. Finally remove the trailing white spaces with sed. What we get is one of the + #strings in the 'cli_vol_task_status_str' char array of cli-rpc-ops.c + + $CLI volume rebalance $1 status | awk '{print $7,$8,$9}' |sed -n 3p |tr -d '[^0-9+\.]'|sed 's/ *$//g' } function remove_brick_status_completed_field { diff --git a/xlators/cluster/dht/src/dht-common.h b/xlators/cluster/dht/src/dht-common.h index 6ba18339b..bdaa8d64d 100644 --- a/xlators/cluster/dht/src/dht-common.h +++ b/xlators/cluster/dht/src/dht-common.h @@ -212,6 +212,10 @@ enum gf_defrag_status_t { GF_DEFRAG_STATUS_STOPPED, GF_DEFRAG_STATUS_COMPLETE, GF_DEFRAG_STATUS_FAILED, + GF_DEFRAG_STATUS_LAYOUT_FIX_STARTED, + GF_DEFRAG_STATUS_LAYOUT_FIX_STOPPED, + GF_DEFRAG_STATUS_LAYOUT_FIX_COMPLETE, + GF_DEFRAG_STATUS_LAYOUT_FIX_FAILED, }; typedef enum gf_defrag_status_t gf_defrag_status_t; diff --git a/xlators/cluster/dht/src/dht-rebalance.c b/xlators/cluster/dht/src/dht-rebalance.c index 5300ff2fe..8c36b7a09 100644 --- a/xlators/cluster/dht/src/dht-rebalance.c +++ b/xlators/cluster/dht/src/dht-rebalance.c @@ -1760,6 +1760,8 @@ log: case GF_DEFRAG_STATUS_FAILED: status = "failed"; break; + default: + break; } gf_log (THIS->name, GF_LOG_INFO, "Rebalance is %s. Time taken is %.2f " diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c index 01f191640..c1c9ff75e 100644 --- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c +++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c @@ -3072,6 +3072,97 @@ out: return ret; } +static int +reassign_defrag_status (dict_t *dict, char *key, gf_defrag_status_t *status) +{ + int ret = 0; + + if (!*status) + return ret; + + switch (*status) { + case GF_DEFRAG_STATUS_STARTED: + *status = GF_DEFRAG_STATUS_LAYOUT_FIX_STARTED; + break; + + case GF_DEFRAG_STATUS_STOPPED: + *status = GF_DEFRAG_STATUS_LAYOUT_FIX_STOPPED; + break; + + case GF_DEFRAG_STATUS_COMPLETE: + *status = GF_DEFRAG_STATUS_LAYOUT_FIX_COMPLETE; + break; + + case GF_DEFRAG_STATUS_FAILED: + *status = GF_DEFRAG_STATUS_LAYOUT_FIX_FAILED; + break; + default: + break; + } + + ret = dict_set_int32(dict, key, *status); + if (ret) + gf_log (THIS->name, GF_LOG_WARNING, + "failed to reset defrag %s in dict", key); + + return ret; +} + +/* Check and reassign the defrag_status enum got from the rebalance process + * of all peers so that the rebalance-status CLI command can display if a + * full-rebalance or just a fix-layout was carried out. + */ +static int +glusterd_op_check_peer_defrag_status (dict_t *dict, int count) +{ + glusterd_volinfo_t *volinfo = NULL; + gf_defrag_status_t status = GF_DEFRAG_STATUS_NOT_STARTED; + char key[256] = {0,}; + char *volname = NULL; + int ret = -1; + int i = 1; + + ret = dict_get_str (dict, "volname", &volname); + if (ret) { + gf_log (THIS->name, GF_LOG_WARNING, "Unable to get volume name"); + goto out; + } + + ret = glusterd_volinfo_find (volname, &volinfo); + if (ret) { + gf_log (THIS->name, GF_LOG_WARNING, FMTSTR_CHECK_VOL_EXISTS, + volname); + goto out; + } + + if (volinfo->rebal.defrag_cmd != GF_DEFRAG_CMD_START_LAYOUT_FIX) { + /* Fix layout was not issued; we don't need to reassign + the status */ + ret = 0; + goto out; + } + + do { + memset (key, 0, 256); + snprintf (key, 256, "status-%d", i); + ret = dict_get_int32 (dict, key, (int32_t *)&status); + if (ret) { + gf_log (THIS->name, GF_LOG_WARNING, + "failed to get defrag %s", key); + goto out; + } + ret = reassign_defrag_status (dict, key, &status); + if (ret) + goto out; + i++; + } while (i <= count); + + ret = 0; +out: + return ret; + +} + /* This function is used to modify the op_ctx dict before sending it back * to cli. This is useful in situations like changing the peer uuids to * hostnames etc. @@ -3181,6 +3272,11 @@ glusterd_op_modify_op_ctx (glusterd_op_t op, void *ctx) if (ret) gf_log (this->name, GF_LOG_WARNING, "Failed uuid to hostname conversion"); + + ret = glusterd_op_check_peer_defrag_status (op_ctx, count); + if (ret) + gf_log (this->name, GF_LOG_ERROR, + "Failed to reset defrag status for fix-layout"); break; default: diff --git a/xlators/mgmt/glusterd/src/glusterd-rebalance.c b/xlators/mgmt/glusterd/src/glusterd-rebalance.c index 60dd9c19b..031de2c9b 100644 --- a/xlators/mgmt/glusterd/src/glusterd-rebalance.c +++ b/xlators/mgmt/glusterd/src/glusterd-rebalance.c @@ -146,8 +146,6 @@ __glusterd_defrag_notify (struct rpc_clnt *rpc, void *mydata, GF_DEFRAG_STATUS_STARTED) { volinfo->rebal.defrag_status = GF_DEFRAG_STATUS_FAILED; - } else { - volinfo->rebal.defrag_cmd = 0; } } @@ -219,6 +217,7 @@ glusterd_handle_defrag_start (glusterd_volinfo_t *volinfo, char *op_errstr, defrag->cmd = cmd; + volinfo->rebal.defrag_cmd = cmd; volinfo->rebal.op = op; LOCK_INIT (&defrag->lock); -- cgit