qemu: Remember CPU def from domain start

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@redhat.com>
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
This commit is contained in:
Jiri Denemark 2017-05-16 13:26:54 +02:00
parent 5c2f01abcb
commit ea6d898311
4 changed files with 24 additions and 2 deletions

View File

@ -77,9 +77,11 @@ virCPUDefCopyModelFilter;
virCPUDefCopyWithoutModel; virCPUDefCopyWithoutModel;
virCPUDefFormat; virCPUDefFormat;
virCPUDefFormatBuf; virCPUDefFormatBuf;
virCPUDefFormatBufFull;
virCPUDefFree; virCPUDefFree;
virCPUDefFreeFeatures; virCPUDefFreeFeatures;
virCPUDefFreeModel; virCPUDefFreeModel;
virCPUDefIsEqual;
virCPUDefParseXML; virCPUDefParseXML;
virCPUDefStealModel; virCPUDefStealModel;
virCPUDefUpdateFeature; virCPUDefUpdateFeature;

View File

@ -1726,6 +1726,8 @@ qemuDomainObjPrivateFree(void *data)
VIR_FREE(priv->migTLSAlias); VIR_FREE(priv->migTLSAlias);
qemuDomainMasterKeyFree(priv); qemuDomainMasterKeyFree(priv);
virCPUDefFree(priv->origCPU);
VIR_FREE(priv); VIR_FREE(priv);
} }
@ -1881,6 +1883,8 @@ qemuDomainObjPrivateXMLFormat(virBufferPtr buf,
virBufferEscapeString(buf, "<channelTargetDir path='%s'/>\n", virBufferEscapeString(buf, "<channelTargetDir path='%s'/>\n",
priv->channelTargetDir); priv->channelTargetDir);
virCPUDefFormatBufFull(buf, priv->origCPU, NULL, false);
return 0; return 0;
} }
@ -2149,6 +2153,9 @@ qemuDomainObjPrivateXMLParse(xmlXPathContextPtr ctxt,
if (qemuDomainSetPrivatePathsOld(driver, vm) < 0) if (qemuDomainSetPrivatePathsOld(driver, vm) < 0)
goto error; goto error;
if (virCPUDefParseXML(ctxt, "./cpu", VIR_CPU_TYPE_GUEST, &priv->origCPU) < 0)
goto error;
return 0; return 0;
error: error:

View File

@ -293,6 +293,10 @@ struct _qemuDomainObjPrivate {
/* Used when fetching/storing the current 'tls-creds' migration setting */ /* Used when fetching/storing the current 'tls-creds' migration setting */
/* (not to be saved in our private XML). */ /* (not to be saved in our private XML). */
char *migTLSAlias; 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) \ # define QEMU_DOMAIN_PRIVATE(vm) \

View File

@ -3915,6 +3915,7 @@ qemuProcessUpdateLiveGuestCPU(virQEMUDriverPtr driver,
qemuDomainObjPrivatePtr priv = vm->privateData; qemuDomainObjPrivatePtr priv = vm->privateData;
int rc; int rc;
int ret = -1; int ret = -1;
virCPUDefPtr orig = NULL;
if (ARCH_IS_X86(def->os.arch)) { if (ARCH_IS_X86(def->os.arch)) {
if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0) if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
@ -3945,10 +3946,17 @@ qemuProcessUpdateLiveGuestCPU(virQEMUDriverPtr driver,
if (qemuProcessVerifyCPUFeatures(def, cpu) < 0) if (qemuProcessVerifyCPUFeatures(def, cpu) < 0)
goto cleanup; goto cleanup;
if ((rc = virCPUUpdateLive(def->os.arch, def->cpu, cpu, disabled)) < 0) if (!(orig = virCPUDefCopy(def->cpu)))
goto cleanup; 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; def->cpu->check = VIR_CPU_CHECK_FULL;
}
} }
ret = 0; ret = 0;
@ -3956,6 +3964,7 @@ qemuProcessUpdateLiveGuestCPU(virQEMUDriverPtr driver,
cleanup: cleanup:
virCPUDataFree(cpu); virCPUDataFree(cpu);
virCPUDataFree(disabled); virCPUDataFree(disabled);
virCPUDefFree(orig);
return ret; return ret;
} }