The virDomainMigratePerform3 currently has a single URI parameter whose meaning varies. It is either - A QEMU migration URI (normal migration) - A libvirtd connection URI (peer2peer migration) Unfortunately when using peer2peer migration, without also using tunnelled migration, it is possible that both URIs are required. This adds a second URI parameter to the virDomainMigratePerform3 method, to cope with this scenario. Each parameter how has a fixed meaning. NB, there is no way to actually take advantage of this yet, since virDomainMigrate/virDomainMigrateToURI do not have any way to provide the 2 separate URIs * daemon/remote.c, src/remote/remote_driver.c, src/remote/remote_protocol.x, src/remote_protocol-structs: Add the second URI parameter to perform3 message * src/driver.h, src/libvirt.c, src/libvirt_internal.h: Add the second URI parameter to Perform3 method * src/libvirt_internal.h, src/qemu/qemu_migration.c, src/qemu/qemu_migration.h: Update to handle URIs correctly --- daemon/remote.c | 13 +++++++++++-- src/driver.h | 2 ++ src/libvirt.c | 37 +++++++++++++++++++++++++------------ src/libvirt_internal.h | 6 ++++-- src/qemu/qemu_driver.c | 12 ++++++++++-- src/qemu/qemu_migration.c | 26 +++++++++++++++++--------- src/qemu/qemu_migration.h | 1 + src/remote/remote_driver.c | 8 ++++++-- src/remote/remote_protocol.x | 6 ++++-- src/remote_protocol-structs | 1 + 10 files changed, 81 insertions(+), 31 deletions(-) diff --git a/daemon/remote.c b/daemon/remote.c index 60f01b4..f85d760 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -3292,6 +3292,8 @@ remoteDispatchDomainMigratePerform3(struct qemud_server *server ATTRIBUTE_UNUSED virDomainPtr dom = NULL; char *xmlin; char *dname; + char *uri; + char *dconnuri; char *cookieout = NULL; int cookieoutlen = 0; int rv = -1; @@ -3306,12 +3308,14 @@ remoteDispatchDomainMigratePerform3(struct qemud_server *server ATTRIBUTE_UNUSED xmlin = args->xmlin == NULL ? NULL : *args->xmlin; dname = args->dname == NULL ? NULL : *args->dname; + uri = args->uri == NULL ? NULL : *args->uri; + dconnuri = args->dconnuri == NULL ? NULL : *args->dconnuri; if (virDomainMigratePerform3(dom, xmlin, args->cookie_in.cookie_in_val, args->cookie_in.cookie_in_len, &cookieout, &cookieoutlen, - args->uri, + dconnuri, uri, args->flags, dname, args->resource) < 0) goto cleanup; @@ -3343,6 +3347,8 @@ remoteDispatchDomainMigrateFinish3(struct qemud_server *server ATTRIBUTE_UNUSED, virDomainPtr dom = NULL; char *cookieout = NULL; int cookieoutlen = 0; + char *uri; + char *dconnuri; int rv = -1; if (!conn) { @@ -3350,11 +3356,14 @@ remoteDispatchDomainMigrateFinish3(struct qemud_server *server ATTRIBUTE_UNUSED, goto cleanup; } + uri = args->uri == NULL ? NULL : *args->uri; + dconnuri = args->dconnuri == NULL ? NULL : *args->dconnuri; + if (virDomainMigrateFinish3(conn, args->dname, args->cookie_in.cookie_in_val, args->cookie_in.cookie_in_len, &cookieout, &cookieoutlen, - args->uri, + dconnuri, uri, args->flags, args->cancelled, &dom) < 0) diff --git a/src/driver.h b/src/driver.h index a1468e8..a5d8fe5 100644 --- a/src/driver.h +++ b/src/driver.h @@ -581,6 +581,7 @@ typedef int int cookieinlen, char **cookieout, int *cookieoutlen, + const char *dconnuri, const char *uri, unsigned long flags, const char *dname, @@ -594,6 +595,7 @@ typedef int int cookieinlen, char **cookieout, int *cookieoutlen, + const char *dconnuri, const char *uri, unsigned long flags, int cancelled, diff --git a/src/libvirt.c b/src/libvirt.c index 7b7323e..2b2c1fd 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -3792,9 +3792,10 @@ virDomainMigrateVersion3(virDomainPtr domain, cookieinlen = cookieoutlen; cookieout = NULL; cookieoutlen = 0; + /* dconnuri not relevant in non-P2P modes, so left NULL here */ ret = domain->conn->driver->domainMigratePerform3 (domain, NULL, cookiein, cookieinlen, - &cookieout, &cookieoutlen, + &cookieout, &cookieoutlen, NULL, uri, flags, dname, bandwidth); /* Perform failed. Make sure Finish doesn't overwrite the error */ @@ -3822,7 +3823,7 @@ finish: dname = dname ? dname : domain->name; ret = dconn->driver->domainMigrateFinish3 (dconn, dname, cookiein, cookieinlen, &cookieout, &cookieoutlen, - uri, flags, cancelled, &ddomain); + NULL, uri, flags, cancelled, &ddomain); /* If ret is 0 then 'ddomain' indicates whether the VM is * running on the dest. If not running, we can restart @@ -3877,6 +3878,7 @@ virDomainMigratePeer2Peer (virDomainPtr domain, const char *xmlin, unsigned long flags, const char *dname, + const char *dconnuri, const char *uri, unsigned long bandwidth) { @@ -3888,7 +3890,7 @@ virDomainMigratePeer2Peer (virDomainPtr domain, return -1; } - tempuri = xmlParseURI(uri); + tempuri = xmlParseURI(dconnuri); if (!tempuri) { virLibConnError(VIR_ERR_INVALID_ARG, __FUNCTION__); virDispatchError(domain->conn); @@ -3915,6 +3917,7 @@ virDomainMigratePeer2Peer (virDomainPtr domain, 0, /* cookieinlen */ NULL, /* cookieoutlen */ NULL, /* cookieoutlen */ + dconnuri, uri, flags, dname, @@ -3926,10 +3929,15 @@ virDomainMigratePeer2Peer (virDomainPtr domain, _("Unable to change target guest XML during migration")); return -1; } + if (uri) { + virLibConnError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Unable to override peer2peer migration URI")); + return -1; + } return domain->conn->driver->domainMigratePerform(domain, NULL, /* cookie */ 0, /* cookielen */ - uri, + dconnuri, flags, dname, bandwidth); @@ -3968,12 +3976,15 @@ virDomainMigrateDirect (virDomainPtr domain, if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn, VIR_DRV_FEATURE_MIGRATION_V3)) { VIR_DEBUG("Using migration protocol 3"); + /* dconn URI not relevant in direct migration, since no + * target libvirtd is involved */ return domain->conn->driver->domainMigratePerform3(domain, xmlin, NULL, /* cookiein */ 0, /* cookieinlen */ NULL, /* cookieoutlen */ NULL, /* cookieoutlen */ + NULL, /* dconnuri */ uri, flags, dname, @@ -4110,7 +4121,7 @@ virDomainMigrate (virDomainPtr domain, VIR_DEBUG("Using peer2peer migration"); if (virDomainMigratePeer2Peer(domain, NULL, flags, dname, - uri ? uri : dstURI, bandwidth) < 0) { + uri ? uri : dstURI, NULL, bandwidth) < 0) { VIR_FREE(dstURI); goto error; } @@ -4256,7 +4267,7 @@ virDomainMigrateToURI (virDomainPtr domain, VIR_DRV_FEATURE_MIGRATION_P2P)) { VIR_DEBUG("Using peer2peer migration"); if (virDomainMigratePeer2Peer(domain, NULL, flags, - dname, duri, bandwidth) < 0) + dname, duri, NULL, bandwidth) < 0) goto error; } else { /* No peer to peer migration supported */ @@ -4758,6 +4769,7 @@ virDomainMigratePerform3(virDomainPtr domain, int cookieinlen, char **cookieout, int *cookieoutlen, + const char *dconnuri, const char *uri, unsigned long flags, const char *dname, @@ -4766,10 +4778,10 @@ virDomainMigratePerform3(virDomainPtr domain, virConnectPtr conn; VIR_DOMAIN_DEBUG(domain, "xmlin=%s cookiein=%p, cookieinlen=%d, " - "cookieout=%p, cookieoutlen=%p, " + "cookieout=%p, cookieoutlen=%p, dconnuri=%s, " "uri=%s, flags=%lu, dname=%s, bandwidth=%lu", NULLSTR(xmlin), cookiein, cookieinlen, - cookieout, cookieoutlen, + cookieout, cookieoutlen, NULLSTR(dconnuri), uri, flags, NULLSTR(dname), bandwidth); virResetLastError(); @@ -4791,7 +4803,7 @@ virDomainMigratePerform3(virDomainPtr domain, ret = conn->driver->domainMigratePerform3(domain, xmlin, cookiein, cookieinlen, cookieout, cookieoutlen, - uri, + dconnuri, uri, flags, dname, bandwidth); if (ret < 0) goto error; @@ -4817,15 +4829,16 @@ virDomainMigrateFinish3(virConnectPtr dconn, int cookieinlen, char **cookieout, int *cookieoutlen, + const char *dconnuri, const char *uri, unsigned long flags, int cancelled, virDomainPtr *newdom) { VIR_DEBUG("dconn=%p, dname=%s, cookiein=%p, cookieinlen=%d, cookieout=%p," - "cookieoutlen=%p, uri=%s, flags=%lu, retcode=%d newdom=%p", + "cookieoutlen=%p, dconnuri=%s, uri=%s, flags=%lu, retcode=%d newdom=%p", dconn, NULLSTR(dname), cookiein, cookieinlen, cookieout, - cookieoutlen, uri, flags, cancelled, newdom); + cookieoutlen, NULLSTR(dconnuri), NULLSTR(uri), flags, cancelled, newdom); virResetLastError(); @@ -4845,7 +4858,7 @@ virDomainMigrateFinish3(virConnectPtr dconn, ret = dconn->driver->domainMigrateFinish3(dconn, dname, cookiein, cookieinlen, cookieout, cookieoutlen, - uri, flags, + dconnuri, uri, flags, cancelled, newdom); if (ret < 0) diff --git a/src/libvirt_internal.h b/src/libvirt_internal.h index c7c1932..3144271 100644 --- a/src/libvirt_internal.h +++ b/src/libvirt_internal.h @@ -161,7 +161,8 @@ int virDomainMigratePerform3(virDomainPtr dom, int cookieinlen, char **cookieout, int *cookieoutlen, - const char *uri, + const char *dconnuri, /* libvirtd URI if Peer2Peer, NULL otherwise */ + const char *uri, /* VM Migration URI */ unsigned long flags, const char *dname, unsigned long resource); @@ -172,7 +173,8 @@ int virDomainMigrateFinish3(virConnectPtr dconn, int cookieinlen, char **cookieout, int *cookieoutlen, - const char *uri, + const char *dconnuri, /* libvirtd URI if Peer2Peer, NULL otherwise */ + const char *uri, /* VM Migration URI */ unsigned long flags, int cancelled, /* Kill the dst VM */ virDomainPtr *newdom); diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index e7b0fa6..978a63a 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -5936,6 +5936,7 @@ qemudDomainMigratePerform (virDomainPtr dom, struct qemud_driver *driver = dom->conn->privateData; virDomainObjPtr vm; int ret = -1; + const char *dconnuri = NULL; virCheckFlags(VIR_MIGRATE_LIVE | VIR_MIGRATE_PEER2PEER | @@ -5956,6 +5957,11 @@ qemudDomainMigratePerform (virDomainPtr dom, goto cleanup; } + if (flags & VIR_MIGRATE_PEER2PEER) { + dconnuri = uri; + uri = NULL; + } + /* Do not output cookies in v2 protocol, since the cookie * length was not sufficiently large, causing failures * migrating between old & new libvirtd. @@ -5963,7 +5969,7 @@ qemudDomainMigratePerform (virDomainPtr dom, * Consume any cookie we were able to decode though */ ret = qemuMigrationPerform(driver, dom->conn, vm, - NULL, uri, cookie, cookielen, + NULL, dconnuri, uri, cookie, cookielen, NULL, NULL, /* No output cookies in v2 */ flags, dname, resource, true); @@ -6184,6 +6190,7 @@ qemuDomainMigratePerform3(virDomainPtr dom, int cookieinlen, char **cookieout, int *cookieoutlen, + const char *dconnuri, const char *uri, unsigned long flags, const char *dname, @@ -6213,7 +6220,7 @@ qemuDomainMigratePerform3(virDomainPtr dom, } ret = qemuMigrationPerform(driver, dom->conn, vm, xmlin, - uri, cookiein, cookieinlen, + dconnuri, uri, cookiein, cookieinlen, cookieout, cookieoutlen, flags, dname, resource, false); @@ -6230,6 +6237,7 @@ qemuDomainMigrateFinish3(virConnectPtr dconn, int cookieinlen, char **cookieout, int *cookieoutlen, + const char *dconnuri ATTRIBUTE_UNUSED, const char *uri ATTRIBUTE_UNUSED, unsigned long flags, int cancelled, diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 6044b87..2e2ccd5 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -1652,7 +1652,7 @@ static int doPeer2PeerMigrate2(struct qemud_driver *driver, virConnectPtr sconn, virConnectPtr dconn, virDomainObjPtr vm, - const char *uri, + const char *dconnuri, unsigned long flags, const char *dname, unsigned long resource) @@ -1753,7 +1753,7 @@ finish: qemuDomainObjEnterRemoteWithDriver(driver, vm); ddomain = dconn->driver->domainMigrateFinish2 (dconn, dname, cookie, cookielen, - uri_out ? uri_out : uri, flags, cancelled); + uri_out ? uri_out : dconnuri, flags, cancelled); qemuDomainObjExitRemoteWithDriver(driver, vm); cleanup: @@ -1787,6 +1787,7 @@ static int doPeer2PeerMigrate3(struct qemud_driver *driver, virConnectPtr dconn, virDomainObjPtr vm, const char *xmlin, + const char *dconnuri, const char *uri, unsigned long flags, const char *dname, @@ -1832,7 +1833,7 @@ static int doPeer2PeerMigrate3(struct qemud_driver *driver, qemuDomainObjEnterRemoteWithDriver(driver, vm); ret = dconn->driver->domainMigratePrepare3 (dconn, cookiein, cookieinlen, &cookieout, &cookieoutlen, - NULL, &uri_out, flags, dname, resource, dom_xml); + uri, &uri_out, flags, dname, resource, dom_xml); qemuDomainObjExitRemoteWithDriver(driver, vm); } VIR_FREE(dom_xml); @@ -1852,7 +1853,7 @@ static int doPeer2PeerMigrate3(struct qemud_driver *driver, * running, but in paused state until the destination can * confirm migration completion. */ - VIR_DEBUG("Perform3 %p uri=%s", sconn, uri_out); + VIR_DEBUG("Perform3 %p uri=%s uri_out=%s", sconn, uri, uri_out); VIR_FREE(cookiein); cookiein = cookieout; cookieinlen = cookieoutlen; @@ -1895,7 +1896,7 @@ finish: qemuDomainObjEnterRemoteWithDriver(driver, vm); ret = dconn->driver->domainMigrateFinish3 (dconn, dname, cookiein, cookieinlen, &cookieout, &cookieoutlen, - uri_out ? uri_out : uri, flags, cancelled, &ddomain); + dconnuri, uri_out ? uri_out : uri, flags, cancelled, &ddomain); qemuDomainObjExitRemoteWithDriver(driver, vm); /* If ret is 0 then 'ddomain' indicates whether the VM is @@ -1952,6 +1953,7 @@ static int doPeer2PeerMigrate(struct qemud_driver *driver, virConnectPtr sconn, virDomainObjPtr vm, const char *xmlin, + const char *dconnuri, const char *uri, unsigned long flags, const char *dname, @@ -1967,7 +1969,7 @@ static int doPeer2PeerMigrate(struct qemud_driver *driver, */ qemuDomainObjEnterRemoteWithDriver(driver, vm); - dconn = virConnectOpen(uri); + dconn = virConnectOpen(dconnuri); qemuDomainObjExitRemoteWithDriver(driver, vm); if (dconn == NULL) { qemuReportError(VIR_ERR_OPERATION_FAILED, @@ -1997,10 +1999,10 @@ static int doPeer2PeerMigrate(struct qemud_driver *driver, if (v3) ret = doPeer2PeerMigrate3(driver, sconn, dconn, vm, xmlin, - uri, flags, dname, resource); + dconnuri, uri, flags, dname, resource); else ret = doPeer2PeerMigrate2(driver, sconn, dconn, vm, - uri, flags, dname, resource); + dconnuri, flags, dname, resource); cleanup: /* don't call virConnectClose(), because that resets any pending errors */ @@ -2016,6 +2018,7 @@ int qemuMigrationPerform(struct qemud_driver *driver, virConnectPtr conn, virDomainObjPtr vm, const char *xmlin, + const char *dconnuri, const char *uri, const char *cookiein, int cookieinlen, @@ -2059,10 +2062,15 @@ int qemuMigrationPerform(struct qemud_driver *driver, } if (doPeer2PeerMigrate(driver, conn, vm, xmlin, - uri, flags, dname, resource) < 0) + dconnuri, uri, flags, dname, resource) < 0) /* doPeer2PeerMigrate already set the error, so just get out */ goto endjob; } else { + if (dconnuri) { + qemuReportError(VIR_ERR_INTERNAL_ERROR, + "%s", _("Unexpected dconnuri parameter with non-peer2peer migration")); + goto endjob; + } if (doNativeMigrate(driver, vm, uri, cookiein, cookieinlen, cookieout, cookieoutlen, flags, dname, resource) < 0) diff --git a/src/qemu/qemu_migration.h b/src/qemu/qemu_migration.h index ece1350..08e3acc 100644 --- a/src/qemu/qemu_migration.h +++ b/src/qemu/qemu_migration.h @@ -63,6 +63,7 @@ int qemuMigrationPerform(struct qemud_driver *driver, virConnectPtr conn, virDomainObjPtr vm, const char *xmlin, + const char *dconnuri, const char *uri, const char *cookiein, int cookieinlen, diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 66393fb..64f5620 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -5174,6 +5174,7 @@ remoteDomainMigratePerform3(virDomainPtr dom, int cookieinlen, char **cookieout, int *cookieoutlen, + const char *dconnuri, const char *uri, unsigned long flags, const char *dname, @@ -5194,9 +5195,10 @@ remoteDomainMigratePerform3(virDomainPtr 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; args.flags = flags; args.dname = dname == NULL ? NULL : (char **) &dname; + args.uri = uri == NULL ? NULL : (char **) &uri; + args.dconnuri = dconnuri == NULL ? NULL : (char **) &dconnuri; args.resource = resource; if (call (dom->conn, priv, 0, REMOTE_PROC_DOMAIN_MIGRATE_PERFORM3, @@ -5233,6 +5235,7 @@ remoteDomainMigrateFinish3(virConnectPtr dconn, int cookieinlen, char **cookieout, int *cookieoutlen, + const char *dconnuri, const char *uri, unsigned long flags, int cancelled, @@ -5252,7 +5255,8 @@ remoteDomainMigrateFinish3(virConnectPtr dconn, args.cookie_in.cookie_in_val = (char *)cookiein; args.cookie_in.cookie_in_len = cookieinlen; args.dname = (char *) dname; - args.uri = (char *) uri; + args.uri = uri == NULL ? NULL : (char **) &uri; + args.dconnuri = dconnuri == NULL ? NULL : (char **) &dconnuri; args.flags = flags; args.cancelled = cancelled; diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x index 842fd0b..58afee0 100644 --- a/src/remote/remote_protocol.x +++ b/src/remote/remote_protocol.x @@ -2014,7 +2014,8 @@ struct remote_domain_migrate_perform3_args { remote_nonnull_domain dom; remote_string xmlin; opaque cookie_in<REMOTE_MIGRATE_COOKIE_MAX>; - remote_nonnull_string uri; + remote_string dconnuri; + remote_string uri; unsigned hyper flags; remote_string dname; unsigned hyper resource; @@ -2027,7 +2028,8 @@ struct remote_domain_migrate_perform3_ret { struct remote_domain_migrate_finish3_args { remote_nonnull_string dname; opaque cookie_in<REMOTE_MIGRATE_COOKIE_MAX>; - remote_nonnull_string uri; + remote_string dconnuri; + remote_string uri; unsigned hyper flags; int cancelled; }; diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs index 971f53a..014e5ac 100644 --- a/src/remote_protocol-structs +++ b/src/remote_protocol-structs @@ -1510,6 +1510,7 @@ struct remote_domain_migrate_perform3_args { u_int cookie_in_len; char * cookie_in_val; } cookie_in; + remote_string dconnuri; remote_nonnull_string uri; uint64_t flags; remote_string dname; -- 1.7.4.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list