[libvirt] [PATCH v4 0/2] persistent live migration with specified XML

v4: wrong param name in commit msg v3: - use shorter name for param and rename args - move qemuMigrationCookieAddPersistent out from qemuMigrationBakeCookie - rebase to master v2: reimplemented with new migration param Libvirt doesn't allow to specify destination persistent domain configuration. VIR_MIGRATE_PARAM_DEST_XML migration param is used for active configuration and persistent configuration is taken from source domain. The problem is mentioned in this bug: https://bugzilla.redhat.com/show_bug.cgi?id=835300 This patch-set introduces new migration param VIR_MIGRATE_PARAM_PERSIST_XML and implements its support in qemu driver. Dmitry Andreev (2): qemuMigrationCookieAddPersistent: move it out and change argument type qemu: migration: new migration param for persistent destination XML include/libvirt/libvirt-domain.h | 15 ++++++++++ src/qemu/qemu_driver.c | 12 +++++--- src/qemu/qemu_migration.c | 64 ++++++++++++++++++++++++---------------- src/qemu/qemu_migration.h | 2 ++ 4 files changed, 63 insertions(+), 30 deletions(-) -- 1.8.3.1

This changes allow to use qemuMigrationCookieAddPersistent with an XML definition that isn't assigned to any domain. --- src/qemu/qemu_migration.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index c0b580d..f723a52 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -507,7 +507,7 @@ qemuMigrationCookieAddLockstate(qemuMigrationCookiePtr mig, static int qemuMigrationCookieAddPersistent(qemuMigrationCookiePtr mig, - virDomainObjPtr dom) + virDomainDefPtr def) { if (mig->flags & QEMU_MIGRATION_COOKIE_PERSISTENT) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", @@ -515,10 +515,10 @@ qemuMigrationCookieAddPersistent(qemuMigrationCookiePtr mig, return -1; } - if (!dom->newDef) + if (!def) return 0; - mig->persistent = dom->newDef; + mig->persistent = def; mig->flags |= QEMU_MIGRATION_COOKIE_PERSISTENT; mig->flagsMandatory |= QEMU_MIGRATION_COOKIE_PERSISTENT; return 0; @@ -1366,10 +1366,6 @@ qemuMigrationBakeCookie(qemuMigrationCookiePtr mig, qemuMigrationCookieAddLockstate(mig, driver, dom) < 0) return -1; - if (flags & QEMU_MIGRATION_COOKIE_PERSISTENT && - qemuMigrationCookieAddPersistent(mig, dom) < 0) - return -1; - if (flags & QEMU_MIGRATION_COOKIE_NETWORK && qemuMigrationCookieAddNetwork(mig, driver, dom) < 0) { return -1; @@ -4569,11 +4565,12 @@ 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) { + (((flags & VIR_MIGRATE_PERSIST_DEST && + qemuMigrationCookieAddPersistent(mig, vm->newDef) < 0)) || + qemuMigrationBakeCookie(mig, driver, vm, cookieout, + cookieoutlen, cookieFlags) < 0)) { VIR_WARN("Unable to encode migration cookie"); } -- 1.8.3.1

On Thu, Mar 17, 2016 at 19:31:44 +0300, Dmitry Andreev wrote:
This changes allow to use qemuMigrationCookieAddPersistent with an XML definition that isn't assigned to any domain. --- src/qemu/qemu_migration.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-)
ACK Jirka

