d759b5
From 8f8cc927a643f9bd02ff37f0fe6167e44359fb12 Mon Sep 17 00:00:00 2001
d759b5
Message-Id: <8f8cc927a643f9bd02ff37f0fe6167e44359fb12@dist-git>
7b4659
From: Jiri Denemark <jdenemar@redhat.com>
7b4659
Date: Fri, 16 Aug 2019 14:52:35 +0200
7b4659
Subject: [PATCH] qemu: Pass correct qemuCaps to virDomainDefParseNode
7b4659
MIME-Version: 1.0
7b4659
Content-Type: text/plain; charset=UTF-8
7b4659
Content-Transfer-Encoding: 8bit
7b4659
7b4659
Since qemuDomainDefPostParse callback requires qemuCaps, we need to make
7b4659
sure it gets the capabilities stored in the domain's private data if the
7b4659
domain is running. Passing NULL may cause QEMU capabilities probing to
7b4659
be triggered in case QEMU binary changed in the meantime. When this
7b4659
happens while a running domain object is locked, QMP event delivered to
7b4659
the domain before QEMU capabilities probing finishes will deadlock the
7b4659
event loop.
7b4659
7b4659
Several general snapshot and checkpoint APIs were lazily passing NULL as
7b4659
the parseOpaque pointer instead of letting their callers pass the right
7b4659
data. This patch fixes all paths leading to virDomainDefParseNode.
7b4659
7b4659
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
7b4659
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
7b4659
(cherry picked from commit 577a1f98fc84e4152c246695942502ef9a45c7f7)
7b4659
7b4659
Conflicts:
7b4659
	src/conf/checkpoint_conf.c
7b4659
	src/conf/checkpoint_conf.h
7b4659
	src/conf/snapshot_conf.c
7b4659
	src/conf/snapshot_conf.h
7b4659
	src/esx/esx_driver.c
7b4659
	src/qemu/qemu_driver.c
7b4659
	src/test/test_driver.c
7b4659
	src/vbox/vbox_common.c
7b4659
	tests/qemudomaincheckpointxml2xmltest.c
7b4659
            - no checkpoint APIs
7b4659
            - snapshot parsing APIs do not have bool *current parameter
7b4659
7b4659
	tests/qemudomainsnapshotxml2xmltest.c
7b4659
            - this is called domainsnapshotxml2xmltest.c downstream
7b4659
            - snapshot parsing APIs do not have bool *current parameter
7b4659
7b4659
https://bugzilla.redhat.com/show_bug.cgi?id=1731783
7b4659
7b4659
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
7b4659
Message-Id: <da71e1d080893d3290d18281cb375588d5bc7e7b.1565959866.git.jdenemar@redhat.com>
7b4659
Reviewed-by: Ján Tomko <jtomko@redhat.com>
7b4659
---
7b4659
 src/conf/snapshot_conf.c          |  9 ++++++---
7b4659
 src/conf/snapshot_conf.h          |  2 ++
7b4659
 src/esx/esx_driver.c              |  2 +-
7b4659
 src/qemu/qemu_driver.c            | 10 +++++++---
7b4659
 src/test/test_driver.c            |  3 ++-
7b4659
 src/vbox/vbox_common.c            |  4 ++--
7b4659
 tests/domainsnapshotxml2xmltest.c |  2 +-
7b4659
 7 files changed, 21 insertions(+), 11 deletions(-)
7b4659
7b4659
diff --git a/src/conf/snapshot_conf.c b/src/conf/snapshot_conf.c
7b4659
index 9c537ac7d1..75df496201 100644
7b4659
--- a/src/conf/snapshot_conf.c
7b4659
+++ b/src/conf/snapshot_conf.c
7b4659
@@ -203,6 +203,7 @@ static virDomainSnapshotDefPtr
7b4659
 virDomainSnapshotDefParse(xmlXPathContextPtr ctxt,
7b4659
                           virCapsPtr caps,
7b4659
                           virDomainXMLOptionPtr xmlopt,
7b4659
+                          void *parseOpaque,
7b4659
                           unsigned int flags)
