[libvirt] [PATCH 11/15] qemu: Remember CPU def from domain start

Jiri Denemark jdenemar at redhat.com
Mon Jun 5 09:26:59 UTC 2017


When starting a domain we update the guest CPU definition to match what
QEMU actually provided (since it is allowed to add or removed some
features unless check='full' is specified). Let's store the original CPU
in domain private data so that we can use it to provide a backward
compatible domain XML.

Signed-off-by: Jiri Denemark <jdenemar at redhat.com>
---
 src/libvirt_private.syms |  2 ++
 src/qemu/qemu_domain.c   |  7 +++++++
 src/qemu/qemu_domain.h   |  4 ++++
 src/qemu/qemu_process.c  | 13 +++++++++++--
 4 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index fad31b475..3b91145c5 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -77,9 +77,11 @@ virCPUDefCopyModelFilter;
 virCPUDefCopyWithoutModel;
 virCPUDefFormat;
 virCPUDefFormatBuf;
+virCPUDefFormatBufFull;
 virCPUDefFree;
 virCPUDefFreeFeatures;
 virCPUDefFreeModel;
+virCPUDefIsEqual;
 virCPUDefParseXML;
 virCPUDefStealModel;
 virCPUDefUpdateFeature;
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 80e9fea98..ba8079ba0 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -1726,6 +1726,8 @@ qemuDomainObjPrivateFree(void *data)
     VIR_FREE(priv->migTLSAlias);
     qemuDomainMasterKeyFree(priv);
 
+    virCPUDefFree(priv->origCPU);
+
     VIR_FREE(priv);
 }
 
@@ -1881,6 +1883,8 @@ qemuDomainObjPrivateXMLFormat(virBufferPtr buf,
     virBufferEscapeString(buf, "<channelTargetDir path='%s'/>\n",
                           priv->channelTargetDir);
 
+    virCPUDefFormatBufFull(buf, priv->origCPU, NULL, false);
+
     return 0;
 }
 
@@ -2149,6 +2153,9 @@ qemuDomainObjPrivateXMLParse(xmlXPathContextPtr ctxt,
     if (qemuDomainSetPrivatePathsOld(driver, vm) < 0)
         goto error;
 
+    if (virCPUDefParseXML(ctxt, "./cpu", VIR_CPU_TYPE_GUEST, &priv->origCPU) < 0)
+        goto error;
+
     return 0;
 
  error:
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index cc2e21bdf..f6dad4378 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -293,6 +293,10 @@ struct _qemuDomainObjPrivate {
     /* Used when fetching/storing the current 'tls-creds' migration setting */
     /* (not to be saved in our private XML). */
     char *migTLSAlias;
+
+    /* CPU def used to start the domain when it differs from the one actually
+     * provided by QEMU. */
+    virCPUDefPtr origCPU;
 };
 
 # define QEMU_DOMAIN_PRIVATE(vm)	\
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index be031b56b..8f4902e10 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -3913,6 +3913,7 @@ qemuProcessUpdateLiveGuestCPU(virQEMUDriverPtr driver,
     qemuDomainObjPrivatePtr priv = vm->privateData;
     int rc;
     int ret = -1;
+    virCPUDefPtr orig = NULL;
 
     if (ARCH_IS_X86(def->os.arch)) {
         if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
@@ -3943,10 +3944,17 @@ qemuProcessUpdateLiveGuestCPU(virQEMUDriverPtr driver,
         if (qemuProcessVerifyCPUFeatures(def, cpu) < 0)
             goto cleanup;
 
-        if ((rc = virCPUUpdateLive(def->os.arch, def->cpu, cpu, disabled)) < 0)
+        if (!(orig = virCPUDefCopy(def->cpu)))
             goto cleanup;
-        else if (rc == 0)
+
+        if ((rc = virCPUUpdateLive(def->os.arch, def->cpu, cpu, disabled)) < 0) {
+            goto cleanup;
+        } else if (rc == 0) {
+            if (!virCPUDefIsEqual(def->cpu, orig, false))
+                VIR_STEAL_PTR(priv->origCPU, orig);
+
             def->cpu->check = VIR_CPU_CHECK_FULL;
+        }
     }
 
     ret = 0;
@@ -3954,6 +3962,7 @@ qemuProcessUpdateLiveGuestCPU(virQEMUDriverPtr driver,
  cleanup:
     virCPUDataFree(cpu);
     virCPUDataFree(disabled);
+    virCPUDefFree(orig);
     return ret;
 }
 
-- 
2.13.0




More information about the libvir-list mailing list