Migration API allows to specify a destination domain XML. If no XML was
specified the source one is used.
Offline domain has only inactive XML and it is replaced by specified
destination XML.
Live migration allows to persist domain on a destination host. In this
case both inactive and active XML should be replaced with specified XML.
The problem is that specified XML only replaces an active one.
https://bugzilla.redhat.com/show_bug.cgi?id=835300
This commit adds a migration cookie with specified destination XML at a
migration beginning phase and sets this XML to destination domain on
the next step.
---
src/qemu/qemu_migration.c | 47 ++++++++++++++++++++++++-----------------------
1 file changed, 24 insertions(+), 23 deletions(-)
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 92d2ce9..b24301d 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -3072,14 +3072,6 @@ qemuMigrationBeginPhase(virQEMUDriverPtr driver,
vm->newDef && virDomainDefHasMemoryHotplug(vm->newDef)))
cookieFlags |= QEMU_MIGRATION_COOKIE_MEMORY_HOTPLUG;
- if (!(mig = qemuMigrationEatCookie(driver, vm, NULL, 0, 0)))
- goto cleanup;
-
- if (qemuMigrationBakeCookie(mig, driver, vm,
- cookieout, cookieoutlen,
- cookieFlags) < 0)
- goto cleanup;
-
if (flags & VIR_MIGRATE_OFFLINE) {
if (flags & (VIR_MIGRATE_NON_SHARED_DISK |
VIR_MIGRATE_NON_SHARED_INC)) {
@@ -3115,6 +3107,18 @@ qemuMigrationBeginPhase(virQEMUDriverPtr driver,
rv = qemuDomainDefFormatLive(driver, vm->def, false, true);
}
+ if (!(mig = qemuMigrationEatCookie(driver, vm, NULL, 0, 0)))
+ goto cleanup;
+
+ if (flags & VIR_MIGRATE_PERSIST_DEST &&
+ qemuMigrationCookieAddPersistent(mig, def ? def : vm->newDef))
+ goto cleanup;
+
+ if (qemuMigrationBakeCookie(mig, driver, vm,
+ cookieout, cookieoutlen,
+ cookieFlags) < 0)
+ goto cleanup;
+
cleanup:
qemuMigrationCookieFree(mig);
virObjectUnref(caps);
@@ -3431,7 +3435,8 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver,
if (!(mig = qemuMigrationEatCookie(driver, vm, cookiein, cookieinlen,
QEMU_MIGRATION_COOKIE_LOCKSTATE |
QEMU_MIGRATION_COOKIE_NBD |
- QEMU_MIGRATION_COOKIE_MEMORY_HOTPLUG)))
+ QEMU_MIGRATION_COOKIE_MEMORY_HOTPLUG |
+ QEMU_MIGRATION_COOKIE_PERSISTENT)))
goto cleanup;
if (STREQ_NULLABLE(protocol, "rdma") &&
@@ -3457,6 +3462,9 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver,
if (flags & VIR_MIGRATE_OFFLINE)
goto done;
+ if (flags & VIR_MIGRATE_PERSIST_DEST)
+ vm->newDef = qemuMigrationCookieGetPersistent(mig);
+
if (tunnel &&
(pipe(dataFD) < 0 || virSetCloseExec(dataFD[1]) < 0)) {
virReportSystemError(errno, "%s",
@@ -3585,7 +3593,10 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver,
}
virDomainObjEndAPI(&vm);
qemuDomainEventQueue(driver, event);
- qemuMigrationCookieFree(mig);
+ if (mig) {
+ virDomainDefFree(qemuMigrationCookieGetPersistent(mig));
+ qemuMigrationCookieFree(mig);
+ }
virObjectUnref(caps);
virNWFilterUnlockFilterUpdates();
return ret;
@@ -4546,8 +4557,7 @@ qemuMigrationRun(virQEMUDriverPtr driver,
cookieFlags |= QEMU_MIGRATION_COOKIE_NETWORK |
QEMU_MIGRATION_COOKIE_STATS;
- if (flags & VIR_MIGRATE_PERSIST_DEST)
- cookieFlags |= QEMU_MIGRATION_COOKIE_PERSISTENT;
+
if (ret == 0 &&
qemuMigrationBakeCookie(mig, driver, vm, cookieout,
cookieoutlen, cookieFlags) < 0) {
@@ -5664,13 +5674,11 @@ qemuMigrationVPAssociatePortProfiles(virDomainDefPtr def)
static int
qemuMigrationPersist(virQEMUDriverPtr driver,
virDomainObjPtr vm,
- qemuMigrationCookiePtr mig,
bool ignoreSaveError)
{
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
virCapsPtr caps = NULL;
virDomainDefPtr vmdef;
- virDomainDefPtr oldDef = NULL;
unsigned int oldPersist = vm->persistent;
virObjectEventPtr event;
int ret = -1;
@@ -5679,8 +5687,6 @@ qemuMigrationPersist(virQEMUDriverPtr driver,
goto cleanup;
vm->persistent = 1;
- oldDef = vm->newDef;
- vm->newDef = qemuMigrationCookieGetPersistent(mig);
if (!(vmdef = virDomainObjGetPersistentDef(caps, driver->xmlopt, vm)))
goto error;
@@ -5699,7 +5705,6 @@ qemuMigrationPersist(virQEMUDriverPtr driver,
ret = 0;
cleanup:
- virDomainDefFree(oldDef);
virObjectUnref(caps);
virObjectUnref(cfg);
return ret;
@@ -5707,8 +5712,6 @@ qemuMigrationPersist(virQEMUDriverPtr driver,
error:
virDomainDefFree(vm->newDef);
vm->persistent = oldPersist;
- vm->newDef = oldDef;
- oldDef = NULL;
goto cleanup;
}
@@ -5762,8 +5765,6 @@ qemuMigrationFinish(virQEMUDriverPtr driver,
cookie_flags = QEMU_MIGRATION_COOKIE_NETWORK |
QEMU_MIGRATION_COOKIE_STATS |
QEMU_MIGRATION_COOKIE_NBD;
- if (flags & VIR_MIGRATE_PERSIST_DEST)
- cookie_flags |= QEMU_MIGRATION_COOKIE_PERSISTENT;
if (!(mig = qemuMigrationEatCookie(driver, vm, cookiein,
cookieinlen, cookie_flags)))
@@ -5771,7 +5772,7 @@ qemuMigrationFinish(virQEMUDriverPtr driver,
if (flags & VIR_MIGRATE_OFFLINE) {
if (retcode == 0 &&
- qemuMigrationPersist(driver, vm, mig, false) == 0)
+ qemuMigrationPersist(driver, vm, false) == 0)
dom = virGetDomain(dconn, vm->def->name, vm->def->uuid);
goto endjob;
}
@@ -5819,7 +5820,7 @@ qemuMigrationFinish(virQEMUDriverPtr driver,
if (flags & VIR_MIGRATE_PERSIST_DEST) {
- if (qemuMigrationPersist(driver, vm, mig, !v3proto) < 0) {
+ if (qemuMigrationPersist(driver, vm, !v3proto) < 0) {
/* Hmpf. Migration was successful, but making it persistent
* was not. If we report successful, then when this domain
* shuts down, management tools are in for a surprise. On the
--
1.8.3.1