---
src/qemu/qemu_driver.c | 302 ++++++++++++++++++++++++++++++++++++++++++++--
src/qemu/qemu_migration.c | 162 ++++++++++++++++++-------
src/qemu/qemu_migration.h | 9 ++
3 files changed, 417 insertions(+), 56 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index e2b85c0..cedec91 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -1095,6 +1095,7 @@ qemuConnectSupportsFeature(virConnectPtr conn, 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;
@@ -10173,6 +10174,43 @@ qemuDomainMigrateBegin3(virDomainPtr domain,
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;
+ virDomainObjPtr vm;
+
+ 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;
+
+ if (!(vm = qemuDomObjFromDomain(domain)))
+ return NULL;
+
+ if (virDomainMigrateBegin3ParamsEnsureACL(domain->conn, vm->def) < 0) {
+ virObjectUnlock(vm);
+ return NULL;
+ }
+
+ return qemuMigrationBegin(domain->conn, vm, xmlin, dname,
+ cookieout, cookieoutlen, flags);
+}
+
+
static int
qemuDomainMigratePrepare3(virConnectPtr dconn,
const char *cookiein,
@@ -10219,6 +10257,66 @@ cleanup:
return ret;
}
+static int
+qemuDomainMigratePrepare3Params(virConnectPtr dconn,
+ virTypedParameterPtr params,
+ int nparams,
+ const char *cookiein,
+ int cookieinlen,
+ char **cookieout,
+ int *cookieoutlen,
+ char **uri_out,
+ unsigned int flags)
+{
+ virQEMUDriverPtr driver = dconn->privateData;
+ virDomainDefPtr def = NULL;
+ const char *dom_xml = NULL;
+ const char *dname = NULL;
+ const char *uri_in = NULL;
+ int ret = -1;
+
+ 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;
+
+ if (flags & VIR_MIGRATE_TUNNELLED) {
+ /* this is a logical error; we never should have gotten here with
+ * VIR_MIGRATE_TUNNELLED set
+ */
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Tunnelled migration requested but invalid "
+ "RPC method called"));
+ goto cleanup;
+ }
+
+ if (!(def = qemuMigrationPrepareDef(driver, dom_xml, dname)))
+ goto cleanup;
+
+ if (virDomainMigratePrepare3ParamsEnsureACL(dconn, def) < 0)
+ goto cleanup;
+
+ ret = qemuMigrationPrepareDirect(driver, dconn,
+ cookiein, cookieinlen,
+ cookieout, cookieoutlen,
+ uri_in, uri_out,
+ &def, flags);
+
+cleanup:
+ virDomainDefFree(def);
+ return ret;
+}
+
static int
qemuDomainMigratePrepareTunnel3(virConnectPtr dconn,
@@ -10260,6 +10358,57 @@ cleanup:
return ret;
}
+static int
+qemuDomainMigratePrepareTunnel3Params(virConnectPtr dconn,
+ virStreamPtr st,
+ virTypedParameterPtr params,
+ int nparams,
+ const char *cookiein,
+ int cookieinlen,
+ char **cookieout,
+ int *cookieoutlen,
+ unsigned int flags)
+{
+ virQEMUDriverPtr driver = dconn->privateData;
+ virDomainDefPtr def = NULL;
+ const char *dom_xml = NULL;
+ const char *dname = NULL;
+ int ret = -1;
+
+ 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;
+
+ if (!(flags & VIR_MIGRATE_TUNNELLED)) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("PrepareTunnel called but no TUNNELLED flag set"));
+ goto cleanup;
+ }
+
+ if (!(def = qemuMigrationPrepareDef(driver, dom_xml, dname)))
+ goto cleanup;
+
+ if (virDomainMigratePrepareTunnel3ParamsEnsureACL(dconn, def) < 0)
+ goto cleanup;
+
+ ret = qemuMigrationPrepareTunnel(driver, dconn,
+ cookiein, cookieinlen,
+ cookieout, cookieoutlen,
+ st, &def, flags);
+
+cleanup:
+ virDomainDefFree(def);
+ return ret;
+}
+
static int
qemuDomainMigratePerform3(virDomainPtr dom,
@@ -10293,6 +10442,56 @@ 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;
+
+ if (virDomainMigratePerform3ParamsEnsureACL(dom->conn, vm->def) < 0) {
+ virObjectUnlock(vm);
+ 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,
@@ -10308,29 +10507,72 @@ 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 (!dname ||
+ !(vm = virDomainObjListFindByName(driver->domains, dname))) {
virReportError(VIR_ERR_NO_DOMAIN,
- _("no domain with matching name '%s'"), dname);
- goto cleanup;
+ _("no domain with matching name '%s'"),
+ NULLSTR(dname));
+ return NULL;
}
- if (virDomainMigrateFinish3EnsureACL(dconn, vm->def) < 0)
- goto cleanup;
+ if (virDomainMigrateFinish3EnsureACL(dconn, vm->def) < 0) {
+ virObjectUnlock(vm);
+ 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;
+ }
+
+ if (virDomainMigrateFinish3ParamsEnsureACL(dconn, vm->def) < 0) {
+ virObjectUnlock(vm);
+ return NULL;
+ }
+
+ return qemuMigrationFinish(driver, dconn, vm,
+ cookiein, cookieinlen,
+ cookieout, cookieoutlen,
+ flags, cancelled, true);
}
+
static int
qemuDomainMigrateConfirm3(virDomainPtr domain,
const char *cookiein,
@@ -10354,6 +10596,34 @@ qemuDomainMigrateConfirm3(virDomainPtr domain,
flags, cancelled);
}
+static int
+qemuDomainMigrateConfirm3Params(virDomainPtr domain,
+ virTypedParameterPtr params,
+ int nparams,
+ const char *cookiein,
+ int cookieinlen,
+ unsigned int flags,
+ int cancelled)
+{
+ virDomainObjPtr vm;
+
+ virCheckFlags(QEMU_MIGRATION_FLAGS, -1);
+
+ if (virTypedParamsValidate(params, nparams, QEMU_MIGRATION_PARAMETERS) < 0)
+ return -1;
+
+ if (!(vm = qemuDomObjFromDomain(domain)))
+ return -1;
+
+ if (virDomainMigrateConfirm3ParamsEnsureACL(domain->conn, vm->def) < 0) {
+ virObjectUnlock(vm);
+ return -1;
+ }
+
+ return qemuMigrationConfirm(domain->conn, vm, cookiein, cookieinlen,
+ flags, cancelled);
+}
+
static int
qemuNodeDeviceGetPciInfo(virNodeDeviceDefPtr def,
@@ -15776,6 +16046,12 @@ static virDriver qemuDriver = {
.nodeGetCPUMap = qemuNodeGetCPUMap, /* 1.0.0 */
.domainFSTrim = qemuDomainFSTrim, /* 1.0.1 */
.domainOpenChannel = qemuDomainOpenChannel, /* 1.0.2 */
+ .domainMigrateBegin3Params = qemuDomainMigrateBegin3Params, /* 1.1.0 */
+ .domainMigratePrepare3Params = qemuDomainMigratePrepare3Params, /* 1.1.0 */
+ .domainMigratePrepareTunnel3Params = qemuDomainMigratePrepareTunnel3Params, /* 1.1.0
*/
+ .domainMigratePerform3Params = qemuDomainMigratePerform3Params, /* 1.1.0 */
+ .domainMigrateFinish3Params = qemuDomainMigrateFinish3Params, /* 1.1.0 */
+ .domainMigrateConfirm3Params = qemuDomainMigrateConfirm3Params, /* 1.1.0 */
};
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 66d62fe..d4a169e 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -56,6 +56,7 @@
#include "viruri.h"
#include "virhook.h"
#include "virstring.h"
+#include "virtypedparam.h"
#define VIR_FROM_THIS VIR_FROM_QEMU
@@ -3564,16 +3565,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;
@@ -3584,15 +3587,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
@@ -3604,6 +3610,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;
@@ -3617,16 +3645,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);
@@ -3641,11 +3680,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;
}
@@ -3654,23 +3697,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) {
@@ -3698,12 +3742,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
@@ -3759,7 +3820,7 @@ finish:
VIR_FREE(uri_out);
VIR_FREE(cookiein);
VIR_FREE(cookieout);
-
+ virTypedParamsFree(params, nparams);
return ret;
}
@@ -3781,6 +3842,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",
@@ -3815,6 +3877,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);
@@ -3826,6 +3890,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 "
@@ -3847,12 +3922,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 dd1d0a1..469c948 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