[libvirt] [PATCH 1/2] virsh: Switch from generated cmd*Edit commands to nongenerated

Michal Privoznik mprivozn at redhat.com
Fri May 18 12:48:38 UTC 2012


Currently, we either generate some cmd*Edit commands (cmdPoolEdit
and cmdNetworkEdit) via sed script or copy the body of cmdEdit
(e.g. cmdInterfaceEdit, cmdNWFilterEdit, etc.). This fact makes
it harder to implement any new feature to our editing system.
Therefore switch to new implementation - define macros to:
- dump XML (EDIT_GET_XML)
- take an action if XML wasn't changed,
  usually just vshPrint() (EDIT_NOT_CHANGED)
- define new object (EDIT_DEFINE) - the edited XML is in @doc_edited
and #include "virsh-edit.c"
---
 cfg.mk             |    4 +-
 po/POTFILES.in     |    1 +
 tools/Makefile.am  |   36 +-----
 tools/virsh-edit.c |   69 +++++++++
 tools/virsh.c      |  394 +++++++++++++++++-----------------------------------
 5 files changed, 199 insertions(+), 305 deletions(-)
 create mode 100644 tools/virsh-edit.c

diff --git a/cfg.mk b/cfg.mk
index 07fb7b2..06a572f 100644
--- a/cfg.mk
+++ b/cfg.mk
@@ -820,9 +820,9 @@ exclude_file_name_regexp--sc_prohibit_xmlURI = ^src/util/viruri\.c$$
 
 exclude_file_name_regexp--sc_prohibit_return_as_function = \.py$$
 
-exclude_file_name_regexp--sc_require_config_h = ^examples/
+exclude_file_name_regexp--sc_require_config_h = ^(examples/|tools/virsh-edit.c$$)
 
-exclude_file_name_regexp--sc_require_config_h_first = ^examples/
+exclude_file_name_regexp--sc_require_config_h_first = ^(examples/|tools/virsh-edit.c$$)
 
 exclude_file_name_regexp--sc_trailing_blank = \
   (/qemuhelpdata/|\.(fig|gif|ico|png)$$)
diff --git a/po/POTFILES.in b/po/POTFILES.in
index cfa9d44..03fb03f 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -169,6 +169,7 @@ src/xenxs/xen_xm.c
 tools/console.c
 tools/libvirt-guests.init.sh
 tools/virsh.c
+tools/virsh-edit.c
 tools/virt-host-validate-common.c
 tools/virt-host-validate-lxc.c
 tools/virt-host-validate-qemu.c
diff --git a/tools/Makefile.am b/tools/Makefile.am
index c0c907e..7b77595 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -111,41 +111,7 @@ virsh_CFLAGS =							\
 		$(COVERAGE_CFLAGS)				\
 		$(LIBXML_CFLAGS)				\
 		$(READLINE_CFLAGS)
-BUILT_SOURCES = virsh-net-edit.c virsh-pool-edit.c
-
-virsh-net-edit.c: virsh.c Makefile.am
-	$(AM_V_GEN)rm -f $@-tmp && \
-	echo '/* Automatically generated from: $^ */' > $@-tmp && \
-	echo 'static bool' >> $@-tmp && \
-	awk '/^cmdEdit/, /^}/' $< \
-	  | sed -e 's/domain/network/g' \
-	      -e 's/Domain/Network/g' \
-	      -e 's/cmdEdit/cmdNetworkEdit/g' \
-	      -e 's/dom/network/g' \
-	      -e 's/int flags.*/int flags = 0;/g' \
-	>> $@-tmp && \
-	chmod a-w $@-tmp && \
-	rm -f $@ && \
-	mv $@-tmp $@
-
-virsh-pool-edit.c: virsh.c Makefile.am
-	$(AM_V_GEN)rm -f $@-tmp && \
-	echo '/* Automatically generated from: $^ */' > $@-tmp && \
-	echo 'static bool' >> $@-tmp && \
-	awk '/^cmdEdit/, /^}/' $< \
-	  | sed -e 's/domain/pool/g' \
-	      -e 's/vshCommandOptDomain/vshCommandOptPool/g' \
-	      -e 's/Domain %s/Pool %s/g' \
-	      -e 's/(ctl, cmd, NULL);/(ctl, cmd, "pool", NULL);/' \
-	      -e 's/Domain/StoragePool/g' \
-	      -e 's/cmdEdit/cmdPoolEdit/g' \
-	      -e 's/\(virStoragePoolDefineXML.*\));/\1, 0);/' \
-	      -e 's/dom/pool/g' \
-	      -e 's/int flags.*/int flags = 0;/g' \
-	>> $@-tmp && \
-	chmod a-w $@-tmp && \
-	rm -f $@ && \
-	mv $@-tmp $@
+BUILT_SOURCES = virsh-edit.c
 
 
 if WITH_WIN_ICON
