]> xenbits.xensource.com Git - libvirt.git/commitdiff
qemu: Add support for optional migration capabilities
authorJiri Denemark <jdenemar@redhat.com>
Mon, 8 Jan 2024 15:31:29 +0000 (16:31 +0100)
committerJiri Denemark <jdenemar@redhat.com>
Mon, 8 Jan 2024 21:39:56 +0000 (22:39 +0100)
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>
src/qemu/qemu_migration.c
src/qemu/qemu_migration_params.c
src/qemu/qemu_migration_params.h

index 3ba0aa502b11e48c92f50a0c0b662e4b69b2cf50..55041190793c0480aad4f45e1b96181c6c6954c2 100644 (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 */
index f441c59d6734491ec5a99f7a3786cafbbdd88d32..cdf437b51c4a8453778dca4ea888e61f28485e68 100644 (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;
-
-        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++) {
index 44f5c2a882bbca5f2a8523a079704c4dff506c36..115d7bc5979586ec1aa507de9ced305e77042fcf 100644 (file)
@@ -142,6 +142,7 @@ int
 qemuMigrationParamsCheck(virDomainObj *vm,
                          int asyncJob,
                          qemuMigrationParams *migParams,
+                         virBitmap *remoteSupported,
                          virBitmap *remoteAuto);
 
 void