We enable various migration capabilities according to the flags passed
to a migration API. Missing support for such capabilities results in an
error because they are required by the corresponding flag. This patch
adds support for additional optional capability we may want to enable
for a given API flag in case it is supported. This is useful for
capabilities which are not critical for the flags to be supported, but
they can make things work better in some way.
Signed-off-by: Jiri Denemark <jdenemar(a)redhat.com>
---
src/qemu/qemu_migration.c | 8 ++---
src/qemu/qemu_migration_params.c | 57 +++++++++++++++++++++++++++++---
src/qemu/qemu_migration_params.h | 1 +
3 files changed, 57 insertions(+), 9 deletions(-)
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 3ba0aa502b..5504119079 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -3172,8 +3172,8 @@ qemuMigrationDstPrepareActive(virQEMUDriver *driver,
if (qemuMigrationDstPrepareAnyBlockDirtyBitmaps(vm, mig, migParams, flags) < 0)
goto error;
- if (qemuMigrationParamsCheck(vm, VIR_ASYNC_JOB_MIGRATION_IN,
- migParams, mig->caps->automatic) < 0)
+ if (qemuMigrationParamsCheck(vm, VIR_ASYNC_JOB_MIGRATION_IN, migParams,
+ mig->caps->supported, mig->caps->automatic)
< 0)
goto error;
/* Save original migration parameters */
@@ -4831,8 +4831,8 @@ qemuMigrationSrcRun(virQEMUDriver *driver,
qemuMigrationSrcRunPrepareBlockDirtyBitmaps(vm, mig, migParams, flags) < 0)
goto error;
- if (qemuMigrationParamsCheck(vm, VIR_ASYNC_JOB_MIGRATION_OUT,
- migParams, mig->caps->automatic) < 0)
+ if (qemuMigrationParamsCheck(vm, VIR_ASYNC_JOB_MIGRATION_OUT, migParams,
+ mig->caps->supported, mig->caps->automatic)
< 0)
goto error;
/* Save original migration parameters */
diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c
index f441c59d67..133f1f762d 100644
--- a/src/qemu/qemu_migration_params.c
+++ b/src/qemu/qemu_migration_params.c
@@ -64,6 +64,11 @@ struct _qemuMigrationParamValue {
struct _qemuMigrationParams {
unsigned long long compMethods; /* bit-wise OR of qemuMigrationCompressMethod */
virBitmap *caps;
+ /* Optional capabilities are enabled only if supported by QEMU */
+ virBitmap *optional;
+ /* A capability present on both optional and remoteOptional bitmaps are
+ * enabled only if they are supported by both sides of migration. */
+ virBitmap *remoteOptional;
qemuMigrationParamValue params[QEMU_MIGRATION_PARAM_LAST];
virJSONValue *blockDirtyBitmapMapping;
};
@@ -141,6 +146,10 @@ struct _qemuMigrationParamsFlagMapItem {
virDomainMigrateFlags flag;
/* Migration capability to be enabled or disabled based on the flag. */
qemuMigrationCapability cap;
+ /* An optional capability to set in addition to @cap in case it is
+ * supported. Depending on @part either one or both sides of migration
+ * has to support the optional capability to be enabled. */
+ qemuMigrationCapability optional;
/* Bit-wise OR of qemuMigrationParty. Determines whether the capability has
* to be enabled on the source, on the destination, or on both sides of
* migration. */
@@ -334,6 +343,8 @@ qemuMigrationParamsNew(void)
params = g_new0(qemuMigrationParams, 1);
params->caps = virBitmapNew(QEMU_MIGRATION_CAP_LAST);
+ params->optional = virBitmapNew(QEMU_MIGRATION_CAP_LAST);
+ params->remoteOptional = virBitmapNew(QEMU_MIGRATION_CAP_LAST);
return g_steal_pointer(¶ms);
}
@@ -353,6 +364,8 @@ qemuMigrationParamsFree(qemuMigrationParams *migParams)
}
virBitmapFree(migParams->caps);
+ virBitmapFree(migParams->optional);
+ virBitmapFree(migParams->remoteOptional);
virJSONValueFree(migParams->blockDirtyBitmapMapping);
g_free(migParams);
}
@@ -698,6 +711,13 @@ qemuMigrationParamsFromFlags(virTypedParameterPtr params,
VIR_DEBUG("Enabling migration capability '%s'",
qemuMigrationCapabilityTypeToString(item->cap));
ignore_value(virBitmapSetBit(migParams->caps, item->cap));
+
+ if (item->optional) {
+ qemuMigrationCapability opt = item->optional;
+ ignore_value(virBitmapSetBit(migParams->optional, opt));
+ if (item->party != party)
+ ignore_value(virBitmapSetBit(migParams->remoteOptional, opt));
+ }
}
}
@@ -1290,6 +1310,7 @@ int
qemuMigrationParamsCheck(virDomainObj *vm,
int asyncJob,
qemuMigrationParams *migParams,
+ virBitmap *remoteSupported,
virBitmap *remoteAuto)
{
qemuDomainJobPrivate *jobPriv = vm->job->privateData;
@@ -1303,16 +1324,42 @@ qemuMigrationParamsCheck(virDomainObj *vm,
party = QEMU_MIGRATION_DESTINATION;
for (cap = 0; cap < QEMU_MIGRATION_CAP_LAST; cap++) {
- bool state = false;
-
- ignore_value(virBitmapGetBit(migParams->caps, cap, &state));
-
- if (state && !qemuMigrationCapsGet(vm, cap)) {
+ bool enable = false;
+ bool optional = false;
+ bool remoteOpt = false;
+ bool remote = false;
+ bool qemu = qemuMigrationCapsGet(vm, cap);
+
+ ignore_value(virBitmapGetBit(migParams->caps, cap, &enable));
+ ignore_value(virBitmapGetBit(migParams->optional, cap, &optional));
+ ignore_value(virBitmapGetBit(migParams->remoteOptional, cap,
&remoteOpt));
+ ignore_value(virBitmapGetBit(remoteSupported, cap, &remote));
+
+ if (enable && !qemu) {
virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED,
_("Migration option '%1$s' is not supported by
QEMU binary"),
qemuMigrationCapabilityTypeToString(cap));
return -1;
}
+
+ if (optional) {
+ if (!qemu) {
+ VIR_DEBUG("Optional migration capability '%s' not supported
by QEMU",
+ qemuMigrationCapabilityTypeToString(cap));
+ optional = false;
+ } else if (remoteOpt && ! remote) {
+ VIR_DEBUG("Optional migration capability '%s' not supported
"
+ "by the other side of migration",
+ qemuMigrationCapabilityTypeToString(cap));
+ optional = false;
+ }
+
+ if (optional) {
+ VIR_DEBUG("Enabling optional migration capability
'%s'",
+ qemuMigrationCapabilityTypeToString(cap));
+ ignore_value(virBitmapSetBit(migParams->caps, cap));
+ }
+ }
}
for (i = 0; i < G_N_ELEMENTS(qemuMigrationParamsAlwaysOn); i++) {
diff --git a/src/qemu/qemu_migration_params.h b/src/qemu/qemu_migration_params.h
index 44f5c2a882..115d7bc597 100644
--- a/src/qemu/qemu_migration_params.h
+++ b/src/qemu/qemu_migration_params.h
@@ -142,6 +142,7 @@ int
qemuMigrationParamsCheck(virDomainObj *vm,
int asyncJob,
qemuMigrationParams *migParams,
+ virBitmap *remoteSupported,
virBitmap *remoteAuto);
void
--
2.43.0