This extends the v3 migration protocol such that the
virDomainMigrateBegin3 and virDomainMigratePerform3
methods accept an application supplied XML config for
the target VM.
If the 'xmlin' parameter is NULL, then Begin3 uses the
current guest XML as normal. A driver implementing the
Begin3 method should either reject all non-NULL 'xmlin'
parameters, or strictly validate that the app supplied
XML does not change guest ABI.
The Perform3 method also needed the xmlin parameter to
cope with the Peer2Peer migration sequence.
NB it is not yet possible to use this capability since
neither of the public virDomainMigrate/virDomainMigrateToURI
methods have a way to pass in XML.
* daemon/remote.c, src/remote/remote_driver.c,
src/remote/remote_protocol.x, src/remote_protocol-structs:
Add 'remote_string xmlin' parameter to begin3/perform3
RPC messages
* src/libvirt.c, src/driver.h, src/libvirt_internal.h: Add
'const char *xmlin' parameter to Begin3/Perform3 methods
* src/qemu/qemu_driver.c, src/qemu/qemu_migration.c,
src/qemu/qemu_migration.h: Pass xmlin parameter around
migration methods
---
.gnulib | 2 +-
daemon/remote.c | 8 +++++-
src/driver.h | 2 +
src/libvirt.c | 49 ++++++++++++++++++++++++++++++-----------
src/libvirt_internal.h | 2 +
src/qemu/qemu_driver.c | 8 ++++--
src/qemu/qemu_migration.c | 17 ++++++++++++--
src/qemu/qemu_migration.h | 2 +
src/remote/remote_driver.c | 4 +++
src/remote/remote_protocol.x | 2 +
src/remote_protocol-structs | 2 +
11 files changed, 76 insertions(+), 22 deletions(-)
diff --git a/.gnulib b/.gnulib
index 2c25c9e..64a5e38 160000
--- a/.gnulib
+++ b/.gnulib
@@ -1 +1 @@
-Subproject commit 2c25c9ebe8db1415bfde25f0a451767332c8cf59
+Subproject commit 64a5e38bced6c8f5117efbed95cdfd8ca133ed54
diff --git a/daemon/remote.c b/daemon/remote.c
index 42e1cb9..03f1a5e 100644
--- a/daemon/remote.c
+++ b/daemon/remote.c
@@ -3165,6 +3165,7 @@ remoteDispatchDomainMigrateBegin3(struct qemud_server *server
ATTRIBUTE_UNUSED,
char *xml = NULL;
virDomainPtr dom = NULL;
char *dname;
+ char *xmlin;
char *cookieout = NULL;
int cookieoutlen = 0;
int rv = -1;
@@ -3177,9 +3178,10 @@ remoteDispatchDomainMigrateBegin3(struct qemud_server *server
ATTRIBUTE_UNUSED,
if (!(dom = get_nonnull_domain(conn, args->dom)))
goto cleanup;
+ xmlin = args->xmlin == NULL ? NULL : *args->xmlin;
dname = args->dname == NULL ? NULL : *args->dname;
- if (!(xml = virDomainMigrateBegin3(dom,
+ if (!(xml = virDomainMigrateBegin3(dom, xmlin,
&cookieout, &cookieoutlen,
args->flags, dname, args->resource)))
goto cleanup;
@@ -3325,6 +3327,7 @@ remoteDispatchDomainMigratePerform3(struct qemud_server *server
ATTRIBUTE_UNUSED
remote_domain_migrate_perform3_ret *ret)
{
virDomainPtr dom = NULL;
+ char *xmlin;
char *dname;
char *cookieout = NULL;
int cookieoutlen = 0;
@@ -3338,9 +3341,10 @@ remoteDispatchDomainMigratePerform3(struct qemud_server *server
ATTRIBUTE_UNUSED
if (!(dom = get_nonnull_domain(conn, args->dom)))
goto cleanup;
+ xmlin = args->xmlin == NULL ? NULL : *args->xmlin;
dname = args->dname == NULL ? NULL : *args->dname;
- if (virDomainMigratePerform3(dom,
+ if (virDomainMigratePerform3(dom, xmlin,
args->cookie_in.cookie_in_val,
args->cookie_in.cookie_in_len,
&cookieout, &cookieoutlen,
diff --git a/src/driver.h b/src/driver.h
index 450dd53..a1468e8 100644
--- a/src/driver.h
+++ b/src/driver.h
@@ -538,6 +538,7 @@ typedef int
typedef char *
(*virDrvDomainMigrateBegin3)
(virDomainPtr domain,
+ const char *xmlin,
char **cookieout,
int *cookieoutlen,
unsigned long flags,
@@ -575,6 +576,7 @@ typedef int
typedef int
(*virDrvDomainMigratePerform3)
(virDomainPtr dom,
+ const char *xmlin,
const char *cookiein,
int cookieinlen,
char **cookieout,
diff --git a/src/libvirt.c b/src/libvirt.c
index ff16c48..7b7323e 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -3719,6 +3719,7 @@ finish:
static virDomainPtr
virDomainMigrateVersion3(virDomainPtr domain,
virConnectPtr dconn,
+ const char *xmlin,
unsigned long flags,
const char *dname,
const char *uri,
@@ -3748,8 +3749,8 @@ virDomainMigrateVersion3(virDomainPtr domain,
VIR_DEBUG("Begin3 %p", domain->conn);
dom_xml = domain->conn->driver->domainMigrateBegin3
- (domain, &cookieout, &cookieoutlen, flags, dname,
- bandwidth);
+ (domain, xmlin, &cookieout, &cookieoutlen,
+ flags, dname, bandwidth);
if (!dom_xml)
goto done;
@@ -3792,7 +3793,8 @@ virDomainMigrateVersion3(virDomainPtr domain,
cookieout = NULL;
cookieoutlen = 0;
ret = domain->conn->driver->domainMigratePerform3
- (domain, cookiein, cookieinlen, &cookieout, &cookieoutlen,
+ (domain, NULL, cookiein, cookieinlen,
+ &cookieout, &cookieoutlen,
uri, flags, dname, bandwidth);
/* Perform failed. Make sure Finish doesn't overwrite the error */
@@ -3872,6 +3874,7 @@ finish:
*/
static int
virDomainMigratePeer2Peer (virDomainPtr domain,
+ const char *xmlin,
unsigned long flags,
const char *dname,
const char *uri,
@@ -3907,6 +3910,7 @@ virDomainMigratePeer2Peer (virDomainPtr domain,
VIR_DRV_FEATURE_MIGRATION_V3)) {
VIR_DEBUG("Using migration protocol 3");
return domain->conn->driver->domainMigratePerform3(domain,
+ xmlin,
NULL, /* cookiein */
0, /* cookieinlen */
NULL, /* cookieoutlen */
@@ -3917,6 +3921,11 @@ virDomainMigratePeer2Peer (virDomainPtr domain,
bandwidth);
} else {
VIR_DEBUG("Using migration protocol 2");
+ if (xmlin) {
+ virLibConnError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Unable to change target guest XML during
migration"));
+ return -1;
+ }
return domain->conn->driver->domainMigratePerform(domain,
NULL, /* cookie */
0, /* cookielen */
@@ -3941,6 +3950,7 @@ virDomainMigratePeer2Peer (virDomainPtr domain,
*/
static int
virDomainMigrateDirect (virDomainPtr domain,
+ const char *xmlin,
unsigned long flags,
const char *dname,
const char *uri,
@@ -3959,6 +3969,7 @@ virDomainMigrateDirect (virDomainPtr domain,
VIR_DRV_FEATURE_MIGRATION_V3)) {
VIR_DEBUG("Using migration protocol 3");
return domain->conn->driver->domainMigratePerform3(domain,
+ xmlin,
NULL, /* cookiein */
0, /* cookieinlen */
NULL, /* cookieoutlen */
@@ -3969,6 +3980,11 @@ virDomainMigrateDirect (virDomainPtr domain,
bandwidth);
} else {
VIR_DEBUG("Using migration protocol 2");
+ if (xmlin) {
+ virLibConnError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Unable to change target guest XML during
migration"));
+ return -1;
+ }
return domain->conn->driver->domainMigratePerform(domain,
NULL, /* cookie */
0, /* cookielen */
@@ -4093,7 +4109,8 @@ virDomainMigrate (virDomainPtr domain,
}
VIR_DEBUG("Using peer2peer migration");
- if (virDomainMigratePeer2Peer(domain, flags, dname, uri ? uri : dstURI,
bandwidth) < 0) {
+ if (virDomainMigratePeer2Peer(domain, NULL, flags, dname,
+ uri ? uri : dstURI, bandwidth) < 0) {
VIR_FREE(dstURI);
goto error;
}
@@ -4118,7 +4135,7 @@ virDomainMigrate (virDomainPtr domain,
VIR_DRV_SUPPORTS_FEATURE(dconn->driver, dconn,
VIR_DRV_FEATURE_MIGRATION_V3)) {
VIR_DEBUG("Using migration protocol 3");
- ddomain = virDomainMigrateVersion3(domain, dconn, flags, dname, uri,
bandwidth);
+ ddomain = virDomainMigrateVersion3(domain, dconn, NULL, flags, dname, uri,
bandwidth);
} else if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
VIR_DRV_FEATURE_MIGRATION_V2) &&
VIR_DRV_SUPPORTS_FEATURE(dconn->driver, dconn,
@@ -4238,7 +4255,8 @@ virDomainMigrateToURI (virDomainPtr domain,
if (VIR_DRV_SUPPORTS_FEATURE (domain->conn->driver, domain->conn,
VIR_DRV_FEATURE_MIGRATION_P2P)) {
VIR_DEBUG("Using peer2peer migration");
- if (virDomainMigratePeer2Peer (domain, flags, dname, duri, bandwidth) <
0)
+ if (virDomainMigratePeer2Peer(domain, NULL, flags,
+ dname, duri, bandwidth) < 0)
goto error;
} else {
/* No peer to peer migration supported */
@@ -4249,7 +4267,8 @@ virDomainMigrateToURI (virDomainPtr domain,
if (VIR_DRV_SUPPORTS_FEATURE (domain->conn->driver, domain->conn,
VIR_DRV_FEATURE_MIGRATION_DIRECT)) {
VIR_DEBUG("Using direct migration");
- if (virDomainMigrateDirect (domain, flags, dname, duri, bandwidth) < 0)
+ if (virDomainMigrateDirect(domain, NULL, flags,
+ dname, duri, bandwidth) < 0)
goto error;
} else {
/* Cannot do a migration with only the perform step */
@@ -4567,6 +4586,7 @@ error:
*/
char *
virDomainMigrateBegin3(virDomainPtr domain,
+ const char *xmlin,
char **cookieout,
int *cookieoutlen,
unsigned long flags,
@@ -4575,9 +4595,9 @@ virDomainMigrateBegin3(virDomainPtr domain,
{
virConnectPtr conn;
- VIR_DOMAIN_DEBUG(domain, "cookieout=%p, cookieoutlen=%p, "
+ VIR_DOMAIN_DEBUG(domain, "xmlin=%s cookieout=%p, cookieoutlen=%p, "
"flags=%lu, dname=%s, bandwidth=%lu",
- cookieout, cookieoutlen, flags,
+ NULLSTR(xmlin), cookieout, cookieoutlen, flags,
NULLSTR(dname), bandwidth);
virResetLastError();
@@ -4596,7 +4616,7 @@ virDomainMigrateBegin3(virDomainPtr domain,
if (conn->driver->domainMigrateBegin3) {
char *xml;
- xml = conn->driver->domainMigrateBegin3(domain,
+ xml = conn->driver->domainMigrateBegin3(domain, xmlin,
cookieout, cookieoutlen,
flags, dname, bandwidth);
VIR_DEBUG("xml %s", NULLSTR(xml));
@@ -4733,6 +4753,7 @@ error:
*/
int
virDomainMigratePerform3(virDomainPtr domain,
+ const char *xmlin,
const char *cookiein,
int cookieinlen,
char **cookieout,
@@ -4744,9 +4765,11 @@ virDomainMigratePerform3(virDomainPtr domain,
{
virConnectPtr conn;
- VIR_DOMAIN_DEBUG(domain, "cookiein=%p, cookieinlen=%d, cookieout=%p,
cookieoutlen=%p,"
+ VIR_DOMAIN_DEBUG(domain, "xmlin=%s cookiein=%p, cookieinlen=%d, "
+ "cookieout=%p, cookieoutlen=%p, "
"uri=%s, flags=%lu, dname=%s, bandwidth=%lu",
- cookiein, cookieinlen, cookieout, cookieoutlen,
+ NULLSTR(xmlin), cookiein, cookieinlen,
+ cookieout, cookieoutlen,
uri, flags, NULLSTR(dname), bandwidth);
virResetLastError();
@@ -4765,7 +4788,7 @@ virDomainMigratePerform3(virDomainPtr domain,
if (conn->driver->domainMigratePerform3) {
int ret;
- ret = conn->driver->domainMigratePerform3(domain,
+ ret = conn->driver->domainMigratePerform3(domain, xmlin,
cookiein, cookieinlen,
cookieout, cookieoutlen,
uri,
diff --git a/src/libvirt_internal.h b/src/libvirt_internal.h
index 81d0c56..c7c1932 100644
--- a/src/libvirt_internal.h
+++ b/src/libvirt_internal.h
@@ -124,6 +124,7 @@ int virDomainMigratePrepareTunnel(virConnectPtr dconn,
char *virDomainMigrateBegin3(virDomainPtr domain,
+ const char *xmlin,
char **cookieout,
int *cookieoutlen,
unsigned long flags,
@@ -155,6 +156,7 @@ int virDomainMigratePrepareTunnel3(virConnectPtr dconn,
int virDomainMigratePerform3(virDomainPtr dom,
+ const char *xmlin,
const char *cookiein,
int cookieinlen,
char **cookieout,
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 44acc6a..2f454f7 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -5961,7 +5961,7 @@ qemudDomainMigratePerform (virDomainPtr dom,
* Consume any cookie we were able to decode though
*/
ret = qemuMigrationPerform(driver, dom->conn, vm,
- uri, cookie, cookielen,
+ NULL, uri, cookie, cookielen,
NULL, NULL, /* No output cookies in v2 */
flags, dname, resource, true);
@@ -6030,6 +6030,7 @@ cleanup:
static char *
qemuDomainMigrateBegin3(virDomainPtr domain,
+ const char *xmlin,
char **cookieout,
int *cookieoutlen,
unsigned long flags,
@@ -6059,7 +6060,7 @@ qemuDomainMigrateBegin3(virDomainPtr domain,
goto cleanup;
}
- xml = qemuMigrationBegin(driver, vm,
+ xml = qemuMigrationBegin(driver, vm, xmlin,
cookieout, cookieoutlen);
cleanup:
@@ -6176,6 +6177,7 @@ cleanup:
static int
qemuDomainMigratePerform3(virDomainPtr dom,
+ const char *xmlin,
const char *cookiein,
int cookieinlen,
char **cookieout,
@@ -6208,7 +6210,7 @@ qemuDomainMigratePerform3(virDomainPtr dom,
goto cleanup;
}
- ret = qemuMigrationPerform(driver, dom->conn, vm,
+ ret = qemuMigrationPerform(driver, dom->conn, vm, xmlin,
uri, cookiein, cookieinlen,
cookieout, cookieoutlen,
flags, dname, resource, false);
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 4d7bc38..077a1b1 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -809,12 +809,19 @@ qemuDomainMigrateGraphicsRelocate(struct qemud_driver *driver,
char *qemuMigrationBegin(struct qemud_driver *driver,
virDomainObjPtr vm,
+ const char *xmlin,
char **cookieout,
int *cookieoutlen)
{
char *rv = NULL;
qemuMigrationCookiePtr mig = NULL;
+ if (xmlin) {
+ qemuReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("Passing XML for the target VM is not yet
supported"));
+ goto cleanup;
+ }
+
if (!virDomainObjIsActive(vm)) {
qemuReportError(VIR_ERR_OPERATION_INVALID,
"%s", _("domain is not running"));
@@ -1725,6 +1732,7 @@ static int doPeer2PeerMigrate3(struct qemud_driver *driver,
virConnectPtr sconn,
virConnectPtr dconn,
virDomainObjPtr vm,
+ const char *xmlin,
const char *uri,
unsigned long flags,
const char *dname,
@@ -1743,7 +1751,7 @@ static int doPeer2PeerMigrate3(struct qemud_driver *driver,
virStreamPtr st = NULL;
VIR_DEBUG("Begin3 %p", sconn);
- dom_xml = qemuMigrationBegin(driver, vm,
+ dom_xml = qemuMigrationBegin(driver, vm, xmlin,
&cookieout, &cookieoutlen);
if (!dom_xml)
goto cleanup;
@@ -1889,6 +1897,7 @@ finish:
static int doPeer2PeerMigrate(struct qemud_driver *driver,
virConnectPtr sconn,
virDomainObjPtr vm,
+ const char *xmlin,
const char *uri,
unsigned long flags,
const char *dname,
@@ -1933,7 +1942,7 @@ static int doPeer2PeerMigrate(struct qemud_driver *driver,
}
if (v3)
- ret = doPeer2PeerMigrate3(driver, sconn, dconn, vm,
+ ret = doPeer2PeerMigrate3(driver, sconn, dconn, vm, xmlin,
uri, flags, dname, resource);
else
ret = doPeer2PeerMigrate2(driver, sconn, dconn, vm,
@@ -1952,6 +1961,7 @@ cleanup:
int qemuMigrationPerform(struct qemud_driver *driver,
virConnectPtr conn,
virDomainObjPtr vm,
+ const char *xmlin,
const char *uri,
const char *cookiein,
int cookieinlen,
@@ -1994,7 +2004,8 @@ int qemuMigrationPerform(struct qemud_driver *driver,
goto endjob;
}
- if (doPeer2PeerMigrate(driver, conn, vm, uri, flags, dname, resource) < 0)
+ if (doPeer2PeerMigrate(driver, conn, vm, xmlin,
+ uri, flags, dname, resource) < 0)
/* doPeer2PeerMigrate already set the error, so just get out */
goto endjob;
} else {
diff --git a/src/qemu/qemu_migration.h b/src/qemu/qemu_migration.h
index f96a0b8..a24b3a8 100644
--- a/src/qemu/qemu_migration.h
+++ b/src/qemu/qemu_migration.h
@@ -34,6 +34,7 @@ int qemuMigrationWaitForCompletion(struct qemud_driver *driver,
virDomainObjPtr
char *qemuMigrationBegin(struct qemud_driver *driver,
virDomainObjPtr vm,
+ const char *xmlin,
char **cookieout,
int *cookieoutlen);
@@ -61,6 +62,7 @@ int qemuMigrationPrepareDirect(struct qemud_driver *driver,
int qemuMigrationPerform(struct qemud_driver *driver,
virConnectPtr conn,
virDomainObjPtr vm,
+ const char *xmlin,
const char *uri,
const char *cookiein,
int cookieinlen,
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index 8c69743..77bd474 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -4982,6 +4982,7 @@ done:
static char *
remoteDomainMigrateBegin3(virDomainPtr domain,
+ const char *xmlin,
char **cookieout,
int *cookieoutlen,
unsigned long flags,
@@ -4999,6 +5000,7 @@ remoteDomainMigrateBegin3(virDomainPtr domain,
memset(&ret, 0, sizeof(ret));
make_nonnull_domain (&args.dom, domain);
+ args.xmlin = xmlin == NULL ? NULL : (char **) &xmlin;
args.flags = flags;
args.dname = dname == NULL ? NULL : (char **) &dname;
args.resource = resource;
@@ -5167,6 +5169,7 @@ error:
static int
remoteDomainMigratePerform3(virDomainPtr dom,
+ const char *xmlin,
const char *cookiein,
int cookieinlen,
char **cookieout,
@@ -5188,6 +5191,7 @@ remoteDomainMigratePerform3(virDomainPtr dom,
make_nonnull_domain(&args.dom, dom);
+ args.xmlin = xmlin == NULL ? NULL : (char **) &xmlin;
args.cookie_in.cookie_in_val = (char *)cookiein;
args.cookie_in.cookie_in_len = cookieinlen;
args.uri = (char *) uri;
diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x
index 5932b2c..37b5a3f 100644
--- a/src/remote/remote_protocol.x
+++ b/src/remote/remote_protocol.x
@@ -1973,6 +1973,7 @@ struct remote_domain_get_state_ret {
struct remote_domain_migrate_begin3_args {
remote_nonnull_domain dom;
+ remote_string xmlin;
unsigned hyper flags;
remote_string dname;
unsigned hyper resource;
@@ -2011,6 +2012,7 @@ struct remote_domain_migrate_prepare_tunnel3_ret {
struct remote_domain_migrate_perform3_args {
remote_nonnull_domain dom;
+ remote_string xmlin;
opaque cookie_in<REMOTE_MIGRATE_COOKIE_MAX>;
remote_nonnull_string uri;
unsigned hyper flags;
diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs
index 5b43cb4..616a44b 100644
--- a/src/remote_protocol-structs
+++ b/src/remote_protocol-structs
@@ -1457,6 +1457,7 @@ struct remote_domain_get_state_ret {
};
struct remote_domain_migrate_begin3_args {
remote_nonnull_domain dom;
+ remote_string xmlin;
uint64_t flags;
remote_string dname;
uint64_t resource;
@@ -1504,6 +1505,7 @@ struct remote_domain_migrate_prepare_tunnel3_ret {
};
struct remote_domain_migrate_perform3_args {
remote_nonnull_domain dom;
+ remote_string xmlin;
struct {
u_int cookie_in_len;
char * cookie_in_val;
--
1.7.4.4