6d3351
From 9281d9a8d447e8b066cc600f1dcca7775920f01e Mon Sep 17 00:00:00 2001
6d3351
Message-Id: <9281d9a8d447e8b066cc600f1dcca7775920f01e@dist-git>
6d3351
From: Jiri Denemark <jdenemar@redhat.com>
6d3351
Date: Fri, 19 May 2017 15:20:31 +0200
6d3351
Subject: [PATCH] qemu: Report the original CPU in migratable xml
6d3351
6d3351
The destination host may not be able to start a domain using the live
6d3351
updated CPU definition because either libvirt or QEMU may not be new
6d3351
enough. Thus we need to send the original guest CPU definition.
6d3351
6d3351
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
6d3351
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
6d3351
(cherry picked from commit 356a2161e293eaab57448a8e68f489e0841efe19)
6d3351
6d3351
https://bugzilla.redhat.com/show_bug.cgi?id=1441662
6d3351
6d3351
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
6d3351
---
6d3351
 src/qemu/qemu_domain.c    | 61 ++++++++++++++++++++++++++++++++++++++---------
6d3351
 src/qemu/qemu_domain.h    |  1 +
6d3351
 src/qemu/qemu_driver.c    | 13 ++++++----
6d3351
 src/qemu/qemu_migration.c |  5 ++--
6d3351
 4 files changed, 63 insertions(+), 17 deletions(-)
6d3351
6d3351
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
6d3351
index 89fd9f9abc..514b56b33c 100644
6d3351
--- a/src/qemu/qemu_domain.c
6d3351
+++ b/src/qemu/qemu_domain.c
6d3351
@@ -4175,11 +4175,13 @@ qemuDomainDefCopy(virQEMUDriverPtr driver,
6d3351
     return ret;
6d3351
 }
6d3351
 
6d3351
-int
6d3351
-qemuDomainDefFormatBuf(virQEMUDriverPtr driver,
6d3351
-                       virDomainDefPtr def,
6d3351
-                       unsigned int flags,
6d3351
-                       virBuffer *buf)
6d3351
+
6d3351
+static int
6d3351
+qemuDomainDefFormatBufInternal(virQEMUDriverPtr driver,
6d3351
+                               virDomainDefPtr def,
6d3351
+                               virCPUDefPtr origCPU,
6d3351
+                               unsigned int flags,
6d3351
+                               virBuffer *buf)
6d3351
 {
6d3351
     int ret = -1;
6d3351
     virDomainDefPtr copy = NULL;
6d3351
@@ -4300,6 +4302,16 @@ qemuDomainDefFormatBuf(virQEMUDriverPtr driver,
6d3351
             if (qemuDomainChrDefDropDefaultPath(def->channels[i], driver) < 0)
6d3351
                 goto cleanup;
6d3351
         }
6d3351
+
6d3351
+        /* Replace the CPU definition updated according to QEMU with the one
6d3351
+         * used for starting the domain. The updated def will be sent
6d3351
+         * separately for backward compatibility.
6d3351
+         */
6d3351
+        if (origCPU) {
6d3351
+            virCPUDefFree(def->cpu);
6d3351
+            if (!(def->cpu = virCPUDefCopy(origCPU)))
6d3351
+                goto cleanup;
6d3351
+        }
6d3351
     }
6d3351
 
6d3351
  format:
6d3351
@@ -4313,13 +4325,26 @@ qemuDomainDefFormatBuf(virQEMUDriverPtr driver,
6d3351
     return ret;
6d3351
 }
6d3351
 
