Blob Blame History Raw
From ca1a22bec82e5cb2f7ed2ec88d55bdc9e5a0dca1 Mon Sep 17 00:00:00 2001
From: Rajesh Joseph <rjoseph@redhat.com>
Date: Wed, 26 Aug 2015 08:28:59 +0530
Subject: [PATCH 316/320] 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: 1245077
Signed-off-by: Rajesh Joseph <rjoseph@redhat.com>
Reviewed-on: http://review.gluster.org/12027
Tested-by: NetBSD Build System <jenkins@build.gluster.org>
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Avra Sengupta <asengupt@redhat.com>
Reviewed-on: https://code.engineering.redhat.com/gerrit/56628
---
 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 ++
 rpc/xdr/src/cli1-xdr.x                        |    6 +-
 xlators/mgmt/glusterd/src/glusterd-snapshot.c |   11 +-
 6 files changed, 357 insertions(+), 121 deletions(-)

diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c
index 0f7b5be..0d3ca29 100644
--- a/cli/src/cli-cmd-parser.c
+++ b/cli/src/cli-cmd-parser.c
@@ -4311,7 +4311,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");
@@ -4391,7 +4391,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 fd76df7..413a326 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 b558a9a..9960635 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);
-
-        /* <snapDelete> */
-        ret = xmlTextWriterStartElement (writer, (xmlChar *)"snapDelete");
-        XML_RET_CHECK_AND_GOTO (ret, out);
-
-        /* <snapshot> */
-        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);
-
-        /* </snapshot> */
-        ret = xmlTextWriterEndElement (writer);
-        XML_RET_CHECK_AND_GOTO (ret, out);
-
-        /* </snapDelete> */
-        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.
  *
@@ -4908,7 +4849,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;
@@ -5338,6 +5279,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);
+
+        /* <snapshot> */
+        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:
+        /* </snapshot> */
+        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)
@@ -5396,6 +5412,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);
+
+        /* <snapStatus> */
+        ret = xmlTextWriterStartElement (local->writer,
+                                         (xmlChar *) "snapDelete");
+        XML_RET_CHECK_AND_GOTO (ret, out);
+
+        /* <snapshots> */
+        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);
+
+        /* </snapshots> */
+        ret = xmlTextWriterEndElement (local->writer);
+        XML_RET_CHECK_AND_GOTO (ret, out);
+
+        /* </snapDelete> */
+        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
@@ -5446,14 +5526,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) {
@@ -5525,6 +5597,96 @@ out:
 }
 
 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 d831af0..a971d02 100644
--- a/cli/src/cli.h
+++ b/cli/src/cli.h
@@ -428,6 +428,24 @@ 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);
 int
diff --git a/rpc/xdr/src/cli1-xdr.x b/rpc/xdr/src/cli1-xdr.x
index 34f324f..73863ae 100644
--- a/rpc/xdr/src/cli1-xdr.x
+++ b/rpc/xdr/src/cli1-xdr.x
@@ -189,13 +189,15 @@ enum gf1_cli_snapshot_config {
 enum  gf1_cli_snapshot_status {
         GF_SNAP_STATUS_TYPE_ALL = 0,
         GF_SNAP_STATUS_TYPE_SNAP,
-        GF_SNAP_STATUS_TYPE_VOL
+        GF_SNAP_STATUS_TYPE_VOL,
+        GF_SNAP_STATUS_TYPE_ITER
 };
 
 enum gf1_cli_snapshot_delete {
         GF_SNAP_DELETE_TYPE_ALL  = 0,
         GF_SNAP_DELETE_TYPE_SNAP = 1,
-        GF_SNAP_DELETE_TYPE_VOL  = 2
+        GF_SNAP_DELETE_TYPE_VOL  = 2,
+        GF_SNAP_DELETE_TYPE_ITER = 3
 };
 
 struct gf_cli_req {
diff --git a/xlators/mgmt/glusterd/src/glusterd-snapshot.c b/xlators/mgmt/glusterd/src/glusterd-snapshot.c
index 6f10ebc..089eb61 100644
--- a/xlators/mgmt/glusterd/src/glusterd-snapshot.c
+++ b/xlators/mgmt/glusterd/src/glusterd-snapshot.c
@@ -5506,15 +5506,16 @@ glusterd_handle_snapshot_delete (rpcsvc_request_t *req, glusterd_op_t op,
         GF_ASSERT (err_str);
         GF_VALIDATE_OR_GOTO (this->name, op_errno, out);
 
-        ret = dict_get_int32 (dict, "delete-cmd", &delete_cmd);
+        ret = dict_get_int32 (dict, "sub-cmd", &delete_cmd);
         if (ret) {
                 gf_msg (this->name, GF_LOG_ERROR, 0,
-                        GD_MSG_COMMAND_NOT_FOUND, "Failed to get delete-cmd");
+                        GD_MSG_COMMAND_NOT_FOUND, "Failed to get sub-cmd");
                 goto out;
         }
 
         switch (delete_cmd) {
         case GF_SNAP_DELETE_TYPE_SNAP:
+        case GF_SNAP_DELETE_TYPE_ITER:
                 ret = glusterd_handle_snapshot_delete_type_snap (req, op, dict,
                                                                  err_str,
                                                                  op_errno, len);
@@ -5647,7 +5648,7 @@ glusterd_snapshot_status_prevalidate (dict_t *dict, char **op_errstr,
                 goto out;
         }
 
-        ret = dict_get_int32 (dict, "status-cmd", &cmd);
+        ret = dict_get_int32 (dict, "sub-cmd", &cmd);
         if (ret) {
                 gf_msg (this->name, GF_LOG_ERROR, 0,
                         GD_MSG_DICT_GET_FAILED,
@@ -7531,7 +7532,7 @@ glusterd_snapshot_status_commit (dict_t *dict, char **op_errstr,
         conf = this->private;
 
         GF_ASSERT (conf);
-        ret = dict_get_int32 (dict, "status-cmd", &cmd);
+        ret = dict_get_int32 (dict, "sub-cmd", &cmd);
         if (ret) {
                 gf_msg (this->name, GF_LOG_ERROR, 0,
                         GD_MSG_DICT_GET_FAILED,
@@ -7539,7 +7540,7 @@ glusterd_snapshot_status_commit (dict_t *dict, char **op_errstr,
                 goto out;
         }
 
-        ret = dict_set_int32 (rsp_dict, "status-cmd", cmd);
+        ret = dict_set_int32 (rsp_dict, "sub-cmd", cmd);
         if (ret) {
                 gf_msg (this->name, GF_LOG_ERROR, 0,
                         GD_MSG_DICT_SET_FAILED,
-- 
1.7.1