7b4659
 {
7b4659
     virDomainSnapshotDefPtr def = NULL;
7b4659
@@ -284,7 +285,7 @@ virDomainSnapshotDefParse(xmlXPathContextPtr ctxt,
7b4659
                 goto cleanup;
7b4659
             }
7b4659
             def->dom = virDomainDefParseNode(ctxt->node->doc, domainNode,
7b4659
-                                             caps, xmlopt, NULL, domainflags);
7b4659
+                                             caps, xmlopt, parseOpaque, domainflags);
7b4659
             if (!def->dom)
7b4659
                 goto cleanup;
7b4659
         } else {
7b4659
@@ -389,6 +390,7 @@ virDomainSnapshotDefParseNode(xmlDocPtr xml,
7b4659
                               xmlNodePtr root,
7b4659
                               virCapsPtr caps,
7b4659
                               virDomainXMLOptionPtr xmlopt,
7b4659
+                              void *parseOpaque,
7b4659
                               unsigned int flags)
7b4659
 {
7b4659
     xmlXPathContextPtr ctxt = NULL;
7b4659
@@ -406,7 +408,7 @@ virDomainSnapshotDefParseNode(xmlDocPtr xml,
7b4659
     }
7b4659
 
7b4659
     ctxt->node = root;
7b4659
-    def = virDomainSnapshotDefParse(ctxt, caps, xmlopt, flags);
7b4659
+    def = virDomainSnapshotDefParse(ctxt, caps, xmlopt, parseOpaque, flags);
7b4659
  cleanup:
7b4659
     xmlXPathFreeContext(ctxt);
7b4659
     return def;
7b4659
@@ -416,6 +418,7 @@ virDomainSnapshotDefPtr
7b4659
 virDomainSnapshotDefParseString(const char *xmlStr,
7b4659
                                 virCapsPtr caps,
7b4659
                                 virDomainXMLOptionPtr xmlopt,
7b4659
+                                void *parseOpaque,
7b4659
                                 unsigned int flags)
7b4659
 {
7b4659
     virDomainSnapshotDefPtr ret = NULL;
7b4659
@@ -425,7 +428,7 @@ virDomainSnapshotDefParseString(const char *xmlStr,
7b4659
     if ((xml = virXMLParse(NULL, xmlStr, _("(domain_snapshot)")))) {
7b4659
         xmlKeepBlanksDefault(keepBlanksDefault);
7b4659
         ret = virDomainSnapshotDefParseNode(xml, xmlDocGetRootElement(xml),
7b4659
-                                            caps, xmlopt, flags);
7b4659
+                                            caps, xmlopt, parseOpaque, flags);
7b4659
         xmlFreeDoc(xml);
7b4659
     }
7b4659
     xmlKeepBlanksDefault(keepBlanksDefault);
7b4659
diff --git a/src/conf/snapshot_conf.h b/src/conf/snapshot_conf.h
7b4659
index 20a42bd572..733f1dd071 100644
7b4659
--- a/src/conf/snapshot_conf.h
7b4659
+++ b/src/conf/snapshot_conf.h
7b4659
@@ -106,11 +106,13 @@ typedef enum {
7b4659
 virDomainSnapshotDefPtr virDomainSnapshotDefParseString(const char *xmlStr,
7b4659
                                                         virCapsPtr caps,
7b4659
                                                         virDomainXMLOptionPtr xmlopt,
7b4659
+                                                        void *parseOpaque,
7b4659
                                                         unsigned int flags);
7b4659
 virDomainSnapshotDefPtr virDomainSnapshotDefParseNode(xmlDocPtr xml,
7b4659
                                                       xmlNodePtr root,
7b4659
                                                       virCapsPtr caps,
7b4659
                                                       virDomainXMLOptionPtr xmlopt,
7b4659
+                                                      void *parseOpaque,
7b4659
                                                       unsigned int flags);
7b4659
 void virDomainSnapshotDefFree(virDomainSnapshotDefPtr def);
7b4659
 char *virDomainSnapshotDefFormat(const char *domain_uuid,
7b4659
diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c
7b4659
index 60aa5fc252..4ef856d71c 100644
7b4659
--- a/src/esx/esx_driver.c
7b4659
+++ b/src/esx/esx_driver.c
7b4659
@@ -4156,7 +4156,7 @@ esxDomainSnapshotCreateXML(virDomainPtr domain, const char *xmlDesc,
7b4659
         return NULL;
7b4659
 
7b4659
     def = virDomainSnapshotDefParseString(xmlDesc, priv->caps,
7b4659
-                                          priv->xmlopt, 0);
7b4659
+                                          priv->xmlopt, NULL, 0);
7b4659
 
7b4659
     if (!def)
7b4659
         return NULL;
7b4659
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
7b4659
index cc7210c6f4..00213a5f80 100644
7b4659
--- a/src/qemu/qemu_driver.c
7b4659
+++ b/src/qemu/qemu_driver.c
7b4659
@@ -431,8 +431,12 @@ qemuDomainSnapshotLoad(virDomainObjPtr vm,
7b4659
     int ret = -1;
7b4659
     virCapsPtr caps = NULL;
7b4659
     int direrr;
7b4659
+    qemuDomainObjPrivatePtr priv;
7b4659
 
7b4659
     virObjectLock(vm);
7b4659
+
7b4659
+    priv = vm->privateData;
7b4659
+
7b4659
     if (virAsprintf(&snapDir, "%s/%s", baseDir, vm->def->name) < 0) {
7b4659
         virReportError(VIR_ERR_INTERNAL_ERROR,
7b4659
                        _("Failed to allocate memory for "
7b4659
@@ -472,6 +476,7 @@ qemuDomainSnapshotLoad(virDomainObjPtr vm,
7b4659
 
7b4659
         def = virDomainSnapshotDefParseString(xmlStr, caps,
7b4659
                                               qemu_driver->xmlopt,
7b4659
+                                              priv->qemuCaps,
7b4659
                                               flags);
7b4659
         if (def == NULL) {
7b4659
             /* Nothing we can do here, skip this one */
7b4659
@@ -15312,6 +15317,7 @@ qemuDomainSnapshotCreateXML(virDomainPtr domain,
7b4659
     if (!(vm = qemuDomObjFromDomain(domain)))
7b4659
         goto cleanup;
7b4659
 
7b4659
+    priv = vm->privateData;
7b4659
     cfg = virQEMUDriverGetConfig(driver);
7b4659
 
7b4659
     if (virDomainSnapshotCreateXMLEnsureACL(domain->conn, vm->def, flags) < 0)
7b4659
@@ -15336,7 +15342,7 @@ qemuDomainSnapshotCreateXML(virDomainPtr domain,
7b4659
         parse_flags |= VIR_DOMAIN_SNAPSHOT_PARSE_OFFLINE;
7b4659
 
7b4659
     if (!(def = virDomainSnapshotDefParseString(xmlDesc, caps, driver->xmlopt,
7b4659
-                                                parse_flags)))
7b4659
+                                                priv->qemuCaps, parse_flags)))
7b4659
         goto cleanup;
7b4659
 
7b4659
     /* reject snapshot names containing slashes or starting with dot as
7b4659
@@ -15405,8 +15411,6 @@ qemuDomainSnapshotCreateXML(virDomainPtr domain,
7b4659
 
7b4659
     qemuDomainObjSetAsyncJobMask(vm, QEMU_JOB_NONE);
7b4659
 
7b4659
-    priv = vm->privateData;
7b4659
-
7b4659
     if (redefine) {
7b4659
         if (virDomainSnapshotRedefinePrep(domain, vm, &def, &snap,
7b4659
                                           driver->xmlopt,
7b4659
diff --git a/src/test/test_driver.c b/src/test/test_driver.c
7b4659
index 1a25b37729..1c7e4f4982 100644
7b4659
--- a/src/test/test_driver.c
7b4659
+++ b/src/test/test_driver.c
7b4659
@@ -849,6 +849,7 @@ testParseDomainSnapshots(testDriverPtr privconn,
7b4659
         def = virDomainSnapshotDefParseNode(ctxt->doc, node,
7b4659
                                             privconn->caps,
7b4659
                                             privconn->xmlopt,
7b4659
+                                            NULL,
7b4659
                                             VIR_DOMAIN_SNAPSHOT_PARSE_DISKS |
7b4659
                                             VIR_DOMAIN_SNAPSHOT_PARSE_INTERNAL |
7b4659
                                             VIR_DOMAIN_SNAPSHOT_PARSE_REDEFINE);
7b4659
@@ -6403,6 +6404,7 @@ testDomainSnapshotCreateXML(virDomainPtr domain,
7b4659
     if (!(def = virDomainSnapshotDefParseString(xmlDesc,
7b4659
                                                 privconn->caps,
7b4659
                                                 privconn->xmlopt,
7b4659
+                                                NULL,
7b4659
                                                 parse_flags)))
7b4659
         goto cleanup;
7b4659
 
7b4659
@@ -6808,7 +6810,6 @@ testDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
7b4659
 }
7b4659
 
7b4659
 
7b4659
-
7b4659
 static virHypervisorDriver testHypervisorDriver = {
7b4659
     .name = "Test",
7b4659
     .connectOpen = testConnectOpen, /* 0.1.1 */
7b4659
diff --git a/src/vbox/vbox_common.c b/src/vbox/vbox_common.c
7b4659
index 664650f217..46d2b7afa3 100644
7b4659
--- a/src/vbox/vbox_common.c
7b4659
+++ b/src/vbox/vbox_common.c
7b4659
@@ -5496,7 +5496,7 @@ vboxDomainSnapshotCreateXML(virDomainPtr dom,
7b4659
                   VIR_DOMAIN_SNAPSHOT_CREATE_CURRENT, NULL);
7b4659
 
7b4659
     if (!(def = virDomainSnapshotDefParseString(xmlDesc, data->caps,
7b4659
-                                                data->xmlopt,
7b4659
+                                                data->xmlopt, NULL,
7b4659
                                                 VIR_DOMAIN_SNAPSHOT_PARSE_DISKS |
7b4659
                                                 VIR_DOMAIN_SNAPSHOT_PARSE_REDEFINE)))
7b4659
         goto cleanup;
7b4659
@@ -6941,7 +6941,7 @@ vboxDomainSnapshotDeleteMetadataOnly(virDomainSnapshotPtr snapshot)
7b4659
     }
7b4659
     def = virDomainSnapshotDefParseString(defXml,
7b4659
                                           data->caps,
7b4659
-                                          data->xmlopt,
7b4659
+                                          data->xmlopt, NULL,
7b4659
                                           VIR_DOMAIN_SNAPSHOT_PARSE_DISKS |
7b4659
                                           VIR_DOMAIN_SNAPSHOT_PARSE_REDEFINE);
7b4659
     if (!def) {
7b4659
diff --git a/tests/domainsnapshotxml2xmltest.c b/tests/domainsnapshotxml2xmltest.c
d759b5
index 2b594e626c..a4e31de811 100644
7b4659
--- a/tests/domainsnapshotxml2xmltest.c
7b4659
+++ b/tests/domainsnapshotxml2xmltest.c
7b4659
@@ -96,7 +96,7 @@ testCompareXMLToXMLFiles(const char *inxml,
7b4659
         goto cleanup;
7b4659
 
7b4659
     if (!(def = virDomainSnapshotDefParseString(inXmlData, driver.caps,
7b4659
-                                                driver.xmlopt,
7b4659
+                                                driver.xmlopt, NULL,
7b4659
                                                 flags)))
7b4659
         goto cleanup;
7b4659
 
7b4659
-- 
7b4659
2.22.1
7b4659