On 25/02/2025 03:58, Peter Xu wrote:
> On Fri, Feb 21, 2025 at 02:36:09PM +0800, Li Zhijian wrote:
>> Similar to migration_channels_and_transport_compatible(), introduce a
>> new helper migration_capabilities_and_transport_compatible() to check if
>> the capabilites is compatible with the transport.
>>
>> Currently, only move the capabilities vs RDMA transport to this
>> function.
>>
>> Signed-off-by: Li Zhijian <lizhij...@fujitsu.com>
> 
> Yeah this is even better, thanks.
> 
> Reviewed-by: Peter Xu <pet...@redhat.com>

Hi Peter,

Thinking one step further, this patch looks promising and can check
most situations. However, on the destination side, if the user first
specifies '-incoming' (with the startup parameter -incoming xxx or
migrate_incoming xxx) and then 'migrate_set_capability xxx on',
the function migration_capabilities_and_transport_compatible() will
not be called to check compatibility, which might lead to migration failure.

To address this, without introducing a new member 'transport' into the 
MigrationState
structure, the code might need to be adjusted to this:

The question is whether we need to consider it now(in this patch set)?

  static bool migration_transport_compatible(MigrationAddress *addr, Error 
**errp)
  {
      return migration_channels_and_transport_compatible(addr, errp) &&
-           migration_capabilities_and_transport_compatible(addr, errp);
+           migration_capabilities_and_transport_compatible(addr->transport,
+               migrate_get_current()->capabilities, errp);
  }

  static gint page_request_addr_cmp(gconstpointer ap, gconstpointer bp)
diff --git a/migration/options.c b/migration/options.c
index bb259d192a9..59f0ed5b528 100644
--- a/migration/options.c
+++ b/migration/options.c
@@ -439,6 +439,29 @@ static bool migrate_incoming_started(void)
      return !!migration_incoming_get_current()->transport_data;
  }
  
+bool
+migration_capabilities_and_transport_compatible(MigrationAddressType transport,
+                                                bool *new_caps,
+                                                Error **errp)
+{
+    if (transport == MIGRATION_ADDRESS_TYPE_RDMA) {
+        if (new_caps[MIGRATION_CAPABILITY_XBZRLE]) {
+            error_setg(errp, "RDMA and XBZRLE can't be used together");
+            return false;
+        }
+        if (new_caps[MIGRATION_CAPABILITY_MULTIFD]) {
+            error_setg(errp, "RDMA and multifd can't be used together");
+            return false;
+        }
+        if (new_caps[MIGRATION_CAPABILITY_POSTCOPY_RAM]) {
+            error_setg(errp, "RDMA and postcopy-ram can't be used together");
+            return false;
+        }
+    }
+
+    return true;
+}
+
  /**
   * @migration_caps_check - check capability compatibility
   *
@@ -602,6 +625,15 @@ bool migrate_caps_check(bool *old_caps, bool *new_caps, 
Error **errp)
          }
      }
  
+    /*
+     * In destination side, check the cases that capability is being set
+     * after incoming thread has started.
+    */
+    if (migrate_rdma() &&
+        !migration_capabilities_and_transport_compatible(
+            MIGRATION_ADDRESS_TYPE_RDMA, new_caps, errp)) {
+        return false;
+    }
      return true;
  }
  
diff --git a/migration/options.h b/migration/options.h
index 762be4e641a..ca6a40e7545 100644
--- a/migration/options.h
+++ b/migration/options.h
@@ -58,6 +58,9 @@ bool migrate_tls(void);
  /* capabilities helpers */
  
  bool migrate_caps_check(bool *old_caps, bool *new_caps, Error **errp);
+bool
+migration_capabilities_and_transport_compatible(MigrationAddressType transport,
+                                                bool *new_caps, Error **errp);

> 

Reply via email to