diff --git a/tools/virsh-edit.c b/tools/virsh-edit.c
new file mode 100644
index 0000000..060dc14
--- /dev/null
+++ b/tools/virsh-edit.c
@@ -0,0 +1,69 @@
+do {
+    char *tmp = NULL;
+    char *doc = NULL;
+    char *doc_edited = NULL;
+    char *doc_reread = NULL;
+
+    /* Get the XML configuration of the domain. */
+    doc = EDIT_GET_XML;
+    if (!doc)
+        goto edit_cleanup;
+
+    /* Create and open the temporary file. */
+    tmp = editWriteToTempFile (ctl, doc);
+    if (!tmp)
+        goto edit_cleanup;
+
+    /* Start the editor. */
+    if (editFile (ctl, tmp) == -1)
+        goto edit_cleanup;
+
+    /* Read back the edited file. */
+    doc_edited = editReadBackFile (ctl, tmp);
+    if (!doc_edited)
+        goto edit_cleanup;
+
+    /* Compare original XML with edited.  Has it changed at all? */
+    if (STREQ (doc, doc_edited)) {
+        EDIT_NOT_CHANGED;
+        ret = true;
+        goto edit_cleanup;
+    }
+
+    /* Now re-read the domain XML.  Did someone else change it while
+     * it was being edited?  This also catches problems such as us
+     * losing a connection or the domain going away.
+     */
+    doc_reread = EDIT_GET_XML;
+    if (!doc_reread)
+        goto edit_cleanup;
+
+    if (STRNEQ (doc, doc_reread)) {
+        vshError(ctl, "%s", _("ERROR: the XML configuration "
+                              "was changed by another user"));
+        goto edit_cleanup;
+    }
+
+    /* Everything checks out, so redefine the domain. */
+    if (!(EDIT_DEFINE))
+        goto edit_cleanup;
+
+    goto edit_continue;
+
+edit_cleanup:
+    VIR_FREE(doc);
+    VIR_FREE(doc_edited);
+    VIR_FREE(doc_reread);
+    if (tmp) {
+        unlink (tmp);
+        VIR_FREE(tmp);
+    }
+    goto cleanup;
+
+} while (0);
+
+edit_continue:
+
+#undef EDIT_GET_XML
+#undef EDIT_NOT_CHANGED
+#undef EDIT_DEFINE
diff --git a/tools/virsh.c b/tools/virsh.c
index 08b3854..fb8ede4 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -3422,9 +3422,6 @@ cmdSaveImageEdit(vshControl *ctl, const vshCmd *cmd)
 {
     const char *file = NULL;
     bool ret = false;
-    char *tmp = NULL;
-    char *doc = NULL;
-    char *doc_edited = NULL;
     unsigned int getxml_flags = VIR_DOMAIN_XML_SECURE;
     unsigned int define_flags = 0;
 
@@ -3448,51 +3445,18 @@ cmdSaveImageEdit(vshControl *ctl, const vshCmd *cmd)
     if (vshCommandOptString(cmd, "file", &file) <= 0)
         return false;
 
-    /* Get the XML configuration of the saved image.  */
-    doc = virDomainSaveImageGetXMLDesc(ctl->conn, file, getxml_flags);
-    if (!doc)
-        goto cleanup;
-
-    /* Create and open the temporary file.  */
-    tmp = editWriteToTempFile(ctl, doc);
-    if (!tmp)
-        goto cleanup;
-
-    /* Start the editor.  */
-    if (editFile(ctl, tmp) == -1)
-        goto cleanup;
-
-    /* Read back the edited file.  */
-    doc_edited = editReadBackFile(ctl, tmp);
-    if (!doc_edited)
-        goto cleanup;
-
-    /* Compare original XML with edited.  Short-circuit if it did not
-     * change, and we do not have any flags.  */
-    if (STREQ(doc, doc_edited) && !define_flags) {
-        vshPrint(ctl, _("Saved image %s XML configuration not changed.\n"),
-                 file);
-        ret = true;
-        goto cleanup;
-    }
-
-    /* Everything checks out, so redefine the xml.  */
-    if (virDomainSaveImageDefineXML(ctl->conn, file, doc_edited,
-                                    define_flags) < 0) {
-        vshError(ctl, _("Failed to update %s"), file);
-        goto cleanup;
-    }
+    #define EDIT_GET_XML \
+        virDomainSaveImageGetXMLDesc(ctl->conn, file, getxml_flags)
+    #define EDIT_NOT_CHANGED \
+        vshPrint(ctl, _("Saved image %s XML configuration not changed.\n"), file)
+    #define EDIT_DEFINE \
+        virDomainSaveImageDefineXML(ctl->conn, file, doc_edited, define_flags)
+    #include "virsh-edit.c"
 
     vshPrint(ctl, _("State file %s edited.\n"), file);
     ret = true;
 
 cleanup:
-    VIR_FREE(doc);
-    VIR_FREE(doc_edited);
-    if (tmp) {
-        unlink(tmp);
-        VIR_FREE(tmp);
-    }
     return ret;
 }
 
