From ea5fff88f6929eb2fadf716af861d290179bdc61 Mon Sep 17 00:00:00 2001
From: eillon <1377437556@qq.com>
Date: Thu, 16 May 2024 15:21:22 +0800
Subject: [PATCH] migration: support onecopy migration

Support onecopy migration for migrating memory pages. This
means pause the source vm and send all dirty pages to dest by once.

This avoids iterative migration and ensures that the migration
time is controllable.

It's useful when the migration bandwidth is very large.

Signed-off-by: eillon <yezhenyu2@huawei.com>
---
 include/libvirt/libvirt-domain.h | 7 +++++++
 src/qemu/qemu_migration.h        | 1 +
 src/qemu/qemu_migration_params.c | 6 ++++++
 src/qemu/qemu_migration_params.h | 1 +
 tools/virsh-domain.c             | 5 +++++
 5 files changed, 20 insertions(+)

diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
index a2549d001c..713562b6c3 100644
--- a/include/libvirt/libvirt-domain.h
+++ b/include/libvirt/libvirt-domain.h
@@ -1108,6 +1108,13 @@ typedef enum {
      * Since: 9.10.0
      */
     VIR_MIGRATE_RETURNPATH = (1 << 21),
+
+    /* Use one-copy mechanism for migrating memory pages. For QEMU/KVM this
+     * means QEMU will pause source vm and send all dirty pages to dest by once.
+     *
+     * Since: 9.10.0
+     */
+    VIR_MIGRATE_ONECOPY = (1 << 22),
 } virDomainMigrateFlags;
 
 
diff --git a/src/qemu/qemu_migration.h b/src/qemu/qemu_migration.h
index 4e1b7dda57..6da44189ce 100644
--- a/src/qemu/qemu_migration.h
+++ b/src/qemu/qemu_migration.h
@@ -63,6 +63,7 @@
      VIR_MIGRATE_POSTCOPY_RESUME | \
      VIR_MIGRATE_ZEROCOPY | \
      VIR_MIGRATE_RETURNPATH | \
+     VIR_MIGRATE_ONECOPY | \
      0)
 
 /* All supported migration parameters and their types. */
diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c
index bf6a5a9cf6..289c3a628f 100644
--- a/src/qemu/qemu_migration_params.c
+++ b/src/qemu/qemu_migration_params.c
@@ -99,6 +99,7 @@ VIR_ENUM_IMPL(qemuMigrationCapability,
               "dirty-bitmaps",
               "return-path",
               "zero-copy-send",
+              "onecopy",
 );
 
 
@@ -195,6 +196,11 @@ static const qemuMigrationParamsFlagMapItem qemuMigrationParamsFlagMap[] = {
      VIR_MIGRATE_RETURNPATH,
      QEMU_MIGRATION_CAP_RETURN_PATH,
      QEMU_MIGRATION_SOURCE | QEMU_MIGRATION_DESTINATION},
+
+    {QEMU_MIGRATION_FLAG_REQUIRED,
+     VIR_MIGRATE_ONECOPY,
+     QEMU_MIGRATION_CAP_ONECOPY,
+     QEMU_MIGRATION_SOURCE},
 };
 
 /* Translation from VIR_MIGRATE_PARAM_* typed parameters to
diff --git a/src/qemu/qemu_migration_params.h b/src/qemu/qemu_migration_params.h
index 5df4d3738e..b704291d3e 100644
--- a/src/qemu/qemu_migration_params.h
+++ b/src/qemu/qemu_migration_params.h
@@ -40,6 +40,7 @@ typedef enum {
     QEMU_MIGRATION_CAP_BLOCK_DIRTY_BITMAPS,
     QEMU_MIGRATION_CAP_RETURN_PATH,
     QEMU_MIGRATION_CAP_ZERO_COPY_SEND,
+    QEMU_MIGRATION_CAP_ONECOPY,
 
     QEMU_MIGRATION_CAP_LAST
 } qemuMigrationCapability;
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index 31f479dbb8..af55e01f08 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -11133,6 +11133,10 @@ static const vshCmdOptDef opts_migrate[] = {
      .type = VSH_OT_INT,
      .help = N_("compress level for zstd compression")
     },
+    {.name = "onecopy",
+     .type = VSH_OT_BOOL,
+     .help = N_("enable one-copy migration")
+    },
     {.name = NULL}
 };
 
@@ -11183,6 +11187,7 @@ doMigrate(void *opaque)
         { "parallel", VIR_MIGRATE_PARALLEL },
         { "suspend", VIR_MIGRATE_PAUSED },
         { "return-path", VIR_MIGRATE_RETURNPATH },
+        { "onecopy", VIR_MIGRATE_ONECOPY },
     };
 
 #ifndef WIN32
-- 
2.51.0.windows.1