1
0
mirror of https://gitlab.com/libvirt/libvirt.git synced 2025-03-20 06:50:22 +03:00

qemu: Add support for optional migration capabilities

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@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
This commit is contained in:
Jiri Denemark 2024-01-08 16:31:29 +01:00
parent efc26a665d
commit 61e34b0856
3 changed files with 55 additions and 7 deletions

View File

@ -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 */

View File

@ -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(&params);
}
@ -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;
bool enable = false;
bool optional = false;
bool remoteOpt = false;
bool remote = false;
bool qemu = qemuMigrationCapsGet(vm, cap);
ignore_value(virBitmapGetBit(migParams->caps, cap, &state));
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 (state && !qemuMigrationCapsGet(vm, cap)) {
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++) {

View File

@ -142,6 +142,7 @@ int
qemuMigrationParamsCheck(virDomainObj *vm,
int asyncJob,
qemuMigrationParams *migParams,
virBitmap *remoteSupported,
virBitmap *remoteAuto);
void