Migration API allows to specify a destination domain configuration. Offline domain has only inactive XML and it is replaced by configuration specified using VIR_MIGRATE_PARAM_DEST_XML param. In case of live migration VIR_MIGRATE_PARAM_DEST_XML param is applied for active XML. This commit introduces the new VIR_MIGRATE_PARAM_PERSIST_XML param that can be used within live migration to replace persistent/inactive configuration. Required for: https://bugzilla.redhat.com/show_bug.cgi?id=835300 --- include/libvirt/libvirt-domain.h | 15 +++++++++++++ src/qemu/qemu_driver.c | 12 ++++++---- src/qemu/qemu_migration.c | 47 ++++++++++++++++++++++++++-------------- src/qemu/qemu_migration.h | 2 ++ 4 files changed, 56 insertions(+), 20 deletions(-) diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h index 4ac29cd..f9dae22 100644 --- a/include/libvirt/libvirt-domain.h +++ b/include/libvirt/libvirt-domain.h @@ -723,6 +723,21 @@ typedef enum { # define VIR_MIGRATE_PARAM_DEST_XML "destination_xml" /** + * VIR_MIGRATE_PARAM_PERSIST_XML: + * + * virDomainMigrate* params field: the new persistant configuration to be used + * for the domain on the destination host as VIR_TYPED_PARAM_STRING. + * This field cannot be used to rename the domain during migration (use + * VIR_MIGRATE_PARAM_DEST_NAME field for that purpose). Domain name in the + * destination XML must match the original domain name. + * + * Omitting this parameter keeps the original domain persistent configuration. + * Using this field with hypervisors that do not support changing domain + * configuration during migration will result in a failure. + */ +# define VIR_MIGRATE_PARAM_PERSIST_XML "persistent_xml" + +/** * VIR_MIGRATE_PARAM_BANDWIDTH: * * virDomainMigrate* params field: the maximum bandwidth (in MiB/s) that will diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index ff01012..e9a16b1 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -12066,7 +12066,7 @@ qemuDomainMigratePerform(virDomainPtr dom, * * Consume any cookie we were able to decode though */ - ret = qemuMigrationPerform(driver, dom->conn, vm, + ret = qemuMigrationPerform(driver, dom->conn, vm, NULL, NULL, dconnuri, uri, NULL, NULL, 0, NULL, 0, cookie, cookielen, NULL, NULL, /* No output cookies in v2 */ @@ -12455,7 +12455,7 @@ qemuDomainMigratePerform3(virDomainPtr dom, return -1; } - return qemuMigrationPerform(driver, dom->conn, vm, xmlin, + return qemuMigrationPerform(driver, dom->conn, vm, xmlin, NULL, dconnuri, uri, NULL, NULL, 0, NULL, 0, cookiein, cookieinlen, cookieout, cookieoutlen, @@ -12476,6 +12476,7 @@ qemuDomainMigratePerform3Params(virDomainPtr dom, virQEMUDriverPtr driver = dom->conn->privateData; virDomainObjPtr vm; const char *dom_xml = NULL; + const char *persist_xml = NULL; const char *dname = NULL; const char *uri = NULL; const char *graphicsuri = NULL; @@ -12510,7 +12511,10 @@ qemuDomainMigratePerform3Params(virDomainPtr dom, &listenAddress) < 0 || virTypedParamsGetInt(params, nparams, VIR_MIGRATE_PARAM_DISKS_PORT, - &nbdPort) < 0) + &nbdPort) < 0 || + virTypedParamsGetString(params, nparams, + VIR_MIGRATE_PARAM_PERSIST_XML, + &persist_xml) < 0) goto cleanup; nmigrate_disks = virTypedParamsGetStringList(params, nparams, @@ -12528,7 +12532,7 @@ qemuDomainMigratePerform3Params(virDomainPtr dom, goto cleanup; } - ret = qemuMigrationPerform(driver, dom->conn, vm, dom_xml, + ret = qemuMigrationPerform(driver, dom->conn, vm, dom_xml, persist_xml, dconnuri, uri, graphicsuri, listenAddress, nmigrate_disks, migrate_disks, nbdPort, cookiein, cookieinlen, cookieout, cookieoutlen, diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index f723a52..5624633 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -4301,6 +4301,7 @@ qemuMigrationConnect(virQEMUDriverPtr driver, static int qemuMigrationRun(virQEMUDriverPtr driver, virDomainObjPtr vm, + const char *persist_xml, const char *cookiein, int cookieinlen, char **cookieout, @@ -4315,6 +4316,7 @@ qemuMigrationRun(virQEMUDriverPtr driver, { int ret = -1; unsigned int migrate_flags = QEMU_MONITOR_MIGRATE_BACKGROUND; + virDomainDefPtr def = NULL; qemuDomainObjPrivatePtr priv = vm->privateData; qemuMigrationCookiePtr mig = NULL; qemuMigrationIOThreadPtr iothread = NULL; @@ -4566,14 +4568,20 @@ qemuMigrationRun(virQEMUDriverPtr driver, cookieFlags |= QEMU_MIGRATION_COOKIE_NETWORK | QEMU_MIGRATION_COOKIE_STATS; + if (flags & VIR_MIGRATE_PERSIST_DEST && persist_xml && + !(def = qemuMigrationPrepareDef(driver, persist_xml, NULL, NULL))) + ret = -1; + if (ret == 0 && (((flags & VIR_MIGRATE_PERSIST_DEST && - qemuMigrationCookieAddPersistent(mig, vm->newDef) < 0)) || + qemuMigrationCookieAddPersistent(mig, + def ? def : vm->newDef) < 0)) || qemuMigrationBakeCookie(mig, driver, vm, cookieout, cookieoutlen, cookieFlags) < 0)) { VIR_WARN("Unable to encode migration cookie"); } + virDomainDefFree(def); qemuMigrationCookieFree(mig); if (events) @@ -4608,6 +4616,7 @@ qemuMigrationRun(virQEMUDriverPtr driver, */ static int doNativeMigrate(virQEMUDriverPtr driver, virDomainObjPtr vm, + const char *persist_xml, const char *uri, const char *cookiein, int cookieinlen, @@ -4666,7 +4675,7 @@ static int doNativeMigrate(virQEMUDriverPtr driver, spec.dest.host.port = uribits->port; spec.fwdType = MIGRATION_FWD_DIRECT; - ret = qemuMigrationRun(driver, vm, cookiein, cookieinlen, cookieout, + ret = qemuMigrationRun(driver, vm, persist_xml, cookiein, cookieinlen, cookieout, cookieoutlen, flags, resource, &spec, dconn, graphicsuri, nmigrate_disks, migrate_disks); @@ -4683,6 +4692,7 @@ static int doNativeMigrate(virQEMUDriverPtr driver, static int doTunnelMigrate(virQEMUDriverPtr driver, virDomainObjPtr vm, virStreamPtr st, + const char *xml_persist, const char *cookiein, int cookieinlen, char **cookieout, @@ -4727,7 +4737,7 @@ static int doTunnelMigrate(virQEMUDriverPtr driver, goto cleanup; } - ret = qemuMigrationRun(driver, vm, cookiein, cookieinlen, cookieout, + ret = qemuMigrationRun(driver, vm, xml_persist, cookiein, cookieinlen, cookieout, cookieoutlen, flags, resource, &spec, dconn, graphicsuri, nmigrate_disks, migrate_disks); @@ -4837,12 +4847,12 @@ static int doPeer2PeerMigrate2(virQEMUDriverPtr driver, VIR_DEBUG("Perform %p", sconn); qemuMigrationJobSetPhase(driver, vm, QEMU_MIGRATION_PHASE_PERFORM2); if (flags & VIR_MIGRATE_TUNNELLED) - ret = doTunnelMigrate(driver, vm, st, + ret = doTunnelMigrate(driver, vm, st, NULL, NULL, 0, NULL, NULL, flags, resource, dconn, NULL, 0, NULL); else - ret = doNativeMigrate(driver, vm, uri_out, + ret = doNativeMigrate(driver, vm, NULL, uri_out, cookie, cookielen, NULL, NULL, /* No out cookie with v2 migration */ flags, resource, dconn, NULL, 0, NULL); @@ -4903,6 +4913,7 @@ doPeer2PeerMigrate3(virQEMUDriverPtr driver, const char *dconnuri, virDomainObjPtr vm, const char *xmlin, + const char *persist_xml, const char *dname, const char *uri, const char *graphicsuri, @@ -5073,13 +5084,13 @@ doPeer2PeerMigrate3(virQEMUDriverPtr driver, cookieout = NULL; cookieoutlen = 0; if (flags & VIR_MIGRATE_TUNNELLED) { - ret = doTunnelMigrate(driver, vm, st, + ret = doTunnelMigrate(driver, vm, st, persist_xml, cookiein, cookieinlen, &cookieout, &cookieoutlen, flags, bandwidth, dconn, graphicsuri, nmigrate_disks, migrate_disks); } else { - ret = doNativeMigrate(driver, vm, uri, + ret = doNativeMigrate(driver, vm, persist_xml, uri, cookiein, cookieinlen, &cookieout, &cookieoutlen, flags, bandwidth, dconn, graphicsuri, @@ -5252,6 +5263,7 @@ static int doPeer2PeerMigrate(virQEMUDriverPtr driver, virConnectPtr sconn, virDomainObjPtr vm, const char *xmlin, + const char *persist_xml, const char *dconnuri, const char *uri, const char *graphicsuri, @@ -5380,9 +5392,9 @@ static int doPeer2PeerMigrate(virQEMUDriverPtr driver, if (*v3proto) { ret = doPeer2PeerMigrate3(driver, sconn, dconn, dconnuri, vm, xmlin, - dname, uri, graphicsuri, listenAddress, - nmigrate_disks, migrate_disks, nbdPort, - resource, useParams, flags); + persist_xml, dname, uri, graphicsuri, + listenAddress, nmigrate_disks, migrate_disks, + nbdPort, resource, useParams, flags); } else { ret = doPeer2PeerMigrate2(driver, sconn, dconn, vm, dconnuri, flags, dname, resource); @@ -5413,6 +5425,7 @@ qemuMigrationPerformJob(virQEMUDriverPtr driver, virConnectPtr conn, virDomainObjPtr vm, const char *xmlin, + const char *persist_xml, const char *dconnuri, const char *uri, const char *graphicsuri, @@ -5453,13 +5466,13 @@ qemuMigrationPerformJob(virQEMUDriverPtr driver, qemuMigrationStoreDomainState(vm); if ((flags & (VIR_MIGRATE_TUNNELLED | VIR_MIGRATE_PEER2PEER))) { - ret = doPeer2PeerMigrate(driver, conn, vm, xmlin, + ret = doPeer2PeerMigrate(driver, conn, vm, xmlin, persist_xml, dconnuri, uri, graphicsuri, listenAddress, nmigrate_disks, migrate_disks, nbdPort, flags, dname, resource, &v3proto); } else { qemuMigrationJobSetPhase(driver, vm, QEMU_MIGRATION_PHASE_PERFORM2); - ret = doNativeMigrate(driver, vm, uri, cookiein, cookieinlen, + ret = doNativeMigrate(driver, vm, persist_xml, uri, cookiein, cookieinlen, cookieout, cookieoutlen, flags, resource, NULL, NULL, 0, NULL); } @@ -5518,6 +5531,7 @@ static int qemuMigrationPerformPhase(virQEMUDriverPtr driver, virConnectPtr conn, virDomainObjPtr vm, + const char *persist_xml, const char *uri, const char *graphicsuri, size_t nmigrate_disks, @@ -5544,7 +5558,7 @@ qemuMigrationPerformPhase(virQEMUDriverPtr driver, virCloseCallbacksUnset(driver->closeCallbacks, vm, qemuMigrationCleanup); - ret = doNativeMigrate(driver, vm, uri, cookiein, cookieinlen, + ret = doNativeMigrate(driver, vm, persist_xml, uri, cookiein, cookieinlen, cookieout, cookieoutlen, flags, resource, NULL, graphicsuri, nmigrate_disks, migrate_disks); @@ -5583,6 +5597,7 @@ qemuMigrationPerform(virQEMUDriverPtr driver, virConnectPtr conn, virDomainObjPtr vm, const char *xmlin, + const char *persist_xml, const char *dconnuri, const char *uri, const char *graphicsuri, @@ -5617,7 +5632,7 @@ qemuMigrationPerform(virQEMUDriverPtr driver, return -1; } - return qemuMigrationPerformJob(driver, conn, vm, xmlin, dconnuri, uri, + return qemuMigrationPerformJob(driver, conn, vm, xmlin, persist_xml, dconnuri, uri, graphicsuri, listenAddress, nmigrate_disks, migrate_disks, nbdPort, cookiein, cookieinlen, @@ -5631,14 +5646,14 @@ qemuMigrationPerform(virQEMUDriverPtr driver, } if (v3proto) { - return qemuMigrationPerformPhase(driver, conn, vm, uri, + return qemuMigrationPerformPhase(driver, conn, vm, persist_xml, uri, graphicsuri, nmigrate_disks, migrate_disks, cookiein, cookieinlen, cookieout, cookieoutlen, flags, resource); } else { - return qemuMigrationPerformJob(driver, conn, vm, xmlin, NULL, + return qemuMigrationPerformJob(driver, conn, vm, xmlin, persist_xml, NULL, uri, graphicsuri, listenAddress, nmigrate_disks, migrate_disks, nbdPort, cookiein, cookieinlen, diff --git a/src/qemu/qemu_migration.h b/src/qemu/qemu_migration.h index d279da4..3270d5b 100644 --- a/src/qemu/qemu_migration.h +++ b/src/qemu/qemu_migration.h @@ -54,6 +54,7 @@ VIR_MIGRATE_PARAM_MIGRATE_DISKS, VIR_TYPED_PARAM_STRING | \ VIR_TYPED_PARAM_MULTIPLE, \ VIR_MIGRATE_PARAM_DISKS_PORT, VIR_TYPED_PARAM_INT, \ + VIR_MIGRATE_PARAM_PERSIST_XML, VIR_TYPED_PARAM_STRING, \ NULL @@ -142,6 +143,7 @@ int qemuMigrationPerform(virQEMUDriverPtr driver, virConnectPtr conn, virDomainObjPtr vm, const char *xmlin, + const char *persist_xml, const char *dconnuri, const char *uri, const char *graphicsuri, -- 1.8.3.1

