All of lore.kernel.org
 help / color / mirror / Atom feed
From: Trieu Huynh <vikingtc4@gmail.com>
To: qemu-devel@nongnu.org
Cc: Trieu Huynh <vikingtc4@gmail.com>, Peter Xu <peterx@redhat.com>,
	Fabiano Rosas <farosas@suse.de>, Eric Blake <eblake@redhat.com>,
	Markus Armbruster <armbru@redhat.com>,
	Paolo Bonzini <pbonzini@redhat.com>
Subject: [PATCH] migration: add optional capabilities field to migrate and migrate-incoming
Date: Sat,  4 Apr 2026 22:27:36 +0700	[thread overview]
Message-ID: <20260404152736.30190-1-viking4@gmail.com> (raw)

From: Trieu Huynh <vikingtc4@gmail.com>

When invoking migration, user must call migrate-set-capabilities as a
separate QMP command before calling migrate or migrate-incoming.

Add an optional 'capabilities' field to both commands. When provided,
the capabilities are applied before the migration starts, in the same
order as a migrate-set-capabilities call would apply them. Existing
callers that do not pass the field are unaffected.

This is particularly useful, eg. for snapshot-load workflows where a
single migrate-incoming call should express the full migration
configuration:

  { "execute": "migrate-incoming",
    "arguments": {
      "uri": "file:/tmp/snapshot",
      "capabilities": [{"capability": "mapped-ram", "state": true}]
    }}

Internal callers (HMP migrate-incoming, vl.c -incoming) pass
has_capabilities=false so their behaviour is unchanged.

Related-to: https://wiki.qemu.org/ToDo/LiveMigration#Allow_QMP_command_%22migrate[_incoming]%22_to_take_capabilities_and_parameters

Signed-off-by: Trieu Huynh <vikingtc4@gmail.com>
---
 migration/migration-hmp-cmds.c |  4 ++--
 migration/migration.c          | 19 +++++++++++++++++++
 qapi/migration.json            | 12 ++++++++++++
 system/vl.c                    |  3 ++-
 4 files changed, 35 insertions(+), 3 deletions(-)

diff --git a/migration/migration-hmp-cmds.c b/migration/migration-hmp-cmds.c
index 0a193b8f54..32c338103d 100644
--- a/migration/migration-hmp-cmds.c
+++ b/migration/migration-hmp-cmds.c
@@ -522,7 +522,7 @@ void hmp_migrate_incoming(Monitor *mon, const QDict *qdict)
     }
     QAPI_LIST_PREPEND(caps, g_steal_pointer(&channel));
 
-    qmp_migrate_incoming(NULL, true, caps, true, false, &err);
+    qmp_migrate_incoming(NULL, true, caps, false, NULL, true, false, &err);
     qapi_free_MigrationChannelList(caps);
 
 end:
@@ -829,7 +829,7 @@ void hmp_migrate(Monitor *mon, const QDict *qdict)
     }
     QAPI_LIST_PREPEND(caps, g_steal_pointer(&channel));
 
-    qmp_migrate(NULL, true, caps, true, resume, &err);
+    qmp_migrate(NULL, true, caps, false, NULL, true, resume, &err);
     if (hmp_handle_error(mon, err)) {
         return;
     }