@@ -8547,10 +8511,7 @@ cmdInterfaceEdit (vshControl *ctl, const vshCmd *cmd)
 {
     bool ret = false;
     virInterfacePtr iface = NULL;
-    char *tmp = NULL;
-    char *doc = NULL;
-    char *doc_edited = NULL;
-    char *doc_reread = NULL;
+    virInterfacePtr iface_edited = NULL;
     unsigned int flags = VIR_INTERFACE_XML_INACTIVE;
 
     if (!vshConnectionUsability(ctl, ctl->conn))
@@ -8560,49 +8521,13 @@ cmdInterfaceEdit (vshControl *ctl, const vshCmd *cmd)
     if (iface == NULL)
         goto cleanup;
 
-    /* Get the XML configuration of the interface. */
-    doc = virInterfaceGetXMLDesc (iface, flags);
-    if (!doc)
-        goto cleanup;
-
-    /* Create and open the temporary file. */
-    tmp = editWriteToTempFile (ctl, doc);
-    if (!tmp) goto cleanup;
-
-    /* Start the editor. */
-    if (editFile (ctl, tmp) == -1) goto cleanup;
-
-    /* Read back the edited file. */
-    doc_edited = editReadBackFile (ctl, tmp);
-    if (!doc_edited) goto cleanup;
-
-    /* Compare original XML with edited.  Has it changed at all? */
-    if (STREQ (doc, doc_edited)) {
-        vshPrint (ctl, _("Interface %s XML configuration not changed.\n"),
-                  virInterfaceGetName (iface));
-        ret = true;
-        goto cleanup;
-    }
-
-    /* Now re-read the interface XML.  Did someone else change it while
-     * it was being edited?  This also catches problems such as us
-     * losing a connection or the interface going away.
-     */
-    doc_reread = virInterfaceGetXMLDesc (iface, flags);
-    if (!doc_reread)
-        goto cleanup;
-
-    if (STRNEQ (doc, doc_reread)) {
-        vshError(ctl, "%s",
-                 _("ERROR: the XML configuration was changed by another user"));
-        goto cleanup;
-    }
-
-    /* Everything checks out, so redefine the interface. */
-    virInterfaceFree (iface);
-    iface = virInterfaceDefineXML(ctl->conn, doc_edited, 0);
-    if (!iface)
-        goto cleanup;
+    #define EDIT_GET_XML virInterfaceGetXMLDesc (iface, flags)
+    #define EDIT_NOT_CHANGED \
+        vshPrint (ctl, _("Interface %s XML configuration not changed.\n"), \
+                  virInterfaceGetName (iface))
+    #define EDIT_DEFINE \
+        iface_edited = virInterfaceDefineXML(ctl->conn, doc_edited, 0)
+    #include "virsh-edit.c"
 
     vshPrint (ctl, _("Interface %s XML configuration edited.\n"),
               virInterfaceGetName(iface));
@@ -8611,16 +8536,9 @@ cmdInterfaceEdit (vshControl *ctl, const vshCmd *cmd)
 
 cleanup:
     if (iface)
-        virInterfaceFree (iface);
-
-    VIR_FREE(doc);
-    VIR_FREE(doc_edited);
-    VIR_FREE(doc_reread);
-
-    if (tmp) {
-        unlink (tmp);
-        VIR_FREE(tmp);
-    }
+        virInterfaceFree(iface);
+    if (iface_edited)
+        virInterfaceFree(iface_edited);
 
     return ret;
 }
