]> git.proxmox.com Git - pve-qemu.git/blobdiff - debian/patches/pve/0040-PVE-Migrate-dirty-bitmap-state-via-savevm.patch
update submodule and patches to 7.1.0
[pve-qemu.git] / debian / patches / pve / 0040-PVE-Migrate-dirty-bitmap-state-via-savevm.patch
diff --git a/debian/patches/pve/0040-PVE-Migrate-dirty-bitmap-state-via-savevm.patch b/debian/patches/pve/0040-PVE-Migrate-dirty-bitmap-state-via-savevm.patch
new file mode 100644 (file)
index 0000000..e80a716
--- /dev/null
@@ -0,0 +1,212 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Stefan Reiter <s.reiter@proxmox.com>
+Date: Thu, 22 Oct 2020 17:34:18 +0200
+Subject: [PATCH] PVE: Migrate dirty bitmap state via savevm
+
+QEMU provides 'savevm' registrations as a mechanism for arbitrary state
+to be migrated along with a VM. Use this to send a serialized version of
+dirty bitmap state data from proxmox-backup-qemu, and restore it on the
+target node.
+
+Also add a flag to query-proxmox-support so qemu-server can determine if
+safe migration is possible and makes sense.
+
+Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
+Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
+---
+ include/migration/misc.h |   3 ++
+ migration/meson.build    |   2 +
+ migration/migration.c    |   1 +
+ migration/pbs-state.c    | 106 +++++++++++++++++++++++++++++++++++++++
+ pve-backup.c             |   1 +
+ qapi/block-core.json     |   6 +++
+ 6 files changed, 119 insertions(+)
+ create mode 100644 migration/pbs-state.c
+
+diff --git a/include/migration/misc.h b/include/migration/misc.h
+index 465906710d..4f0aeceb6f 100644
+--- a/include/migration/misc.h
++++ b/include/migration/misc.h
+@@ -75,4 +75,7 @@ bool migration_in_bg_snapshot(void);
+ /* migration/block-dirty-bitmap.c */
+ void dirty_bitmap_mig_init(void);
++/* migration/pbs-state.c */
++void pbs_state_mig_init(void);
++
+ #endif
+diff --git a/migration/meson.build b/migration/meson.build
+index 0842d00cd2..d012f4d8d3 100644
+--- a/migration/meson.build
++++ b/migration/meson.build
+@@ -6,8 +6,10 @@ migration_files = files(
+   'vmstate.c',
+   'qemu-file.c',
+   'yank_functions.c',
++  'pbs-state.c',
+ )
+ softmmu_ss.add(migration_files)
++softmmu_ss.add(libproxmox_backup_qemu)
+ softmmu_ss.add(files(
+   'block-dirty-bitmap.c',
+diff --git a/migration/migration.c b/migration/migration.c
+index bb8bbddfe4..8109e468eb 100644
+--- a/migration/migration.c
++++ b/migration/migration.c
+@@ -229,6 +229,7 @@ void migration_object_init(void)
+     blk_mig_init();
+     ram_mig_init();
+     dirty_bitmap_mig_init();
++    pbs_state_mig_init();
+ }
+ void migration_cancel(const Error *error)
+diff --git a/migration/pbs-state.c b/migration/pbs-state.c
+new file mode 100644
+index 0000000000..29f2b3860d
+--- /dev/null
++++ b/migration/pbs-state.c
+@@ -0,0 +1,106 @@
++/*
++ * PBS (dirty-bitmap) state migration
++ */
++
++#include "qemu/osdep.h"
++#include "migration/misc.h"
++#include "qemu-file.h"
++#include "migration/vmstate.h"
++#include "migration/register.h"
++#include "proxmox-backup-qemu.h"
++
++typedef struct PBSState {
++    bool active;
++} PBSState;
++
++/* state is accessed via this static variable directly, 'opaque' is NULL */
++static PBSState pbs_state;
++
++static void pbs_state_save_pending(QEMUFile *f, void *opaque,
++                                      uint64_t max_size,
++                                      uint64_t *res_precopy_only,
++                                      uint64_t *res_compatible,
++                                      uint64_t *res_postcopy_only)
++{
++    /* we send everything in save_setup, so nothing is ever pending */
++}
++
++/* receive PBS state via f and deserialize, called on target */
++static int pbs_state_load(QEMUFile *f, void *opaque, int version_id)
++{
++    /* safe cast, we cannot migrate to target with less bits than source */
++    size_t buf_size = (size_t)qemu_get_be64(f);
++
++    uint8_t *buf = (uint8_t *)malloc(buf_size);
++    size_t read = qemu_get_buffer(f, buf, buf_size);
++
++    if (read < buf_size) {
++        fprintf(stderr, "error receiving PBS state: not enough data\n");
++        return -EIO;
++    }
++
++    proxmox_import_state(buf, buf_size);
++
++    free(buf);
++    return 0;
++}
++
++/* serialize PBS state and send to target via f, called on source */
++static int pbs_state_save_setup(QEMUFile *f, void *opaque)
++{
++    size_t buf_size;
++    uint8_t *buf = proxmox_export_state(&buf_size);
++
++    /* LV encoding */
++    qemu_put_be64(f, buf_size);
++    qemu_put_buffer(f, buf, buf_size);
++
++    proxmox_free_state_buf(buf);
++    pbs_state.active = false;
++    return 0;
++}
++
++static bool pbs_state_is_active(void *opaque)
++{
++    /* we need to return active exactly once, else .save_setup is never called,
++     * but if we'd just return true the migration doesn't make progress since
++     * it'd be waiting for us */
++    return pbs_state.active;
++}
++
++static bool pbs_state_is_active_iterate(void *opaque)
++{
++    /* we don't iterate, everything is sent in save_setup */
++    return pbs_state_is_active(opaque);
++}
++
++static bool pbs_state_has_postcopy(void *opaque)
++{
++    /* PBS state can't change during a migration (since that's blocking any
++     * potential backups), so we can copy everything before the VM is stopped */
++    return false;
++}
++
++static void pbs_state_save_cleanup(void *opaque)
++{
++    /* reset active after migration succeeds or fails */
++    pbs_state.active = false;
++}
++
++static SaveVMHandlers savevm_pbs_state_handlers = {
++    .save_setup = pbs_state_save_setup,
++    .has_postcopy = pbs_state_has_postcopy,
++    .save_live_pending = pbs_state_save_pending,
++    .is_active_iterate = pbs_state_is_active_iterate,
++    .load_state = pbs_state_load,
++    .is_active = pbs_state_is_active,
++    .save_cleanup = pbs_state_save_cleanup,
++};
++
++void pbs_state_mig_init(void)
++{
++    pbs_state.active = true;
++    register_savevm_live("pbs-state", 0, 1,
++                         &savevm_pbs_state_handlers,
++                         NULL);
++}
+diff --git a/pve-backup.c b/pve-backup.c
+index 6f05796fad..5fa3cc1352 100644
+--- a/pve-backup.c
++++ b/pve-backup.c
+@@ -1132,6 +1132,7 @@ ProxmoxSupportStatus *qmp_query_proxmox_support(Error **errp)
+     ret->pbs_library_version = g_strdup(proxmox_backup_qemu_version());
+     ret->pbs_dirty_bitmap = true;
+     ret->pbs_dirty_bitmap_savevm = true;
++    ret->pbs_dirty_bitmap_migration = true;
+     ret->query_bitmap_info = true;
+     return ret;
+ }
+diff --git a/qapi/block-core.json b/qapi/block-core.json
+index cb17d00fe0..bd978ea562 100644
+--- a/qapi/block-core.json
++++ b/qapi/block-core.json
+@@ -879,6 +879,11 @@
+ # @pbs-dirty-bitmap-savevm: True if 'dirty-bitmaps' migration capability can
+ #                           safely be set for savevm-async.
+ #
++# @pbs-dirty-bitmap-migration: True if safe migration of dirty-bitmaps including
++#                              PBS state is supported. Enabling 'dirty-bitmaps'
++#                              migration cap if this is false/unset may lead
++#                              to crashes on migration!
++#
+ # @pbs-library-version: Running version of libproxmox-backup-qemu0 library.
+ #
+ ##
+@@ -886,6 +891,7 @@
+   'data': { 'pbs-dirty-bitmap': 'bool',
+             'query-bitmap-info': 'bool',
+             'pbs-dirty-bitmap-savevm': 'bool',
++            'pbs-dirty-bitmap-migration': 'bool',
+             'pbs-library-version': 'str' } }
+ ##