6d3351
-char *qemuDomainDefFormatXML(virQEMUDriverPtr driver,
6d3351
-                             virDomainDefPtr def,
6d3351
-                             unsigned int flags)
6d3351
+
6d3351
+int
6d3351
+qemuDomainDefFormatBuf(virQEMUDriverPtr driver,
6d3351
+                       virDomainDefPtr def,
6d3351
+                       unsigned int flags,
6d3351
+                       virBufferPtr buf)
6d3351
+{
6d3351
+    return qemuDomainDefFormatBufInternal(driver, def, NULL, flags, buf);
6d3351
+}
6d3351
+
6d3351
+
6d3351
+static char *
6d3351
+qemuDomainDefFormatXMLInternal(virQEMUDriverPtr driver,
6d3351
+                               virDomainDefPtr def,
6d3351
+                               virCPUDefPtr origCPU,
6d3351
+                               unsigned int flags)
6d3351
 {
6d3351
     virBuffer buf = VIR_BUFFER_INITIALIZER;
6d3351
 
6d3351
-    if (qemuDomainDefFormatBuf(driver, def, flags, &buf) < 0) {
6d3351
+    if (qemuDomainDefFormatBufInternal(driver, def, origCPU, flags, &buf) < 0) {
6d3351
         virBufferFreeAndReset(&buf;;
6d3351
         return NULL;
6d3351
     }
6d3351
@@ -4333,26 +4358,40 @@ char *qemuDomainDefFormatXML(virQEMUDriverPtr driver,
6d3351
     return virBufferContentAndReset(&buf;;
6d3351
 }
6d3351
 
6d3351
+
6d3351
+char *
6d3351
+qemuDomainDefFormatXML(virQEMUDriverPtr driver,
6d3351
+                       virDomainDefPtr def,
6d3351
+                       unsigned int flags)
6d3351
+{
6d3351
+    return qemuDomainDefFormatXMLInternal(driver, def, NULL, flags);
6d3351
+}
6d3351
+
6d3351
+
6d3351
 char *qemuDomainFormatXML(virQEMUDriverPtr driver,
6d3351
                           virDomainObjPtr vm,
6d3351
                           unsigned int flags)
6d3351
 {
6d3351
     virDomainDefPtr def;
6d3351
+    qemuDomainObjPrivatePtr priv = vm->privateData;
6d3351
+    virCPUDefPtr origCPU = NULL;
6d3351
 
6d3351
     if ((flags & VIR_DOMAIN_XML_INACTIVE) && vm->newDef) {
6d3351
         def = vm->newDef;
6d3351
     } else {
6d3351
         def = vm->def;
6d3351
+        origCPU = priv->origCPU;
6d3351
         if (virDomainObjIsActive(vm))
6d3351
             flags &= ~VIR_DOMAIN_XML_UPDATE_CPU;
6d3351
     }
6d3351
 
6d3351
-    return qemuDomainDefFormatXML(driver, def, flags);
6d3351
+    return qemuDomainDefFormatXMLInternal(driver, def, origCPU, flags);
6d3351
 }
6d3351
 
6d3351
 char *
6d3351
 qemuDomainDefFormatLive(virQEMUDriverPtr driver,
6d3351
                         virDomainDefPtr def,
6d3351
+                        virCPUDefPtr origCPU,
6d3351
                         bool inactive,
6d3351
                         bool compatible)
6d3351
 {
6d3351
@@ -4363,7 +4402,7 @@ qemuDomainDefFormatLive(virQEMUDriverPtr driver,
6d3351
     if (compatible)
6d3351
         flags |= VIR_DOMAIN_XML_MIGRATABLE;
6d3351
 
6d3351
-    return qemuDomainDefFormatXML(driver, def, flags);
6d3351
+    return qemuDomainDefFormatXMLInternal(driver, def, origCPU, flags);
6d3351
 }
6d3351
 
6d3351
 
6d3351
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
6d3351
index 0c5dad60e1..9567458849 100644
6d3351
--- a/src/qemu/qemu_domain.h
6d3351
+++ b/src/qemu/qemu_domain.h
6d3351
@@ -515,6 +515,7 @@ char *qemuDomainFormatXML(virQEMUDriverPtr driver,
6d3351
 
6d3351
 char *qemuDomainDefFormatLive(virQEMUDriverPtr driver,
6d3351
                               virDomainDefPtr def,
6d3351
+                              virCPUDefPtr origCPU,
6d3351
                               bool inactive,
6d3351
                               bool compatible);
6d3351
 
6d3351
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
6d3351
index dbb1ea9475..f5c5c302be 100644
6d3351
--- a/src/qemu/qemu_driver.c
6d3351
+++ b/src/qemu/qemu_driver.c
6d3351
@@ -3330,9 +3330,9 @@ qemuDomainSaveInternal(virQEMUDriverPtr driver, virDomainPtr dom,
6d3351
             virDomainDefFree(def);
6d3351
             goto endjob;
6d3351
         }
6d3351
-        xml = qemuDomainDefFormatLive(driver, def, true, true);
6d3351
+        xml = qemuDomainDefFormatLive(driver, def, NULL, true, true);
6d3351
     } else {
6d3351
-        xml = qemuDomainDefFormatLive(driver, vm->def, true, true);
6d3351
+        xml = qemuDomainDefFormatLive(driver, vm->def, priv->origCPU, true, true);
6d3351
     }
6d3351
     if (!xml) {
6d3351
         virReportError(VIR_ERR_OPERATION_FAILED,
6d3351
@@ -14512,7 +14512,8 @@ qemuDomainSnapshotCreateActiveExternal(virConnectPtr conn,
6d3351
                                                     "snapshot", false)) < 0)
6d3351
             goto cleanup;
6d3351
 
6d3351
-        if (!(xml = qemuDomainDefFormatLive(driver, vm->def, true, true)) ||
6d3351
+        if (!(xml = qemuDomainDefFormatLive(driver, vm->def, priv->origCPU,
6d3351
+                                            true, true)) ||
6d3351
             !(snap->def->cookie = (virObjectPtr) qemuDomainSaveCookieNew(vm)))
6d3351
             goto cleanup;
6d3351
 
6d3351
@@ -14623,6 +14624,7 @@ qemuDomainSnapshotCreateXML(virDomainPtr domain,
6d3351
     bool align_match = true;
6d3351
     virQEMUDriverConfigPtr cfg = NULL;
6d3351
     virCapsPtr caps = NULL;
6d3351
+    qemuDomainObjPrivatePtr priv;
6d3351
 
6d3351
     virCheckFlags(VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE |
6d3351
                   VIR_DOMAIN_SNAPSHOT_CREATE_CURRENT |
6d3351
@@ -14740,6 +14742,8 @@ qemuDomainSnapshotCreateXML(virDomainPtr domain,
6d3351
 
6d3351
     qemuDomainObjSetAsyncJobMask(vm, QEMU_JOB_NONE);
6d3351
 
6d3351
+    priv = vm->privateData;
6d3351
+
6d3351
     if (redefine) {
6d3351
         if (virDomainSnapshotRedefinePrep(domain, vm, &def, &snap,
6d3351
                                           driver->xmlopt,
6d3351
@@ -14748,7 +14752,8 @@ qemuDomainSnapshotCreateXML(virDomainPtr domain,
6d3351
     } else {
6d3351
         /* Easiest way to clone inactive portion of vm->def is via
6d3351
          * conversion in and back out of xml.  */
6d3351
-        if (!(xml = qemuDomainDefFormatLive(driver, vm->def, true, true)) ||
6d3351
+        if (!(xml = qemuDomainDefFormatLive(driver, vm->def, priv->origCPU,
6d3351
+                                            true, true)) ||
6d3351
             !(def->dom = virDomainDefParseString(xml, caps, driver->xmlopt, NULL,
6d3351
                                                  VIR_DOMAIN_DEF_PARSE_INACTIVE |
6d3351
                                                  VIR_DOMAIN_DEF_PARSE_SKIP_VALIDATE)))
6d3351
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
6d3351
index 5bf9bd10f7..ec5af7a612 100644
6d3351
--- a/src/qemu/qemu_migration.c
6d3351
+++ b/src/qemu/qemu_migration.c
6d3351
@@ -2028,9 +2028,10 @@ qemuMigrationBeginPhase(virQEMUDriverPtr driver,
6d3351
         if (!qemuDomainDefCheckABIStability(driver, vm->def, def))
6d3351
             goto cleanup;
6d3351
 
6d3351
-        rv = qemuDomainDefFormatLive(driver, def, false, true);
6d3351
+        rv = qemuDomainDefFormatLive(driver, def, NULL, false, true);
6d3351
     } else {
6d3351
-        rv = qemuDomainDefFormatLive(driver, vm->def, false, true);
6d3351
+        rv = qemuDomainDefFormatLive(driver, vm->def, priv->origCPU,
6d3351
+                                     false, true);
6d3351
     }
6d3351
 
6d3351
  cleanup:
6d3351
-- 
6d3351
2.13.1
6d3351