7b4659
From 7a3e5357cdd44f372dc8020395bdfd818d3453ed Mon Sep 17 00:00:00 2001
7b4659
Message-Id: <7a3e5357cdd44f372dc8020395bdfd818d3453ed@dist-git>
7b4659
From: Jiri Denemark <jdenemar@redhat.com>
7b4659
Date: Fri, 16 Aug 2019 14:52:27 +0200
7b4659
Subject: [PATCH] qemu: Pass qemuCaps to qemuDomainDefCopy
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
This patch fixes all paths leading to qemuDomainDefCopy.
7b4659
7b4659
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
7b4659
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
7b4659
(cherry picked from commit a42f889591c16235e0fe349e509af896fa1ea5ff)
7b4659
7b4659
Conflicts:
7b4659
	src/qemu/qemu_driver.c
7b4659
            - context
7b4659
7b4659
https://bugzilla.redhat.com/show_bug.cgi?id=1731783
7b4659
https://bugzilla.redhat.com/show_bug.cgi?id=1742023
7b4659
7b4659
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
7b4659
Message-Id: <6ecee413894eadadaf37884be7dd4136ad2de403.1565959866.git.jdenemar@redhat.com>
7b4659
Reviewed-by: Ján Tomko <jtomko@redhat.com>
7b4659
---
7b4659
 src/qemu/qemu_domain.c    | 16 ++++++++++------
7b4659
 src/qemu/qemu_domain.h    |  2 ++
7b4659
 src/qemu/qemu_driver.c    |  9 +++++----
7b4659
 src/qemu/qemu_migration.c |  4 ++--
7b4659
 4 files changed, 19 insertions(+), 12 deletions(-)