@@ -9984,10 +9902,7 @@ cmdNWFilterEdit (vshControl *ctl, const vshCmd *cmd)
 {
     bool ret = false;
     virNWFilterPtr nwfilter = NULL;
-    char *tmp = NULL;
-    char *doc = NULL;
-    char *doc_edited = NULL;
-    char *doc_reread = NULL;
+    virNWFilterPtr nwfilter_edited = NULL;
 
     if (!vshConnectionUsability(ctl, ctl->conn))
         goto cleanup;
@@ -9996,49 +9911,14 @@ cmdNWFilterEdit (vshControl *ctl, const vshCmd *cmd)
     if (nwfilter == NULL)
         goto cleanup;
 
-    /* Get the XML configuration of the interface. */
-    doc = virNWFilterGetXMLDesc (nwfilter, 0);
-    if (!doc)
-        goto cleanup;
-
-    /* Create and open the temporary file. */
-    tmp = editWriteToTempFile (ctl, doc);
-    if (!tmp) goto cleanup;
-
-    /* Start the editor. */
-    if (editFile (ctl, tmp) == -1) goto cleanup;
-
-    /* Read back the edited file. */
-    doc_edited = editReadBackFile (ctl, tmp);
-    if (!doc_edited) goto cleanup;
-
-    /* Compare original XML with edited.  Has it changed at all? */
-    if (STREQ (doc, doc_edited)) {
-        vshPrint (ctl, _("Network filter %s XML configuration not changed.\n"),
-                  virNWFilterGetName (nwfilter));
-        ret = true;
-        goto cleanup;
-    }
-
-    /* Now re-read the network filter XML.  Did someone else change it while
-     * it was being edited?  This also catches problems such as us
-     * losing a connection or the interface going away.
-     */
-    doc_reread = virNWFilterGetXMLDesc (nwfilter, 0);
-    if (!doc_reread)
-        goto cleanup;
-
-    if (STRNEQ (doc, doc_reread)) {
-        vshError(ctl, "%s",
-                 _("ERROR: the XML configuration was changed by another user"));
-        goto cleanup;
-    }
-
-    /* Everything checks out, so redefine the interface. */
-    virNWFilterFree (nwfilter);
-    nwfilter = virNWFilterDefineXML(ctl->conn, doc_edited);
-    if (!nwfilter)
-        goto cleanup;
+    #define EDIT_GET_XML virNWFilterGetXMLDesc (nwfilter, 0)
+    #define EDIT_NOT_CHANGED \
+        vshPrint (ctl, _("Network filter %s XML " \
+                         "configuration not changed.\n"), \
+                  virNWFilterGetName (nwfilter))
+    #define EDIT_DEFINE \
+        nwfilter_edited = virNWFilterDefineXML(ctl->conn, doc_edited)
+    #include "virsh-edit.c"
 
     vshPrint (ctl, _("Network filter %s XML configuration edited.\n"),
               virNWFilterGetName(nwfilter));
@@ -10047,16 +9927,9 @@ cmdNWFilterEdit (vshControl *ctl, const vshCmd *cmd)
 
 cleanup:
     if (nwfilter)
-        virNWFilterFree (nwfilter);
-
-    VIR_FREE(doc);
-    VIR_FREE(doc_edited);
-    VIR_FREE(doc_reread);
-
-    if (tmp) {
-        unlink (tmp);
-        VIR_FREE(tmp);
-    }
+        virNWFilterFree(nwfilter);
+    if (nwfilter_edited)
+        virNWFilterFree(nwfilter_edited);
 
     return ret;
 }
