static int
qemuMigrationSrcResume(virDomainObj *vm,
- qemuMigrationParams *migParams G_GNUC_UNUSED,
+ qemuMigrationParams *migParams,
const char *cookiein,
int cookieinlen,
char **cookieout,
int *cookieoutlen,
- qemuMigrationSpec *spec)
+ qemuMigrationSpec *spec,
+ unsigned long flags)
{
qemuDomainObjPrivate *priv = vm->privateData;
virQEMUDriver *driver = priv->driver;
if (!mig)
return -1;
+ if (qemuMigrationParamsApply(driver, vm, VIR_ASYNC_JOB_MIGRATION_OUT,
+ migParams, flags) < 0)
+ return -1;
+
if (qemuDomainObjEnterMonitorAsync(driver, vm,
VIR_ASYNC_JOB_MIGRATION_OUT) < 0)
return -1;
if (STREQ(uribits->scheme, "unix")) {
if ((flags & VIR_MIGRATE_TLS) &&
+ !(flags & VIR_MIGRATE_POSTCOPY_RESUME) &&
!qemuMigrationParamsTLSHostnameIsSet(migParams)) {
virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
_("Explicit destination hostname is required "
if (flags & VIR_MIGRATE_POSTCOPY_RESUME) {
ret = qemuMigrationSrcResume(vm, migParams, cookiein, cookieinlen,
- cookieout, cookieoutlen, &spec);
+ cookieout, cookieoutlen, &spec, flags);
} else {
ret = qemuMigrationSrcRun(driver, vm, persist_xml, cookiein, cookieinlen,
cookieout, cookieoutlen, flags, resource,
typedef struct _qemuMigrationParamInfoItem qemuMigrationParamInfoItem;
struct _qemuMigrationParamInfoItem {
qemuMigrationParamType type;
+ bool applyOnPostcopyResume;
};
/* Migration capabilities which should always be enabled as long as they
},
[QEMU_MIGRATION_PARAM_MAX_POSTCOPY_BANDWIDTH] = {
.type = QEMU_MIGRATION_PARAM_TYPE_ULL,
+ .applyOnPostcopyResume = true,
},
[QEMU_MIGRATION_PARAM_MULTIFD_CHANNELS] = {
.type = QEMU_MIGRATION_PARAM_TYPE_INT,
virJSONValue *
-qemuMigrationParamsToJSON(qemuMigrationParams *migParams)
+qemuMigrationParamsToJSON(qemuMigrationParams *migParams,
+ bool postcopyResume)
{
g_autoptr(virJSONValue) params = virJSONValueNewObject();
size_t i;
if (!pv->set)
continue;
+ if (postcopyResume && !qemuMigrationParamInfo[i].applyOnPostcopyResume)
+ continue;
+
switch (qemuMigrationParamInfo[i].type) {
case QEMU_MIGRATION_PARAM_TYPE_INT:
rc = virJSONValueObjectAppendNumberInt(params, name, pv->value.i);
*
* Send parameters stored in @migParams to QEMU. If @apiFlags is non-zero, some
* parameters that do not make sense for the enabled flags will be ignored.
+ * VIR_MIGRATE_POSTCOPY_RESUME is the only flag checked currently.
*
* Returns 0 on success, -1 on failure.
*/
virDomainObj *vm,
int asyncJob,
qemuMigrationParams *migParams,
- unsigned long apiFlags G_GNUC_UNUSED)
+ unsigned long apiFlags)
{
qemuDomainObjPrivate *priv = vm->privateData;
bool xbzrleCacheSize_old = false;
g_autoptr(virJSONValue) params = NULL;
g_autoptr(virJSONValue) caps = NULL;
qemuMigrationParam xbzrle = QEMU_MIGRATION_PARAM_XBZRLE_CACHE_SIZE;
+ bool postcopyResume = !!(apiFlags & VIR_MIGRATE_POSTCOPY_RESUME);
int ret = -1;
if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
return -1;
- if (asyncJob == VIR_ASYNC_JOB_NONE) {
- if (!virBitmapIsAllClear(migParams->caps)) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("Migration capabilities can only be set by "
- "a migration job"));
- goto cleanup;
- }
- } else {
- if (!(caps = qemuMigrationCapsToJSON(priv->migrationCaps, migParams->caps)))
- goto cleanup;
+ /* Changing capabilities is only allowed before migration starts, we need
+ * to skip them when resuming post-copy migration.
+ */
+ if (!postcopyResume) {
+ if (asyncJob == VIR_ASYNC_JOB_NONE) {
+ if (!virBitmapIsAllClear(migParams->caps)) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Migration capabilities can only be set by "
+ "a migration job"));
+ goto cleanup;
+ }
+ } else {
+ if (!(caps = qemuMigrationCapsToJSON(priv->migrationCaps, migParams->caps)))
+ goto cleanup;
- if (virJSONValueArraySize(caps) > 0 &&
- qemuMonitorSetMigrationCapabilities(priv->mon, &caps) < 0)
- goto cleanup;
+ if (virJSONValueArraySize(caps) > 0 &&
+ qemuMonitorSetMigrationCapabilities(priv->mon, &caps) < 0)
+ goto cleanup;
+ }
}
/* If QEMU is too old to support xbzrle-cache-size migration parameter,
migParams->params[xbzrle].set = false;
}
- if (!(params = qemuMigrationParamsToJSON(migParams)))
+ if (!(params = qemuMigrationParamsToJSON(migParams, postcopyResume)))
goto cleanup;
if (virJSONValueObjectKeysNumber(params) > 0 &&