On Thu, Mar 17, 2016 at 19:31:45 +0300, Dmitry Andreev wrote:
Migration API allows to specify a destination domain configuration. Offline domain has only inactive XML and it is replaced by configuration specified using VIR_MIGRATE_PARAM_DEST_XML param. In case of live migration VIR_MIGRATE_PARAM_DEST_XML param is applied for active XML.
This commit introduces the new VIR_MIGRATE_PARAM_PERSIST_XML param that can be used within live migration to replace persistent/inactive configuration.
Required for: https://bugzilla.redhat.com/show_bug.cgi?id=835300 --- include/libvirt/libvirt-domain.h | 15 +++++++++++++ src/qemu/qemu_driver.c | 12 ++++++---- src/qemu/qemu_migration.c | 47 ++++++++++++++++++++++++++-------------- src/qemu/qemu_migration.h | 2 ++ 4 files changed, 56 insertions(+), 20 deletions(-)
diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h index 4ac29cd..f9dae22 100644 --- a/include/libvirt/libvirt-domain.h +++ b/include/libvirt/libvirt-domain.h @@ -723,6 +723,21 @@ typedef enum { # define VIR_MIGRATE_PARAM_DEST_XML "destination_xml"
/** + * VIR_MIGRATE_PARAM_PERSIST_XML: + * + * virDomainMigrate* params field: the new persistant configuration to be used
s/persistant/persistent/
+ * for the domain on the destination host as VIR_TYPED_PARAM_STRING. + * This field cannot be used to rename the domain during migration (use + * VIR_MIGRATE_PARAM_DEST_NAME field for that purpose). Domain name in the + * destination XML must match the original domain name. + * + * Omitting this parameter keeps the original domain persistent configuration. + * Using this field with hypervisors that do not support changing domain + * configuration during migration will result in a failure. + */ +# define VIR_MIGRATE_PARAM_PERSIST_XML "persistent_xml" + +/** * VIR_MIGRATE_PARAM_BANDWIDTH: * * virDomainMigrate* params field: the maximum bandwidth (in MiB/s) that will ... diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index f723a52..5624633 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c ... @@ -4566,14 +4568,20 @@ qemuMigrationRun(virQEMUDriverPtr driver, cookieFlags |= QEMU_MIGRATION_COOKIE_NETWORK | QEMU_MIGRATION_COOKIE_STATS;
+ if (flags & VIR_MIGRATE_PERSIST_DEST && persist_xml && + !(def = qemuMigrationPrepareDef(driver, persist_xml, NULL, NULL))) + ret = -1; +
I think this should be done before we start migration.
if (ret == 0 && (((flags & VIR_MIGRATE_PERSIST_DEST && - qemuMigrationCookieAddPersistent(mig, vm->newDef) < 0)) || + qemuMigrationCookieAddPersistent(mig, + def ? def : vm->newDef) < 0)) ||
And we can use a single variable for both vm->newDef and def depending on persist_xml.
qemuMigrationBakeCookie(mig, driver, vm, cookieout, cookieoutlen, cookieFlags) < 0)) { VIR_WARN("Unable to encode migration cookie"); }
+ virDomainDefFree(def); qemuMigrationCookieFree(mig);
if (events)
...
@@ -4683,6 +4692,7 @@ static int doNativeMigrate(virQEMUDriverPtr driver, static int doTunnelMigrate(virQEMUDriverPtr driver, virDomainObjPtr vm, virStreamPtr st, + const char *xml_persist,
s/xml_persist/persist_xml/ to keep the name consistent accros the file.
const char *cookiein, int cookieinlen, char **cookieout,
... To avoid sending another version of this patch for review, which already took too long (this is my fault, sorry for that), I suggest squashing the following patch in and pushing the result. Jirka diff --git i/include/libvirt/libvirt-domain.h w/include/libvirt/libvirt-domain.h index 697670f..9936cb2 100644 --- i/include/libvirt/libvirt-domain.h +++ w/include/libvirt/libvirt-domain.h @@ -729,7 +729,7 @@ typedef enum { /** * VIR_MIGRATE_PARAM_PERSIST_XML: * - * virDomainMigrate* params field: the new persistant configuration to be used + * virDomainMigrate* params field: the new persistent configuration to be used * for the domain on the destination host as VIR_TYPED_PARAM_STRING. * This field cannot be used to rename the domain during migration (use * VIR_MIGRATE_PARAM_DEST_NAME field for that purpose). Domain name in the diff --git i/src/qemu/qemu_migration.c w/src/qemu/qemu_migration.c index eee8ec2..680c9ba 100644 --- i/src/qemu/qemu_migration.c +++ w/src/qemu/qemu_migration.c @@ -4504,7 +4504,6 @@ qemuMigrationRun(virQEMUDriverPtr driver, { int ret = -1; unsigned int migrate_flags = QEMU_MONITOR_MIGRATE_BACKGROUND; - virDomainDefPtr def = NULL; qemuDomainObjPrivatePtr priv = vm->privateData; qemuMigrationCookiePtr mig = NULL; qemuMigrationIOThreadPtr iothread = NULL; @@ -4516,6 +4515,7 @@ qemuMigrationRun(virQEMUDriverPtr driver, bool events = virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATION_EVENT); bool inPostCopy = false; unsigned int waitFlags; + virDomainDefPtr persistDef = NULL; int rc; VIR_DEBUG("driver=%p, vm=%p, cookiein=%s, cookieinlen=%d, " @@ -4549,6 +4549,17 @@ qemuMigrationRun(virQEMUDriverPtr driver, if (events) priv->signalIOError = abort_on_error; + if (flags & VIR_MIGRATE_PERSIST_DEST) { + if (persist_xml) { + persistDef = qemuMigrationPrepareDef(driver, persist_xml, + NULL, NULL); + if (!persistDef) + goto cleanup; + } else { + persistDef = vm->newDef; + } + } + mig = qemuMigrationEatCookie(driver, vm, cookiein, cookieinlen, cookieFlags | QEMU_MIGRATION_COOKIE_GRAPHICS); if (!mig) @@ -4769,20 +4780,15 @@ qemuMigrationRun(virQEMUDriverPtr driver, cookieFlags |= QEMU_MIGRATION_COOKIE_NETWORK | QEMU_MIGRATION_COOKIE_STATS; - if (flags & VIR_MIGRATE_PERSIST_DEST && persist_xml && - !(def = qemuMigrationPrepareDef(driver, persist_xml, NULL, NULL))) - ret = -1; - if (ret == 0 && - (((flags & VIR_MIGRATE_PERSIST_DEST && - qemuMigrationCookieAddPersistent(mig, - def ? def : vm->newDef) < 0)) || - qemuMigrationBakeCookie(mig, driver, vm, cookieout, - cookieoutlen, cookieFlags) < 0)) { + (qemuMigrationCookieAddPersistent(mig, persistDef) < 0 || + qemuMigrationBakeCookie(mig, driver, vm, cookieout, + cookieoutlen, cookieFlags) < 0)) { VIR_WARN("Unable to encode migration cookie"); } - virDomainDefFree(def); + if (persistDef != vm->newDef) + virDomainDefFree(persistDef); qemuMigrationCookieFree(mig); if (events) @@ -4902,7 +4908,7 @@ static int doNativeMigrate(virQEMUDriverPtr driver, static int doTunnelMigrate(virQEMUDriverPtr driver, virDomainObjPtr vm, virStreamPtr st, - const char *xml_persist, + const char *persist_xml, const char *cookiein, int cookieinlen, char **cookieout, @@ -4948,9 +4954,9 @@ static int doTunnelMigrate(virQEMUDriverPtr driver, goto cleanup; } - ret = qemuMigrationRun(driver, vm, xml_persist, cookiein, cookieinlen, cookieout, - cookieoutlen, flags, resource, &spec, dconn, - graphicsuri, nmigrate_disks, migrate_disks, + ret = qemuMigrationRun(driver, vm, persist_xml, cookiein, cookieinlen, + cookieout, cookieoutlen, flags, resource, &spec, + dconn, graphicsuri, nmigrate_disks, migrate_disks, compression); cleanup:

On 15.04.2016 21:12, Jiri Denemark wrote:
On Thu, Mar 17, 2016 at 19:31:45 +0300, Dmitry Andreev wrote:
Migration API allows to specify a destination domain configuration. Offline domain has only inactive XML and it is replaced by configuration specified using VIR_MIGRATE_PARAM_DEST_XML param. In case of live migration VIR_MIGRATE_PARAM_DEST_XML param is applied for active XML.
This commit introduces the new VIR_MIGRATE_PARAM_PERSIST_XML param that can be used within live migration to replace persistent/inactive configuration.
Required for: https://bugzilla.redhat.com/show_bug.cgi?id=835300 --- include/libvirt/libvirt-domain.h | 15 +++++++++++++ src/qemu/qemu_driver.c | 12 ++++++---- src/qemu/qemu_migration.c | 47 ++++++++++++++++++++++++++-------------- src/qemu/qemu_migration.h | 2 ++ 4 files changed, 56 insertions(+), 20 deletions(-)
diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h index 4ac29cd..f9dae22 100644 --- a/include/libvirt/libvirt-domain.h +++ b/include/libvirt/libvirt-domain.h @@ -723,6 +723,21 @@ typedef enum { # define VIR_MIGRATE_PARAM_DEST_XML "destination_xml"
/** + * VIR_MIGRATE_PARAM_PERSIST_XML: + * + * virDomainMigrate* params field: the new persistant configuration to be used
s/persistant/persistent/
+ * for the domain on the destination host as VIR_TYPED_PARAM_STRING. + * This field cannot be used to rename the domain during migration (use + * VIR_MIGRATE_PARAM_DEST_NAME field for that purpose). Domain name in the + * destination XML must match the original domain name. + * + * Omitting this parameter keeps the original domain persistent configuration. + * Using this field with hypervisors that do not support changing domain + * configuration during migration will result in a failure. + */ +# define VIR_MIGRATE_PARAM_PERSIST_XML "persistent_xml" + +/** * VIR_MIGRATE_PARAM_BANDWIDTH: * * virDomainMigrate* params field: the maximum bandwidth (in MiB/s) that will ... diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index f723a52..5624633 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c ... @@ -4566,14 +4568,20 @@ qemuMigrationRun(virQEMUDriverPtr driver, cookieFlags |= QEMU_MIGRATION_COOKIE_NETWORK | QEMU_MIGRATION_COOKIE_STATS;
+ if (flags & VIR_MIGRATE_PERSIST_DEST && persist_xml && + !(def = qemuMigrationPrepareDef(driver, persist_xml, NULL, NULL))) + ret = -1; +
I think this should be done before we start migration.
if (ret == 0 && (((flags & VIR_MIGRATE_PERSIST_DEST && - qemuMigrationCookieAddPersistent(mig, vm->newDef) < 0)) || + qemuMigrationCookieAddPersistent(mig, + def ? def : vm->newDef) < 0)) ||
And we can use a single variable for both vm->newDef and def depending on persist_xml.
qemuMigrationBakeCookie(mig, driver, vm, cookieout, cookieoutlen, cookieFlags) < 0)) { VIR_WARN("Unable to encode migration cookie"); }
+ virDomainDefFree(def); qemuMigrationCookieFree(mig);
if (events)
...
@@ -4683,6 +4692,7 @@ static int doNativeMigrate(virQEMUDriverPtr driver, static int doTunnelMigrate(virQEMUDriverPtr driver, virDomainObjPtr vm, virStreamPtr st, + const char *xml_persist,
s/xml_persist/persist_xml/ to keep the name consistent accros the file.
const char *cookiein, int cookieinlen, char **cookieout,
...
To avoid sending another version of this patch for review, which already took too long (this is my fault, sorry for that), I suggest squashing the following patch in and pushing the result.
I'm OK with the following patch. Thanks!
Jirka
diff --git i/include/libvirt/libvirt-domain.h w/include/libvirt/libvirt-domain.h index 697670f..9936cb2 100644 --- i/include/libvirt/libvirt-domain.h +++ w/include/libvirt/libvirt-domain.h @@ -729,7 +729,7 @@ typedef enum { /** * VIR_MIGRATE_PARAM_PERSIST_XML: * - * virDomainMigrate* params field: the new persistant configuration to be used + * virDomainMigrate* params field: the new persistent configuration to be used * for the domain on the destination host as VIR_TYPED_PARAM_STRING. * This field cannot be used to rename the domain during migration (use * VIR_MIGRATE_PARAM_DEST_NAME field for that purpose). Domain name in the diff --git i/src/qemu/qemu_migration.c w/src/qemu/qemu_migration.c index eee8ec2..680c9ba 100644 --- i/src/qemu/qemu_migration.c +++ w/src/qemu/qemu_migration.c @@ -4504,7 +4504,6 @@ qemuMigrationRun(virQEMUDriverPtr driver, { int ret = -1; unsigned int migrate_flags = QEMU_MONITOR_MIGRATE_BACKGROUND; - virDomainDefPtr def = NULL; qemuDomainObjPrivatePtr priv = vm->privateData; qemuMigrationCookiePtr mig = NULL; qemuMigrationIOThreadPtr iothread = NULL; @@ -4516,6 +4515,7 @@ qemuMigrationRun(virQEMUDriverPtr driver, bool events = virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATION_EVENT); bool inPostCopy = false; unsigned int waitFlags; + virDomainDefPtr persistDef = NULL; int rc;
VIR_DEBUG("driver=%p, vm=%p, cookiein=%s, cookieinlen=%d, " @@ -4549,6 +4549,17 @@ qemuMigrationRun(virQEMUDriverPtr driver, if (events) priv->signalIOError = abort_on_error;
+ if (flags & VIR_MIGRATE_PERSIST_DEST) { + if (persist_xml) { + persistDef = qemuMigrationPrepareDef(driver, persist_xml, + NULL, NULL); + if (!persistDef) + goto cleanup; + } else { + persistDef = vm->newDef; + } + } + mig = qemuMigrationEatCookie(driver, vm, cookiein, cookieinlen, cookieFlags | QEMU_MIGRATION_COOKIE_GRAPHICS); if (!mig) @@ -4769,20 +4780,15 @@ qemuMigrationRun(virQEMUDriverPtr driver, cookieFlags |= QEMU_MIGRATION_COOKIE_NETWORK | QEMU_MIGRATION_COOKIE_STATS;
- if (flags & VIR_MIGRATE_PERSIST_DEST && persist_xml && - !(def = qemuMigrationPrepareDef(driver, persist_xml, NULL, NULL))) - ret = -1; - if (ret == 0 && - (((flags & VIR_MIGRATE_PERSIST_DEST && - qemuMigrationCookieAddPersistent(mig, - def ? def : vm->newDef) < 0)) || - qemuMigrationBakeCookie(mig, driver, vm, cookieout, - cookieoutlen, cookieFlags) < 0)) { + (qemuMigrationCookieAddPersistent(mig, persistDef) < 0 || + qemuMigrationBakeCookie(mig, driver, vm, cookieout, + cookieoutlen, cookieFlags) < 0)) { VIR_WARN("Unable to encode migration cookie"); }
- virDomainDefFree(def); + if (persistDef != vm->newDef) + virDomainDefFree(persistDef); qemuMigrationCookieFree(mig);
if (events) @@ -4902,7 +4908,7 @@ static int doNativeMigrate(virQEMUDriverPtr driver, static int doTunnelMigrate(virQEMUDriverPtr driver, virDomainObjPtr vm, virStreamPtr st, - const char *xml_persist, + const char *persist_xml, const char *cookiein, int cookieinlen, char **cookieout, @@ -4948,9 +4954,9 @@ static int doTunnelMigrate(virQEMUDriverPtr driver, goto cleanup; }
- ret = qemuMigrationRun(driver, vm, xml_persist, cookiein, cookieinlen, cookieout, - cookieoutlen, flags, resource, &spec, dconn, - graphicsuri, nmigrate_disks, migrate_disks, + ret = qemuMigrationRun(driver, vm, persist_xml, cookiein, cookieinlen, + cookieout, cookieoutlen, flags, resource, &spec, + dconn, graphicsuri, nmigrate_disks, migrate_disks, compression);
cleanup:
-- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list

ping On 17.03.2016 19:31, Dmitry Andreev wrote:
v4: wrong param name in commit msg
v3: - use shorter name for param and rename args - move qemuMigrationCookieAddPersistent out from qemuMigrationBakeCookie - rebase to master
v2: reimplemented with new migration param
Libvirt doesn't allow to specify destination persistent domain configuration. VIR_MIGRATE_PARAM_DEST_XML migration param is used for active configuration and persistent configuration is taken from source domain. The problem is mentioned in this bug: https://bugzilla.redhat.com/show_bug.cgi?id=835300
This patch-set introduces new migration param VIR_MIGRATE_PARAM_PERSIST_XML and implements its support in qemu driver.
Dmitry Andreev (2): qemuMigrationCookieAddPersistent: move it out and change argument type qemu: migration: new migration param for persistent destination XML
include/libvirt/libvirt-domain.h | 15 ++++++++++ src/qemu/qemu_driver.c | 12 +++++--- src/qemu/qemu_migration.c | 64 ++++++++++++++++++++++++---------------- src/qemu/qemu_migration.h | 2 ++ 4 files changed, 63 insertions(+), 30 deletions(-)

On Thu, Mar 17, 2016 at 19:31:43 +0300, Dmitry Andreev wrote:
v4: wrong param name in commit msg
v3: - use shorter name for param and rename args - move qemuMigrationCookieAddPersistent out from qemuMigrationBakeCookie - rebase to master
v2: reimplemented with new migration param
Pushed now with the suggested changes for 2/2. Jirka
participants (2)
-
Dmitry Andreev
-
Jiri Denemark