From fd47635a4ffab621a2357c99cd1edd0482940bd5 Mon Sep 17 00:00:00 2001 From: Rajesh Joseph Date: Wed, 26 Aug 2015 08:28:59 +0530 Subject: gluster/cli: snapshot delete all does not work with xml Problem: snapshot delete all command fails with --xml option Fix: Provided xml support for delete all command Change-Id: I77cad131473a9160e188c783f442b6a38a37f758 BUG: 1257533 Signed-off-by: Rajesh Joseph Reviewed-on: http://review.gluster.org/12027 Tested-by: NetBSD Build System Tested-by: Gluster Build System Reviewed-by: Avra Sengupta --- cli/src/cli-cmd-parser.c | 4 +- cli/src/cli-rpc-ops.c | 141 +++++++++++++++------- cli/src/cli-xml-output.c | 298 ++++++++++++++++++++++++++++++++++++----------- cli/src/cli.h | 18 +++ 4 files changed, 347 insertions(+), 114 deletions(-) (limited to 'cli') diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c index 393af341635..2335474a222 100644 --- a/cli/src/cli-cmd-parser.c +++ b/cli/src/cli-cmd-parser.c @@ -4306,7 +4306,7 @@ cli_snap_delete_parse (dict_t *dict, const char **words, int wordcount, } } - ret = dict_set_int32 (dict, "delete-cmd", cmd); + ret = dict_set_int32 (dict, "sub-cmd", cmd); if (ret) { gf_log ("cli", GF_LOG_ERROR, "Could not save " "type of snapshot delete"); @@ -4386,7 +4386,7 @@ cli_snap_status_parse (dict_t *dict, const char **words, int wordcount) out: if (ret == 0) { - ret = dict_set_int32 (dict, "status-cmd", cmd); + ret = dict_set_int32 (dict, "sub-cmd", cmd); if (ret) { gf_log ("cli", GF_LOG_ERROR, "Could not save cmd " "of snapshot status"); diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c index 3df9226d9e9..7a1fc75d64a 100644 --- a/cli/src/cli-rpc-ops.c +++ b/cli/src/cli-rpc-ops.c @@ -8694,17 +8694,32 @@ cli_snapshot_remove_reply (gf_cli_rsp *rsp, dict_t *dict, call_frame_t *frame) GF_ASSERT (rsp); GF_ASSERT (dict); - if (rsp->op_ret) { - cli_err ("snapshot delete: failed: %s", - rsp->op_errstr ? rsp->op_errstr : - "Please check log file for details"); - ret = rsp->op_ret; - goto out; - } + local = frame->local; - ret = dict_get_int32 (dict, "delete-cmd", &delete_cmd); + ret = dict_get_int32 (dict, "sub-cmd", &delete_cmd); if (ret) { - gf_log ("cli", GF_LOG_ERROR, "Could not get delete-cmd"); + gf_log ("cli", GF_LOG_ERROR, "Could not get sub-cmd"); + goto end; + } + + if ((global_state->mode & GLUSTER_MODE_XML) && + (delete_cmd == GF_SNAP_DELETE_TYPE_SNAP)) { + ret = cli_xml_output_snap_delete_begin (local, rsp->op_ret, + rsp->op_errno, + rsp->op_errstr); + if (ret) { + gf_log ("cli", GF_LOG_ERROR, "Failed to create " + "xml output for delete"); + goto end; + } + } + + + if (rsp->op_ret && !(global_state->mode & GLUSTER_MODE_XML)) { + cli_err ("snapshot delete: failed: %s", + rsp->op_errstr ? rsp->op_errstr : + "Please check log file for details"); + ret = rsp->op_ret; goto out; } @@ -8727,17 +8742,37 @@ cli_snapshot_remove_reply (gf_cli_rsp *rsp, dict_t *dict, call_frame_t *frame) goto out; } - ret = dict_get_str (dict, "snapname", &snap_name); - if (ret) { - gf_log ("cli", GF_LOG_ERROR, "Failed to get snapname"); - goto out; - } + if (global_state->mode & GLUSTER_MODE_XML) { + ret = cli_xml_snapshot_delete (local->writer, local->doc, + dict, rsp); + if (ret) { + gf_log ("cli", GF_LOG_ERROR, "Failed to create " + "xml output for snapshot delete command"); + goto out; + } + /* Error out in case of the op already failed */ + if (rsp->op_ret) { + ret = rsp->op_ret; + goto out; + } + } else { + ret = dict_get_str (dict, "snapname", &snap_name); + if (ret) { + gf_log ("cli", GF_LOG_ERROR, "Failed to get snapname"); + goto out; + } - cli_out ("snapshot delete: %s: snap removed successfully", - snap_name); + cli_out ("snapshot delete: %s: snap removed successfully", + snap_name); + } ret = 0; out: + if ((global_state->mode & GLUSTER_MODE_XML) && + (delete_cmd == GF_SNAP_DELETE_TYPE_SNAP)) { + ret = cli_xml_output_snap_delete_end (local); + } +end: return ret; } @@ -9465,8 +9500,8 @@ cli_populate_req_dict_for_delete (dict_t *snap_dict, dict_t *dict, size_t index) GF_ASSERT (snap_dict); GF_ASSERT (dict); - ret = dict_set_int32 (snap_dict, "delete-cmd", - GF_SNAP_DELETE_TYPE_SNAP); + ret = dict_set_int32 (snap_dict, "sub-cmd", + GF_SNAP_DELETE_TYPE_ITER); if (ret) { gf_log ("cli", GF_LOG_ERROR, "Could not save command " "type in snap dictionary"); @@ -9518,7 +9553,7 @@ cli_populate_req_dict_for_status (dict_t *snap_dict, dict_t *dict, int index) { GF_ASSERT (snap_dict); GF_ASSERT (dict); - ret = dict_set_uint32 (snap_dict, "status-cmd", + ret = dict_set_uint32 (snap_dict, "sub-cmd", GF_SNAP_STATUS_TYPE_SNAP); if (ret) { gf_log ("cli", GF_LOG_ERROR, "Could not save command " @@ -9605,7 +9640,7 @@ cli_snapshot_status (dict_t *dict, gf_cli_rsp *rsp, goto out; } - ret = dict_get_int32 (dict, "status-cmd", &status_cmd); + ret = dict_get_int32 (dict, "sub-cmd", &status_cmd); if (ret) { gf_log ("cli", GF_LOG_ERROR, "Could not fetch status type"); goto out; @@ -9690,9 +9725,10 @@ gf_cli_snapshot_cbk (struct rpc_req *req, struct iovec *iov, goto out; } - /* Snapshot status command is handled separately */ + /* Snapshot status and delete command is handled separately */ if (global_state->mode & GLUSTER_MODE_XML && - GF_SNAP_OPTION_TYPE_STATUS != type) { + GF_SNAP_OPTION_TYPE_STATUS != type && + GF_SNAP_OPTION_TYPE_DELETE != type) { ret = cli_xml_output_snapshot (type, dict, rsp.op_ret, rsp.op_errno, rsp.op_errstr); if (ret) { @@ -9958,10 +9994,10 @@ gf_cli_snapshot_for_delete (call_frame_t *frame, xlator_t *this, options = data; - ret = dict_get_int32 (local->dict, "delete-cmd", &cmd); + ret = dict_get_int32 (local->dict, "sub-cmd", &cmd); if (ret) { gf_log ("cli", GF_LOG_ERROR, "Failed to get " - "delete-cmd"); + "sub-cmd"); goto out; } @@ -9979,7 +10015,18 @@ gf_cli_snapshot_for_delete (call_frame_t *frame, xlator_t *this, goto out; } - if (snapcount == 0) { + if (global_state->mode & GLUSTER_MODE_XML) { +#ifdef HAVE_LIB_XML + ret = xmlTextWriterWriteFormatElement (local->writer, + (xmlChar *)"snapCount", + "%d", snapcount); + if (ret) { + gf_log ("cli", GF_LOG_ERROR, "Failed to write " + "xml element \"snapCount\""); + goto out; + } +#endif /* HAVE_LIB_XML */ + } else if (snapcount == 0) { cli_out ("No snapshots present"); goto out; } @@ -10072,9 +10119,9 @@ gf_cli_snapshot_for_status (call_frame_t *frame, xlator_t *this, local = frame->local; options = data; - ret = dict_get_int32 (local->dict, "status-cmd", &cmd); + ret = dict_get_int32 (local->dict, "sub-cmd", &cmd); if (ret) { - gf_log ("cli", GF_LOG_ERROR, "Failed to get status-cmd"); + gf_log ("cli", GF_LOG_ERROR, "Failed to get sub-cmd"); goto out; } @@ -10093,7 +10140,7 @@ gf_cli_snapshot_for_status (call_frame_t *frame, xlator_t *this, goto out; } - if (snapcount == 0) { + if (snapcount == 0 && !(global_state->mode & GLUSTER_MODE_XML)) { cli_out ("No snapshots present"); } @@ -10164,12 +10211,11 @@ gf_cli_snapshot (call_frame_t *frame, xlator_t *this, ret = dict_get_int32 (local->dict, "type", &type); - if (GF_SNAP_OPTION_TYPE_STATUS == type && - global_state->mode & GLUSTER_MODE_XML) { - ret = cli_xml_output_snap_status_begin (local, 0, 0, NULL); + if (global_state->mode & GLUSTER_MODE_XML) { + ret = cli_xml_snapshot_begin_composite_op (local); if (ret) { - gf_log ("cli", GF_LOG_ERROR, "Error creating xml " - "output"); + gf_log ("cli", GF_LOG_ERROR, "Failed to begin " + "snapshot xml composite op"); goto out; } } @@ -10182,7 +10228,7 @@ gf_cli_snapshot (call_frame_t *frame, xlator_t *this, if (ret) { gf_log ("cli", GF_LOG_ERROR, "cli_to_glusterd for " "snapshot failed"); - goto out; + goto xmlend; } if (GF_SNAP_OPTION_TYPE_STATUS == type) { @@ -10190,17 +10236,9 @@ gf_cli_snapshot (call_frame_t *frame, xlator_t *this, if (ret) { gf_log ("cli", GF_LOG_ERROR, "cli to glusterd " "for snapshot status command failed"); - goto out; } - if (global_state->mode & GLUSTER_MODE_XML) { - ret = cli_xml_output_snap_status_end (local); - if (ret) { - gf_log ("cli", GF_LOG_ERROR, "Error creating " - "xml output"); - goto out; - } - } + goto xmlend; } if (GF_SNAP_OPTION_TYPE_DELETE == type) { @@ -10208,12 +10246,22 @@ gf_cli_snapshot (call_frame_t *frame, xlator_t *this, if (ret) { gf_log ("cli", GF_LOG_ERROR, "cli to glusterd " "for snapshot delete command failed"); - goto out; } + + goto xmlend; } ret = 0; +xmlend: + if (global_state->mode & GLUSTER_MODE_XML) { + ret = cli_xml_snapshot_end_composite_op (local); + if (ret) { + gf_log ("cli", GF_LOG_ERROR, "Failed to end " + "snapshot xml composite op"); + goto out; + } + } out: if (ret && local && GF_SNAP_OPTION_TYPE_STATUS == type) { tmp_ret = dict_get_str (local->dict, "op_err_str", &err_str); @@ -10229,6 +10277,11 @@ out: gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret); GF_FREE (req.dict.dict_val); + + if (global_state->mode & GLUSTER_MODE_XML) { + /* XML mode handles its own error */ + ret = 0; + } return ret; } diff --git a/cli/src/cli-xml-output.c b/cli/src/cli-xml-output.c index 9c3d17a7b64..fcbc72d51eb 100644 --- a/cli/src/cli-xml-output.c +++ b/cli/src/cli-xml-output.c @@ -4101,65 +4101,6 @@ out: return ret; } -/* This function will generate snapshot delete output in xml format. - * - * @param writer xmlTextWriterPtr - * @param doc xmlDocPtr - * @param dict dict containing delete output - * - * @return 0 on success and -1 on failure - */ -static int -cli_xml_snapshot_delete (xmlTextWriterPtr writer, xmlDocPtr doc, dict_t *dict) -{ - int ret = -1; - char *str_value = NULL; - - GF_ASSERT (writer); - GF_ASSERT (doc); - GF_ASSERT (dict); - - /* */ - ret = xmlTextWriterStartElement (writer, (xmlChar *)"snapDelete"); - XML_RET_CHECK_AND_GOTO (ret, out); - - /* */ - ret = xmlTextWriterStartElement (writer, (xmlChar *)"snapshot"); - XML_RET_CHECK_AND_GOTO (ret, out); - - ret = dict_get_str (dict, "snapname", &str_value); - if (ret) { - gf_log ("cli", GF_LOG_ERROR, "Failed to get snap name"); - goto out; - } - - ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *) "name", - "%s", str_value); - XML_RET_CHECK_AND_GOTO (ret, out); - - ret = dict_get_str (dict, "snapuuid", &str_value); - if (ret) { - gf_log ("cli", GF_LOG_ERROR, "Failed to get snap uuid"); - goto out; - } - - ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *) "uuid", - "%s", str_value); - XML_RET_CHECK_AND_GOTO (ret, out); - - /* */ - ret = xmlTextWriterEndElement (writer); - XML_RET_CHECK_AND_GOTO (ret, out); - - /* */ - ret = xmlTextWriterEndElement (writer); - XML_RET_CHECK_AND_GOTO (ret, out); - - ret = 0; -out: - - return ret; -} /* This function will generate snapshot restore output in xml format. * @@ -4912,7 +4853,7 @@ cli_xml_snapshot_status (xmlTextWriterPtr writer, xmlDocPtr doc, dict_t *dict) ret = xmlTextWriterStartElement (writer, (xmlChar *)"snapStatus"); XML_RET_CHECK_AND_GOTO (ret, out); - ret = dict_get_int32 (dict, "status-cmd", &status_cmd); + ret = dict_get_int32 (dict, "sub-cmd", &status_cmd); if (ret) { gf_log ("cli", GF_LOG_ERROR, "Could not fetch status type"); goto out; @@ -5342,6 +5283,81 @@ out: } #endif /* HAVE_LIB_XML */ +/* This function will generate snapshot delete output in xml format. + * + * @param writer xmlTextWriterPtr + * @param doc xmlDocPtr + * @param dict dict containing delete output + * @param rsp cli response + * + * @return 0 on success and -1 on failure + */ +int +cli_xml_snapshot_delete (xmlTextWriterPtr writer, xmlDocPtr doc, dict_t *dict, + gf_cli_rsp *rsp) +{ + int ret = -1; +#ifdef HAVE_LIB_XML + char *str_value = NULL; + + GF_ASSERT (writer); + GF_ASSERT (doc); + GF_ASSERT (dict); + + /* */ + ret = xmlTextWriterStartElement (writer, (xmlChar *)"snapshot"); + XML_RET_CHECK_AND_GOTO (ret, out); + + ret = dict_get_str (dict, "snapname", &str_value); + if (ret) { + gf_log ("cli", GF_LOG_ERROR, "Failed to get snap name"); + goto xmlend; + } + + if (!rsp->op_ret) { + ret = xmlTextWriterWriteFormatElement (writer, + (xmlChar *) "status", + "Success"); + XML_RET_CHECK_AND_GOTO (ret, xmlend); + } else { + ret = xmlTextWriterWriteFormatElement (writer, + (xmlChar *) "status", + "Failure"); + XML_RET_CHECK_AND_GOTO (ret, xmlend); + + ret = cli_xml_output_common (writer, rsp->op_ret, + rsp->op_errno, + rsp->op_errstr); + XML_RET_CHECK_AND_GOTO (ret, xmlend); + } + + + ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *) "name", + "%s", str_value); + XML_RET_CHECK_AND_GOTO (ret, xmlend); + + ret = dict_get_str (dict, "snapuuid", &str_value); + if (ret) { + gf_log ("cli", GF_LOG_ERROR, "Failed to get snap uuid"); + goto xmlend; + } + + ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *) "uuid", + "%s", str_value); + XML_RET_CHECK_AND_GOTO (ret, out); + +xmlend: + /* */ + ret = xmlTextWriterEndElement (writer); + XML_RET_CHECK_AND_GOTO (ret, out); + +#endif /* HAVE_LIB_XML */ + ret = 0; +out: + + return ret; +} + int cli_xml_output_snap_status_begin (cli_local_t *local, int op_ret, int op_errno, char *op_errstr) @@ -5400,6 +5416,70 @@ out: #endif } +int +cli_xml_output_snap_delete_begin (cli_local_t *local, int op_ret, int op_errno, + char *op_errstr) +{ +#if (HAVE_LIB_XML) + int ret = -1; + int delete_cmd = -1; + + GF_ASSERT (local); + + ret = cli_begin_xml_output (&(local->writer), &(local->doc)); + XML_RET_CHECK_AND_GOTO (ret, out); + + ret = dict_get_int32 (local->dict, "sub-cmd", &delete_cmd); + if (ret) { + gf_log ("cli", GF_LOG_ERROR, "Failed to get sub-cmd"); + goto out; + } + + ret = cli_xml_output_common (local->writer, op_ret, op_errno, + op_errstr); + XML_RET_CHECK_AND_GOTO (ret, out); + + /* */ + ret = xmlTextWriterStartElement (local->writer, + (xmlChar *) "snapDelete"); + XML_RET_CHECK_AND_GOTO (ret, out); + + /* */ + ret = xmlTextWriterStartElement (local->writer, (xmlChar *)"snapshots"); + XML_RET_CHECK_AND_GOTO (ret, out); + +out: + gf_log ("cli", GF_LOG_TRACE, "Returning %d", ret); + return ret; +#else + return 0; +#endif +} + +int +cli_xml_output_snap_delete_end (cli_local_t *local) +{ +#if (HAVE_LIB_XML) + int ret = -1; + + GF_ASSERT (local); + + /* */ + ret = xmlTextWriterEndElement (local->writer); + XML_RET_CHECK_AND_GOTO (ret, out); + + /* */ + ret = xmlTextWriterEndElement (local->writer); + XML_RET_CHECK_AND_GOTO(ret, out); + + ret = cli_end_xml_output (local->writer, local->doc); +out: + gf_log ("cli", GF_LOG_TRACE, "Returning %d", ret); + return ret; +#else + return 0; +#endif +} /* This function will generate xml output for all the snapshot commands * * @param cmd_type command type @@ -5450,14 +5530,6 @@ cli_xml_output_snapshot (int cmd_type, dict_t *dict, int op_ret, goto out; } break; - case GF_SNAP_OPTION_TYPE_DELETE: - ret = cli_xml_snapshot_delete (writer, doc, dict); - if (ret) { - gf_log ("cli", GF_LOG_ERROR, "Failed to create " - "xml output for snapshot delete command"); - goto out; - } - break; case GF_SNAP_OPTION_TYPE_RESTORE: ret = cli_xml_snapshot_restore (writer, doc, dict); if (ret) { @@ -5528,6 +5600,96 @@ out: #endif /* HAVE_LIB_XML */ } +int +cli_xml_snapshot_begin_composite_op (cli_local_t *local) +{ + int ret = -1; +#ifdef HAVE_LIB_XML + int cmd = -1; + int type = -1; + + ret = dict_get_int32 (local->dict, "sub-cmd", &cmd); + if (ret) { + gf_log ("cli", GF_LOG_ERROR, "Failed to get " + "sub-cmd"); + ret = 0; + goto out; + } + + if (cmd == GF_SNAP_STATUS_TYPE_SNAP || + cmd == GF_SNAP_DELETE_TYPE_SNAP){ + ret = 0; + goto out; + } + + ret = dict_get_int32 (local->dict, "type", &type); + if (ret) { + gf_log ("cli", GF_LOG_ERROR, "Failed to get snapshot " + "command type from dictionary"); + goto out; + } + + if (GF_SNAP_OPTION_TYPE_STATUS == type) + ret = cli_xml_output_snap_status_begin (local, 0, 0, NULL); + else if (GF_SNAP_OPTION_TYPE_DELETE == type) + ret = cli_xml_output_snap_delete_begin (local, 0, 0, NULL); + + if (ret) { + gf_log ("cli", GF_LOG_ERROR, "Error creating xml output"); + goto out; + } + +#endif /* HAVE_LIB_XML */ + ret = 0; +out: + return ret; +} + +int +cli_xml_snapshot_end_composite_op (cli_local_t *local) +{ + int ret = -1; +#ifdef HAVE_LIB_XML + int cmd = -1; + int type = -1; + + ret = dict_get_int32 (local->dict, "sub-cmd", &cmd); + if (ret) { + gf_log ("cli", GF_LOG_ERROR, "Failed to get " + "sub-cmd"); + ret = 0; + goto out; + } + + if (cmd == GF_SNAP_STATUS_TYPE_SNAP || + cmd == GF_SNAP_DELETE_TYPE_SNAP){ + ret = 0; + goto out; + } + + ret = dict_get_int32 (local->dict, "type", &type); + if (ret) { + gf_log ("cli", GF_LOG_ERROR, "Failed to get snapshot " + "command type from dictionary"); + goto out; + } + + if (GF_SNAP_OPTION_TYPE_STATUS == type) + ret = cli_xml_output_snap_status_end (local); + else if (GF_SNAP_OPTION_TYPE_DELETE == type) + ret = cli_xml_output_snap_delete_end (local); + + if (ret) { + gf_log ("cli", GF_LOG_ERROR, "Error creating xml " + "output"); + goto out; + } +#endif /* HAVE_LIB_XML */ + ret = 0; +out: + return ret; +} + int cli_xml_snapshot_status_single_snap (cli_local_t *local, dict_t *dict, char *key) diff --git a/cli/src/cli.h b/cli/src/cli.h index deadd2d0a5d..47da896efb7 100644 --- a/cli/src/cli.h +++ b/cli/src/cli.h @@ -422,6 +422,24 @@ cli_xml_output_vol_gsync (dict_t *dict, int op_ret, int op_errno, int cli_xml_output_vol_status_tasks_detail (cli_local_t *local, dict_t *dict); +int +cli_xml_output_common (xmlTextWriterPtr writer, int op_ret, int op_errno, + char *op_errstr); +int +cli_xml_snapshot_delete (xmlTextWriterPtr writer, xmlDocPtr doc, dict_t *dict, + gf_cli_rsp *rsp); +int +cli_xml_snapshot_begin_composite_op (cli_local_t *local); + +int +cli_xml_snapshot_end_composite_op (cli_local_t *local); + +int +cli_xml_output_snap_delete_begin (cli_local_t *local, int op_ret, int op_errno, + char *op_errstr); +int +cli_xml_output_snap_delete_end (cli_local_t *local); + int cli_xml_output_snap_status_begin (cli_local_t *local, int op_ret, int op_errno, char *op_errstr); -- cgit