qemu: Report the original CPU in migratable xml

The destination host may not be able to start a domain using the live
updated CPU definition because either libvirt or QEMU may not be new
enough. Thus we need to send the original guest CPU definition.

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
This commit is contained in:
Jiri Denemark 2017-05-19 15:20:31 +02:00
parent ea6d898311
commit 356a2161e2
4 changed files with 63 additions and 17 deletions

View File

@ -4216,11 +4216,13 @@ qemuDomainDefCopy(virQEMUDriverPtr driver,
return ret;
}
int
qemuDomainDefFormatBuf(virQEMUDriverPtr driver,
virDomainDefPtr def,
unsigned int flags,
virBuffer *buf)
static int
qemuDomainDefFormatBufInternal(virQEMUDriverPtr driver,
virDomainDefPtr def,
virCPUDefPtr origCPU,
unsigned int flags,
virBuffer *buf)
{
int ret = -1;
virDomainDefPtr copy = NULL;
@ -4341,6 +4343,16 @@ qemuDomainDefFormatBuf(virQEMUDriverPtr driver,
if (qemuDomainChrDefDropDefaultPath(def->channels[i], driver) < 0)
goto cleanup;
}
/* Replace the CPU definition updated according to QEMU with the one
* used for starting the domain. The updated def will be sent
* separately for backward compatibility.
*/
if (origCPU) {
virCPUDefFree(def->cpu);
if (!(def->cpu = virCPUDefCopy(origCPU)))
goto cleanup;
}
}
format:
@ -4354,13 +4366,26 @@ qemuDomainDefFormatBuf(virQEMUDriverPtr driver,
return ret;
}
char *qemuDomainDefFormatXML(virQEMUDriverPtr driver,
virDomainDefPtr def,
unsigned int flags)
int
qemuDomainDefFormatBuf(virQEMUDriverPtr driver,
virDomainDefPtr def,
unsigned int flags,
virBufferPtr buf)
{
return qemuDomainDefFormatBufInternal(driver, def, NULL, flags, buf);
}
static char *
qemuDomainDefFormatXMLInternal(virQEMUDriverPtr driver,
virDomainDefPtr def,
virCPUDefPtr origCPU,
unsigned int flags)
{
virBuffer buf = VIR_BUFFER_INITIALIZER;
if (qemuDomainDefFormatBuf(driver, def, flags, &buf) < 0) {
if (qemuDomainDefFormatBufInternal(driver, def, origCPU, flags, &buf) < 0) {
virBufferFreeAndReset(&buf);
return NULL;
}
@ -4374,26 +4399,40 @@ char *qemuDomainDefFormatXML(virQEMUDriverPtr driver,
return virBufferContentAndReset(&buf);
}
char *
qemuDomainDefFormatXML(virQEMUDriverPtr driver,
virDomainDefPtr def,
unsigned int flags)
{
return qemuDomainDefFormatXMLInternal(driver, def, NULL, flags);
}
char *qemuDomainFormatXML(virQEMUDriverPtr driver,
virDomainObjPtr vm,
unsigned int flags)
{
virDomainDefPtr def;
qemuDomainObjPrivatePtr priv = vm->privateData;
virCPUDefPtr origCPU = NULL;
if ((flags & VIR_DOMAIN_XML_INACTIVE) && vm->newDef) {
def = vm->newDef;
} else {
def = vm->def;
origCPU = priv->origCPU;
if (virDomainObjIsActive(vm))
flags &= ~VIR_DOMAIN_XML_UPDATE_CPU;
}
return qemuDomainDefFormatXML(driver, def, flags);
return qemuDomainDefFormatXMLInternal(driver, def, origCPU, flags);
}
char *
qemuDomainDefFormatLive(virQEMUDriverPtr driver,
virDomainDefPtr def,
virCPUDefPtr origCPU,
bool inactive,
bool compatible)
{
@ -4404,7 +4443,7 @@ qemuDomainDefFormatLive(virQEMUDriverPtr driver,
if (compatible)
flags |= VIR_DOMAIN_XML_MIGRATABLE;
return qemuDomainDefFormatXML(driver, def, flags);
return qemuDomainDefFormatXMLInternal(driver, def, origCPU, flags);
}

View File

@ -515,6 +515,7 @@ char *qemuDomainFormatXML(virQEMUDriverPtr driver,
char *qemuDomainDefFormatLive(virQEMUDriverPtr driver,
virDomainDefPtr def,
virCPUDefPtr origCPU,
bool inactive,
bool compatible);

View File

@ -3344,9 +3344,9 @@ qemuDomainSaveInternal(virQEMUDriverPtr driver, virDomainPtr dom,
virDomainDefFree(def);
goto endjob;
}
xml = qemuDomainDefFormatLive(driver, def, true, true);
xml = qemuDomainDefFormatLive(driver, def, NULL, true, true);
} else {
xml = qemuDomainDefFormatLive(driver, vm->def, true, true);
xml = qemuDomainDefFormatLive(driver, vm->def, priv->origCPU, true, true);
}
if (!xml) {
virReportError(VIR_ERR_OPERATION_FAILED,
@ -14511,7 +14511,8 @@ qemuDomainSnapshotCreateActiveExternal(virConnectPtr conn,
"snapshot", false)) < 0)
goto cleanup;
if (!(xml = qemuDomainDefFormatLive(driver, vm->def, true, true)) ||
if (!(xml = qemuDomainDefFormatLive(driver, vm->def, priv->origCPU,
true, true)) ||
!(snap->def->cookie = (virObjectPtr) qemuDomainSaveCookieNew(vm)))
goto cleanup;
@ -14622,6 +14623,7 @@ qemuDomainSnapshotCreateXML(virDomainPtr domain,
bool align_match = true;
virQEMUDriverConfigPtr cfg = NULL;
virCapsPtr caps = NULL;
qemuDomainObjPrivatePtr priv;
virCheckFlags(VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE |
VIR_DOMAIN_SNAPSHOT_CREATE_CURRENT |
@ -14739,6 +14741,8 @@ qemuDomainSnapshotCreateXML(virDomainPtr domain,
qemuDomainObjSetAsyncJobMask(vm, QEMU_JOB_NONE);
priv = vm->privateData;
if (redefine) {
if (virDomainSnapshotRedefinePrep(domain, vm, &def, &snap,
driver->xmlopt,
@ -14747,7 +14751,8 @@ qemuDomainSnapshotCreateXML(virDomainPtr domain,
} else {
/* Easiest way to clone inactive portion of vm->def is via
* conversion in and back out of xml. */
if (!(xml = qemuDomainDefFormatLive(driver, vm->def, true, true)) ||
if (!(xml = qemuDomainDefFormatLive(driver, vm->def, priv->origCPU,
true, true)) ||
!(def->dom = virDomainDefParseString(xml, caps, driver->xmlopt, NULL,
VIR_DOMAIN_DEF_PARSE_INACTIVE |
VIR_DOMAIN_DEF_PARSE_SKIP_VALIDATE)))

View File

@ -2059,9 +2059,10 @@ qemuMigrationBeginPhase(virQEMUDriverPtr driver,
if (!qemuDomainDefCheckABIStability(driver, vm->def, def))
goto cleanup;
rv = qemuDomainDefFormatLive(driver, def, false, true);
rv = qemuDomainDefFormatLive(driver, def, NULL, false, true);
} else {
rv = qemuDomainDefFormatLive(driver, vm->def, false, true);
rv = qemuDomainDefFormatLive(driver, vm->def, priv->origCPU,
false, true);
}
cleanup: