summaryrefslogtreecommitdiffstats
path: root/cli/src/cli-xml-output.c
diff options
context:
space:
mode:
Diffstat (limited to 'cli/src/cli-xml-output.c')
-rw-r--r--cli/src/cli-xml-output.c379
1 files changed, 343 insertions, 36 deletions
diff --git a/cli/src/cli-xml-output.c b/cli/src/cli-xml-output.c
index 543ea713d..d8884d44b 100644
--- a/cli/src/cli-xml-output.c
+++ b/cli/src/cli-xml-output.c
@@ -14,6 +14,12 @@
#include "compat.h"
#include "syscall.h"
+
+enum gf_task_types {
+ GF_TASK_TYPE_REBALANCE,
+ GF_TASK_TYPE_REMOVE_BRICK
+};
+
/*
* IMPORTANT NOTE:
* All exported functions in this file which use libxml need use a
@@ -1383,6 +1389,86 @@ out:
#if (HAVE_LIB_XML)
int
+cli_xml_output_remove_brick_task_params (xmlTextWriterPtr writer, dict_t *dict,
+ char *prefix)
+{
+ int ret = -1;
+ char key[1024] = {0,};
+ int count = 0;
+ int i = 0;
+ char *brick = NULL;
+
+ /* <params> */
+ ret = xmlTextWriterStartElement (writer, (xmlChar *)"params");
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ snprintf (key, sizeof (key), "%s.count", prefix);
+ ret = dict_get_int32 (dict, key, &count);
+ if (ret)
+ goto out;
+
+ for (i = 1; i <= count; i++) {
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.brick%d", prefix, i);
+ ret = dict_get_str (dict, key, &brick);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer,
+ (xmlChar *)"brick",
+ "%s", brick);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+ brick = NULL;
+ }
+
+ /* </param> */
+ ret = xmlTextWriterEndElement (writer);
+
+out:
+ gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
+int
+cli_xml_output_replace_brick_task_params (xmlTextWriterPtr writer, dict_t *dict,
+ char *prefix)
+{
+
+ int ret = -1;
+ char key[1024] = {0,};
+ char *brick = NULL;
+
+ /* <params> */
+ ret = xmlTextWriterStartElement (writer, (xmlChar *)"params");
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ snprintf (key, sizeof (key), "%s.src-brick", prefix);
+ ret = dict_get_str (dict, key, &brick);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"srcBrick",
+ "%s", brick);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.dst-brick", prefix);
+ ret = dict_get_str (dict, key, &brick);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"dstBrick",
+ "%s", brick);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+
+ /* </param> */
+ ret = xmlTextWriterEndElement (writer);
+
+out:
+ gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
+int
cli_xml_output_vol_status_tasks (cli_local_t *local, dict_t *dict) {
int ret = -1;
char *task_type = NULL;
@@ -1436,6 +1522,36 @@ cli_xml_output_vol_status_tasks (cli_local_t *local, dict_t *dict) {
"%d", status);
XML_RET_CHECK_AND_GOTO (ret, out);
+ if (!strcmp (task_type, "Replace brick")) {
+ if (status) {
+ status = GF_DEFRAG_STATUS_COMPLETE;
+ } else {
+ status = GF_DEFRAG_STATUS_STARTED;
+ }
+ }
+
+ ret = xmlTextWriterWriteFormatElement (local->writer,
+ (xmlChar *)"statusStr",
+ "%s",
+ cli_vol_task_status_str[status]);
+
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "task%d", i);
+ if (!strcmp (task_type, "Replace brick")) {
+ ret = cli_xml_output_replace_brick_task_params
+ (local->writer, dict, key);
+ if (ret)
+ goto out;
+ } else if (!strcmp (task_type, "Remove brick")) {
+ ret = cli_xml_output_remove_brick_task_params
+ (local->writer, dict, key);
+ if (ret)
+ goto out;
+ }
+
+
/* </task> */
ret = xmlTextWriterEndElement (local->writer);
XML_RET_CHECK_AND_GOTO (ret, out);
@@ -1444,11 +1560,40 @@ cli_xml_output_vol_status_tasks (cli_local_t *local, dict_t *dict) {
/* </tasks> */
ret = xmlTextWriterEndElement (local->writer);
-
out:
gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
return ret;
}
+
+int
+cli_xml_output_vol_status_tasks_detail (cli_local_t *local, dict_t *dict)
+{
+ int ret = -1;
+ char *volname = NULL;
+
+ /*<volume>*/
+ ret = xmlTextWriterStartElement (local->writer, (xmlChar *)"volume");
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ ret = dict_get_str (dict, "volname", &volname);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (local->writer,
+ (xmlChar *)"volName", "%s",
+ volname);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ ret = cli_xml_output_vol_status_tasks (local, dict);
+ if (ret)
+ goto out;
+
+ /* </volume> */
+ ret = xmlTextWriterEndElement (local->writer);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+out:
+ return ret;
+}
#endif
int
@@ -1568,7 +1713,6 @@ cli_xml_output_vol_status (cli_local_t *local, dict_t *dict)
goto out;
}
break;
-
default:
break;
@@ -1578,7 +1722,11 @@ cli_xml_output_vol_status (cli_local_t *local, dict_t *dict)
XML_RET_CHECK_AND_GOTO (ret, out);
}
- if ((cmd & GF_CLI_STATUS_MASK) == GF_CLI_STATUS_NONE) {
+ /* Tasks are only present when a normal volume status call is done on a
+ * single volume or on all volumes
+ */
+ if (((cmd & GF_CLI_STATUS_MASK) == GF_CLI_STATUS_NONE) &&
+ (cmd & (GF_CLI_STATUS_VOL|GF_CLI_STATUS_ALL))) {
ret = cli_xml_output_vol_status_tasks (local, dict);
if (ret)
goto out;
@@ -2337,6 +2485,7 @@ cli_xml_output_vol_info (cli_local_t *local, dict_t *dict)
int count = 0;
char *volname = NULL;
char *volume_id = NULL;
+ char *uuid = NULL;
int type = 0;
int status = 0;
int brick_count = 0;
@@ -2348,7 +2497,9 @@ cli_xml_output_vol_info (cli_local_t *local, dict_t *dict)
char key[1024] = {0,};
int i = 0;
int j = 1;
-
+ char *caps = NULL;
+ int k __attribute__((unused)) = 0;
+ char *snap_volume = NULL;
ret = dict_get_int32 (dict, "count", &count);
if (ret)
@@ -2390,6 +2541,18 @@ cli_xml_output_vol_info (cli_local_t *local, dict_t *dict)
"%d", status);
XML_RET_CHECK_AND_GOTO (ret, out);
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "volume%d.snap_volume", i);
+ ret = dict_get_str (dict, key, &snap_volume);
+ if (ret)
+ goto out;
+ if (snap_volume) {
+ ret = xmlTextWriterWriteFormatElement (local->writer,
+ (xmlChar *)"snapVol",
+ "%s", snap_volume);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+ }
+
ret =xmlTextWriterWriteFormatElement
(local->writer, (xmlChar *)"statusStr", "%s",
cli_vol_status_str[status]);
@@ -2464,20 +2627,95 @@ cli_xml_output_vol_info (cli_local_t *local, dict_t *dict)
"%d", transport);
XML_RET_CHECK_AND_GOTO (ret, out);
+#ifdef HAVE_BD_XLATOR
+ /* <xlators> */
+ ret = xmlTextWriterStartElement (local->writer,
+ (xmlChar *)"xlators");
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ for (k = 0; ; k++) {
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key),"volume%d.xlator%d", i, k);
+ ret = dict_get_str (dict, key, &caps);
+ if (ret)
+ break;
+
+ /* <xlator> */
+ ret = xmlTextWriterStartElement (local->writer,
+ (xmlChar *)"xlator");
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ ret = xmlTextWriterWriteFormatElement
+ (local->writer, (xmlChar *)"name", "%s", caps);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ /* <capabilities> */
+ ret = xmlTextWriterStartElement (local->writer,
+ (xmlChar *)
+ "capabilities");
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ j = 0;
+ for (j = 0; ;j++) {
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key),
+ "volume%d.xlator%d.caps%d", i, k, j);
+ ret = dict_get_str (dict, key, &caps);
+ if (ret)
+ break;
+ ret = xmlTextWriterWriteFormatElement
+ (local->writer, (xmlChar *)"capability",
+ "%s", caps);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+ }
+ /* </capabilities> */
+ ret = xmlTextWriterEndElement (local->writer);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+ /* </xlator> */
+ ret = xmlTextWriterEndElement (local->writer);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+ }
+ ret = xmlTextWriterFullEndElement (local->writer);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+ /* </xlators> */
+#else
+ caps = 0; /* Avoid compiler warnings when BD not enabled */
+#endif
+ j = 1;
+
/* <bricks> */
ret = xmlTextWriterStartElement (local->writer,
(xmlChar *)"bricks");
XML_RET_CHECK_AND_GOTO (ret, out);
while (j <= brick_count) {
+ ret = xmlTextWriterStartElement
+ (local->writer, (xmlChar *)"brick");
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "volume%d.brick%d.uuid",
+ i, j);
+ ret = dict_get_str (dict, key, &uuid);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatAttribute
+ (local->writer, (xmlChar *)"uuid", "%s",
+ uuid);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
memset (key, 0, sizeof (key));
snprintf (key, sizeof (key), "volume%d.brick%d", i, j);
ret = dict_get_str (dict, key, &brick);
if (ret)
goto out;
- ret = xmlTextWriterWriteFormatElement
- (local->writer, (xmlChar *)"brick", "%s",
- brick);
+ ret = xmlTextWriterWriteFormatString
+ (local->writer, "%s", brick);
XML_RET_CHECK_AND_GOTO (ret, out);
+
+ /* </brick> */
+ ret = xmlTextWriterEndElement (local->writer);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
j++;
}
/* </bricks> */
@@ -2495,12 +2733,12 @@ cli_xml_output_vol_info (cli_local_t *local, dict_t *dict)
ret = xmlTextWriterEndElement (local->writer);
XML_RET_CHECK_AND_GOTO (ret, out);
}
- GF_FREE (local->get_vol.volname);
+
if (volname) {
+ GF_FREE (local->get_vol.volname);
local->get_vol.volname = gf_strdup (volname);
local->vol_count += count;
}
-
out:
gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
return ret;
@@ -2737,7 +2975,6 @@ cli_xml_output_peer_status (dict_t *dict, int op_ret, int op_errno,
int connected = 0;
int state_id = 0;
char *state_str = NULL;
- int port = 0;
int i = 1;
char key[1024] = {0,};
@@ -2801,34 +3038,23 @@ cli_xml_output_peer_status (dict_t *dict, int op_ret, int op_errno,
memset (key, 0, sizeof (key));
snprintf (key, sizeof (key), "friend%d.stateId", i);
ret = dict_get_int32 (dict, key, &state_id);
- if (ret)
- goto out;
+ if (!ret) {
+ /* ignore */
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *)"state",
- "%d", state_id);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ ret = xmlTextWriterWriteFormatElement (writer,
+ (xmlChar *)"state", "%d", state_id);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+ }
memset (key, 0, sizeof (key));
snprintf (key, sizeof (key), "friend%d.state", i);
ret = dict_get_str (dict, key, &state_str);
- if (ret)
- goto out;
-
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *)"stateStr",
- "%s", state_str);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ if (!ret) {
+ /* ignore */
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "friend%d.port", i);
- ret = dict_get_int32 (dict, key, &port);
- if (port != 0) {
- ret = xmlTextWriterWriteFormatElement
- (writer, (xmlChar *)"port", "%d", port);
+ ret = xmlTextWriterWriteFormatElement (writer,
+ (xmlChar *)"stateStr", "%s", state_str);
XML_RET_CHECK_AND_GOTO (ret, out);
-
- port = 0;
}
/* </peer> */
@@ -2856,22 +3082,29 @@ out:
#if (HAVE_LIB_XML)
/* Used for rebalance stop/status, remove-brick status */
int
-cli_xml_output_vol_rebalance_status (xmlTextWriterPtr writer, dict_t *dict)
+cli_xml_output_vol_rebalance_status (xmlTextWriterPtr writer, dict_t *dict,
+ enum gf_task_types task_type)
{
int ret = -1;
int count = 0;
char *node_name = NULL;
+ char *node_uuid = NULL;
uint64_t files = 0;
uint64_t size = 0;
uint64_t lookups = 0;
int status_rcd = 0;
uint64_t failures = 0;
+ uint64_t skipped = 0;
uint64_t total_files = 0;
uint64_t total_size = 0;
uint64_t total_lookups = 0;
uint64_t total_failures = 0;
+ uint64_t total_skipped = 0;
char key[1024] = {0,};
int i = 0;
+ int overall_status = -1;
+ double elapsed = 0;
+ double overall_elapsed = 0;
if (!dict) {
ret = 0;
@@ -2893,13 +3126,22 @@ cli_xml_output_vol_rebalance_status (xmlTextWriterPtr writer, dict_t *dict)
XML_RET_CHECK_AND_GOTO (ret, out);
memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "node-uuid-%d", i);
+ snprintf (key, sizeof (key), "node-name-%d", i);
ret = dict_get_str (dict, key, &node_name);
if (ret)
goto out;
ret = xmlTextWriterWriteFormatElement (writer,
(xmlChar *)"nodeName",
"%s", node_name);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "node-uuid-%d", i);
+ ret = dict_get_str (dict, key, &node_uuid);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer,
+ (xmlChar *)"id",
+ "%s", node_uuid);
XML_RET_CHECK_AND_GOTO (ret, out);
memset (key, 0, sizeof (key));
@@ -2946,6 +3188,27 @@ cli_xml_output_vol_rebalance_status (xmlTextWriterPtr writer, dict_t *dict)
"%"PRIu64, failures);
XML_RET_CHECK_AND_GOTO (ret, out);
+ /* skipped-%d is not available for remove brick in dict,
+ so using failures as skipped count in case of remove-brick
+ similar to logic used in CLI(non xml output) */
+ if (task_type == GF_TASK_TYPE_REBALANCE) {
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "skipped-%d", i);
+ }
+ else {
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "failures-%d", i);
+ }
+
+ ret = dict_get_uint64 (dict, key, &skipped);
+ if (ret)
+ goto out;
+ total_skipped += skipped;
+ ret = xmlTextWriterWriteFormatElement (writer,
+ (xmlChar *)"skipped",
+ "%"PRIu64, skipped);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
memset (key, 0, sizeof (key));
snprintf (key, sizeof (key), "status-%d", i);
ret = dict_get_int32 (dict, key, &status_rcd);
@@ -2956,6 +3219,33 @@ cli_xml_output_vol_rebalance_status (xmlTextWriterPtr writer, dict_t *dict)
"%d", status_rcd);
XML_RET_CHECK_AND_GOTO (ret, out);
+ ret = xmlTextWriterWriteFormatElement (writer,
+ (xmlChar *)"statusStr",
+ "%s",
+ cli_vol_task_status_str[status_rcd]);
+
+ memset (key, 0, 256);
+ snprintf (key, 256, "run-time-%d", i);
+ ret = dict_get_double (dict, key, &elapsed);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement (writer,
+ (xmlChar *)"runtime",
+ "%.2f", elapsed);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ if (elapsed > overall_elapsed) {
+ overall_elapsed = elapsed;
+ }
+
+ if (-1 == overall_status)
+ overall_status = status_rcd;
+ else if ((GF_DEFRAG_STATUS_COMPLETE == overall_status ||
+ status_rcd > overall_status) &&
+ (status_rcd != GF_DEFRAG_STATUS_COMPLETE))
+ overall_status = status_rcd;
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
/* </node> */
ret = xmlTextWriterEndElement (writer);
XML_RET_CHECK_AND_GOTO (ret, out);
@@ -2982,7 +3272,22 @@ cli_xml_output_vol_rebalance_status (xmlTextWriterPtr writer, dict_t *dict)
"%"PRIu64, total_failures);
XML_RET_CHECK_AND_GOTO (ret, out);
- // TODO : Aggregate status
+ ret = xmlTextWriterWriteFormatElement (writer,(xmlChar *)"skipped",
+ "%"PRIu64, total_skipped);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ ret = xmlTextWriterWriteFormatElement (writer,(xmlChar *)"status",
+ "%d", overall_status);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ ret = xmlTextWriterWriteFormatElement (writer,(xmlChar *)"statusStr",
+ "%s",
+ cli_vol_task_status_str[overall_status]);
+ XML_RET_CHECK_AND_GOTO (ret, out);
+
+ ret = xmlTextWriterWriteFormatElement (writer,(xmlChar *)"runtime",
+ "%.2f", overall_elapsed);
+ XML_RET_CHECK_AND_GOTO (ret, out);
/* </aggregate> */
ret = xmlTextWriterEndElement (writer);
@@ -3029,7 +3334,8 @@ cli_xml_output_vol_rebalance (gf_cli_defrag_type op, dict_t *dict, int op_ret,
XML_RET_CHECK_AND_GOTO (ret, out);
if ((GF_DEFRAG_CMD_STOP == op) || (GF_DEFRAG_CMD_STATUS == op)) {
- ret = cli_xml_output_vol_rebalance_status (writer, dict);
+ ret = cli_xml_output_vol_rebalance_status (writer, dict,
+ GF_TASK_TYPE_REBALANCE);
if (ret)
goto out;
}
@@ -3080,7 +3386,8 @@ cli_xml_output_vol_remove_brick (gf_boolean_t status_op, dict_t *dict,
}
if (status_op) {
- ret = cli_xml_output_vol_rebalance_status (writer, dict);
+ ret = cli_xml_output_vol_rebalance_status (writer, dict,
+ GF_TASK_TYPE_REMOVE_BRICK);
if (ret)
goto out;
}