7b4659
7b4659
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
7b4659
index 81699110fc..bf6013d42a 100644
7b4659
--- a/src/qemu/qemu_domain.c
7b4659
+++ b/src/qemu/qemu_domain.c
7b4659
@@ -7203,6 +7203,7 @@ qemuDomainObjExitRemote(virDomainObjPtr obj,
7b4659
 
7b4659
 static virDomainDefPtr
7b4659
 qemuDomainDefFromXML(virQEMUDriverPtr driver,
7b4659
+                     virQEMUCapsPtr qemuCaps,
7b4659
                      const char *xml)
7b4659
 {
7b4659
     virCapsPtr caps;
7b4659
@@ -7211,7 +7212,7 @@ qemuDomainDefFromXML(virQEMUDriverPtr driver,
7b4659
     if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
7b4659
         return NULL;
7b4659
 
7b4659
-    def = virDomainDefParseString(xml, caps, driver->xmlopt, NULL,
7b4659
+    def = virDomainDefParseString(xml, caps, driver->xmlopt, qemuCaps,
7b4659
                                   VIR_DOMAIN_DEF_PARSE_INACTIVE |
7b4659
                                   VIR_DOMAIN_DEF_PARSE_SKIP_VALIDATE);
7b4659
 
7b4659
@@ -7222,6 +7223,7 @@ qemuDomainDefFromXML(virQEMUDriverPtr driver,
7b4659
 
7b4659
 virDomainDefPtr
7b4659
 qemuDomainDefCopy(virQEMUDriverPtr driver,
7b4659
+                  virQEMUCapsPtr qemuCaps,
7b4659
                   virDomainDefPtr src,
7b4659
                   unsigned int flags)
7b4659
 {
7b4659
@@ -7231,7 +7233,7 @@ qemuDomainDefCopy(virQEMUDriverPtr driver,
7b4659
     if (!(xml = qemuDomainDefFormatXML(driver, src, flags)))
7b4659
         return NULL;
7b4659
 
7b4659
-    ret = qemuDomainDefFromXML(driver, xml);
7b4659
+    ret = qemuDomainDefFromXML(driver, qemuCaps, xml);
7b4659
 
7b4659
     VIR_FREE(xml);
7b4659
     return ret;
7b4659
@@ -9052,6 +9054,7 @@ qemuDomainMigratableDefCheckABIStability(virQEMUDriverPtr driver,
7b4659
 
7b4659
 bool
7b4659
 qemuDomainDefCheckABIStability(virQEMUDriverPtr driver,
7b4659
+                               virQEMUCapsPtr qemuCaps,
7b4659
                                virDomainDefPtr src,
7b4659
                                virDomainDefPtr dst)
7b4659
 {
7b4659
@@ -9059,8 +9062,8 @@ qemuDomainDefCheckABIStability(virQEMUDriverPtr driver,
7b4659
     virDomainDefPtr migratableDefDst = NULL;
7b4659
     bool ret = false;
7b4659
 
7b4659
-    if (!(migratableDefSrc = qemuDomainDefCopy(driver, src, COPY_FLAGS)) ||
7b4659
-        !(migratableDefDst = qemuDomainDefCopy(driver, dst, COPY_FLAGS)))
7b4659
+    if (!(migratableDefSrc = qemuDomainDefCopy(driver, qemuCaps, src, COPY_FLAGS)) ||
7b4659
+        !(migratableDefDst = qemuDomainDefCopy(driver, qemuCaps, dst, COPY_FLAGS)))
7b4659
         goto cleanup;
7b4659
 
7b4659
     ret = qemuDomainMigratableDefCheckABIStability(driver,
7b4659
@@ -9079,14 +9082,15 @@ qemuDomainCheckABIStability(virQEMUDriverPtr driver,
7b4659
                             virDomainObjPtr vm,
7b4659
                             virDomainDefPtr dst)
7b4659
 {
7b4659
+    qemuDomainObjPrivatePtr priv = vm->privateData;
7b4659
     virDomainDefPtr migratableSrc = NULL;
7b4659
     virDomainDefPtr migratableDst = NULL;
7b4659
     char *xml = NULL;
7b4659
     bool ret = false;
7b4659
 
7b4659
     if (!(xml = qemuDomainFormatXML(driver, vm, COPY_FLAGS)) ||
7b4659
-        !(migratableSrc = qemuDomainDefFromXML(driver, xml)) ||
7b4659
-        !(migratableDst = qemuDomainDefCopy(driver, dst, COPY_FLAGS)))
7b4659
+        !(migratableSrc = qemuDomainDefFromXML(driver, priv->qemuCaps, xml)) ||
7b4659
+        !(migratableDst = qemuDomainDefCopy(driver, priv->qemuCaps, dst, COPY_FLAGS)))
7b4659
         goto cleanup;
7b4659
 
7b4659
     ret = qemuDomainMigratableDefCheckABIStability(driver,
7b4659
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
7b4659
index cc406e3ca0..29283105cb 100644
7b4659
--- a/src/qemu/qemu_domain.h
7b4659
+++ b/src/qemu/qemu_domain.h
7b4659
@@ -594,6 +594,7 @@ int qemuDomainObjExitRemote(virDomainObjPtr obj,
7b4659
     ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;
7b4659
 
7b4659
 virDomainDefPtr qemuDomainDefCopy(virQEMUDriverPtr driver,
7b4659
+                                  virQEMUCapsPtr qemuCaps,
7b4659
                                   virDomainDefPtr src,
7b4659
                                   unsigned int flags);
7b4659
 
7b4659
@@ -769,6 +770,7 @@ int qemuDomainUpdateMemoryDeviceInfo(virQEMUDriverPtr driver,
7b4659
                                      int asyncJob);
7b4659
 
7b4659
 bool qemuDomainDefCheckABIStability(virQEMUDriverPtr driver,
7b4659
+                                    virQEMUCapsPtr qemuCaps,
7b4659
                                     virDomainDefPtr src,
7b4659
                                     virDomainDefPtr dst);
7b4659
 
7b4659
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
7b4659
index 25818f5d8c..a486c66a5f 100644
7b4659
--- a/src/qemu/qemu_driver.c
7b4659
+++ b/src/qemu/qemu_driver.c
7b4659
@@ -6325,7 +6325,7 @@ qemuDomainSaveImageUpdateDef(virQEMUDriverPtr driver,
7b4659
                                            VIR_DOMAIN_DEF_PARSE_INACTIVE)))
7b4659
         goto cleanup;
7b4659
 
7b4659
-    if (!(newdef_migr = qemuDomainDefCopy(driver,
7b4659
+    if (!(newdef_migr = qemuDomainDefCopy(driver, NULL,
7b4659
                                           newdef,
7b4659
                                           QEMU_DOMAIN_FORMAT_LIVE_FLAGS |
7b4659
                                           VIR_DOMAIN_XML_MIGRATABLE)))
7b4659
@@ -16052,7 +16052,7 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
7b4659
     switch ((virDomainState) snap->def->state) {
7b4659
     case VIR_DOMAIN_RUNNING:
7b4659
     case VIR_DOMAIN_PAUSED:
7b4659
-
7b4659
+        priv = vm->privateData;
7b4659
         start_flags |= VIR_QEMU_PROCESS_START_PAUSED;
7b4659
 
7b4659
         /* Transitions 2, 3, 5, 6, 8, 9 */
7b4659
@@ -16079,7 +16079,9 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
7b4659
                     if (!(config->cpu = virCPUDefCopy(cookie->cpu)))
7b4659
                         goto endjob;
7b4659
 
7b4659
-                    compatible = qemuDomainDefCheckABIStability(driver, vm->def,
7b4659
+                    compatible = qemuDomainDefCheckABIStability(driver,
7b4659
+                                                                priv->qemuCaps,
7b4659
+                                                                vm->def,
7b4659
                                                                 config);
7b4659
                 } else {
7b4659
                     compatible = qemuDomainCheckABIStability(driver, vm, config);
7b4659
@@ -16123,7 +16125,6 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
7b4659
                 }
7b4659
             }
7b4659
 
7b4659
-            priv = vm->privateData;
7b4659
             if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) {
7b4659
                 /* Transitions 5, 6 */
7b4659
                 if (qemuProcessStopCPUs(driver, vm,
7b4659
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
7b4659
index 67940330aa..4af105b997 100644
7b4659
--- a/src/qemu/qemu_migration.c
7b4659
+++ b/src/qemu/qemu_migration.c
7b4659
@@ -2378,7 +2378,7 @@ qemuMigrationDstPrepareAny(virQEMUDriverPtr driver,
7b4659
                 if (!newdef)
7b4659
                     goto cleanup;
7b4659
 
7b4659
-                if (!qemuDomainDefCheckABIStability(driver, *def, newdef)) {
7b4659
+                if (!qemuDomainDefCheckABIStability(driver, NULL, *def, newdef)) {
7b4659
                     virDomainDefFree(newdef);
7b4659
                     goto cleanup;
7b4659
                 }
7b4659
@@ -3417,7 +3417,7 @@ qemuMigrationSrcRun(virQEMUDriverPtr driver,
7b4659
                 goto error;
7b4659
         } else {
7b4659
             virDomainDefPtr def = vm->newDef ? vm->newDef : vm->def;
7b4659
-            if (!(persistDef = qemuDomainDefCopy(driver, def,
7b4659
+            if (!(persistDef = qemuDomainDefCopy(driver, priv->qemuCaps, def,
7b4659
                                                  VIR_DOMAIN_XML_SECURE |
7b4659
                                                  VIR_DOMAIN_XML_MIGRATABLE)))
7b4659
                 goto error;
7b4659
-- 
7b4659
2.22.1
7b4659