diff options
Diffstat (limited to 'cli/src/cli-xml-output.c')
| -rw-r--r-- | cli/src/cli-xml-output.c | 842 |
1 files changed, 722 insertions, 120 deletions
diff --git a/cli/src/cli-xml-output.c b/cli/src/cli-xml-output.c index 34b046cc9..d8884d44b 100644 --- a/cli/src/cli-xml-output.c +++ b/cli/src/cli-xml-output.c @@ -15,6 +15,39 @@ #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 + * #if (HAVE_LIB_XML), #else, #endif + * For eg, + * int exported_func () { + * #if (HAVE_LIB_XML) + * <Stuff using libxml> + * #else + * return 0; + * #endif + * } + * + * All other functions, which are called internally within this file need to be + * within #if (HAVE_LIB_XML), #endif statements + * For eg, + * #if (HAVE_LIB_XML) + * int internal_func () + * { + * } + * #endif + * + * Following the above formate ensures that all xml related code is compliled + * only when libxml2 is present, and also keeps the rest of the codebase free + * of #if (HAVE_LIB_XML) + */ + + #if (HAVE_LIB_XML) #include <libxml/encoding.h> @@ -30,18 +63,11 @@ }while (0) \ int -cli_begin_xml_output (xmlTextWriterPtr *writer, xmlBufferPtr *buf) +cli_begin_xml_output (xmlTextWriterPtr *writer, xmlDocPtr *doc) { int ret = -1; - *buf = xmlBufferCreateSize (8192); - if (*buf == NULL) { - ret = -1; - goto out; - } - xmlBufferSetAllocationScheme (*buf, XML_BUFFER_ALLOC_DOUBLEIT); - - *writer = xmlNewTextWriterMemory (*buf, 0); + *writer = xmlNewTextWriterDoc (doc, 0); if (writer == NULL) { ret = -1; goto out; @@ -60,7 +86,7 @@ out: } int -cli_end_xml_output (xmlTextWriterPtr writer, xmlBufferPtr buf) +cli_end_xml_output (xmlTextWriterPtr writer, xmlDocPtr doc) { int ret = -1; @@ -71,10 +97,12 @@ cli_end_xml_output (xmlTextWriterPtr writer, xmlBufferPtr buf) ret = xmlTextWriterEndDocument (writer); XML_RET_CHECK_AND_GOTO (ret, out); - cli_out ("%s", (const char *)buf->content); + + /* Dump xml document to stdout and pretty format it */ + xmlSaveFormatFileEnc ("-", doc, "UTF-8", 1); xmlFreeTextWriter (writer); - xmlBufferFree (buf); + xmlFreeDoc (doc); out: gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret); @@ -96,7 +124,7 @@ cli_xml_output_common (xmlTextWriterPtr writer, int op_ret, int op_errno, XML_RET_CHECK_AND_GOTO (ret, out); ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"opErrstr", - "%s", op_errstr); + "%s", op_errstr); XML_RET_CHECK_AND_GOTO (ret, out); out: @@ -112,9 +140,9 @@ cli_xml_output_str (char *op, char *str, int op_ret, int op_errno, #if (HAVE_LIB_XML) int ret = -1; xmlTextWriterPtr writer = NULL; - xmlBufferPtr buf = NULL; + xmlDocPtr doc = NULL; - ret = cli_begin_xml_output (&writer, &buf); + ret = cli_begin_xml_output (&writer, &doc); if (ret) goto out; @@ -122,15 +150,21 @@ cli_xml_output_str (char *op, char *str, int op_ret, int op_errno, if (ret) goto out; - ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"cliOp", - "%s", op); - XML_RET_CHECK_AND_GOTO (ret, out); + if (op) { + ret = xmlTextWriterWriteFormatElement (writer, + (xmlChar *)"cliOp", + "%s", op); + XML_RET_CHECK_AND_GOTO (ret, out); + } - ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"output", - "%s", str); - XML_RET_CHECK_AND_GOTO (ret, out); + if (str) { + ret = xmlTextWriterWriteFormatElement (writer, + (xmlChar *)"output", + "%s", str); + XML_RET_CHECK_AND_GOTO (ret, out); + } - ret = cli_end_xml_output (writer, buf); + ret = cli_end_xml_output (writer, doc); out: gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret); @@ -164,9 +198,9 @@ cli_xml_output_dict ( char *op, dict_t *dict, int op_ret, int op_errno, #if (HAVE_LIB_XML) int ret = -1; xmlTextWriterPtr writer = NULL; - xmlBufferPtr buf = NULL; + xmlDocPtr doc = NULL; - ret = cli_begin_xml_output (&writer, &buf); + ret = cli_begin_xml_output (&writer, &doc); if (ret) goto out; @@ -185,7 +219,7 @@ cli_xml_output_dict ( char *op, dict_t *dict, int op_ret, int op_errno, ret = xmlTextWriterEndElement (writer); XML_RET_CHECK_AND_GOTO (ret, out); - ret = cli_end_xml_output (writer, buf); + ret = cli_end_xml_output (writer, doc); out: gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret); return ret; @@ -1306,7 +1340,7 @@ cli_xml_output_vol_status_begin (cli_local_t *local, int op_ret, int op_errno, #if (HAVE_LIB_XML) int ret = -1; - ret = cli_begin_xml_output (&(local->writer), &(local->buf)); + ret = cli_begin_xml_output (&(local->writer), &(local->doc)); XML_RET_CHECK_AND_GOTO (ret, out); ret = cli_xml_output_common (local->writer, op_ret, op_errno, @@ -1344,7 +1378,7 @@ cli_xml_output_vol_status_end (cli_local_t *local) ret = xmlTextWriterEndElement (local->writer); XML_RET_CHECK_AND_GOTO(ret, out); - ret = cli_end_xml_output (local->writer, local->buf); + ret = cli_end_xml_output (local->writer, local->doc); out: gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret); return ret; @@ -1353,6 +1387,215 @@ out: #endif } +#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; + char *task_id_str = NULL; + int status = 0; + int tasks = 0; + char key[1024] = {0,}; + int i = 0; + + /* <tasks> */ + ret = xmlTextWriterStartElement (local->writer, (xmlChar *)"tasks"); + XML_RET_CHECK_AND_GOTO (ret, out); + + ret = dict_get_int32 (dict, "tasks", &tasks); + if (ret) + goto out; + + for (i = 0; i < tasks; i++) { + /* <task> */ + ret = xmlTextWriterStartElement (local->writer, + (xmlChar *)"task"); + XML_RET_CHECK_AND_GOTO (ret, out); + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "task%d.type", i); + ret = dict_get_str (dict, key, &task_type); + if (ret) + goto out; + ret = xmlTextWriterWriteFormatElement (local->writer, + (xmlChar *)"type", + "%s", task_type); + XML_RET_CHECK_AND_GOTO (ret, out); + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "task%d.id", i); + ret = dict_get_str (dict, key, &task_id_str); + if (ret) + goto out; + ret = xmlTextWriterWriteFormatElement (local->writer, + (xmlChar *)"id", + "%s", task_id_str); + XML_RET_CHECK_AND_GOTO (ret, out); + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "task%d.status", i); + ret = dict_get_int32 (dict, key, &status); + if (ret) + goto out; + ret = xmlTextWriterWriteFormatElement (local->writer, + (xmlChar *)"status", + "%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); + } + + /* </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 cli_xml_output_vol_status (cli_local_t *local, dict_t *dict) { @@ -1470,7 +1713,6 @@ cli_xml_output_vol_status (cli_local_t *local, dict_t *dict) goto out; } break; - default: break; @@ -1480,6 +1722,16 @@ cli_xml_output_vol_status (cli_local_t *local, dict_t *dict) XML_RET_CHECK_AND_GOTO (ret, out); } + /* 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; + } + /* </volume> */ ret = xmlTextWriterEndElement (local->writer); XML_RET_CHECK_AND_GOTO (ret, out); @@ -1606,7 +1858,7 @@ cli_xml_output_vol_top (dict_t *dict, int op_ret, int op_errno, #if (HAVE_LIB_XML) int ret = -1; xmlTextWriterPtr writer = NULL; - xmlBufferPtr buf = NULL; + xmlDocPtr doc = NULL; int brick_count = 0; int top_op = GF_CLI_TOP_NONE; char *brick_name = NULL; @@ -1620,7 +1872,7 @@ cli_xml_output_vol_top (dict_t *dict, int op_ret, int op_errno, int i = 0; int j = 0; - ret = cli_begin_xml_output (&writer, &buf); + ret = cli_begin_xml_output (&writer, &doc); if (ret) goto out; @@ -1709,8 +1961,6 @@ cli_xml_output_vol_top (dict_t *dict, int op_ret, int op_errno, case GF_CLI_TOP_WRITE: case GF_CLI_TOP_OPENDIR: case GF_CLI_TOP_READDIR: - if (!members) - continue; break; @@ -1736,9 +1986,6 @@ cli_xml_output_vol_top (dict_t *dict, int op_ret, int op_errno, "%f", time_taken); } - if (!members) - continue; - break; default: @@ -1768,7 +2015,7 @@ cli_xml_output_vol_top (dict_t *dict, int op_ret, int op_errno, /* </volTop> */ ret = xmlTextWriterEndElement (writer); XML_RET_CHECK_AND_GOTO (ret, out); - ret = cli_end_xml_output (writer, buf); + ret = cli_end_xml_output (writer, doc); out: gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret); @@ -1963,7 +2210,7 @@ cli_xml_output_vol_profile (dict_t *dict, int op_ret, int op_errno, #if (HAVE_LIB_XML) int ret = -1; xmlTextWriterPtr writer = NULL; - xmlBufferPtr buf = NULL; + xmlDocPtr doc = NULL; char *volname = NULL; int op = GF_CLI_STATS_NONE; int brick_count = 0; @@ -1972,7 +2219,7 @@ cli_xml_output_vol_profile (dict_t *dict, int op_ret, int op_errno, char key[1024] = {0,}; int i = 0; - ret = cli_begin_xml_output (&writer, &buf); + ret = cli_begin_xml_output (&writer, &doc); if (ret) goto out; @@ -2052,7 +2299,7 @@ cont: ret = xmlTextWriterEndElement (writer); XML_RET_CHECK_AND_GOTO (ret, out); - ret = cli_end_xml_output (writer, buf); + ret = cli_end_xml_output (writer, doc); out: gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret); return ret; @@ -2068,13 +2315,13 @@ cli_xml_output_vol_list (dict_t *dict, int op_ret, int op_errno, #if (HAVE_LIB_XML) int ret = -1; xmlTextWriterPtr writer = NULL; - xmlBufferPtr buf = NULL; + xmlDocPtr doc = NULL; int count = 0; char *volname = NULL; char key[1024] = {0,}; int i = 0; - ret = cli_begin_xml_output (&writer, &buf); + ret = cli_begin_xml_output (&writer, &doc); if (ret) goto out; @@ -2109,7 +2356,7 @@ cli_xml_output_vol_list (dict_t *dict, int op_ret, int op_errno, ret = xmlTextWriterEndElement (writer); XML_RET_CHECK_AND_GOTO (ret, out); - ret = cli_end_xml_output (writer, buf); + ret = cli_end_xml_output (writer, doc); out: gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret); return ret; @@ -2163,15 +2410,44 @@ out: return ret; } +struct tmp_xml_option_logger { + char *key; + xmlTextWriterPtr writer; +}; + +static int +_output_vol_info_option (dict_t *d, char *k, data_t *v, + void *data) +{ + int ret = 0; + char *ptr = NULL; + struct tmp_xml_option_logger *tmp = NULL; + + tmp = data; + + ptr = strstr (k, "option."); + if (!ptr) + goto out; + + if (!v) { + ret = -1; + goto out; + } + ret = cli_xml_output_vol_info_option (tmp->writer, tmp->key, k, + v->data); + +out: + return ret; +} + int cli_xml_output_vol_info_options (xmlTextWriterPtr writer, dict_t *dict, char *prefix) { int ret = -1; int opt_count = 0; - data_t *value = 0; - char *ptr = NULL; char key[1024] = {0,}; + struct tmp_xml_option_logger tmp = {0,}; snprintf (key, sizeof (key), "%s.opt_count", prefix); ret = dict_get_int32 (dict, key, &opt_count); @@ -2186,26 +2462,9 @@ cli_xml_output_vol_info_options (xmlTextWriterPtr writer, dict_t *dict, XML_RET_CHECK_AND_GOTO (ret, out); snprintf (key, sizeof (key), "%s.option.", prefix); - int _output_vol_info_option (dict_t *d, char *k, data_t *v, - void *data) - { - int ret = 0; - ptr = strstr (k, "option."); - if (!ptr) - goto internal_out; - - value = v; - if (!value) { - ret = -1; - goto internal_out; - } - ret = cli_xml_output_vol_info_option (writer, key, k, - v->data); - - internal_out: - return ret; - } - ret = dict_foreach (dict, _output_vol_info_option, NULL); + tmp.key = key; + tmp.writer = writer; + ret = dict_foreach (dict, _output_vol_info_option, &tmp); if (ret) goto out; @@ -2226,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; @@ -2237,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) @@ -2279,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]); @@ -2353,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> */ @@ -2384,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; @@ -2407,7 +2756,7 @@ cli_xml_output_vol_info_begin (cli_local_t *local, int op_ret, int op_errno, GF_ASSERT (local); - ret = cli_begin_xml_output (&(local->writer), &(local->buf)); + ret = cli_begin_xml_output (&(local->writer), &(local->doc)); if (ret) goto out; @@ -2455,7 +2804,7 @@ cli_xml_output_vol_info_end (cli_local_t *local) ret = xmlTextWriterEndElement (local->writer); XML_RET_CHECK_AND_GOTO (ret, out); - ret = cli_end_xml_output (local->writer, local->buf); + ret = cli_end_xml_output (local->writer, local->doc); out: gf_log ("cli", GF_LOG_ERROR, "Returning %d", ret); @@ -2473,7 +2822,7 @@ cli_xml_output_vol_quota_limit_list (char *volname, char *limit_list, #if (HAVE_LIB_XML) int ret = -1; xmlTextWriterPtr writer = NULL; - xmlBufferPtr buf = NULL; + xmlDocPtr doc = NULL; int64_t size = 0; int64_t limit_value = 0; int i = 0; @@ -2491,7 +2840,7 @@ cli_xml_output_vol_quota_limit_list (char *volname, char *limit_list, GF_ASSERT (volname); GF_ASSERT (limit_list); - ret = cli_begin_xml_output (&writer, &buf); + ret = cli_begin_xml_output (&writer, &doc); if (ret) goto out; @@ -2601,7 +2950,7 @@ cont: ret = xmlTextWriterEndElement (writer); XML_RET_CHECK_AND_GOTO (ret, out); - ret = cli_end_xml_output (writer, buf); + ret = cli_end_xml_output (writer, doc); out: GF_FREE (size_str); @@ -2619,18 +2968,17 @@ cli_xml_output_peer_status (dict_t *dict, int op_ret, int op_errno, #if (HAVE_LIB_XML) int ret = -1; xmlTextWriterPtr writer = NULL; - xmlBufferPtr buf = NULL; + xmlDocPtr doc = NULL; int count = 0; char *uuid = NULL; char *hostname = NULL; int connected = 0; int state_id = 0; char *state_str = NULL; - int port = 0; int i = 1; char key[1024] = {0,}; - ret = cli_begin_xml_output (&writer, &buf); + ret = cli_begin_xml_output (&writer, &doc); if (ret) goto out; @@ -2690,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; + if (!ret) { + /* ignore */ - ret = xmlTextWriterWriteFormatElement (writer, - (xmlChar *)"stateStr", - "%s", state_str); - XML_RET_CHECK_AND_GOTO (ret, out); - - 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> */ @@ -2732,7 +3069,7 @@ cont: ret = xmlTextWriterEndElement (writer); XML_RET_CHECK_AND_GOTO (ret, out); - ret = cli_end_xml_output (writer, buf); + ret = cli_end_xml_output (writer, doc); out: gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret); @@ -2745,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; @@ -2782,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)); @@ -2835,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); @@ -2845,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); @@ -2871,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); @@ -2890,9 +3306,10 @@ cli_xml_output_vol_rebalance (gf_cli_defrag_type op, dict_t *dict, int op_ret, #if (HAVE_LIB_XML) int ret = -1; xmlTextWriterPtr writer = NULL; - xmlBufferPtr buf = NULL; + xmlDocPtr doc = NULL; + char *task_id_str = NULL; - ret = cli_begin_xml_output (&writer, &buf); + ret = cli_begin_xml_output (&writer, &doc); if (ret) goto out; @@ -2904,12 +3321,21 @@ cli_xml_output_vol_rebalance (gf_cli_defrag_type op, dict_t *dict, int op_ret, ret = xmlTextWriterStartElement (writer, (xmlChar *)"volRebalance"); XML_RET_CHECK_AND_GOTO (ret, out); + ret = dict_get_str (dict, GF_REBALANCE_TID_KEY, &task_id_str); + if (ret == 0) { + ret = xmlTextWriterWriteFormatElement (writer, + (xmlChar *)"task-id", + "%s", task_id_str); + XML_RET_CHECK_AND_GOTO (ret, out); + } + ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"op", "%d", op); 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; } @@ -2919,7 +3345,7 @@ cli_xml_output_vol_rebalance (gf_cli_defrag_type op, dict_t *dict, int op_ret, XML_RET_CHECK_AND_GOTO (ret, out); - ret = cli_end_xml_output (writer, buf); + ret = cli_end_xml_output (writer, doc); out: gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret); @@ -2936,9 +3362,10 @@ cli_xml_output_vol_remove_brick (gf_boolean_t status_op, dict_t *dict, #if (HAVE_LIB_XML) int ret = -1; xmlTextWriterPtr writer = NULL; - xmlBufferPtr buf = NULL; + xmlDocPtr doc = NULL; + char *task_id_str = NULL; - ret = cli_begin_xml_output (&writer, &buf); + ret = cli_begin_xml_output (&writer, &doc); if (ret) goto out; @@ -2950,8 +3377,17 @@ cli_xml_output_vol_remove_brick (gf_boolean_t status_op, dict_t *dict, ret = xmlTextWriterStartElement (writer, (xmlChar *)"volRemoveBrick"); XML_RET_CHECK_AND_GOTO (ret, out); + ret = dict_get_str (dict, GF_REMOVE_BRICK_TID_KEY, &task_id_str); + if (ret == 0) { + ret = xmlTextWriterWriteFormatElement (writer, + (xmlChar *)"task-id", + "%s", task_id_str); + XML_RET_CHECK_AND_GOTO (ret, out); + } + 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; } @@ -2961,7 +3397,7 @@ cli_xml_output_vol_remove_brick (gf_boolean_t status_op, dict_t *dict, XML_RET_CHECK_AND_GOTO (ret, out); - ret = cli_end_xml_output (writer, buf); + ret = cli_end_xml_output (writer, doc); out: gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret); @@ -2980,10 +3416,11 @@ cli_xml_output_vol_replace_brick (gf1_cli_replace_op op, dict_t *dict, int status = 0; uint64_t files = 0; char *current_file = 0; + char *task_id_str = NULL; xmlTextWriterPtr writer = NULL; - xmlBufferPtr buf = NULL; + xmlDocPtr doc = NULL; - ret = cli_begin_xml_output (&writer, &buf); + ret = cli_begin_xml_output (&writer, &doc); if (ret) goto out; @@ -2995,6 +3432,14 @@ cli_xml_output_vol_replace_brick (gf1_cli_replace_op op, dict_t *dict, ret = xmlTextWriterStartElement (writer, (xmlChar *)"volReplaceBrick"); XML_RET_CHECK_AND_GOTO (ret, out); + ret = dict_get_str (dict, GF_REPLACE_BRICK_TID_KEY, &task_id_str); + if (ret == 0) { + ret = xmlTextWriterWriteFormatElement (writer, + (xmlChar *)"task-id", + "%s", task_id_str); + XML_RET_CHECK_AND_GOTO (ret, out); + } + ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"op", "%d", op); XML_RET_CHECK_AND_GOTO (ret, out); @@ -3032,7 +3477,7 @@ cont: ret = xmlTextWriterEndElement (writer); XML_RET_CHECK_AND_GOTO (ret, out); - ret = cli_end_xml_output (writer, buf); + ret = cli_end_xml_output (writer, doc); out: gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret); @@ -3049,11 +3494,11 @@ cli_xml_output_vol_create (dict_t *dict, int op_ret, int op_errno, #if (HAVE_LIB_XML) int ret = -1; xmlTextWriterPtr writer = NULL; - xmlBufferPtr buf = NULL; + xmlDocPtr doc = NULL; char *volname = NULL; char *volid = NULL; - ret = cli_begin_xml_output (&writer, &buf); + ret = cli_begin_xml_output (&writer, &doc); if (ret) goto out; @@ -3095,7 +3540,7 @@ cli_xml_output_vol_create (dict_t *dict, int op_ret, int op_errno, XML_RET_CHECK_AND_GOTO (ret, out); } - ret = cli_end_xml_output (writer, buf); + ret = cli_end_xml_output (writer, doc); out: gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret); @@ -3112,13 +3557,13 @@ cli_xml_output_generic_volume (char *op, dict_t *dict, int op_ret, int op_errno, #if (HAVE_LIB_XML) int ret = -1; xmlTextWriterPtr writer = NULL; - xmlBufferPtr buf = NULL; + xmlDocPtr doc = NULL; char *volname = NULL; char *volid = NULL; GF_ASSERT (op); - ret = cli_begin_xml_output (&writer, &buf); + ret = cli_begin_xml_output (&writer, &doc); if (ret) goto out; @@ -3159,7 +3604,7 @@ cli_xml_output_generic_volume (char *op, dict_t *dict, int op_ret, int op_errno, XML_RET_CHECK_AND_GOTO (ret, out); } - ret = cli_end_xml_output (writer, buf); + ret = cli_end_xml_output (writer, doc); out: gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret); @@ -3168,3 +3613,160 @@ out: return 0; #endif } + +#if (HAVE_LIB_XML) +int +cli_xml_output_vol_gsync_status (dict_t *dict, xmlTextWriterPtr writer) +{ + char master_key[PATH_MAX] = ""; + char slave_key[PATH_MAX] = ""; + char status_key[PATH_MAX] = ""; + char node_key[PATH_MAX] = ""; + char *master = NULL; + char *slave = NULL; + char *status = NULL; + char *node = NULL; + int ret = -1; + int gsync_count = 0; + int i = 1; + + ret = dict_get_int32 (dict, "gsync-count", &gsync_count); + if (ret) + goto out; + + for (i=1; i <= gsync_count; i++) { + snprintf (node_key, sizeof(node_key), "node%d", i); + snprintf (master_key, sizeof(master_key), "master%d", i); + snprintf (slave_key, sizeof(slave_key), "slave%d", i); + snprintf (status_key, sizeof(status_key), "status%d", i); + + ret = dict_get_str (dict, node_key, &node); + if (ret) + goto out; + + ret = dict_get_str (dict, master_key, &master); + if (ret) + goto out; + + ret = dict_get_str (dict, slave_key, &slave); + if (ret) + goto out; + + ret = dict_get_str (dict, status_key, &status); + if (ret) + goto out; + + /* <pair> */ + ret = xmlTextWriterStartElement (writer, (xmlChar *)"pair"); + XML_RET_CHECK_AND_GOTO (ret, out); + + ret = xmlTextWriterWriteFormatElement (writer, + (xmlChar *)"node", + "%s", node); + XML_RET_CHECK_AND_GOTO (ret, out); + + ret = xmlTextWriterWriteFormatElement (writer, + (xmlChar *)"master", + "%s", master); + XML_RET_CHECK_AND_GOTO (ret, out); + + ret = xmlTextWriterWriteFormatElement (writer, + (xmlChar *)"slave", + "%s", slave); + XML_RET_CHECK_AND_GOTO (ret, out); + + ret = xmlTextWriterWriteFormatElement (writer, + (xmlChar *)"status", + "%s", status); + XML_RET_CHECK_AND_GOTO (ret, out); + + /* </pair> */ + ret = xmlTextWriterEndElement (writer); + XML_RET_CHECK_AND_GOTO (ret, out); + + } + +out: + gf_log ("cli",GF_LOG_DEBUG, "Returning %d", ret); + return ret; +} +#endif + +int +cli_xml_output_vol_gsync (dict_t *dict, int op_ret, int op_errno, + char *op_errstr) +{ +#if (HAVE_LIB_XML) + int ret = -1; + xmlTextWriterPtr writer = NULL; + xmlDocPtr doc = NULL; + char *master = NULL; + char *slave = NULL; + int type = 0; + + GF_ASSERT (dict); + + ret = cli_begin_xml_output (&writer, &doc); + if (ret) + goto out; + + ret = cli_xml_output_common (writer, op_ret, op_errno, op_errstr); + if (ret) + goto out; + + /* <geoRep> */ + ret = xmlTextWriterStartElement (writer, (xmlChar *)"geoRep"); + XML_RET_CHECK_AND_GOTO (ret, out); + + ret = dict_get_int32 (dict, "type", &type); + if (ret) { + gf_log ("cli", GF_LOG_ERROR, "Failed to get type"); + goto out; + } + + ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"type", + "%d", type); + XML_RET_CHECK_AND_GOTO (ret, out); + + switch (type) { + case GF_GSYNC_OPTION_TYPE_START: + case GF_GSYNC_OPTION_TYPE_STOP: + if (dict_get_str (dict, "master", &master) != 0) + master = "???"; + if (dict_get_str (dict, "slave", &slave) != 0) + slave = "???"; + + ret = xmlTextWriterWriteFormatElement (writer, + (xmlChar *)"master", + "%s", master); + XML_RET_CHECK_AND_GOTO (ret, out); + + ret = xmlTextWriterWriteFormatElement (writer, + (xmlChar *)"slave", + "%s", slave); + XML_RET_CHECK_AND_GOTO (ret, out); + + break; + + case GF_GSYNC_OPTION_TYPE_CONFIG: + break; + case GF_GSYNC_OPTION_TYPE_STATUS: + ret = cli_xml_output_vol_gsync_status(dict, writer); + break; + default: + ret = 0; + break; + } + + /* </geoRep> */ + ret = xmlTextWriterEndElement (writer); + XML_RET_CHECK_AND_GOTO (ret, out); + + ret = cli_end_xml_output (writer, doc); +out: + gf_log ("cli",GF_LOG_DEBUG, "Returning %d", ret); + return ret; +#else + return 0; +#endif +} |