@@ -15806,10 +15679,7 @@ cmdEdit (vshControl *ctl, const vshCmd *cmd)
 {
     bool ret = false;
     virDomainPtr dom = NULL;
-    char *tmp = NULL;
-    char *doc = NULL;
-    char *doc_edited = NULL;
-    char *doc_reread = NULL;
+    virDomainPtr dom_edited = NULL;
     unsigned int flags = VIR_DOMAIN_XML_SECURE | VIR_DOMAIN_XML_INACTIVE;
 
     if (!vshConnectionUsability(ctl, ctl->conn))
@@ -15819,49 +15689,12 @@ cmdEdit (vshControl *ctl, const vshCmd *cmd)
     if (dom == NULL)
         goto cleanup;
 
-    /* Get the XML configuration of the domain. */
-    doc = virDomainGetXMLDesc (dom, flags);
-    if (!doc)
-        goto cleanup;
-
-    /* Create and open the temporary file. */
-    tmp = editWriteToTempFile (ctl, doc);
-    if (!tmp) goto cleanup;
-
-    /* Start the editor. */
-    if (editFile (ctl, tmp) == -1) goto cleanup;
-
-    /* Read back the edited file. */
-    doc_edited = editReadBackFile (ctl, tmp);
-    if (!doc_edited) goto cleanup;
-
-    /* Compare original XML with edited.  Has it changed at all? */
-    if (STREQ (doc, doc_edited)) {
-        vshPrint (ctl, _("Domain %s XML configuration not changed.\n"),
-                  virDomainGetName (dom));
-        ret = true;
-        goto cleanup;
-    }
-
-    /* Now re-read the domain XML.  Did someone else change it while
-     * it was being edited?  This also catches problems such as us
-     * losing a connection or the domain going away.
-     */
-    doc_reread = virDomainGetXMLDesc (dom, flags);
-    if (!doc_reread)
-        goto cleanup;
-
-    if (STRNEQ (doc, doc_reread)) {
-        vshError(ctl,
-                 "%s", _("ERROR: the XML configuration was changed by another user"));
-        goto cleanup;
-    }
-
-    /* Everything checks out, so redefine the domain. */
-    virDomainFree (dom);
-    dom = virDomainDefineXML(ctl->conn, doc_edited);
-    if (!dom)
-        goto cleanup;
+    #define EDIT_GET_XML virDomainGetXMLDesc (dom, flags)
+    #define EDIT_NOT_CHANGED \
+        vshPrint (ctl, _("Domain %s XML configuration not changed.\n"), \
+                  virDomainGetName (dom))
+    #define EDIT_DEFINE dom_edited = virDomainDefineXML(ctl->conn, doc_edited)
+    #include "virsh-edit.c"
 
     vshPrint (ctl, _("Domain %s XML configuration edited.\n"),
               virDomainGetName(dom));
@@ -15870,16 +15703,9 @@ cmdEdit (vshControl *ctl, const vshCmd *cmd)
 
  cleanup:
     if (dom)
-        virDomainFree (dom);
-
-    VIR_FREE(doc);
-    VIR_FREE(doc_edited);
-    VIR_FREE(doc_reread);
-
-    if (tmp) {
-        unlink (tmp);
-        VIR_FREE(tmp);
-    }
+        virDomainFree(dom);
+    if (dom_edited)
+        virDomainFree(dom_edited);
 
     return ret;
 }
