summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMohammed Rafi KC <rkavunga@redhat.com>2015-05-02 17:31:07 +0530
committerVijay Bellur <vbellur@redhat.com>2015-05-09 10:26:36 -0700
commitec055e1e6908ac829efc103deb548cc0a774cf23 (patch)
treef16809b02ecf9c4cc17785b2a4a8e705f8101a98
parentc5866f0575216727e38af3500b32e81e1efc72b7 (diff)
cli/tiering: Enhance cli output for tiering
back port of http://review.gluster.org/10284 Fix for handling cli output for attach-tier and detach-tier >Change-Id: I4d17f4b09612754fe1b8cec6c2e14927029b9678 >BUG: 1211562 >Signed-off-by: Mohammed Rafi KC <rkavunga@redhat.com> >Reviewed-on: http://review.gluster.org/10284 >Reviewed-by: Dan Lambright <dlambrig@redhat.com> >Tested-by: Gluster Build System <jenkins@build.gluster.com> >Tested-by: NetBSD Build System >Reviewed-by: Vijay Bellur <vbellur@redhat.com> Change-Id: Ic30c8f0a104d89bf98f5d0069937a34674ee3f2d BUG: 1220052 Signed-off-by: Mohammed Rafi KC <rkavunga@redhat.com> Reviewed-on: http://review.gluster.org/10713 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Vijay Bellur <vbellur@redhat.com>
-rw-r--r--cli/src/cli-cmd-parser.c2
-rw-r--r--cli/src/cli-cmd-volume.c2
-rw-r--r--cli/src/cli-rpc-ops.c378
-rw-r--r--cli/src/cli-xml-output.c10
-rw-r--r--cli/src/cli.h6
-rw-r--r--rpc/xdr/src/cli1-xdr.x3
-rwxr-xr-xtests/basic/tier/tier.t2
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-brick-ops.c4
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-rebalance.c7
9 files changed, 394 insertions, 20 deletions
diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c
index 310c5f06033..2ca5948d552 100644
--- a/cli/src/cli-cmd-parser.c
+++ b/cli/src/cli-cmd-parser.c
@@ -1696,7 +1696,7 @@ cli_cmd_volume_detach_tier_parse (const char **words, int wordcount,
else
command = GF_OP_CMD_DETACH_COMMIT;
} else if (!strcmp(word, "stop"))
- command = GF_DEFRAG_CMD_STOP_DETACH_TIER;
+ command = GF_OP_CMD_STOP_DETACH_TIER;
else if (!strcmp(word, "status"))
command = GF_DEFRAG_CMD_STATUS;
else
diff --git a/cli/src/cli-cmd-volume.c b/cli/src/cli-cmd-volume.c
index 7b2fb079e50..ecd838d52c0 100644
--- a/cli/src/cli-cmd-volume.c
+++ b/cli/src/cli-cmd-volume.c
@@ -939,7 +939,7 @@ cli_cmd_volume_detach_tier_cbk (struct cli_state *state,
if (ret)
goto out;
- ret = dict_set_int32 (options, "count", 1);
+ ret = dict_set_int32 (options, "count", 0);
if (ret)
goto out;
diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c
index 932fe5f8cb7..ce6f4672d92 100644
--- a/cli/src/cli-rpc-ops.c
+++ b/cli/src/cli-rpc-ops.c
@@ -2028,6 +2028,302 @@ out:
}
int
+gf_cli_attach_tier_cbk (struct rpc_req *req, struct iovec *iov,
+ int count, void *myframe)
+{
+ gf_cli_rsp rsp = {0,};
+ int ret = -1;
+ char msg[1024] = {0,};
+
+ if (-1 == req->rpc_status) {
+ goto out;
+ }
+
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
+ if (ret < 0) {
+ gf_log (((call_frame_t *) myframe)->this->name, GF_LOG_ERROR,
+ "Failed to decode xdr response");
+ goto out;
+ }
+
+
+ gf_log ("cli", GF_LOG_INFO, "Received resp to attach tier");
+
+ if (rsp.op_ret && strcmp (rsp.op_errstr, ""))
+ snprintf (msg, sizeof (msg), "%s", rsp.op_errstr);
+ else
+ snprintf (msg, sizeof (msg), "Attach tier %s",
+ (rsp.op_ret) ? "unsuccessful" : "successful");
+
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ ret = cli_xml_output_str ("volAttachTier", msg, rsp.op_ret,
+ rsp.op_errno, rsp.op_errstr);
+ if (ret)
+ gf_log ("cli", GF_LOG_ERROR,
+ "Error outputting to xml");
+ goto out;
+ }
+
+ if (rsp.op_ret)
+ cli_err ("volume attach-tier: failed: %s", msg);
+ else
+ cli_out ("volume attach-tier: success");
+ ret = rsp.op_ret;
+
+out:
+ cli_cmd_broadcast_response (ret);
+ free (rsp.dict.dict_val);
+ free (rsp.op_errstr);
+ return ret;
+}
+
+int
+gf_cli_detach_tier_cbk (struct rpc_req *req, struct iovec *iov,
+ int count, void *myframe)
+{
+
+ gf_cli_rsp rsp = {0,};
+ int ret = -1;
+ char msg[1024] = {0,};
+ gf1_op_commands cmd = GF_OP_CMD_NONE;
+ char *cmd_str = "unknown";
+ cli_local_t *local = NULL;
+ call_frame_t *frame = NULL;
+ char *task_id_str = NULL;
+ dict_t *rsp_dict = NULL;
+
+ if (-1 == req->rpc_status) {
+ goto out;
+ }
+
+ frame = myframe;
+ local = frame->local;
+
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
+ if (ret < 0) {
+ gf_log (frame->this->name, GF_LOG_ERROR,
+ "Failed to decode xdr response");
+ goto out;
+ }
+
+ ret = dict_get_int32 (local->dict, "command", (int32_t *)&cmd);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "failed to get command");
+ goto out;
+ }
+
+ if (rsp.dict.dict_len) {
+ rsp_dict = dict_new ();
+ if (!rsp_dict) {
+ ret = -1;
+ goto out;
+ }
+
+ ret = dict_unserialize (rsp.dict.dict_val, rsp.dict.dict_len,
+ &rsp_dict);
+ if (ret) {
+ gf_log ("cli", GF_LOG_ERROR,
+ "Failed to unserialize rsp_dict");
+ goto out;
+ }
+ }
+
+ switch (cmd) {
+ case GF_OP_CMD_DETACH_START:
+ cmd_str = "start";
+
+ ret = dict_get_str (rsp_dict, GF_REMOVE_BRICK_TID_KEY,
+ &task_id_str);
+ if (ret) {
+ gf_log ("cli", GF_LOG_ERROR,
+ "remove-brick-id is not present in dict");
+ }
+ break;
+ case GF_OP_CMD_DETACH_COMMIT:
+ cmd_str = "commit";
+ break;
+ case GF_OP_CMD_DETACH_COMMIT_FORCE:
+ cmd_str = "commit force";
+ break;
+ default:
+ cmd_str = "unknown";
+ break;
+ }
+
+ gf_log ("cli", GF_LOG_INFO, "Received resp to detach-tier");
+
+ if (rsp.op_ret && strcmp (rsp.op_errstr, ""))
+ snprintf (msg, sizeof (msg), "%s", rsp.op_errstr);
+ else
+ snprintf (msg, sizeof (msg), "Detach tier %s %s", cmd_str,
+ (rsp.op_ret) ? "unsuccessful" : "successful");
+
+
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ ret = cli_xml_output_vol_remove_brick_detach_tier (
+ _gf_false, rsp_dict,
+ rsp.op_ret, rsp.op_errno,
+ msg, "volDetachTier");
+
+ if (ret)
+ gf_log ("cli", GF_LOG_ERROR,
+ "Error outputting to xml");
+ goto out;
+ }
+
+ if (rsp.op_ret) {
+ cli_err ("volume detach-tier %s: failed: %s", cmd_str,
+ msg);
+ } else {
+ cli_out ("volume detach-tier %s: success", cmd_str);
+ if (GF_OP_CMD_DETACH_START == cmd && task_id_str != NULL)
+ cli_out ("ID: %s", task_id_str);
+ if (GF_OP_CMD_DETACH_COMMIT == cmd)
+ cli_out ("Check the detached bricks to ensure all files"
+ " are migrated.\nIf files with data are "
+ "found on the brick path, copy them via a "
+ "gluster mount point before re-purposing the "
+ "removed brick. ");
+ }
+
+ ret = rsp.op_ret;
+
+out:
+ cli_cmd_broadcast_response (ret);
+ free (rsp.dict.dict_val);
+ free (rsp.op_errstr);
+
+ return ret;
+}
+
+int
+gf_cli_detach_tier_status_cbk (struct rpc_req *req, struct iovec *iov,
+ int count, void *myframe)
+{
+ gf_cli_rsp rsp = {0,};
+ int ret = -1;
+ dict_t *dict = NULL;
+ char msg[1024] = {0,};
+ int32_t command = 0;
+ gf1_op_commands cmd = GF_OP_CMD_NONE;
+ cli_local_t *local = NULL;
+ call_frame_t *frame = NULL;
+ char *cmd_str = "unknown";
+
+ if (-1 == req->rpc_status) {
+ goto out;
+ }
+
+ frame = myframe;
+
+ ret = xdr_to_generic (*iov, &rsp,
+ (xdrproc_t)xdr_gf_cli_rsp);
+ if (ret < 0) {
+ gf_log (frame->this->name, GF_LOG_ERROR,
+ "Failed to decode xdr response");
+ goto out;
+ }
+
+ if (frame)
+ local = frame->local;
+ ret = dict_get_int32 (local->dict, "command", &command);
+ if (ret)
+ goto out;
+ cmd = command;
+
+ switch (cmd) {
+ case GF_OP_CMD_STOP_DETACH_TIER:
+ cmd_str = "stop";
+ break;
+ case GF_OP_CMD_STATUS:
+ cmd_str = "status";
+ break;
+ default:
+ break;
+ }
+
+ ret = rsp.op_ret;
+ if (rsp.op_ret == -1) {
+ if (strcmp (rsp.op_errstr, ""))
+ snprintf (msg, sizeof (msg), "volume detach-tier %s: "
+ "failed: %s", cmd_str, rsp.op_errstr);
+ else
+ snprintf (msg, sizeof (msg), "volume detach-tier %s: "
+ "failed", cmd_str);
+
+ if (global_state->mode & GLUSTER_MODE_XML)
+ goto xml_output;
+
+ cli_err ("%s", msg);
+ goto out;
+ }
+
+ if (rsp.dict.dict_len) {
+ /* Unserialize the dictionary */
+ dict = dict_new ();
+
+ ret = dict_unserialize (rsp.dict.dict_val,
+ rsp.dict.dict_len,
+ &dict);
+ if (ret < 0) {
+ strncpy (msg, "failed to unserialize req-buffer to "
+ "dictionary", sizeof (msg));
+
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ rsp.op_ret = -1;
+ goto xml_output;
+ }
+
+ gf_log ("cli", GF_LOG_ERROR, "%s", msg);
+ goto out;
+ }
+ }
+xml_output:
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ if (strcmp (rsp.op_errstr, "")) {
+ ret = cli_xml_output_vol_remove_brick_detach_tier (
+ _gf_true, dict,
+ rsp.op_ret,
+ rsp.op_errno,
+ rsp.op_errstr,
+ "volDetachTier");
+ } else {
+ ret = cli_xml_output_vol_remove_brick_detach_tier
+ (_gf_true, dict,
+ rsp.op_ret,
+ rsp.op_errno,
+ msg,
+ "volDetachTier");
+ }
+ goto out;
+ }
+
+ ret = gf_cli_print_rebalance_status (dict, GF_TASK_TYPE_REMOVE_BRICK);
+ if (ret) {
+ gf_log ("cli", GF_LOG_ERROR, "Failed to print remove-brick "
+ "rebalance status");
+ goto out;
+ }
+
+ if ((cmd == GF_OP_CMD_STOP_DETACH_TIER) && (rsp.op_ret == 0)) {
+ cli_out ("'detach-tier' process may be in the middle of a "
+ "file migration.\nThe process will be fully stopped "
+ "once the migration of the file is complete.\nPlease "
+ "check detach-tier process for completion before "
+ "doing any further brick related tasks on the "
+ "volume.");
+ }
+
+out:
+ free (rsp.dict.dict_val); /* malloced by xdr */
+ if (dict)
+ dict_unref (dict);
+ cli_cmd_broadcast_response (ret);
+ return ret;
+}
+
+
+int
gf_cli_add_brick_cbk (struct rpc_req *req, struct iovec *iov,
int count, void *myframe)
{
@@ -2163,15 +2459,19 @@ gf_cli3_remove_brick_status_cbk (struct rpc_req *req, struct iovec *iov,
xml_output:
if (global_state->mode & GLUSTER_MODE_XML) {
if (strcmp (rsp.op_errstr, "")) {
- ret = cli_xml_output_vol_remove_brick (_gf_true, dict,
+ ret = cli_xml_output_vol_remove_brick_detach_tier (
+ _gf_true, dict,
rsp.op_ret,
rsp.op_errno,
- rsp.op_errstr);
+ rsp.op_errstr,
+ "volRemoveBrick");
} else {
- ret = cli_xml_output_vol_remove_brick (_gf_true, dict,
+ ret = cli_xml_output_vol_remove_brick_detach_tier (
+ _gf_true, dict,
rsp.op_ret,
rsp.op_errno,
- msg);
+ msg,
+ "volRemoveBrick");
}
goto out;
}
@@ -2282,9 +2582,10 @@ gf_cli_remove_brick_cbk (struct rpc_req *req, struct iovec *iov,
(rsp.op_ret) ? "unsuccessful": "successful");
if (global_state->mode & GLUSTER_MODE_XML) {
- ret = cli_xml_output_vol_remove_brick (_gf_false, rsp_dict,
+ ret = cli_xml_output_vol_remove_brick_detach_tier (
+ _gf_false, rsp_dict,
rsp.op_ret, rsp.op_errno,
- msg);
+ msg, "volRemoveBrick");
if (ret)
gf_log ("cli", GF_LOG_ERROR,
"Error outputting to xml");
@@ -3828,7 +4129,7 @@ gf_cli_attach_tier (call_frame_t *frame, xlator_t *this,
if (ret)
goto out;
- ret = cli_to_glusterd (&req, frame, gf_cli_add_brick_cbk,
+ ret = cli_to_glusterd (&req, frame, gf_cli_attach_tier_cbk,
(xdrproc_t) xdr_gf_cli_req, dict,
GLUSTER_CLI_ATTACH_TIER, this,
cli_rpc_prog, NULL);
@@ -3843,10 +4144,71 @@ int32_t
gf_cli_detach_tier (call_frame_t *frame, xlator_t *this,
void *data)
{
- return gf_cli_remove_brick(frame, this, data);
+ gf_cli_req req = { {0,} };
+ gf_cli_req status_req = { {0,} };
+ int ret = 0;
+ dict_t *dict = NULL;
+ int32_t command = 0;
+ char *volname = NULL;
+ int32_t cmd = 0;
+
+ if (!frame || !this || !data) {
+ ret = -1;
+ goto out;
+ }
+
+ dict = data;
+
+ ret = dict_get_str (dict, "volname", &volname);
+ if (ret)
+ goto out;
+
+ ret = dict_get_int32 (dict, "command", &command);
+ if (ret)
+ goto out;
+
+ if ((command != GF_OP_CMD_STATUS) &&
+ (command != GF_DEFRAG_CMD_STOP_DETACH_TIER)) {
+
+
+ ret = cli_to_glusterd (&req, frame, gf_cli_detach_tier_cbk,
+ (xdrproc_t) xdr_gf_cli_req, dict,
+ GLUSTER_CLI_REMOVE_BRICK, this,
+ cli_rpc_prog, NULL);
+ } else {
+ /* Need rebalance status to be sent :-) */
+ if (command == GF_OP_CMD_STATUS)
+ cmd |= GF_DEFRAG_CMD_STATUS;
+ else
+ cmd |= GF_DEFRAG_CMD_STOP;
+
+ ret = dict_set_int32 (dict, "rebalance-command", (int32_t) cmd);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Failed to set dict");
+ goto out;
+ }
+
+ ret = cli_to_glusterd (&status_req, frame,
+ gf_cli_detach_tier_status_cbk,
+ (xdrproc_t) xdr_gf_cli_req, dict,
+ GLUSTER_CLI_DEFRAG_VOLUME, this,
+ cli_rpc_prog, NULL);
+
+ }
+
+out:
+ gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
+
+ GF_FREE (req.dict.dict_val);
+
+ GF_FREE (status_req.dict.dict_val);
+
+ return ret;
}
+
int32_t
gf_cli_remove_brick (call_frame_t *frame, xlator_t *this,
void *data)
diff --git a/cli/src/cli-xml-output.c b/cli/src/cli-xml-output.c
index f9013ed2726..d41aebc8cad 100644
--- a/cli/src/cli-xml-output.c
+++ b/cli/src/cli-xml-output.c
@@ -3371,8 +3371,10 @@ out:
}
int
-cli_xml_output_vol_remove_brick (gf_boolean_t status_op, dict_t *dict,
- int op_ret, int op_errno, char *op_errstr)
+cli_xml_output_vol_remove_brick_detach_tier (gf_boolean_t status_op,
+ dict_t *dict, int op_ret,
+ int op_errno, char *op_errstr,
+ const char *op)
{
#if (HAVE_LIB_XML)
int ret = -1;
@@ -3388,8 +3390,7 @@ cli_xml_output_vol_remove_brick (gf_boolean_t status_op, dict_t *dict,
if (ret)
goto out;
- /* <volRemoveBrick> */
- ret = xmlTextWriterStartElement (writer, (xmlChar *)"volRemoveBrick");
+ ret = xmlTextWriterStartElement (writer, (xmlChar *) op);
XML_RET_CHECK_AND_GOTO (ret, out);
ret = dict_get_str (dict, GF_REMOVE_BRICK_TID_KEY, &task_id_str);
@@ -3407,7 +3408,6 @@ cli_xml_output_vol_remove_brick (gf_boolean_t status_op, dict_t *dict,
goto out;
}
- /* </volRemoveBrick> */
ret = xmlTextWriterEndElement (writer);
XML_RET_CHECK_AND_GOTO (ret, out);
diff --git a/cli/src/cli.h b/cli/src/cli.h
index 3da58dd22d8..c9283b5b875 100644
--- a/cli/src/cli.h
+++ b/cli/src/cli.h
@@ -403,8 +403,10 @@ cli_xml_output_vol_rebalance (gf_cli_defrag_type op, dict_t *dict, int op_ret,
int op_errno, char *op_errstr);
int
-cli_xml_output_vol_remove_brick (gf_boolean_t status_op, dict_t *dict,
- int op_ret, int op_errno, char *op_errstr);
+cli_xml_output_vol_remove_brick_detach_tier (gf_boolean_t status_op,
+ dict_t *dict, int op_ret,
+ int op_errno, char *op_errstr,
+ const char *op);
int
cli_xml_output_vol_replace_brick (char *op, dict_t *dict, int op_ret,
diff --git a/rpc/xdr/src/cli1-xdr.x b/rpc/xdr/src/cli1-xdr.x
index cdf8e725788..0d5d3cc360c 100644
--- a/rpc/xdr/src/cli1-xdr.x
+++ b/rpc/xdr/src/cli1-xdr.x
@@ -52,7 +52,8 @@ enum gf_bitrot_type {
GF_OP_CMD_COMMIT_FORCE,
GF_OP_CMD_DETACH_START,
GF_OP_CMD_DETACH_COMMIT,
- GF_OP_CMD_DETACH_COMMIT_FORCE
+ GF_OP_CMD_DETACH_COMMIT_FORCE,
+ GF_OP_CMD_STOP_DETACH_TIER
};
enum gf_quota_type {
diff --git a/tests/basic/tier/tier.t b/tests/basic/tier/tier.t
index fe15395cf4b..81abc5779ab 100755
--- a/tests/basic/tier/tier.t
+++ b/tests/basic/tier/tier.t
@@ -122,7 +122,7 @@ TEST $CLI volume rebalance $V0 tier status
TEST $CLI volume detach-tier $V0 start
-TEST $CLI volume detach-tier $V0 commit
+TEST $CLI volume detach-tier $V0 commit force
EXPECT "0" file_on_slow_tier d1/data.txt
diff --git a/xlators/mgmt/glusterd/src/glusterd-brick-ops.c b/xlators/mgmt/glusterd/src/glusterd-brick-ops.c
index cffabfe34e2..6ed65976aea 100644
--- a/xlators/mgmt/glusterd/src/glusterd-brick-ops.c
+++ b/xlators/mgmt/glusterd/src/glusterd-brick-ops.c
@@ -1671,10 +1671,12 @@ glusterd_op_stage_remove_brick (dict_t *dict, char **op_errstr)
}
case GF_OP_CMD_STOP:
+ case GF_OP_CMD_STOP_DETACH_TIER:
ret = 0;
break;
case GF_OP_CMD_COMMIT:
+ case GF_OP_CMD_DETACH_COMMIT:
if (volinfo->decommission_in_progress) {
errstr = gf_strdup ("use 'force' option as migration "
"is in progress");
@@ -1724,7 +1726,6 @@ glusterd_op_stage_remove_brick (dict_t *dict, char **op_errstr)
break;
- case GF_OP_CMD_DETACH_COMMIT:
case GF_OP_CMD_DETACH_COMMIT_FORCE:
case GF_OP_CMD_COMMIT_FORCE:
break;
@@ -2014,6 +2015,7 @@ glusterd_op_remove_brick (dict_t *dict, char **op_errstr)
goto out;
case GF_OP_CMD_STOP:
+ case GF_OP_CMD_STOP_DETACH_TIER:
{
/* Fall back to the old volume file */
cds_list_for_each_entry_safe (brickinfo, tmp, &volinfo->bricks,
diff --git a/xlators/mgmt/glusterd/src/glusterd-rebalance.c b/xlators/mgmt/glusterd/src/glusterd-rebalance.c
index 84d9210a105..48d9a706042 100644
--- a/xlators/mgmt/glusterd/src/glusterd-rebalance.c
+++ b/xlators/mgmt/glusterd/src/glusterd-rebalance.c
@@ -681,6 +681,13 @@ glusterd_op_stage_rebalance (dict_t *dict, char **op_errstr)
goto out;
}
}
+ if ((strstr(cmd_str, "detach-tier") != NULL) &&
+ (volinfo->rebal.op != GD_OP_REMOVE_BRICK)) {
+ snprintf (msg, sizeof(msg), "Detach-tier not started.");
+ ret = -1;
+ goto out;
+ }
+
break;
default:
break;