diff --git a/migration/migration.c b/migration/migration.c
index 5c9aaa6e58..eb1a734dd9 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -1752,6 +1752,8 @@ void migrate_del_blocker(Error **reasonp)
 
 void qmp_migrate_incoming(const char *uri, bool has_channels,
                           MigrationChannelList *channels,
+                          bool has_capabilities,
+                          MigrationCapabilityStatusList *capabilities,
                           bool has_exit_on_error, bool exit_on_error,
                           Error **errp)
 {
@@ -1772,6 +1774,14 @@ void qmp_migrate_incoming(const char *uri, bool has_channels,
         return;
     }
 
+    if (has_capabilities) {
+        qmp_migrate_set_capabilities(capabilities, errp);
+        if (*errp) {
+            yank_unregister_instance(MIGRATION_YANK_INSTANCE);
+            return;
+        }
+    }
+
     mis->exit_on_error =
         has_exit_on_error ? exit_on_error : INMIGRATE_DEFAULT_EXIT_ON_ERROR;
 
@@ -2020,6 +2030,8 @@ static gboolean migration_connect_outgoing_cb(QIOChannel *channel,
 
 void qmp_migrate(const char *uri, bool has_channels,
                  MigrationChannelList *channels,
+                 bool has_capabilities,
+                 MigrationCapabilityStatusList *capabilities,
                  bool has_resume, bool resume, Error **errp)
 {
     MigrationState *s = migrate_get_current();
@@ -2036,6 +2048,13 @@ void qmp_migrate(const char *uri, bool has_channels,
         return;
     }
 
+    if (has_capabilities) {
+        qmp_migrate_set_capabilities(capabilities, errp);
+        if (*errp) {
+            return;
+        }
+    }
+
     if (!migrate_prepare(s, has_resume && resume, errp)) {
         /* Error detected, put into errp */
         return;
diff --git a/qapi/migration.json b/qapi/migration.json
index 7134d4ce47..58d934f8fe 100644
--- a/qapi/migration.json
+++ b/qapi/migration.json
@@ -1388,6 +1388,11 @@
 # @channels: list of migration stream channels with each stream in the
 #     list connected to a destination interface endpoint.
 #
+# @capabilities: list of migration capabilities to set before
+#     starting the migration.  Equivalent to calling
+#     `migrate-set-capabilities` before `migrate`, but more
+#     convenient.
+#
 # @resume: when set, use the new uri/channels specified to resume
 #     paused postcopy migration.  This flag should only be used if
 #     the previous postcopy migration was interrupted.  The command
@@ -1453,6 +1458,7 @@
 { 'command': 'migrate',
   'data': {'*uri': 'str',
            '*channels': [ 'MigrationChannel' ],
+           '*capabilities': ['MigrationCapabilityStatus'],
            '*resume': 'bool' } }
 
 ##
@@ -1467,6 +1473,11 @@
 # @channels: list of migration stream channels with each stream in the
 #     list connected to a destination interface endpoint.
 #
+# @capabilities: list of migration capabilities to set before
+#     starting the migration.  Equivalent to calling
+#     `migrate-set-capabilities` before `migrate-incoming`, but more
+#     convenient.
+#
 # @exit-on-error: Exit on incoming migration failure.  Default true.
 #     When set to false, the failure triggers a
 #     :qapi:event:`MIGRATION` event, and error details could be
@@ -1525,6 +1536,7 @@
 { 'command': 'migrate-incoming',
              'data': {'*uri': 'str',
                       '*channels': [ 'MigrationChannel' ],
+                      '*capabilities': ['MigrationCapabilityStatus'],
                       '*exit-on-error': 'bool' } }
 
 ##
diff --git a/system/vl.c b/system/vl.c
index 246623b319..ed569d75e7 100644
--- a/system/vl.c
+++ b/system/vl.c
@@ -2826,7 +2826,8 @@ void qmp_x_exit_preconfig(Error **errp)
                 g_new0(MigrationChannelList, 1);
 
             channels->value = incoming_channels[MIGRATION_CHANNEL_TYPE_MAIN];
-            qmp_migrate_incoming(NULL, true, channels, true, true, &local_err);
+            qmp_migrate_incoming(NULL, true, channels, false, NULL, true,
+                                 true, &local_err);
             if (local_err) {
                 error_reportf_err(local_err, "-incoming %s: ", incoming);
                 exit(1);
-- 
2.43.0



             reply	other threads:[~2026-04-04 15:28 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-04-04 15:27 Trieu Huynh [this message]
2026-04-06 13:43 ` [PATCH] migration: add optional capabilities field to migrate and migrate-incoming Fabiano Rosas
2026-04-08 19:57   ` Trieu Huynh

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260404152736.30190-1-viking4@gmail.com \
    --to=vikingtc4@gmail.com \
    --cc=armbru@redhat.com \
    --cc=eblake@redhat.com \
    --cc=farosas@suse.de \
    --cc=pbonzini@redhat.com \
    --cc=peterx@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.