@@ -15899,8 +15725,41 @@ static const vshCmdOptDef opts_network_edit[] = {
     {NULL, 0, 0, NULL}
 };
 
-/* This is generated from this file by a sed script in the Makefile. */
-#include "virsh-net-edit.c"
+static bool
+cmdNetworkEdit (vshControl *ctl, const vshCmd *cmd)
+{
+    bool ret = false;
+    virNetworkPtr network = NULL;
+    virNetworkPtr network_edited = NULL;
+    unsigned int flags = 0;
+
+    if (!vshConnectionUsability(ctl, ctl->conn))
+        goto cleanup;
+
+    network = vshCommandOptNetwork (ctl, cmd, NULL);
+    if (network == NULL)
+        goto cleanup;
+
+    #define EDIT_GET_XML virNetworkGetXMLDesc (network, flags)
+    #define EDIT_NOT_CHANGED \
+        vshPrint (ctl, _("Network %s XML configuration not changed.\n"), \
+                  virNetworkGetName (network))
+    #define EDIT_DEFINE network_edited = virNetworkDefineXML(ctl->conn, doc_edited)
+    #include "virsh-edit.c"
+
+    vshPrint (ctl, _("Network %s XML configuration edited.\n"),
+              virNetworkGetName(network));
+
+    ret = true;
+
+ cleanup:
+    if (network)
+        virNetworkFree(network);
+    if (network_edited)
+        virNetworkFree(network_edited);
+
+    return ret;
+}
 
 /*
  * "pool-edit" command
@@ -15916,8 +15775,42 @@ static const vshCmdOptDef opts_pool_edit[] = {
     {NULL, 0, 0, NULL}
 };
 
-/* This is generated from this file by a sed script in the Makefile. */
-#include "virsh-pool-edit.c"
+static bool
+cmdPoolEdit (vshControl *ctl, const vshCmd *cmd)
+{
+    bool ret = false;
+    virStoragePoolPtr pool = NULL;
+    virStoragePoolPtr pool_edited = NULL;
+    unsigned int flags = 0;
+
+    if (!vshConnectionUsability(ctl, ctl->conn))
+        goto cleanup;
+
+    pool = vshCommandOptPool (ctl, cmd, "pool", NULL);
+    if (pool == NULL)
+        goto cleanup;
+
+    #define EDIT_GET_XML virStoragePoolGetXMLDesc (pool, flags)
+    #define EDIT_NOT_CHANGED \
+        vshPrint (ctl, _("Pool %s XML configuration not changed.\n"), \
+                  virStoragePoolGetName (pool))
+    #define EDIT_DEFINE \
+        pool_edited = virStoragePoolDefineXML(ctl->conn, doc_edited, 0)
+    #include "virsh-edit.c"
+
+    vshPrint (ctl, _("Pool %s XML configuration edited.\n"),
+              virStoragePoolGetName(pool));
+
+    ret = true;
+
+ cleanup:
+    if (pool)
+        virStoragePoolFree(pool);
+    if (pool_edited)
+        virStoragePoolFree(pool_edited);
+
+    return ret;
+}
 
 /*
  * "quit" command
@@ -16310,9 +16203,6 @@ cmdSnapshotEdit(vshControl *ctl, const vshCmd *cmd)
     const char *name;
     const char *edited_name;
     bool ret = false;
-    char *tmp = NULL;
-    char *doc = NULL;
-    char *doc_edited = NULL;
     unsigned int getxml_flags = VIR_DOMAIN_XML_SECURE;
     unsigned int define_flags = VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE;
     bool rename_okay = vshCommandOptBool(cmd, "rename");
@@ -16339,45 +16229,17 @@ cmdSnapshotEdit(vshControl *ctl, const vshCmd *cmd)
                           &snapshot, &name) < 0)
         goto cleanup;
 
-    /* Get the XML configuration of the snapshot.  */
-    doc = virDomainSnapshotGetXMLDesc(snapshot, getxml_flags);
-    if (!doc)
-        goto cleanup;
-
-    /* strstr is safe here, since xml came from libvirt API and not user */
-    if (strstr(doc, "<state>disk-snapshot</state>"))
-        define_flags |= VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY;
-
-    /* Create and open the temporary file.  */
-    tmp = editWriteToTempFile(ctl, doc);
-    if (!tmp)
-        goto cleanup;
-
-    /* Start the editor.  */
-    if (editFile(ctl, tmp) == -1)
-        goto cleanup;
-
-    /* Read back the edited file.  */
-    doc_edited = editReadBackFile(ctl, tmp);
-    if (!doc_edited)
-        goto cleanup;
-
-    /* Compare original XML with edited.  Short-circuit if it did not
-     * change, and we do not have any flags.  */
-    if (STREQ(doc, doc_edited) &&
-        !(define_flags & VIR_DOMAIN_SNAPSHOT_CREATE_CURRENT)) {
-        vshPrint(ctl, _("Snapshot %s XML configuration not changed.\n"),
-                 name);
-        ret = true;
-        goto cleanup;
-    }
-
-    /* Everything checks out, so redefine the xml.  */
-    edited = virDomainSnapshotCreateXML(dom, doc_edited, define_flags);
-    if (!edited) {
-        vshError(ctl, _("Failed to update %s"), name);
-        goto cleanup;
-    }
+    #define EDIT_GET_XML \
+        virDomainSnapshotGetXMLDesc(snapshot, getxml_flags);
+    #define EDIT_NOT_CHANGED \
+        if (define_flags & VIR_DOMAIN_SNAPSHOT_CREATE_CURRENT) \
+            goto cleanup; \
+        vshPrint(ctl, _("Snapshot %s XML configuration not changed.\n"), name)
+    #define EDIT_DEFINE \
+        (strstr(doc, "<state>disk-snapshot</state>") ? \
+        define_flags |= VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY : 0), \
+        edited = virDomainSnapshotCreateXML(dom, doc_edited, define_flags)
+    #include "virsh-edit.c"
 
     edited_name = virDomainSnapshotGetName(edited);
     if (STREQ(name, edited_name)) {
@@ -16406,16 +16268,12 @@ cmdSnapshotEdit(vshControl *ctl, const vshCmd *cmd)
     ret = true;
 
 cleanup:
-    VIR_FREE(doc);
-    VIR_FREE(doc_edited);
-    if (tmp) {
-        unlink(tmp);
-        VIR_FREE(tmp);
-    }
-    if (snapshot)
-        virDomainSnapshotFree(snapshot);
     if (edited)
         virDomainSnapshotFree(edited);
+    else
+        vshError(ctl, _("Failed to update %s"), name);
+    if (snapshot)
+        virDomainSnapshotFree(snapshot);
     if (dom)
         virDomainFree(dom);
     return ret;
-- 
1.7.8.5




More information about the libvir-list mailing list