---
src/qemu/qemu_driver.c | 350 +++++++++++++++++++++++++++++++++++++++-------
src/qemu/qemu_migration.c | 162 +++++++++++++++------
src/qemu/qemu_migration.h | 9 ++
3 files changed, 431 insertions(+), 90 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index a682e36..c040287 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -1086,6 +1086,7 @@ qemuConnectSupportsFeature(virConnectPtr conn ATTRIBUTE_UNUSED, int
feature)
case VIR_DRV_FEATURE_TYPED_PARAM_STRING:
case VIR_DRV_FEATURE_XML_MIGRATABLE:
case VIR_DRV_FEATURE_MIGRATION_OFFLINE:
+ case VIR_DRV_FEATURE_MIGRATION_PARAMS:
return 1;
default:
return 0;
@@ -9887,21 +9888,18 @@ cleanup:
*******************************************************************/
static char *
-qemuDomainMigrateBegin3(virDomainPtr domain,
- const char *xmlin,
- char **cookieout,
- int *cookieoutlen,
- unsigned long flags,
- const char *dname,
- unsigned long resource ATTRIBUTE_UNUSED)
+qemuDomainMigrateBegin3Internal(virDomainPtr domain,
+ const char *xmlin,
+ const char *dname,
+ char **cookieout,
+ int *cookieoutlen,
+ unsigned long flags)
{
virQEMUDriverPtr driver = domain->conn->privateData;
virDomainObjPtr vm;
char *xml = NULL;
enum qemuDomainAsyncJob asyncJob;
- virCheckFlags(QEMU_MIGRATION_FLAGS, NULL);
-
if (!(vm = qemuDomObjFromDomain(domain)))
return NULL;
@@ -9969,26 +9967,66 @@ endjob:
goto cleanup;
}
+static char *
+qemuDomainMigrateBegin3(virDomainPtr domain,
+ const char *xmlin,
+ char **cookieout,
+ int *cookieoutlen,
+ unsigned long flags,
+ const char *dname,
+ unsigned long resource ATTRIBUTE_UNUSED)
+{
+ virCheckFlags(QEMU_MIGRATION_FLAGS, NULL);
+
+ return qemuDomainMigrateBegin3Internal(domain, xmlin, dname,
+ cookieout, cookieoutlen, flags);
+}
+
+static char *
+qemuDomainMigrateBegin3Params(virDomainPtr domain,
+ virTypedParameterPtr params,
+ int nparams,
+ char **cookieout,
+ int *cookieoutlen,
+ unsigned int flags)
+{
+ const char *xmlin = NULL;
+ const char *dname = NULL;
+
+ virCheckFlags(QEMU_MIGRATION_FLAGS, NULL);
+ if (virTypedParamsValidate(params, nparams, QEMU_MIGRATION_PARAMETERS) < 0)
+ return NULL;
+
+ if (virTypedParamsGetString(params, nparams,
+ VIR_MIGRATE_PARAM_DEST_XML,
+ &xmlin) < 0 ||
+ virTypedParamsGetString(params, nparams,
+ VIR_MIGRATE_PARAM_DEST_NAME,
+ &dname) < 0)
+ return NULL;
+
+ return qemuDomainMigrateBegin3Internal(domain, xmlin, dname,
+ cookieout, cookieoutlen, flags);
+}
+
+
static int
-qemuDomainMigratePrepare3(virConnectPtr dconn,
- const char *cookiein,
- int cookieinlen,
- char **cookieout,
- int *cookieoutlen,
- const char *uri_in,
- char **uri_out,
- unsigned long flags,
- const char *dname,
- unsigned long resource ATTRIBUTE_UNUSED,
- const char *dom_xml)
+qemuDomainMigratePrepare3Internal(virConnectPtr dconn,
+ const char *dom_xml,
+ const char *dname,
+ const char *uri_in,
+ const char *cookiein,
+ int cookieinlen,
+ char **cookieout,
+ int *cookieoutlen,
+ char **uri_out,
+ unsigned long flags)
{
virQEMUDriverPtr driver = dconn->privateData;
virCapsPtr caps = NULL;
virDomainDefPtr def = NULL;
int ret = -1;
- virCheckFlags(QEMU_MIGRATION_FLAGS, -1);
-
*uri_out = NULL;
if (flags & VIR_MIGRATE_TUNNELLED) {
@@ -10032,26 +10070,78 @@ cleanup:
return ret;
}
+static int
+qemuDomainMigratePrepare3(virConnectPtr dconn,
+ const char *cookiein,
+ int cookieinlen,
+ char **cookieout,
+ int *cookieoutlen,
+ const char *uri_in,
+ char **uri_out,
+ unsigned long flags,
+ const char *dname,
+ unsigned long resource ATTRIBUTE_UNUSED,
+ const char *dom_xml)
+{
+ virCheckFlags(QEMU_MIGRATION_FLAGS, -1);
+
+ return qemuDomainMigratePrepare3Internal(dconn, dom_xml, dname, uri_in,
+ cookiein, cookieinlen, cookieout,
+ cookieoutlen, uri_out, flags);
+}
static int
-qemuDomainMigratePrepareTunnel3(virConnectPtr dconn,
- virStreamPtr st,
+qemuDomainMigratePrepare3Params(virConnectPtr dconn,
+ virTypedParameterPtr params,
+ int nparams,
const char *cookiein,
int cookieinlen,
char **cookieout,
int *cookieoutlen,
- unsigned long flags,
- const char *dname,
- unsigned long resource ATTRIBUTE_UNUSED,
- const char *dom_xml)
+ char **uri_out,
+ unsigned int flags)
+{
+ const char *dom_xml = NULL;
+ const char *dname = NULL;
+ const char *uri_in = NULL;
+
+ virCheckFlags(QEMU_MIGRATION_FLAGS, -1);
+ if (virTypedParamsValidate(params, nparams, QEMU_MIGRATION_PARAMETERS) < 0)
+ return -1;
+
+ if (virTypedParamsGetString(params, nparams,
+ VIR_MIGRATE_PARAM_DEST_XML,
+ &dom_xml) < 0 ||
+ virTypedParamsGetString(params, nparams,
+ VIR_MIGRATE_PARAM_DEST_NAME,
+ &dname) < 0 ||
+ virTypedParamsGetString(params, nparams,
+ VIR_MIGRATE_PARAM_URI,
+ &uri_in) < 0)
+ return -1;
+
+ return qemuDomainMigratePrepare3Internal(dconn, dom_xml, dname, uri_in,
+ cookiein, cookieinlen, cookieout,
+ cookieoutlen, uri_out, flags);
+}
+
+
+static int
+qemuDomainMigratePrepareTunnel3Internal(virConnectPtr dconn,
+ virStreamPtr st,
+ const char *dom_xml,
+ const char *dname,
+ const char *cookiein,
+ int cookieinlen,
+ char **cookieout,
+ int *cookieoutlen,
+ unsigned long flags)
{
virQEMUDriverPtr driver = dconn->privateData;
virCapsPtr caps = NULL;
virDomainDefPtr def = NULL;
int ret = -1;
- virCheckFlags(QEMU_MIGRATION_FLAGS, -1);
-
if (!dom_xml) {
virReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("no domain XML passed"));
@@ -10093,6 +10183,58 @@ cleanup:
return ret;
}
+static int
+qemuDomainMigratePrepareTunnel3(virConnectPtr dconn,
+ virStreamPtr st,
+ const char *cookiein,
+ int cookieinlen,
+ char **cookieout,
+ int *cookieoutlen,
+ unsigned long flags,
+ const char *dname,
+ unsigned long resource ATTRIBUTE_UNUSED,
+ const char *dom_xml)
+{
+ virCheckFlags(QEMU_MIGRATION_FLAGS, -1);
+
+ return qemuDomainMigratePrepareTunnel3Internal(dconn, st, dom_xml, dname,
+ cookiein, cookieinlen,
+ cookieout, cookieoutlen,
+ flags);
+}
+
+static int
+qemuDomainMigratePrepareTunnel3Params(virConnectPtr dconn,
+ virStreamPtr st,
+ virTypedParameterPtr params,
+ int nparams,
+ const char *cookiein,
+ int cookieinlen,
+ char **cookieout,
+ int *cookieoutlen,
+ unsigned int flags)
+{
+ const char *dom_xml = NULL;
+ const char *dname = NULL;
+
+ virCheckFlags(QEMU_MIGRATION_FLAGS, -1);
+ if (virTypedParamsValidate(params, nparams, QEMU_MIGRATION_PARAMETERS) < 0)
+ return -1;
+
+ if (virTypedParamsGetString(params, nparams,
+ VIR_MIGRATE_PARAM_DEST_XML,
+ &dom_xml) < 0 ||
+ virTypedParamsGetString(params, nparams,
+ VIR_MIGRATE_PARAM_DEST_NAME,
+ &dname) < 0)
+ return -1;
+
+ return qemuDomainMigratePrepareTunnel3Internal(dconn, st, dom_xml, dname,
+ cookiein, cookieinlen,
+ cookieout, cookieoutlen,
+ flags);
+}
+
static int
qemuDomainMigratePerform3(virDomainPtr dom,
@@ -10121,6 +10263,51 @@ qemuDomainMigratePerform3(virDomainPtr dom,
flags, dname, resource, true);
}
+static int
+qemuDomainMigratePerform3Params(virDomainPtr dom,
+ const char *dconnuri,
+ virTypedParameterPtr params,
+ int nparams,
+ const char *cookiein,
+ int cookieinlen,
+ char **cookieout,
+ int *cookieoutlen,
+ unsigned int flags)
+{
+ virQEMUDriverPtr driver = dom->conn->privateData;
+ virDomainObjPtr vm;
+ const char *dom_xml = NULL;
+ const char *dname = NULL;
+ const char *uri = NULL;
+ unsigned long long bandwidth = 0;
+
+ virCheckFlags(QEMU_MIGRATION_FLAGS, -1);
+ if (virTypedParamsValidate(params, nparams, QEMU_MIGRATION_PARAMETERS) < 0)
+ return -1;
+
+ if (virTypedParamsGetString(params, nparams,
+ VIR_MIGRATE_PARAM_DEST_XML,
+ &dom_xml) < 0 ||
+ virTypedParamsGetString(params, nparams,
+ VIR_MIGRATE_PARAM_DEST_NAME,
+ &dname) < 0 ||
+ virTypedParamsGetString(params, nparams,
+ VIR_MIGRATE_PARAM_URI,
+ &uri) < 0 ||
+ virTypedParamsGetULLong(params, nparams,
+ VIR_MIGRATE_PARAM_BANDWIDTH,
+ &bandwidth) < 0)
+ return -1;
+
+ if (!(vm = qemuDomObjFromDomain(dom)))
+ return -1;
+
+ return qemuMigrationPerform(driver, dom->conn, vm, dom_xml,
+ dconnuri, uri, cookiein, cookieinlen,
+ cookieout, cookieoutlen,
+ flags, dname, bandwidth, true);
+}
+
static virDomainPtr
qemuDomainMigrateFinish3(virConnectPtr dconn,
@@ -10136,32 +10323,66 @@ qemuDomainMigrateFinish3(virConnectPtr dconn,
{
virQEMUDriverPtr driver = dconn->privateData;
virDomainObjPtr vm;
- virDomainPtr dom = NULL;
virCheckFlags(QEMU_MIGRATION_FLAGS, NULL);
- vm = virDomainObjListFindByName(driver->domains, dname);
- if (!vm) {
+ if (!(vm = virDomainObjListFindByName(driver->domains, dname))) {
virReportError(VIR_ERR_NO_DOMAIN,
_("no domain with matching name '%s'"), dname);
- goto cleanup;
+ return NULL;
}
- dom = qemuMigrationFinish(driver, dconn, vm,
- cookiein, cookieinlen,
- cookieout, cookieoutlen,
- flags, cancelled, true);
+ return qemuMigrationFinish(driver, dconn, vm,
+ cookiein, cookieinlen,
+ cookieout, cookieoutlen,
+ flags, cancelled, true);
+}
-cleanup:
- return dom;
+static virDomainPtr
+qemuDomainMigrateFinish3Params(virConnectPtr dconn,
+ virTypedParameterPtr params,
+ int nparams,
+ const char *cookiein,
+ int cookieinlen,
+ char **cookieout,
+ int *cookieoutlen,
+ unsigned int flags,
+ int cancelled)
+{
+ virQEMUDriverPtr driver = dconn->privateData;
+ virDomainObjPtr vm;
+ const char *dname = NULL;
+
+ virCheckFlags(QEMU_MIGRATION_FLAGS, NULL);
+ if (virTypedParamsValidate(params, nparams, QEMU_MIGRATION_PARAMETERS) < 0)
+ return NULL;
+
+ if (virTypedParamsGetString(params, nparams,
+ VIR_MIGRATE_PARAM_DEST_NAME,
+ &dname) < 0)
+ return NULL;
+
+ if (!dname ||
+ !(vm = virDomainObjListFindByName(driver->domains, dname))) {
+ virReportError(VIR_ERR_NO_DOMAIN,
+ _("no domain with matching name '%s'"),
+ NULLSTR(dname));
+ return NULL;
+ }
+
+ return qemuMigrationFinish(driver, dconn, vm,
+ cookiein, cookieinlen,
+ cookieout, cookieoutlen,
+ flags, cancelled, true);
}
+
static int
-qemuDomainMigrateConfirm3(virDomainPtr domain,
- const char *cookiein,
- int cookieinlen,
- unsigned long flags,
- int cancelled)
+qemuDomainMigrateConfirm3Internal(virDomainPtr domain,
+ const char *cookiein,
+ int cookieinlen,
+ unsigned long flags,
+ int cancelled)
{
virQEMUDriverPtr driver = domain->conn->privateData;
virDomainObjPtr vm;
@@ -10169,8 +10390,6 @@ qemuDomainMigrateConfirm3(virDomainPtr domain,
enum qemuMigrationJobPhase phase;
virQEMUDriverConfigPtr cfg = NULL;
- virCheckFlags(QEMU_MIGRATION_FLAGS, -1);
-
if (!(vm = qemuDomObjFromDomain(domain)))
return -1;
@@ -10209,6 +10428,37 @@ cleanup:
return ret;
}
+static int
+qemuDomainMigrateConfirm3(virDomainPtr domain,
+ const char *cookiein,
+ int cookieinlen,
+ unsigned long flags,
+ int cancelled)
+{
+ virCheckFlags(QEMU_MIGRATION_FLAGS, -1);
+
+ return qemuDomainMigrateConfirm3Internal(domain, cookiein, cookieinlen,
+ flags, cancelled);
+}
+
+static int
+qemuDomainMigrateConfirm3Params(virDomainPtr domain,
+ virTypedParameterPtr params,
+ int nparams,
+ const char *cookiein,
+ int cookieinlen,
+ unsigned int flags,
+ int cancelled)
+{
+ virCheckFlags(QEMU_MIGRATION_FLAGS, -1);
+
+ if (virTypedParamsValidate(params, nparams, QEMU_MIGRATION_PARAMETERS) < 0)
+ return -1;
+
+ return qemuDomainMigrateConfirm3Internal(domain, cookiein, cookieinlen,
+ flags, cancelled);
+}
+
static int
qemuNodeDeviceGetPciInfo(virNodeDevicePtr dev,
@@ -15378,6 +15628,12 @@ static virDriver qemuDriver = {
.nodeGetCPUMap = qemuNodeGetCPUMap, /* 1.0.0 */
.domainFSTrim = qemuDomainFSTrim, /* 1.0.1 */
.domainOpenChannel = qemuDomainOpenChannel, /* 1.0.2 */
+ .domainMigrateBegin3Params = qemuDomainMigrateBegin3Params, /* 1.0.7 */
+ .domainMigratePrepare3Params = qemuDomainMigratePrepare3Params, /* 1.0.7 */
+ .domainMigratePrepareTunnel3Params = qemuDomainMigratePrepareTunnel3Params, /* 1.0.7
*/
+ .domainMigratePerform3Params = qemuDomainMigratePerform3Params, /* 1.0.7 */
+ .domainMigrateFinish3Params = qemuDomainMigrateFinish3Params, /* 1.0.7 */
+ .domainMigrateConfirm3Params = qemuDomainMigrateConfirm3Params, /* 1.0.7 */
};
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 8de38fe..6243d75 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -55,6 +55,7 @@
#include "viruri.h"
#include "virhook.h"
#include "virstring.h"
+#include "virtypedparam.h"
#define VIR_FROM_THIS VIR_FROM_QEMU
@@ -3306,16 +3307,18 @@ cleanup:
* from libvirt.c, but running in source libvirtd context,
* instead of client app context & also adding in tunnel
* handling */
-static int doPeer2PeerMigrate3(virQEMUDriverPtr driver,
- virConnectPtr sconn,
- virConnectPtr dconn,
- virDomainObjPtr vm,
- const char *xmlin,
- const char *dconnuri,
- const char *uri,
- unsigned long flags,
- const char *dname,
- unsigned long resource)
+static int
+doPeer2PeerMigrate3(virQEMUDriverPtr driver,
+ virConnectPtr sconn,
+ virConnectPtr dconn,
+ const char *dconnuri,
+ virDomainObjPtr vm,
+ const char *xmlin,
+ const char *dname,
+ const char *uri,
+ unsigned long long bandwidth,
+ bool useParams,
+ unsigned long flags)
{
virDomainPtr ddomain = NULL;
char *uri_out = NULL;
@@ -3326,15 +3329,18 @@ static int doPeer2PeerMigrate3(virQEMUDriverPtr driver,
int cookieoutlen = 0;
int ret = -1;
virErrorPtr orig_err = NULL;
- bool cancelled;
+ bool cancelled = true;
virStreamPtr st = NULL;
unsigned int destflags = flags & ~VIR_MIGRATE_ABORT_ON_ERROR;
- VIR_DEBUG("driver=%p, sconn=%p, dconn=%p, vm=%p, xmlin=%s, "
- "dconnuri=%s, uri=%s, flags=%lx, dname=%s, resource=%lu",
- driver, sconn, dconn, vm, NULLSTR(xmlin),
- NULLSTR(dconnuri), NULLSTR(uri), flags,
- NULLSTR(dname), resource);
+ virTypedParameterPtr params = NULL;
+ int nparams = 0;
+ int maxparams = 0;
+
+ VIR_DEBUG("driver=%p, sconn=%p, dconn=%p, dconnuri=%s, vm=%p, xmlin=%s, "
+ "dname=%s, uri=%s, bandwidth=%llu, useParams=%d, flags=%lx",
+ driver, sconn, dconn, NULLSTR(dconnuri), vm, NULLSTR(xmlin),
+ NULLSTR(dname), NULLSTR(uri), bandwidth, useParams, flags);
/* Unlike the virDomainMigrateVersion3 counterpart, we don't need
* to worry about auto-setting the VIR_MIGRATE_CHANGE_PROTECTION
@@ -3346,6 +3352,28 @@ static int doPeer2PeerMigrate3(virQEMUDriverPtr driver,
if (!dom_xml)
goto cleanup;
+ if (useParams) {
+ if (virTypedParamsAddString(¶ms, &nparams, &maxparams,
+ VIR_MIGRATE_PARAM_DEST_XML, dom_xml) < 0)
+ goto cleanup;
+
+ if (dname &&
+ virTypedParamsAddString(¶ms, &nparams, &maxparams,
+ VIR_MIGRATE_PARAM_DEST_NAME, dname) < 0)
+ goto cleanup;
+
+ if (uri &&
+ virTypedParamsAddString(¶ms, &nparams, &maxparams,
+ VIR_MIGRATE_PARAM_URI, uri) < 0)
+ goto cleanup;
+
+ if (bandwidth &&
+ virTypedParamsAddULLong(¶ms, &nparams, &maxparams,
+ VIR_MIGRATE_PARAM_BANDWIDTH,
+ bandwidth) < 0)
+ goto cleanup;
+ }
+
if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_PAUSED)
flags |= VIR_MIGRATE_PAUSED;
@@ -3359,16 +3387,27 @@ static int doPeer2PeerMigrate3(virQEMUDriverPtr driver,
goto cleanup;
qemuDomainObjEnterRemote(vm);
- ret = dconn->driver->domainMigratePrepareTunnel3
- (dconn, st, cookiein, cookieinlen,
- &cookieout, &cookieoutlen,
- destflags, dname, resource, dom_xml);
+ if (useParams) {
+ ret = dconn->driver->domainMigratePrepareTunnel3Params
+ (dconn, st, params, nparams, cookiein, cookieinlen,
+ &cookieout, &cookieoutlen, destflags);
+ } else {
+ ret = dconn->driver->domainMigratePrepareTunnel3
+ (dconn, st, cookiein, cookieinlen, &cookieout, &cookieoutlen,
+ destflags, dname, bandwidth, dom_xml);
+ }
qemuDomainObjExitRemote(vm);
} else {
qemuDomainObjEnterRemote(vm);
- ret = dconn->driver->domainMigratePrepare3
- (dconn, cookiein, cookieinlen, &cookieout, &cookieoutlen,
- uri, &uri_out, destflags, dname, resource, dom_xml);
+ if (useParams) {
+ ret = dconn->driver->domainMigratePrepare3Params
+ (dconn, params, nparams, cookiein, cookieinlen,
+ &cookieout, &cookieoutlen, &uri_out, destflags);
+ } else {
+ ret = dconn->driver->domainMigratePrepare3
+ (dconn, cookiein, cookieinlen, &cookieout, &cookieoutlen,
+ uri, &uri_out, destflags, dname, bandwidth, dom_xml);
+ }
qemuDomainObjExitRemote(vm);
}
VIR_FREE(dom_xml);
@@ -3383,11 +3422,15 @@ static int doPeer2PeerMigrate3(virQEMUDriverPtr driver,
goto finish;
}
- if (!(flags & VIR_MIGRATE_TUNNELLED) &&
- (uri_out == NULL)) {
+ if (uri_out) {
+ uri = uri_out;
+ if (useParams &&
+ virTypedParamsReplaceString(¶ms, &nparams,
+ VIR_MIGRATE_PARAM_URI, uri_out) < 0)
+ goto finish;
+ } else if (!uri && !(flags & VIR_MIGRATE_TUNNELLED)) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("domainMigratePrepare3 did not set uri"));
- cancelled = true;
goto finish;
}
@@ -3396,23 +3439,24 @@ static int doPeer2PeerMigrate3(virQEMUDriverPtr driver,
* running, but in paused state until the destination can
* confirm migration completion.
*/
- VIR_DEBUG("Perform3 %p uri=%s uri_out=%s", sconn, uri, uri_out);
+ VIR_DEBUG("Perform3 %p uri=%s", sconn, NULLSTR(uri));
qemuMigrationJobSetPhase(driver, vm, QEMU_MIGRATION_PHASE_PERFORM3);
VIR_FREE(cookiein);
cookiein = cookieout;
cookieinlen = cookieoutlen;
cookieout = NULL;
cookieoutlen = 0;
- if (flags & VIR_MIGRATE_TUNNELLED)
+ if (flags & VIR_MIGRATE_TUNNELLED) {
ret = doTunnelMigrate(driver, vm, st,
cookiein, cookieinlen,
&cookieout, &cookieoutlen,
- flags, resource, dconn);
- else
- ret = doNativeMigrate(driver, vm, uri_out,
+ flags, bandwidth, dconn);
+ } else {
+ ret = doNativeMigrate(driver, vm, uri,
cookiein, cookieinlen,
&cookieout, &cookieoutlen,
- flags, resource, dconn);
+ flags, bandwidth, dconn);
+ }
/* Perform failed. Make sure Finish doesn't overwrite the error */
if (ret < 0) {
@@ -3440,12 +3484,29 @@ finish:
cookieinlen = cookieoutlen;
cookieout = NULL;
cookieoutlen = 0;
- dname = dname ? dname : vm->def->name;
- qemuDomainObjEnterRemote(vm);
- ddomain = dconn->driver->domainMigrateFinish3
- (dconn, dname, cookiein, cookieinlen, &cookieout, &cookieoutlen,
- dconnuri, uri_out ? uri_out : uri, destflags, cancelled);
- qemuDomainObjExitRemote(vm);
+
+ if (useParams) {
+ if (virTypedParamsGetString(params, nparams,
+ VIR_MIGRATE_PARAM_DEST_NAME, NULL) <= 0
&&
+ virTypedParamsReplaceString(¶ms, &nparams,
+ VIR_MIGRATE_PARAM_DEST_NAME,
+ vm->def->name) < 0) {
+ ddomain = NULL;
+ } else {
+ qemuDomainObjEnterRemote(vm);
+ ddomain = dconn->driver->domainMigrateFinish3Params
+ (dconn, params, nparams, cookiein, cookieinlen,
+ &cookieout, &cookieoutlen, destflags, cancelled);
+ qemuDomainObjExitRemote(vm);
+ }
+ } else {
+ dname = dname ? dname : vm->def->name;
+ qemuDomainObjEnterRemote(vm);
+ ddomain = dconn->driver->domainMigrateFinish3
+ (dconn, dname, cookiein, cookieinlen, &cookieout, &cookieoutlen,
+ dconnuri, uri, destflags, cancelled);
+ qemuDomainObjExitRemote(vm);
+ }
/* If ddomain is NULL, then we were unable to start
* the guest on the target, and must restart on the
@@ -3501,7 +3562,7 @@ finish:
VIR_FREE(uri_out);
VIR_FREE(cookiein);
VIR_FREE(cookieout);
-
+ virTypedParamsFree(params, nparams);
return ret;
}
@@ -3523,6 +3584,7 @@ static int doPeer2PeerMigrate(virQEMUDriverPtr driver,
virErrorPtr orig_err = NULL;
bool offline = false;
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+ bool useParams;
VIR_DEBUG("driver=%p, sconn=%p, vm=%p, xmlin=%s, dconnuri=%s, "
"uri=%s, flags=%lx, dname=%s, resource=%lu",
@@ -3557,6 +3619,8 @@ static int doPeer2PeerMigrate(virQEMUDriverPtr driver,
*/
*v3proto = VIR_DRV_SUPPORTS_FEATURE(dconn->driver, dconn,
VIR_DRV_FEATURE_MIGRATION_V3);
+ useParams = VIR_DRV_SUPPORTS_FEATURE(dconn->driver, dconn,
+ VIR_DRV_FEATURE_MIGRATION_PARAMS);
if (flags & VIR_MIGRATE_OFFLINE)
offline = VIR_DRV_SUPPORTS_FEATURE(dconn->driver, dconn,
VIR_DRV_FEATURE_MIGRATION_OFFLINE);
@@ -3568,6 +3632,17 @@ static int doPeer2PeerMigrate(virQEMUDriverPtr driver,
goto cleanup;
}
+ /* Only xmlin, dname, uri, and bandwidth parameters can be used with
+ * old-style APIs. */
+#if 0
+ if (!useParams && /* any new parameter */) {
+ virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
+ _("Migration APIs with extensible parameters are not "
+ "supported but extended parameters were passed"));
+ goto cleanup;
+ }
+#endif
+
if (flags & VIR_MIGRATE_OFFLINE && !offline) {
virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
_("offline migration is not supported by "
@@ -3589,12 +3664,13 @@ static int doPeer2PeerMigrate(virQEMUDriverPtr driver,
* Therefore it is safe to clear the bit here. */
flags &= ~VIR_MIGRATE_CHANGE_PROTECTION;
- if (*v3proto)
- ret = doPeer2PeerMigrate3(driver, sconn, dconn, vm, xmlin,
- dconnuri, uri, flags, dname, resource);
- else
+ if (*v3proto) {
+ ret = doPeer2PeerMigrate3(driver, sconn, dconn, dconnuri, vm, xmlin,
+ dname, uri, resource, useParams, flags);
+ } else {
ret = doPeer2PeerMigrate2(driver, sconn, dconn, vm,
dconnuri, flags, dname, resource);
+ }
cleanup:
orig_err = virSaveLastError();
diff --git a/src/qemu/qemu_migration.h b/src/qemu/qemu_migration.h
index 5b21ca2..e44cf3b 100644
--- a/src/qemu/qemu_migration.h
+++ b/src/qemu/qemu_migration.h
@@ -41,6 +41,15 @@
VIR_MIGRATE_COMPRESSED | \
VIR_MIGRATE_ABORT_ON_ERROR)
+/* All supported migration parameters and their types. */
+# define QEMU_MIGRATION_PARAMETERS \
+ VIR_MIGRATE_PARAM_URI, VIR_TYPED_PARAM_STRING, \
+ VIR_MIGRATE_PARAM_DEST_NAME, VIR_TYPED_PARAM_STRING, \
+ VIR_MIGRATE_PARAM_DEST_XML, VIR_TYPED_PARAM_STRING, \
+ VIR_MIGRATE_PARAM_BANDWIDTH, VIR_TYPED_PARAM_ULLONG, \
+ NULL
+
+
enum qemuMigrationJobPhase {
QEMU_MIGRATION_PHASE_NONE = 0,
QEMU_MIGRATION_PHASE_PERFORM2,
--
1.8.2.1