[pve-devel] [PATCH pve-qemu 1/2] Update to QEMU 5.2

Stefan Reiter s.reiter at proxmox.com
Tue Jan 26 17:10:26 CET 2021


Lots of patches touched and some slight changes to the build process
since QEMU switched to meson as their build system. Functionality-wise
very little rebasing required.

One new patch is introduced, 0057, to fix VMA backups and clean up some
code in general with new 5.2 features now available to us (namely
coroutine-enabled QMP).

Signed-off-by: Stefan Reiter <s.reiter at proxmox.com>
---

Initial tests look good, migration, snapshots and backup (PBS and VMA) appear to
be working fine, but of course more testing is always appreciated!

My live-restore series ('alloc-track') would need a rebasing of course, but
since that one requires a v2 anyway I've decided to send this in the meantime.

 debian/control                                |   1 +
 ...u-img-convert-Don-t-pre-zero-images.patch} |   4 +-
 ...-always-align-copied-region-to-clust.patch |  34 -
 ...sb-fix-setup_len-init-CVE-2020-14364.patch |  87 ---
 ...k-file-change-locking-default-to-off.patch |   2 +-
 ...djust-network-script-path-to-etc-kvm.patch |  17 +-
 ...he-CPU-model-to-kvm64-32-instead-of-.patch |   4 +-
 ...ui-spice-default-to-pve-certificates.patch |   4 +-
 .../0005-PVE-Config-smm_available-false.patch |   4 +-
 ...lock-rbd-disable-rbd_cache_writethro.patch |   4 +-
 .../0008-PVE-Up-qmp-add-get_link_status.patch |   6 +-
 ...return-success-on-info-without-snaps.patch |   4 +-
 ...dd-add-osize-and-read-from-to-stdin-.patch |  18 +-
 ...E-Up-qemu-img-dd-add-isize-parameter.patch |  12 +-
 ...PVE-Up-qemu-img-dd-add-n-skip_create.patch |  10 +-
 ...virtio-balloon-improve-query-balloon.patch |  22 +-
 .../0015-PVE-qapi-modify-query-machines.patch |  12 +-
 .../0016-PVE-qapi-modify-spice-query.patch    |   8 +-
 .../0017-PVE-internal-snapshot-async.patch    | 481 ++++++--------
 ...add-optional-buffer-size-to-QEMUFile.patch |  12 +-
 ...add-the-zeroinit-block-driver-filter.patch |  36 +-
 ...-Add-dummy-id-command-line-parameter.patch |  10 +-
 ...t-target-i386-disable-LINT0-after-re.patch |   2 +-
 ...le-posix-make-locking-optiono-on-cre.patch |  20 +-
 ...3-PVE-monitor-disable-oob-capability.patch |   4 +-
 ...sed-balloon-qemu-4-0-config-size-fal.patch |   4 +-
 ...E-Allow-version-code-in-machine-type.patch |  36 +-
 ...VE-Backup-add-vma-backup-format-code.patch |  97 +--
 ...-Backup-add-backup-dump-block-driver.patch |  36 +-
 ...ckup-proxmox-backup-patches-for-qemu.patch | 127 ++--
 ...estore-new-command-to-restore-from-p.patch |  39 +-
 ...d-support-for-sync-bitmap-mode-never.patch |  76 +--
 ...-support-for-conditional-and-always-.patch |  10 +-
 ...check-for-bitmap-mode-without-bitmap.patch |   6 +-
 ...-to-bdrv_dirty_bitmap_merge_internal.patch |   6 +-
 ...5-iotests-add-test-for-bitmap-mirror.patch |   2 +-
 .../0036-mirror-move-some-checks-to-qmp.patch |   8 +-
 ...irty-bitmap-tracking-for-incremental.patch |  18 +-
 ...name-incremental-to-use-dirty-bitmap.patch |   8 +-
 ...ckup-add-compress-and-encrypt-option.patch |  10 +-
 ...k-driver-to-map-backup-archives-into.patch |  80 +--
 ...dd-query_proxmox_support-QMP-command.patch |   6 +-
 ...issing-crypt-and-compress-parameters.patch |   2 +-
 ...rite-callback-with-big-blocks-correc.patch |   2 +-
 ...-block-handling-to-PBS-dump-callback.patch |   2 +-
 ...E-add-query-pbs-bitmap-info-QMP-call.patch |  14 +-
 ...ct-stderr-to-journal-when-daemonized.patch |  40 +-
 ...d-sequential-job-transaction-support.patch |   2 +-
 ...-transaction-to-synchronize-job-stat.patch |   2 +-
 ...ore-coroutines-and-don-t-block-on-fi.patch |   6 +-
 ...n-up-error-handling-for-create_backu.patch |   2 +-
 ...grate-dirty-bitmap-state-via-savevm.patch} |  39 +-
 ...dirty-bitmap-fix-larger-granularity-.patch |  33 -
 ...irty-bitmap-migrate-other-bitmaps-e.patch} |   6 +-
 ...multiple-CREATED-jobs-in-sequential.patch} |   2 +-
 ...routine-QMP-for-backup-cancel_backup.patch | 595 ++++++++++++++++++
 debian/patches/series                         |  12 +-
 debian/pve-qemu-kvm.install                   |   2 -
 debian/rules                                  |  12 +-
 qemu                                          |   2 +-
 60 files changed, 1277 insertions(+), 885 deletions(-)
 rename debian/patches/extra/{0002-Revert-qemu-img-convert-Don-t-pre-zero-images.patch => 0001-Revert-qemu-img-convert-Don-t-pre-zero-images.patch} (91%)
 delete mode 100644 debian/patches/extra/0001-block-block-copy-always-align-copied-region-to-clust.patch
 delete mode 100644 debian/patches/extra/0003-usb-fix-setup_len-init-CVE-2020-14364.patch
 rename debian/patches/pve/{0055-PVE-Migrate-dirty-bitmap-state-via-savevm.patch => 0054-PVE-Migrate-dirty-bitmap-state-via-savevm.patch} (90%)
 delete mode 100644 debian/patches/pve/0054-migration-block-dirty-bitmap-fix-larger-granularity-.patch
 rename debian/patches/pve/{0056-migration-block-dirty-bitmap-migrate-other-bitmaps-e.patch => 0055-migration-block-dirty-bitmap-migrate-other-bitmaps-e.patch} (89%)
 rename debian/patches/pve/{0057-PVE-fix-aborting-multiple-CREATED-jobs-in-sequential.patch => 0056-PVE-fix-aborting-multiple-CREATED-jobs-in-sequential.patch} (97%)
 create mode 100644 debian/patches/pve/0057-PVE-Use-coroutine-QMP-for-backup-cancel_backup.patch

diff --git a/debian/control b/debian/control
index ee913e8..696d064 100644
--- a/debian/control
+++ b/debian/control
@@ -28,6 +28,7 @@ Build-Depends: autotools-dev,
                libsystemd-dev,
                libusb-1.0-0-dev (>= 1.0.17-1),
                libusbredirparser-dev (>= 0.6-2),
+               meson,
                python3-minimal,
                python3-sphinx,
                quilt,
diff --git a/debian/patches/extra/0002-Revert-qemu-img-convert-Don-t-pre-zero-images.patch b/debian/patches/extra/0001-Revert-qemu-img-convert-Don-t-pre-zero-images.patch
similarity index 91%
rename from debian/patches/extra/0002-Revert-qemu-img-convert-Don-t-pre-zero-images.patch
rename to debian/patches/extra/0001-Revert-qemu-img-convert-Don-t-pre-zero-images.patch
index 604feb3..0e7331f 100644
--- a/debian/patches/extra/0002-Revert-qemu-img-convert-Don-t-pre-zero-images.patch
+++ b/debian/patches/extra/0001-Revert-qemu-img-convert-Don-t-pre-zero-images.patch
@@ -12,10 +12,10 @@ https://bugzilla.proxmox.com/show_bug.cgi?id=3002
  1 file changed, 9 insertions(+)
 
 diff --git a/qemu-img.c b/qemu-img.c
-index 9635e9c001..c7884d248a 100644
+index 8bdea40b58..f9050bfaad 100644
 --- a/qemu-img.c
 +++ b/qemu-img.c
-@@ -2079,6 +2079,15 @@ static int convert_do_copy(ImgConvertState *s)
+@@ -2104,6 +2104,15 @@ static int convert_do_copy(ImgConvertState *s)
          s->has_zero_init = bdrv_has_zero_init(blk_bs(s->target));
      }
  
diff --git a/debian/patches/extra/0001-block-block-copy-always-align-copied-region-to-clust.patch b/debian/patches/extra/0001-block-block-copy-always-align-copied-region-to-clust.patch
deleted file mode 100644
index fe8589e..0000000
--- a/debian/patches/extra/0001-block-block-copy-always-align-copied-region-to-clust.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Stefan Reiter <s.reiter at proxmox.com>
-Date: Thu, 6 Aug 2020 15:43:58 +0200
-Subject: [PATCH] block/block-copy: always align copied region to cluster size
-
-Since commit 42ac214406e0 (block/block-copy: refactor task creation)
-block_copy_task_create calculates the area to be copied via
-bdrv_dirty_bitmap_next_dirty_area, but that can return an unaligned byte
-count if the image's last cluster end is not aligned to the bitmap's
-granularity.
-
-Always ALIGN_UP the resulting bytes value to satisfy block_copy_do_copy,
-which requires the 'bytes' parameter to be aligned to cluster size.
-
-Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov at virtuozzo.com>
-Signed-off-by: Stefan Reiter <s.reiter at proxmox.com>
----
- block/block-copy.c | 3 +++
- 1 file changed, 3 insertions(+)
-
-diff --git a/block/block-copy.c b/block/block-copy.c
-index f7428a7c08..a30b9097ef 100644
---- a/block/block-copy.c
-+++ b/block/block-copy.c
-@@ -142,6 +142,9 @@ static BlockCopyTask *block_copy_task_create(BlockCopyState *s,
-         return NULL;
-     }
- 
-+    assert(QEMU_IS_ALIGNED(offset, s->cluster_size));
-+    bytes = QEMU_ALIGN_UP(bytes, s->cluster_size);
-+
-     /* region is dirty, so no existent tasks possible in it */
-     assert(!find_conflicting_task(s, offset, bytes));
- 
diff --git a/debian/patches/extra/0003-usb-fix-setup_len-init-CVE-2020-14364.patch b/debian/patches/extra/0003-usb-fix-setup_len-init-CVE-2020-14364.patch
deleted file mode 100644
index 57b99a4..0000000
--- a/debian/patches/extra/0003-usb-fix-setup_len-init-CVE-2020-14364.patch
+++ /dev/null
@@ -1,87 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Gerd Hoffmann <kraxel at redhat.com>
-Date: Tue, 25 Aug 2020 07:36:36 +0200
-Subject: [PATCH] usb: fix setup_len init (CVE-2020-14364)
-
-Store calculated setup_len in a local variable, verify it, and only
-write it to the struct (USBDevice->setup_len) in case it passed the
-sanity checks.
-
-This prevents other code (do_token_{in,out} functions specifically)
-from working with invalid USBDevice->setup_len values and overrunning
-the USBDevice->setup_buf[] buffer.
-
-Fixes: CVE-2020-14364
-Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
-Tested-by: Gonglei <arei.gonglei at huawei.com>
-Reviewed-by: Li Qiang <liq3ea at gmail.com>
-Message-id: 20200825053636.29648-1-kraxel at redhat.com
-(cherry picked from commit b946434f2659a182afc17e155be6791ebfb302eb)
-Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
----
- hw/usb/core.c | 16 ++++++++++------
- 1 file changed, 10 insertions(+), 6 deletions(-)
-
-diff --git a/hw/usb/core.c b/hw/usb/core.c
-index 5abd128b6b..5234dcc73f 100644
---- a/hw/usb/core.c
-+++ b/hw/usb/core.c
-@@ -129,6 +129,7 @@ void usb_wakeup(USBEndpoint *ep, unsigned int stream)
- static void do_token_setup(USBDevice *s, USBPacket *p)
- {
-     int request, value, index;
-+    unsigned int setup_len;
- 
-     if (p->iov.size != 8) {
-         p->status = USB_RET_STALL;
-@@ -138,14 +139,15 @@ static void do_token_setup(USBDevice *s, USBPacket *p)
-     usb_packet_copy(p, s->setup_buf, p->iov.size);
-     s->setup_index = 0;
-     p->actual_length = 0;
--    s->setup_len   = (s->setup_buf[7] << 8) | s->setup_buf[6];
--    if (s->setup_len > sizeof(s->data_buf)) {
-+    setup_len = (s->setup_buf[7] << 8) | s->setup_buf[6];
-+    if (setup_len > sizeof(s->data_buf)) {
-         fprintf(stderr,
-                 "usb_generic_handle_packet: ctrl buffer too small (%d > %zu)\n",
--                s->setup_len, sizeof(s->data_buf));
-+                setup_len, sizeof(s->data_buf));
-         p->status = USB_RET_STALL;
-         return;
-     }
-+    s->setup_len = setup_len;
- 
-     request = (s->setup_buf[0] << 8) | s->setup_buf[1];
-     value   = (s->setup_buf[3] << 8) | s->setup_buf[2];
-@@ -259,26 +261,28 @@ static void do_token_out(USBDevice *s, USBPacket *p)
- static void do_parameter(USBDevice *s, USBPacket *p)
- {
-     int i, request, value, index;
-+    unsigned int setup_len;
- 
-     for (i = 0; i < 8; i++) {
-         s->setup_buf[i] = p->parameter >> (i*8);
-     }
- 
-     s->setup_state = SETUP_STATE_PARAM;
--    s->setup_len   = (s->setup_buf[7] << 8) | s->setup_buf[6];
-     s->setup_index = 0;
- 
-     request = (s->setup_buf[0] << 8) | s->setup_buf[1];
-     value   = (s->setup_buf[3] << 8) | s->setup_buf[2];
-     index   = (s->setup_buf[5] << 8) | s->setup_buf[4];
- 
--    if (s->setup_len > sizeof(s->data_buf)) {
-+    setup_len = (s->setup_buf[7] << 8) | s->setup_buf[6];
-+    if (setup_len > sizeof(s->data_buf)) {
-         fprintf(stderr,
-                 "usb_generic_handle_packet: ctrl buffer too small (%d > %zu)\n",
--                s->setup_len, sizeof(s->data_buf));
-+                setup_len, sizeof(s->data_buf));
-         p->status = USB_RET_STALL;
-         return;
-     }
-+    s->setup_len = setup_len;
- 
-     if (p->pid == USB_TOKEN_OUT) {
-         usb_packet_copy(p, s->data_buf, s->setup_len);
diff --git a/debian/patches/pve/0001-PVE-Config-block-file-change-locking-default-to-off.patch b/debian/patches/pve/0001-PVE-Config-block-file-change-locking-default-to-off.patch
index cf9b54c..9d7bec1 100644
--- a/debian/patches/pve/0001-PVE-Config-block-file-change-locking-default-to-off.patch
+++ b/debian/patches/pve/0001-PVE-Config-block-file-change-locking-default-to-off.patch
@@ -14,7 +14,7 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
  1 file changed, 2 insertions(+), 2 deletions(-)
 
 diff --git a/block/file-posix.c b/block/file-posix.c
-index 9a00d4190a..bb72e1e5ca 100644
+index d5fd1dbcd2..bda3e606dc 100644
 --- a/block/file-posix.c
 +++ b/block/file-posix.c
 @@ -508,7 +508,7 @@ static QemuOptsList raw_runtime_opts = {
diff --git a/debian/patches/pve/0002-PVE-Config-Adjust-network-script-path-to-etc-kvm.patch b/debian/patches/pve/0002-PVE-Config-Adjust-network-script-path-to-etc-kvm.patch
index 6068532..17e6fa5 100644
--- a/debian/patches/pve/0002-PVE-Config-Adjust-network-script-path-to-etc-kvm.patch
+++ b/debian/patches/pve/0002-PVE-Config-Adjust-network-script-path-to-etc-kvm.patch
@@ -5,22 +5,21 @@ Subject: [PATCH] PVE: [Config] Adjust network script path to /etc/kvm/
 
 Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
 ---
- include/net/net.h | 5 +++--
- 1 file changed, 3 insertions(+), 2 deletions(-)
+ include/net/net.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
 
 diff --git a/include/net/net.h b/include/net/net.h
-index e7ef42d62b..4fd1144e58 100644
+index 778fc787ca..fb2db6bb75 100644
 --- a/include/net/net.h
 +++ b/include/net/net.h
-@@ -209,8 +209,9 @@ void netdev_add(QemuOpts *opts, Error **errp);
+@@ -210,8 +210,8 @@ void netdev_add(QemuOpts *opts, Error **errp);
  int net_hub_id_for_client(NetClientState *nc, int *id);
  NetClientState *net_hub_port_find(int hub_id);
  
--#define DEFAULT_NETWORK_SCRIPT "/etc/qemu-ifup"
--#define DEFAULT_NETWORK_DOWN_SCRIPT "/etc/qemu-ifdown"
-+#define DEFAULT_NETWORK_SCRIPT "/etc/kvm/kvm-ifup"
-+#define DEFAULT_NETWORK_DOWN_SCRIPT "/etc/kvm/kvm-ifdown"
-+
+-#define DEFAULT_NETWORK_SCRIPT CONFIG_SYSCONFDIR "/qemu-ifup"
+-#define DEFAULT_NETWORK_DOWN_SCRIPT CONFIG_SYSCONFDIR "/qemu-ifdown"
++#define DEFAULT_NETWORK_SCRIPT CONFIG_SYSCONFDIR "/kvm/kvm-ifup"
++#define DEFAULT_NETWORK_DOWN_SCRIPT CONFIG_SYSCONFDIR "/kvm/kvm-ifdown"
  #define DEFAULT_BRIDGE_HELPER CONFIG_QEMU_HELPERDIR "/qemu-bridge-helper"
  #define DEFAULT_BRIDGE_INTERFACE "br0"
  
diff --git a/debian/patches/pve/0003-PVE-Config-set-the-CPU-model-to-kvm64-32-instead-of-.patch b/debian/patches/pve/0003-PVE-Config-set-the-CPU-model-to-kvm64-32-instead-of-.patch
index c906ed0..3b08513 100644
--- a/debian/patches/pve/0003-PVE-Config-set-the-CPU-model-to-kvm64-32-instead-of-.patch
+++ b/debian/patches/pve/0003-PVE-Config-set-the-CPU-model-to-kvm64-32-instead-of-.patch
@@ -10,10 +10,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
  1 file changed, 2 insertions(+), 2 deletions(-)
 
 diff --git a/target/i386/cpu.h b/target/i386/cpu.h
-index e1a5c174dc..8973d3160f 100644
+index 88e8586f8f..93563ee0c2 100644
 --- a/target/i386/cpu.h
 +++ b/target/i386/cpu.h
-@@ -1975,9 +1975,9 @@ uint64_t cpu_get_tsc(CPUX86State *env);
+@@ -1973,9 +1973,9 @@ uint64_t cpu_get_tsc(CPUX86State *env);
  #define CPU_RESOLVING_TYPE TYPE_X86_CPU
  
  #ifdef TARGET_X86_64
diff --git a/debian/patches/pve/0004-PVE-Config-ui-spice-default-to-pve-certificates.patch b/debian/patches/pve/0004-PVE-Config-ui-spice-default-to-pve-certificates.patch
index fb4ee8f..f02a0f8 100644
--- a/debian/patches/pve/0004-PVE-Config-ui-spice-default-to-pve-certificates.patch
+++ b/debian/patches/pve/0004-PVE-Config-ui-spice-default-to-pve-certificates.patch
@@ -9,10 +9,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
  1 file changed, 9 insertions(+), 6 deletions(-)
 
 diff --git a/ui/spice-core.c b/ui/spice-core.c
-index ecc2ec2c55..ca04965ead 100644
+index eea52f5389..d09ee7f09e 100644
 --- a/ui/spice-core.c
 +++ b/ui/spice-core.c
-@@ -668,32 +668,35 @@ void qemu_spice_init(void)
+@@ -667,32 +667,35 @@ static void qemu_spice_init(void)
  
      if (tls_port) {
          x509_dir = qemu_opt_get(opts, "x509-dir");
diff --git a/debian/patches/pve/0005-PVE-Config-smm_available-false.patch b/debian/patches/pve/0005-PVE-Config-smm_available-false.patch
index ff8fde9..59fd521 100644
--- a/debian/patches/pve/0005-PVE-Config-smm_available-false.patch
+++ b/debian/patches/pve/0005-PVE-Config-smm_available-false.patch
@@ -10,10 +10,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
  1 file changed, 1 insertion(+), 1 deletion(-)
 
 diff --git a/hw/i386/x86.c b/hw/i386/x86.c
-index 67bee1bcb8..d954bf77b9 100644
+index 5944fc44ed..31b481b4e9 100644
 --- a/hw/i386/x86.c
 +++ b/hw/i386/x86.c
-@@ -856,7 +856,7 @@ bool x86_machine_is_smm_enabled(X86MachineState *x86ms)
+@@ -1115,7 +1115,7 @@ bool x86_machine_is_smm_enabled(const X86MachineState *x86ms)
      if (tcg_enabled() || qtest_enabled()) {
          smm_available = true;
      } else if (kvm_enabled()) {
diff --git a/debian/patches/pve/0007-PVE-Config-rbd-block-rbd-disable-rbd_cache_writethro.patch b/debian/patches/pve/0007-PVE-Config-rbd-block-rbd-disable-rbd_cache_writethro.patch
index 3bf4925..7180411 100644
--- a/debian/patches/pve/0007-PVE-Config-rbd-block-rbd-disable-rbd_cache_writethro.patch
+++ b/debian/patches/pve/0007-PVE-Config-rbd-block-rbd-disable-rbd_cache_writethro.patch
@@ -18,10 +18,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
  1 file changed, 2 insertions(+)
 
 diff --git a/block/rbd.c b/block/rbd.c
-index 688074c64b..8ae39abb46 100644
+index 9bd2bce716..c7195a2342 100644
 --- a/block/rbd.c
 +++ b/block/rbd.c
-@@ -651,6 +651,8 @@ static int qemu_rbd_connect(rados_t *cluster, rados_ioctx_t *io_ctx,
+@@ -609,6 +609,8 @@ static int qemu_rbd_connect(rados_t *cluster, rados_ioctx_t *io_ctx,
          rados_conf_set(*cluster, "rbd_cache", "false");
      }
  
diff --git a/debian/patches/pve/0008-PVE-Up-qmp-add-get_link_status.patch b/debian/patches/pve/0008-PVE-Up-qmp-add-get_link_status.patch
index cae1f1b..4930618 100644
--- a/debian/patches/pve/0008-PVE-Up-qmp-add-get_link_status.patch
+++ b/debian/patches/pve/0008-PVE-Up-qmp-add-get_link_status.patch
@@ -11,10 +11,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
  3 files changed, 43 insertions(+)
 
 diff --git a/net/net.c b/net/net.c
-index bbaedb3c7a..9de23ec834 100644
+index 6a2c3d9567..a1e9514fb8 100644
 --- a/net/net.c
 +++ b/net/net.c
-@@ -1276,6 +1276,33 @@ void hmp_info_network(Monitor *mon, const QDict *qdict)
+@@ -1277,6 +1277,33 @@ void hmp_info_network(Monitor *mon, const QDict *qdict)
      }
  }
  
@@ -49,7 +49,7 @@ index bbaedb3c7a..9de23ec834 100644
  {
      NetClientState *nc;
 diff --git a/qapi/net.json b/qapi/net.json
-index ddb113e5e5..eb3b785984 100644
+index a3a1336001..b8092c4e20 100644
 --- a/qapi/net.json
 +++ b/qapi/net.json
 @@ -35,6 +35,21 @@
diff --git a/debian/patches/pve/0010-PVE-Up-qemu-img-return-success-on-info-without-snaps.patch b/debian/patches/pve/0010-PVE-Up-qemu-img-return-success-on-info-without-snaps.patch
index 8a4ca3a..d15050e 100644
--- a/debian/patches/pve/0010-PVE-Up-qemu-img-return-success-on-info-without-snaps.patch
+++ b/debian/patches/pve/0010-PVE-Up-qemu-img-return-success-on-info-without-snaps.patch
@@ -9,10 +9,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
  1 file changed, 2 insertions(+), 1 deletion(-)
 
 diff --git a/qemu-img.c b/qemu-img.c
-index 5308773811..45aa024acc 100644
+index f9050bfaad..7e6666b5f7 100644
 --- a/qemu-img.c
 +++ b/qemu-img.c
-@@ -2955,7 +2955,8 @@ static int img_info(int argc, char **argv)
+@@ -3022,7 +3022,8 @@ static int img_info(int argc, char **argv)
      list = collect_image_info_list(image_opts, filename, fmt, chain,
                                     force_share);
      if (!list) {
diff --git a/debian/patches/pve/0011-PVE-Up-qemu-img-dd-add-osize-and-read-from-to-stdin-.patch b/debian/patches/pve/0011-PVE-Up-qemu-img-dd-add-osize-and-read-from-to-stdin-.patch
index 3b73980..07a877e 100644
--- a/debian/patches/pve/0011-PVE-Up-qemu-img-dd-add-osize-and-read-from-to-stdin-.patch
+++ b/debian/patches/pve/0011-PVE-Up-qemu-img-dd-add-osize-and-read-from-to-stdin-.patch
@@ -37,7 +37,7 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
  2 files changed, 121 insertions(+), 74 deletions(-)
 
 diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
-index b89c019b76..91d18a4819 100644
+index b3620f29e5..e70ef3dc91 100644
 --- a/qemu-img-cmds.hx
 +++ b/qemu-img-cmds.hx
 @@ -58,9 +58,9 @@ SRST
@@ -53,10 +53,10 @@ index b89c019b76..91d18a4819 100644
  
  DEF("info", img_info,
 diff --git a/qemu-img.c b/qemu-img.c
-index 45aa024acc..af54d0896e 100644
+index 7e6666b5f7..44cf942bd2 100644
 --- a/qemu-img.c
 +++ b/qemu-img.c
-@@ -4819,10 +4819,12 @@ static int img_bitmap(int argc, char **argv)
+@@ -4897,10 +4897,12 @@ static int img_bitmap(int argc, char **argv)
  #define C_IF      04
  #define C_OF      010
  #define C_SKIP    020
@@ -69,7 +69,7 @@ index 45aa024acc..af54d0896e 100644
  };
  
  struct DdIo {
-@@ -4898,6 +4900,19 @@ static int img_dd_skip(const char *arg,
+@@ -4976,6 +4978,19 @@ static int img_dd_skip(const char *arg,
      return 0;
  }
  
@@ -89,7 +89,7 @@ index 45aa024acc..af54d0896e 100644
  static int img_dd(int argc, char **argv)
  {
      int ret = 0;
-@@ -4938,6 +4953,7 @@ static int img_dd(int argc, char **argv)
+@@ -5016,6 +5031,7 @@ static int img_dd(int argc, char **argv)
          { "if", img_dd_if, C_IF },
          { "of", img_dd_of, C_OF },
          { "skip", img_dd_skip, C_SKIP },
@@ -97,7 +97,7 @@ index 45aa024acc..af54d0896e 100644
          { NULL, NULL, 0 }
      };
      const struct option long_options[] = {
-@@ -5016,8 +5032,13 @@ static int img_dd(int argc, char **argv)
+@@ -5094,8 +5110,13 @@ static int img_dd(int argc, char **argv)
          arg = NULL;
      }
  
@@ -113,7 +113,7 @@ index 45aa024acc..af54d0896e 100644
          ret = -1;
          goto out;
      }
-@@ -5029,85 +5050,101 @@ static int img_dd(int argc, char **argv)
+@@ -5107,85 +5128,101 @@ static int img_dd(int argc, char **argv)
          goto out;
      }
  
@@ -279,7 +279,7 @@ index 45aa024acc..af54d0896e 100644
      }
  
      if (dd.flags & C_SKIP && (in.offset > INT64_MAX / in.bsz ||
-@@ -5125,11 +5162,17 @@ static int img_dd(int argc, char **argv)
+@@ -5203,11 +5240,17 @@ static int img_dd(int argc, char **argv)
  
      for (out_pos = 0; in_pos < size; block_count++) {
          int in_ret, out_ret;
@@ -301,7 +301,7 @@ index 45aa024acc..af54d0896e 100644
          }
          if (in_ret < 0) {
              error_report("error while reading from input image file: %s",
-@@ -5139,9 +5182,13 @@ static int img_dd(int argc, char **argv)
+@@ -5217,9 +5260,13 @@ static int img_dd(int argc, char **argv)
          }
          in_pos += in_ret;
  
diff --git a/debian/patches/pve/0012-PVE-Up-qemu-img-dd-add-isize-parameter.patch b/debian/patches/pve/0012-PVE-Up-qemu-img-dd-add-isize-parameter.patch
index edcb94e..ff2ff47 100644
--- a/debian/patches/pve/0012-PVE-Up-qemu-img-dd-add-isize-parameter.patch
+++ b/debian/patches/pve/0012-PVE-Up-qemu-img-dd-add-isize-parameter.patch
@@ -15,10 +15,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
  1 file changed, 25 insertions(+), 3 deletions(-)
 
 diff --git a/qemu-img.c b/qemu-img.c
-index af54d0896e..0f1d464392 100644
+index 44cf942bd2..5ce60e8a45 100644
 --- a/qemu-img.c
 +++ b/qemu-img.c
-@@ -4820,11 +4820,13 @@ static int img_bitmap(int argc, char **argv)
+@@ -4898,11 +4898,13 @@ static int img_bitmap(int argc, char **argv)
  #define C_OF      010
  #define C_SKIP    020
  #define C_OSIZE   040
@@ -32,7 +32,7 @@ index af54d0896e..0f1d464392 100644
  };
  
  struct DdIo {
-@@ -4913,6 +4915,19 @@ static int img_dd_osize(const char *arg,
+@@ -4991,6 +4993,19 @@ static int img_dd_osize(const char *arg,
      return 0;
  }
  
@@ -52,7 +52,7 @@ index af54d0896e..0f1d464392 100644
  static int img_dd(int argc, char **argv)
  {
      int ret = 0;
-@@ -4927,12 +4942,14 @@ static int img_dd(int argc, char **argv)
+@@ -5005,12 +5020,14 @@ static int img_dd(int argc, char **argv)
      int c, i;
      const char *out_fmt = "raw";
      const char *fmt = NULL;
@@ -68,7 +68,7 @@ index af54d0896e..0f1d464392 100644
      };
      struct DdIo in = {
          .bsz = 512, /* Block size is by default 512 bytes */
-@@ -4954,6 +4971,7 @@ static int img_dd(int argc, char **argv)
+@@ -5032,6 +5049,7 @@ static int img_dd(int argc, char **argv)
          { "of", img_dd_of, C_OF },
          { "skip", img_dd_skip, C_SKIP },
          { "osize", img_dd_osize, C_OSIZE },
@@ -76,7 +76,7 @@ index af54d0896e..0f1d464392 100644
          { NULL, NULL, 0 }
      };
      const struct option long_options[] = {
-@@ -5160,14 +5178,18 @@ static int img_dd(int argc, char **argv)
+@@ -5238,14 +5256,18 @@ static int img_dd(int argc, char **argv)
  
      in.buf = g_new(uint8_t, in.bsz);
  
diff --git a/debian/patches/pve/0013-PVE-Up-qemu-img-dd-add-n-skip_create.patch b/debian/patches/pve/0013-PVE-Up-qemu-img-dd-add-n-skip_create.patch
index aca640b..3230c04 100644
--- a/debian/patches/pve/0013-PVE-Up-qemu-img-dd-add-n-skip_create.patch
+++ b/debian/patches/pve/0013-PVE-Up-qemu-img-dd-add-n-skip_create.patch
@@ -9,10 +9,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
  1 file changed, 14 insertions(+), 9 deletions(-)
 
 diff --git a/qemu-img.c b/qemu-img.c
-index 0f1d464392..9635e9c001 100644
+index 5ce60e8a45..86bfd0288b 100644
 --- a/qemu-img.c
 +++ b/qemu-img.c
-@@ -4944,7 +4944,7 @@ static int img_dd(int argc, char **argv)
+@@ -5022,7 +5022,7 @@ static int img_dd(int argc, char **argv)
      const char *fmt = NULL;
      int64_t size = 0, readsize = 0;
      int64_t block_count = 0, out_pos, in_pos;
@@ -21,7 +21,7 @@ index 0f1d464392..9635e9c001 100644
      struct DdInfo dd = {
          .flags = 0,
          .count = 0,
-@@ -4982,7 +4982,7 @@ static int img_dd(int argc, char **argv)
+@@ -5060,7 +5060,7 @@ static int img_dd(int argc, char **argv)
          { 0, 0, 0, 0 }
      };
  
@@ -30,7 +30,7 @@ index 0f1d464392..9635e9c001 100644
          if (c == EOF) {
              break;
          }
-@@ -5002,6 +5002,9 @@ static int img_dd(int argc, char **argv)
+@@ -5080,6 +5080,9 @@ static int img_dd(int argc, char **argv)
          case 'h':
              help();
              break;
@@ -40,7 +40,7 @@ index 0f1d464392..9635e9c001 100644
          case 'U':
              force_share = true;
              break;
-@@ -5142,13 +5145,15 @@ static int img_dd(int argc, char **argv)
+@@ -5220,13 +5223,15 @@ static int img_dd(int argc, char **argv)
                                  size - in.bsz * in.offset, &error_abort);
          }
  
diff --git a/debian/patches/pve/0014-PVE-virtio-balloon-improve-query-balloon.patch b/debian/patches/pve/0014-PVE-virtio-balloon-improve-query-balloon.patch
index dd83122..4bd835f 100644
--- a/debian/patches/pve/0014-PVE-virtio-balloon-improve-query-balloon.patch
+++ b/debian/patches/pve/0014-PVE-virtio-balloon-improve-query-balloon.patch
@@ -10,11 +10,11 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
 ---
  hw/virtio/virtio-balloon.c | 33 +++++++++++++++++++++++++++++++--
  monitor/hmp-cmds.c         | 30 +++++++++++++++++++++++++++++-
- qapi/misc.json             | 22 +++++++++++++++++++++-
+ qapi/machine.json          | 22 +++++++++++++++++++++-
  3 files changed, 81 insertions(+), 4 deletions(-)
 
 diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c
-index 22cb5df717..6513adb0a6 100644
+index b22b5beda3..6e581439bf 100644
 --- a/hw/virtio/virtio-balloon.c
 +++ b/hw/virtio/virtio-balloon.c
 @@ -805,8 +805,37 @@ static uint64_t virtio_balloon_get_features(VirtIODevice *vdev, uint64_t f,
@@ -58,10 +58,10 @@ index 22cb5df717..6513adb0a6 100644
  
  static void virtio_balloon_to_target(void *opaque, ram_addr_t target)
 diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
-index ae4b6a4246..6e26ea2cd0 100644
+index 65d8ff4849..705f08a8f1 100644
 --- a/monitor/hmp-cmds.c
 +++ b/monitor/hmp-cmds.c
-@@ -660,7 +660,35 @@ void hmp_info_balloon(Monitor *mon, const QDict *qdict)
+@@ -695,7 +695,35 @@ void hmp_info_balloon(Monitor *mon, const QDict *qdict)
          return;
      }
  
@@ -98,13 +98,13 @@ index ae4b6a4246..6e26ea2cd0 100644
  
      qapi_free_BalloonInfo(info);
  }
-diff --git a/qapi/misc.json b/qapi/misc.json
-index 9d32820dc1..44b1fb6fa7 100644
---- a/qapi/misc.json
-+++ b/qapi/misc.json
-@@ -226,10 +226,30 @@
- #
- # @actual: the number of bytes the balloon currently contains
+diff --git a/qapi/machine.json b/qapi/machine.json
+index 7c9a263778..3e59199280 100644
+--- a/qapi/machine.json
++++ b/qapi/machine.json
+@@ -1205,10 +1205,30 @@
+ # @actual: the logical size of the VM in bytes
+ #          Formula used: logical_vm_size = vm_ram_size - balloon_size
  #
 +# @last_update: time when stats got updated from guest
 +#
diff --git a/debian/patches/pve/0015-PVE-qapi-modify-query-machines.patch b/debian/patches/pve/0015-PVE-qapi-modify-query-machines.patch
index efb2984..8b403fa 100644
--- a/debian/patches/pve/0015-PVE-qapi-modify-query-machines.patch
+++ b/debian/patches/pve/0015-PVE-qapi-modify-query-machines.patch
@@ -13,7 +13,7 @@ Signed-off-by: Dietmar Maurer <dietmar at proxmox.com>
  2 files changed, 9 insertions(+), 1 deletion(-)
 
 diff --git a/hw/core/machine-qmp-cmds.c b/hw/core/machine-qmp-cmds.c
-index 963088b798..32f630549e 100644
+index 5362c80a18..3fcb82ce2f 100644
 --- a/hw/core/machine-qmp-cmds.c
 +++ b/hw/core/machine-qmp-cmds.c
 @@ -234,6 +234,12 @@ MachineInfoList *qmp_query_machines(Error **errp)
@@ -30,10 +30,10 @@ index 963088b798..32f630549e 100644
              info->default_cpu_type = g_strdup(mc->default_cpu_type);
              info->has_default_cpu_type = true;
 diff --git a/qapi/machine.json b/qapi/machine.json
-index 481b1f07ec..268044a34b 100644
+index 3e59199280..dfc1a49d3c 100644
 --- a/qapi/machine.json
 +++ b/qapi/machine.json
-@@ -342,6 +342,8 @@
+@@ -318,6 +318,8 @@
  #
  # @is-default: whether the machine is default
  #
@@ -42,12 +42,12 @@ index 481b1f07ec..268044a34b 100644
  # @cpu-max: maximum number of CPUs supported by the machine type
  #           (since 1.5.0)
  #
-@@ -361,7 +363,7 @@
+@@ -339,7 +341,7 @@
  ##
  { 'struct': 'MachineInfo',
    'data': { 'name': 'str', '*alias': 'str',
 -            '*is-default': 'bool', 'cpu-max': 'int',
 +            '*is-default': 'bool', '*is-current': 'bool', 'cpu-max': 'int',
              'hotpluggable-cpus': 'bool',  'numa-mem-supported': 'bool',
-             'deprecated': 'bool', '*default-cpu-type': 'str' } }
- 
+             'deprecated': 'bool', '*default-cpu-type': 'str',
+             '*default-ram-id': 'str' } }
diff --git a/debian/patches/pve/0016-PVE-qapi-modify-spice-query.patch b/debian/patches/pve/0016-PVE-qapi-modify-spice-query.patch
index e600590..437fc8e 100644
--- a/debian/patches/pve/0016-PVE-qapi-modify-spice-query.patch
+++ b/debian/patches/pve/0016-PVE-qapi-modify-spice-query.patch
@@ -12,10 +12,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
  2 files changed, 8 insertions(+)
 
 diff --git a/qapi/ui.json b/qapi/ui.json
-index 9d6721037f..af87b18db9 100644
+index 6c7b33cb72..39ff301d1e 100644
 --- a/qapi/ui.json
 +++ b/qapi/ui.json
-@@ -214,11 +214,14 @@
+@@ -215,11 +215,14 @@
  #
  # @channels: a list of @SpiceChannel for each active spice channel
  #
@@ -31,10 +31,10 @@ index 9d6721037f..af87b18db9 100644
    'if': 'defined(CONFIG_SPICE)' }
  
 diff --git a/ui/spice-core.c b/ui/spice-core.c
-index ca04965ead..243466c13d 100644
+index d09ee7f09e..da3d2644d1 100644
 --- a/ui/spice-core.c
 +++ b/ui/spice-core.c
-@@ -539,6 +539,11 @@ SpiceInfo *qmp_query_spice(Error **errp)
+@@ -538,6 +538,11 @@ static SpiceInfo *qmp_query_spice_real(Error **errp)
      micro = SPICE_SERVER_VERSION & 0xff;
      info->compiled_version = g_strdup_printf("%d.%d.%d", major, minor, micro);
  
diff --git a/debian/patches/pve/0017-PVE-internal-snapshot-async.patch b/debian/patches/pve/0017-PVE-internal-snapshot-async.patch
index 817aad4..3f6ef67 100644
--- a/debian/patches/pve/0017-PVE-internal-snapshot-async.patch
+++ b/debian/patches/pve/0017-PVE-internal-snapshot-async.patch
@@ -15,36 +15,22 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
 Signed-off-by: Dietmar Maurer <dietmar at proxmox.com>
 Signed-off-by: Wolfgang Bumiller <w.bumiller at proxmox.com>
 ---
- Makefile.objs                |   1 +
  hmp-commands-info.hx         |  13 +
  hmp-commands.hx              |  32 +++
- include/block/aio.h          |  10 +
  include/migration/snapshot.h |   1 +
  include/monitor/hmp.h        |   5 +
+ migration/meson.build        |   1 +
+ migration/savevm-async.c     | 542 +++++++++++++++++++++++++++++++++++
  monitor/hmp-cmds.c           |  57 ++++
  qapi/migration.json          |  34 +++
  qapi/misc.json               |  32 +++
  qemu-options.hx              |  12 +
- savevm-async.c               | 542 +++++++++++++++++++++++++++++++++++
  softmmu/vl.c                 |  10 +
- util/async.c                 |  30 ++
- 13 files changed, 779 insertions(+)
- create mode 100644 savevm-async.c
+ 11 files changed, 739 insertions(+)
+ create mode 100644 migration/savevm-async.c
 
-diff --git a/Makefile.objs b/Makefile.objs
-index d22b3b45d7..a1307c12a8 100644
---- a/Makefile.objs
-+++ b/Makefile.objs
-@@ -46,6 +46,7 @@ common-obj-y += bootdevice.o iothread.o
- common-obj-y += dump/
- common-obj-y += job-qmp.o
- common-obj-y += monitor/
-+common-obj-y += savevm-async.o
- common-obj-y += net/
- common-obj-y += qdev-monitor.o
- common-obj-$(CONFIG_WIN32) += os-win32.o
 diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx
-index 30209e3903..ae8ff21789 100644
+index 117ba25f91..b3b797ca28 100644
 --- a/hmp-commands-info.hx
 +++ b/hmp-commands-info.hx
 @@ -580,6 +580,19 @@ SRST
@@ -68,10 +54,10 @@ index 30209e3903..ae8ff21789 100644
          .name       = "balloon",
          .args_type  = "",
 diff --git a/hmp-commands.hx b/hmp-commands.hx
-index 60f395c276..2b58ac4a1c 100644
+index ff2d7aa8f3..d18b911969 100644
 --- a/hmp-commands.hx
 +++ b/hmp-commands.hx
-@@ -1829,3 +1829,35 @@ ERST
+@@ -1866,3 +1866,35 @@ ERST
          .flags      = "p",
      },
  
@@ -107,34 +93,6 @@ index 60f395c276..2b58ac4a1c 100644
 +        .help       = "Resume VM after snaphot.",
 +        .cmd = hmp_savevm_end,
 +    },
-diff --git a/include/block/aio.h b/include/block/aio.h
-index b2f703fa3f..c37617b404 100644
---- a/include/block/aio.h
-+++ b/include/block/aio.h
-@@ -17,6 +17,7 @@
- #ifdef CONFIG_LINUX_IO_URING
- #include <liburing.h>
- #endif
-+#include "qemu/coroutine.h"
- #include "qemu/queue.h"
- #include "qemu/event_notifier.h"
- #include "qemu/thread.h"
-@@ -654,6 +655,15 @@ static inline bool aio_node_check(AioContext *ctx, bool is_external)
-  */
- void aio_co_schedule(AioContext *ctx, struct Coroutine *co);
- 
-+/**
-+ * aio_co_reschedule_self:
-+ * @new_ctx: the new context
-+ *
-+ * Move the currently running coroutine to new_ctx. If the coroutine is already
-+ * running in new_ctx, do nothing.
-+ */
-+void coroutine_fn aio_co_reschedule_self(AioContext *new_ctx);
-+
- /**
-  * aio_co_wake:
-  * @co: the coroutine
 diff --git a/include/migration/snapshot.h b/include/migration/snapshot.h
 index c85b6ec75b..4411b7121d 100644
 --- a/include/migration/snapshot.h
@@ -147,7 +105,7 @@ index c85b6ec75b..4411b7121d 100644
  
  #endif
 diff --git a/include/monitor/hmp.h b/include/monitor/hmp.h
-index c986cfd28b..243952d32f 100644
+index ed2913fd18..4e06f89e8e 100644
 --- a/include/monitor/hmp.h
 +++ b/include/monitor/hmp.h
 @@ -25,6 +25,7 @@ void hmp_info_status(Monitor *mon, const QDict *qdict);
@@ -169,190 +127,23 @@ index c986cfd28b..243952d32f 100644
  void hmp_sendkey(Monitor *mon, const QDict *qdict);
  void hmp_screendump(Monitor *mon, const QDict *qdict);
  void hmp_chardev_add(Monitor *mon, const QDict *qdict);
-diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
-index 6e26ea2cd0..280bb447a6 100644
---- a/monitor/hmp-cmds.c
-+++ b/monitor/hmp-cmds.c
-@@ -1904,6 +1904,63 @@ void hmp_info_memory_devices(Monitor *mon, const QDict *qdict)
-     hmp_handle_error(mon, err);
- }
- 
-+void hmp_savevm_start(Monitor *mon, const QDict *qdict)
-+{
-+    Error *errp = NULL;
-+    const char *statefile = qdict_get_try_str(qdict, "statefile");
-+
-+    qmp_savevm_start(statefile != NULL, statefile, &errp);
-+    hmp_handle_error(mon, errp);
-+}
-+
-+void hmp_snapshot_drive(Monitor *mon, const QDict *qdict)
-+{
-+    Error *errp = NULL;
-+    const char *name = qdict_get_str(qdict, "name");
-+    const char *device = qdict_get_str(qdict, "device");
-+
-+    qmp_snapshot_drive(device, name, &errp);
-+    hmp_handle_error(mon, errp);
-+}
-+
-+void hmp_delete_drive_snapshot(Monitor *mon, const QDict *qdict)
-+{
-+    Error *errp = NULL;
-+    const char *name = qdict_get_str(qdict, "name");
-+    const char *device = qdict_get_str(qdict, "device");
-+
-+    qmp_delete_drive_snapshot(device, name, &errp);
-+    hmp_handle_error(mon, errp);
-+}
-+
-+void hmp_savevm_end(Monitor *mon, const QDict *qdict)
-+{
-+    Error *errp = NULL;
-+
-+    qmp_savevm_end(&errp);
-+    hmp_handle_error(mon, errp);
-+}
-+
-+void hmp_info_savevm(Monitor *mon, const QDict *qdict)
-+{
-+    SaveVMInfo *info;
-+    info = qmp_query_savevm(NULL);
-+
-+    if (info->has_status) {
-+        monitor_printf(mon, "savevm status: %s\n", info->status);
-+        monitor_printf(mon, "total time: %" PRIu64 " milliseconds\n",
-+                       info->total_time);
-+    } else {
-+        monitor_printf(mon, "savevm status: not running\n");
-+    }
-+    if (info->has_bytes) {
-+        monitor_printf(mon, "Bytes saved: %"PRIu64"\n", info->bytes);
-+    }
-+    if (info->has_error) {
-+        monitor_printf(mon, "Error: %s\n", info->error);
-+    }
-+}
-+
- void hmp_info_iothreads(Monitor *mon, const QDict *qdict)
- {
-     IOThreadInfoList *info_list = qmp_query_iothreads(NULL);
-diff --git a/qapi/migration.json b/qapi/migration.json
-index ea53b23dca..c556257544 100644
---- a/qapi/migration.json
-+++ b/qapi/migration.json
-@@ -225,6 +225,40 @@
-            '*compression': 'CompressionStats',
-            '*socket-address': ['SocketAddress'] } }
- 
-+##
-+# @SaveVMInfo:
-+#
-+# Information about current migration process.
-+#
-+# @status: string describing the current savevm status.
-+#          This can be 'active', 'completed', 'failed'.
-+#          If this field is not returned, no savevm process
-+#          has been initiated
-+#
-+# @error: string containing error message is status is failed.
-+#
-+# @total-time: total amount of milliseconds since savevm started.
-+#        If savevm has ended, it returns the total save time
-+#
-+# @bytes: total amount of data transfered
-+#
-+# Since: 1.3
-+##
-+{ 'struct': 'SaveVMInfo',
-+  'data': {'*status': 'str', '*error': 'str',
-+           '*total-time': 'int', '*bytes': 'int'} }
-+
-+##
-+# @query-savevm:
-+#
-+# Returns information about current savevm process.
-+#
-+# Returns: @SaveVMInfo
-+#
-+# Since: 1.3
-+##
-+{ 'command': 'query-savevm', 'returns': 'SaveVMInfo' }
-+
- ##
- # @query-migrate:
- #
-diff --git a/qapi/misc.json b/qapi/misc.json
-index 44b1fb6fa7..9895899f8b 100644
---- a/qapi/misc.json
-+++ b/qapi/misc.json
-@@ -1168,6 +1168,38 @@
- ##
- { 'command': 'query-fdsets', 'returns': ['FdsetInfo'] }
- 
-+##
-+# @savevm-start:
-+#
-+# Prepare for snapshot and halt VM. Save VM state to statefile.
-+#
-+##
-+{ 'command': 'savevm-start', 'data': { '*statefile': 'str' } }
-+
-+##
-+# @snapshot-drive:
-+#
-+# Create an internal drive snapshot.
-+#
-+##
-+{ 'command': 'snapshot-drive', 'data': { 'device': 'str', 'name': 'str' } }
-+
-+##
-+# @delete-drive-snapshot:
-+#
-+# Delete a drive snapshot.
-+#
-+##
-+{ 'command': 'delete-drive-snapshot', 'data': { 'device': 'str', 'name': 'str' } }
-+
-+##
-+# @savevm-end:
-+#
-+# Resume VM after a snapshot.
-+#
-+##
-+{ 'command': 'savevm-end' }
-+
- ##
- # @AcpiTableOptions:
- #
-diff --git a/qemu-options.hx b/qemu-options.hx
-index 708583b4ce..d32995cc50 100644
---- a/qemu-options.hx
-+++ b/qemu-options.hx
-@@ -3866,6 +3866,18 @@ SRST
-     Start right away with a saved state (``loadvm`` in monitor)
- ERST
- 
-+DEF("loadstate", HAS_ARG, QEMU_OPTION_loadstate, \
-+    "-loadstate file\n" \
-+    "                start right away with a saved state\n",
-+    QEMU_ARCH_ALL)
-+SRST
-+``-loadstate file``
-+  Start right away with a saved state. This option does not rollback
-+  disk state like @code{loadvm}, so user must make sure that disk
-+  have correct state. @var{file} can be any valid device URL. See the section
-+  for "Device URL Syntax" for more information.
-+ERST
-+
- #ifndef _WIN32
- DEF("daemonize", 0, QEMU_OPTION_daemonize, \
-     "-daemonize      daemonize QEMU after initializing\n", QEMU_ARCH_ALL)
-diff --git a/savevm-async.c b/savevm-async.c
+diff --git a/migration/meson.build b/migration/meson.build
+index 980e37865c..e62b79b60f 100644
+--- a/migration/meson.build
++++ b/migration/meson.build
+@@ -23,6 +23,7 @@ softmmu_ss.add(files(
+   'multifd-zlib.c',
+   'postcopy-ram.c',
+   'savevm.c',
++  'savevm-async.c',
+   'socket.c',
+   'tls.c',
+ ))
+diff --git a/migration/savevm-async.c b/migration/savevm-async.c
 new file mode 100644
 index 0000000000..f918e18dce
 --- /dev/null
-+++ b/savevm-async.c
++++ b/migration/savevm-async.c
 @@ -0,0 +1,542 @@
 +#include "qemu/osdep.h"
 +#include "migration/migration.h"
@@ -896,11 +687,190 @@ index 0000000000..f918e18dce
 +    }
 +    return ret;
 +}
+diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
+index 705f08a8f1..e71e4f2929 100644
+--- a/monitor/hmp-cmds.c
++++ b/monitor/hmp-cmds.c
+@@ -1949,6 +1949,63 @@ void hmp_info_memory_devices(Monitor *mon, const QDict *qdict)
+     hmp_handle_error(mon, err);
+ }
+ 
++void hmp_savevm_start(Monitor *mon, const QDict *qdict)
++{
++    Error *errp = NULL;
++    const char *statefile = qdict_get_try_str(qdict, "statefile");
++
++    qmp_savevm_start(statefile != NULL, statefile, &errp);
++    hmp_handle_error(mon, errp);
++}
++
++void hmp_snapshot_drive(Monitor *mon, const QDict *qdict)
++{
++    Error *errp = NULL;
++    const char *name = qdict_get_str(qdict, "name");
++    const char *device = qdict_get_str(qdict, "device");
++
++    qmp_snapshot_drive(device, name, &errp);
++    hmp_handle_error(mon, errp);
++}
++
++void hmp_delete_drive_snapshot(Monitor *mon, const QDict *qdict)
++{
++    Error *errp = NULL;
++    const char *name = qdict_get_str(qdict, "name");
++    const char *device = qdict_get_str(qdict, "device");
++
++    qmp_delete_drive_snapshot(device, name, &errp);
++    hmp_handle_error(mon, errp);
++}
++
++void hmp_savevm_end(Monitor *mon, const QDict *qdict)
++{
++    Error *errp = NULL;
++
++    qmp_savevm_end(&errp);
++    hmp_handle_error(mon, errp);
++}
++
++void hmp_info_savevm(Monitor *mon, const QDict *qdict)
++{
++    SaveVMInfo *info;
++    info = qmp_query_savevm(NULL);
++
++    if (info->has_status) {
++        monitor_printf(mon, "savevm status: %s\n", info->status);
++        monitor_printf(mon, "total time: %" PRIu64 " milliseconds\n",
++                       info->total_time);
++    } else {
++        monitor_printf(mon, "savevm status: not running\n");
++    }
++    if (info->has_bytes) {
++        monitor_printf(mon, "Bytes saved: %"PRIu64"\n", info->bytes);
++    }
++    if (info->has_error) {
++        monitor_printf(mon, "Error: %s\n", info->error);
++    }
++}
++
+ void hmp_info_iothreads(Monitor *mon, const QDict *qdict)
+ {
+     IOThreadInfoList *info_list = qmp_query_iothreads(NULL);
+diff --git a/qapi/migration.json b/qapi/migration.json
+index 3c75820527..72cc490697 100644
+--- a/qapi/migration.json
++++ b/qapi/migration.json
+@@ -242,6 +242,40 @@
+            '*compression': 'CompressionStats',
+            '*socket-address': ['SocketAddress'] } }
+ 
++##
++# @SaveVMInfo:
++#
++# Information about current migration process.
++#
++# @status: string describing the current savevm status.
++#          This can be 'active', 'completed', 'failed'.
++#          If this field is not returned, no savevm process
++#          has been initiated
++#
++# @error: string containing error message is status is failed.
++#
++# @total-time: total amount of milliseconds since savevm started.
++#        If savevm has ended, it returns the total save time
++#
++# @bytes: total amount of data transfered
++#
++# Since: 1.3
++##
++{ 'struct': 'SaveVMInfo',
++  'data': {'*status': 'str', '*error': 'str',
++           '*total-time': 'int', '*bytes': 'int'} }
++
++##
++# @query-savevm:
++#
++# Returns information about current savevm process.
++#
++# Returns: @SaveVMInfo
++#
++# Since: 1.3
++##
++{ 'command': 'query-savevm', 'returns': 'SaveVMInfo' }
++
+ ##
+ # @query-migrate:
+ #
+diff --git a/qapi/misc.json b/qapi/misc.json
+index 40df513856..b7e132698e 100644
+--- a/qapi/misc.json
++++ b/qapi/misc.json
+@@ -476,6 +476,38 @@
+ ##
+ { 'command': 'query-fdsets', 'returns': ['FdsetInfo'] }
+ 
++##
++# @savevm-start:
++#
++# Prepare for snapshot and halt VM. Save VM state to statefile.
++#
++##
++{ 'command': 'savevm-start', 'data': { '*statefile': 'str' } }
++
++##
++# @snapshot-drive:
++#
++# Create an internal drive snapshot.
++#
++##
++{ 'command': 'snapshot-drive', 'data': { 'device': 'str', 'name': 'str' } }
++
++##
++# @delete-drive-snapshot:
++#
++# Delete a drive snapshot.
++#
++##
++{ 'command': 'delete-drive-snapshot', 'data': { 'device': 'str', 'name': 'str' } }
++
++##
++# @savevm-end:
++#
++# Resume VM after a snapshot.
++#
++##
++{ 'command': 'savevm-end' }
++
+ ##
+ # @CommandLineParameterType:
+ #
+diff --git a/qemu-options.hx b/qemu-options.hx
+index 104632ea34..c1352312c2 100644
+--- a/qemu-options.hx
++++ b/qemu-options.hx
+@@ -3903,6 +3903,18 @@ SRST
+     Start right away with a saved state (``loadvm`` in monitor)
+ ERST
+ 
++DEF("loadstate", HAS_ARG, QEMU_OPTION_loadstate, \
++    "-loadstate file\n" \
++    "                start right away with a saved state\n",
++    QEMU_ARCH_ALL)
++SRST
++``-loadstate file``
++  Start right away with a saved state. This option does not rollback
++  disk state like @code{loadvm}, so user must make sure that disk
++  have correct state. @var{file} can be any valid device URL. See the section
++  for "Device URL Syntax" for more information.
++ERST
++
+ #ifndef _WIN32
+ DEF("daemonize", 0, QEMU_OPTION_daemonize, \
+     "-daemonize      daemonize QEMU after initializing\n", QEMU_ARCH_ALL)
 diff --git a/softmmu/vl.c b/softmmu/vl.c
-index 4eb9d1f7fd..670b7e427c 100644
+index e6e0ad5a92..03152c816c 100644
 --- a/softmmu/vl.c
 +++ b/softmmu/vl.c
-@@ -2844,6 +2844,7 @@ void qemu_init(int argc, char **argv, char **envp)
+@@ -2878,6 +2878,7 @@ void qemu_init(int argc, char **argv, char **envp)
      int optind;
      const char *optarg;
      const char *loadvm = NULL;
@@ -908,7 +878,7 @@ index 4eb9d1f7fd..670b7e427c 100644
      MachineClass *machine_class;
      const char *cpu_option;
      const char *vga_model = NULL;
-@@ -3408,6 +3409,9 @@ void qemu_init(int argc, char **argv, char **envp)
+@@ -3439,6 +3440,9 @@ void qemu_init(int argc, char **argv, char **envp)
              case QEMU_OPTION_loadvm:
                  loadvm = optarg;
                  break;
@@ -918,7 +888,7 @@ index 4eb9d1f7fd..670b7e427c 100644
              case QEMU_OPTION_full_screen:
                  dpy.has_full_screen = true;
                  dpy.full_screen = true;
-@@ -4464,6 +4468,12 @@ void qemu_init(int argc, char **argv, char **envp)
+@@ -4478,6 +4482,12 @@ void qemu_init(int argc, char **argv, char **envp)
              autostart = 0;
              exit(1);
          }
@@ -931,44 +901,3 @@ index 4eb9d1f7fd..670b7e427c 100644
      }
      if (replay_mode != REPLAY_MODE_NONE) {
          replay_vmstate_init();
-diff --git a/util/async.c b/util/async.c
-index 1319eee3bc..b68e73f488 100644
---- a/util/async.c
-+++ b/util/async.c
-@@ -559,6 +559,36 @@ void aio_co_schedule(AioContext *ctx, Coroutine *co)
-     aio_context_unref(ctx);
- }
- 
-+typedef struct AioCoRescheduleSelf {
-+    Coroutine *co;
-+    AioContext *new_ctx;
-+} AioCoRescheduleSelf;
-+
-+static void aio_co_reschedule_self_bh(void *opaque)
-+{
-+    AioCoRescheduleSelf *data = opaque;
-+    aio_co_schedule(data->new_ctx, data->co);
-+}
-+
-+void coroutine_fn aio_co_reschedule_self(AioContext *new_ctx)
-+{
-+    AioContext *old_ctx = qemu_get_current_aio_context();
-+
-+    if (old_ctx != new_ctx) {
-+        AioCoRescheduleSelf data = {
-+            .co = qemu_coroutine_self(),
-+            .new_ctx = new_ctx,
-+        };
-+        /*
-+         * We can't directly schedule the coroutine in the target context
-+         * because this would be racy: The other thread could try to enter the
-+         * coroutine before it has yielded in this one.
-+         */
-+        aio_bh_schedule_oneshot(old_ctx, aio_co_reschedule_self_bh, &data);
-+        qemu_coroutine_yield();
-+    }
-+}
-+
- void aio_co_wake(struct Coroutine *co)
- {
-     AioContext *ctx;
diff --git a/debian/patches/pve/0018-add-optional-buffer-size-to-QEMUFile.patch b/debian/patches/pve/0018-add-optional-buffer-size-to-QEMUFile.patch
index efa45af..f83e3a8 100644
--- a/debian/patches/pve/0018-add-optional-buffer-size-to-QEMUFile.patch
+++ b/debian/patches/pve/0018-add-optional-buffer-size-to-QEMUFile.patch
@@ -8,9 +8,9 @@ increase performance storing the state onto ceph.
 
 Signed-off-by: Wolfgang Bumiller <w.bumiller at proxmox.com>
 ---
- migration/qemu-file.c | 36 ++++++++++++++++++++++++------------
- migration/qemu-file.h |  1 +
- savevm-async.c        |  4 ++--
+ migration/qemu-file.c    | 36 ++++++++++++++++++++++++------------
+ migration/qemu-file.h    |  1 +
+ migration/savevm-async.c |  4 ++--
  3 files changed, 27 insertions(+), 14 deletions(-)
 
 diff --git a/migration/qemu-file.c b/migration/qemu-file.c
@@ -159,10 +159,10 @@ index a9b6d6ccb7..8752d27c74 100644
  void qemu_file_set_hooks(QEMUFile *f, const QEMUFileHooks *hooks);
  int qemu_get_fd(QEMUFile *f);
  int qemu_fclose(QEMUFile *f);
-diff --git a/savevm-async.c b/savevm-async.c
+diff --git a/migration/savevm-async.c b/migration/savevm-async.c
 index f918e18dce..156b7a030e 100644
---- a/savevm-async.c
-+++ b/savevm-async.c
+--- a/migration/savevm-async.c
++++ b/migration/savevm-async.c
 @@ -392,7 +392,7 @@ void qmp_savevm_start(bool has_statefile, const char *statefile, Error **errp)
          goto restart;
      }
diff --git a/debian/patches/pve/0019-PVE-block-add-the-zeroinit-block-driver-filter.patch b/debian/patches/pve/0019-PVE-block-add-the-zeroinit-block-driver-filter.patch
index 7c24b16..ce302e8 100644
--- a/debian/patches/pve/0019-PVE-block-add-the-zeroinit-block-driver-filter.patch
+++ b/debian/patches/pve/0019-PVE-block-add-the-zeroinit-block-driver-filter.patch
@@ -5,29 +5,29 @@ Subject: [PATCH] PVE: block: add the zeroinit block driver filter
 
 Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
 ---
- block/Makefile.objs |   1 +
- block/zeroinit.c    | 198 ++++++++++++++++++++++++++++++++++++++++++++
- 2 files changed, 199 insertions(+)
+ block/meson.build |   1 +
+ block/zeroinit.c  | 196 ++++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 197 insertions(+)
  create mode 100644 block/zeroinit.c
 
-diff --git a/block/Makefile.objs b/block/Makefile.objs
-index 19c6f371c9..d1a9227b8f 100644
---- a/block/Makefile.objs
-+++ b/block/Makefile.objs
-@@ -11,6 +11,7 @@ block-obj-$(CONFIG_QED) += qed.o qed-l2-cache.o qed-table.o qed-cluster.o
- block-obj-$(CONFIG_QED) += qed-check.o
- block-obj-y += vhdx.o vhdx-endian.o vhdx-log.o
- block-obj-y += quorum.o
-+block-obj-y += zeroinit.o
- block-obj-y += blkdebug.o blkverify.o blkreplay.o
- block-obj-$(CONFIG_PARALLELS) += parallels.o
- block-obj-y += blklogwrites.o
+diff --git a/block/meson.build b/block/meson.build
+index 5dcc1e5cce..c10d544864 100644
+--- a/block/meson.build
++++ b/block/meson.build
+@@ -39,6 +39,7 @@ block_ss.add(files(
+   'vmdk.c',
+   'vpc.c',
+   'write-threshold.c',
++  'zeroinit.c',
+ ), zstd, zlib)
+ 
+ softmmu_ss.add(when: 'CONFIG_TCG', if_true: files('blkreplay.c'))
 diff --git a/block/zeroinit.c b/block/zeroinit.c
 new file mode 100644
-index 0000000000..4fbb80eab0
+index 0000000000..5529627f7e
 --- /dev/null
 +++ b/block/zeroinit.c
-@@ -0,0 +1,198 @@
+@@ -0,0 +1,196 @@
 +/*
 + * Filter to fake a zero-initialized block device.
 + *
@@ -212,8 +212,6 @@ index 0000000000..4fbb80eab0
 +
 +    .bdrv_has_zero_init               = zeroinit_has_zero_init,
 +
-+    .bdrv_co_block_status             = bdrv_co_block_status_from_file,
-+
 +    .bdrv_co_pdiscard                 = zeroinit_co_pdiscard,
 +
 +    .bdrv_co_truncate                 = zeroinit_co_truncate,
diff --git a/debian/patches/pve/0020-PVE-Add-dummy-id-command-line-parameter.patch b/debian/patches/pve/0020-PVE-Add-dummy-id-command-line-parameter.patch
index aa56372..73ded0c 100644
--- a/debian/patches/pve/0020-PVE-Add-dummy-id-command-line-parameter.patch
+++ b/debian/patches/pve/0020-PVE-Add-dummy-id-command-line-parameter.patch
@@ -14,10 +14,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
  2 files changed, 11 insertions(+)
 
 diff --git a/qemu-options.hx b/qemu-options.hx
-index d32995cc50..abfde19ce0 100644
+index c1352312c2..9a0cb6780e 100644
 --- a/qemu-options.hx
 +++ b/qemu-options.hx
-@@ -914,6 +914,9 @@ DEFHEADING()
+@@ -906,6 +906,9 @@ DEFHEADING()
  
  DEFHEADING(Block device options:)
  
@@ -28,10 +28,10 @@ index d32995cc50..abfde19ce0 100644
      "-fda/-fdb file  use 'file' as floppy disk 0/1 image\n", QEMU_ARCH_ALL)
  DEF("fdb", HAS_ARG, QEMU_OPTION_fdb, "", QEMU_ARCH_ALL)
 diff --git a/softmmu/vl.c b/softmmu/vl.c
-index 670b7e427c..366e30e594 100644
+index 03152c816c..da204d24f0 100644
 --- a/softmmu/vl.c
 +++ b/softmmu/vl.c
-@@ -2832,6 +2832,7 @@ static void create_default_memdev(MachineState *ms, const char *path)
+@@ -2866,6 +2866,7 @@ static char *find_datadir(void)
  void qemu_init(int argc, char **argv, char **envp)
  {
      int i;
@@ -39,7 +39,7 @@ index 670b7e427c..366e30e594 100644
      int snapshot, linux_boot;
      const char *initrd_filename;
      const char *kernel_filename, *kernel_cmdline;
-@@ -3530,6 +3531,13 @@ void qemu_init(int argc, char **argv, char **envp)
+@@ -3557,6 +3558,13 @@ void qemu_init(int argc, char **argv, char **envp)
                      exit(1);
                  }
                  break;
diff --git a/debian/patches/pve/0021-PVE-Config-Revert-target-i386-disable-LINT0-after-re.patch b/debian/patches/pve/0021-PVE-Config-Revert-target-i386-disable-LINT0-after-re.patch
index f6d39fa..bc3d98b 100644
--- a/debian/patches/pve/0021-PVE-Config-Revert-target-i386-disable-LINT0-after-re.patch
+++ b/debian/patches/pve/0021-PVE-Config-Revert-target-i386-disable-LINT0-after-re.patch
@@ -11,7 +11,7 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
  1 file changed, 9 insertions(+)
 
 diff --git a/hw/intc/apic_common.c b/hw/intc/apic_common.c
-index 81addd6390..c2026b07c5 100644
+index 502e94effc..590ef6ec8e 100644
 --- a/hw/intc/apic_common.c
 +++ b/hw/intc/apic_common.c
 @@ -278,6 +278,15 @@ static void apic_reset_common(DeviceState *dev)
diff --git a/debian/patches/pve/0022-PVE-Up-Config-file-posix-make-locking-optiono-on-cre.patch b/debian/patches/pve/0022-PVE-Up-Config-file-posix-make-locking-optiono-on-cre.patch
index 271e5df..52c0046 100644
--- a/debian/patches/pve/0022-PVE-Up-Config-file-posix-make-locking-optiono-on-cre.patch
+++ b/debian/patches/pve/0022-PVE-Up-Config-file-posix-make-locking-optiono-on-cre.patch
@@ -13,10 +13,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
  2 files changed, 43 insertions(+), 21 deletions(-)
 
 diff --git a/block/file-posix.c b/block/file-posix.c
-index bb72e1e5ca..914bd1f367 100644
+index bda3e606dc..037839622e 100644
 --- a/block/file-posix.c
 +++ b/block/file-posix.c
-@@ -2390,6 +2390,7 @@ raw_co_create(BlockdevCreateOptions *options, Error **errp)
+@@ -2388,6 +2388,7 @@ raw_co_create(BlockdevCreateOptions *options, Error **errp)
      int fd;
      uint64_t perm, shared;
      int result = 0;
@@ -24,7 +24,7 @@ index bb72e1e5ca..914bd1f367 100644
  
      /* Validate options and set default values */
      assert(options->driver == BLOCKDEV_DRIVER_FILE);
-@@ -2431,19 +2432,22 @@ raw_co_create(BlockdevCreateOptions *options, Error **errp)
+@@ -2428,19 +2429,22 @@ raw_co_create(BlockdevCreateOptions *options, Error **errp)
      perm = BLK_PERM_WRITE | BLK_PERM_RESIZE;
      shared = BLK_PERM_ALL & ~BLK_PERM_RESIZE;
  
@@ -59,7 +59,7 @@ index bb72e1e5ca..914bd1f367 100644
      }
  
      /* Clear the file by truncating it to 0 */
-@@ -2497,13 +2501,15 @@ raw_co_create(BlockdevCreateOptions *options, Error **errp)
+@@ -2494,13 +2498,15 @@ raw_co_create(BlockdevCreateOptions *options, Error **errp)
      }
  
  out_unlock:
@@ -82,7 +82,7 @@ index bb72e1e5ca..914bd1f367 100644
      }
  
  out_close:
-@@ -2528,6 +2534,7 @@ static int coroutine_fn raw_co_create_opts(BlockDriver *drv,
+@@ -2525,6 +2531,7 @@ static int coroutine_fn raw_co_create_opts(BlockDriver *drv,
      PreallocMode prealloc;
      char *buf = NULL;
      Error *local_err = NULL;
@@ -90,7 +90,7 @@ index bb72e1e5ca..914bd1f367 100644
  
      /* Skip file: protocol prefix */
      strstart(filename, "file:", &filename);
-@@ -2550,6 +2557,18 @@ static int coroutine_fn raw_co_create_opts(BlockDriver *drv,
+@@ -2547,6 +2554,18 @@ static int coroutine_fn raw_co_create_opts(BlockDriver *drv,
          return -EINVAL;
      }
  
@@ -109,7 +109,7 @@ index bb72e1e5ca..914bd1f367 100644
      options = (BlockdevCreateOptions) {
          .driver     = BLOCKDEV_DRIVER_FILE,
          .u.file     = {
-@@ -2561,6 +2580,8 @@ static int coroutine_fn raw_co_create_opts(BlockDriver *drv,
+@@ -2558,6 +2577,8 @@ static int coroutine_fn raw_co_create_opts(BlockDriver *drv,
              .nocow              = nocow,
              .has_extent_size_hint = has_extent_size_hint,
              .extent_size_hint   = extent_size_hint,
@@ -118,7 +118,7 @@ index bb72e1e5ca..914bd1f367 100644
          },
      };
      return raw_co_create(&options, errp);
-@@ -3107,7 +3128,7 @@ static int raw_check_perm(BlockDriverState *bs, uint64_t perm, uint64_t shared,
+@@ -3104,7 +3125,7 @@ static int raw_check_perm(BlockDriverState *bs, uint64_t perm, uint64_t shared,
      }
  
      /* Copy locks to the new fd */
@@ -128,10 +128,10 @@ index bb72e1e5ca..914bd1f367 100644
                                     false, errp);
          if (ret < 0) {
 diff --git a/qapi/block-core.json b/qapi/block-core.json
-index 197bdc1c36..ea5fae22ae 100644
+index 04ad80bc1e..7957b9867d 100644
 --- a/qapi/block-core.json
 +++ b/qapi/block-core.json
-@@ -4178,7 +4178,8 @@
+@@ -4203,7 +4203,8 @@
              'size':                 'size',
              '*preallocation':       'PreallocMode',
              '*nocow':               'bool',
diff --git a/debian/patches/pve/0023-PVE-monitor-disable-oob-capability.patch b/debian/patches/pve/0023-PVE-monitor-disable-oob-capability.patch
index c509f78..f51c112 100644
--- a/debian/patches/pve/0023-PVE-monitor-disable-oob-capability.patch
+++ b/debian/patches/pve/0023-PVE-monitor-disable-oob-capability.patch
@@ -18,10 +18,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
  1 file changed, 1 insertion(+), 2 deletions(-)
 
 diff --git a/monitor/qmp.c b/monitor/qmp.c
-index d433ceae5b..a16cf3532d 100644
+index b42f8c6af3..2e37d11bd3 100644
 --- a/monitor/qmp.c
 +++ b/monitor/qmp.c
-@@ -409,8 +409,7 @@ void monitor_init_qmp(Chardev *chr, bool pretty, Error **errp)
+@@ -466,8 +466,7 @@ void monitor_init_qmp(Chardev *chr, bool pretty, Error **errp)
      qemu_chr_fe_set_echo(&mon->common.chr, true);
  
      /* Note: we run QMP monitor in I/O thread when @chr supports that */
diff --git a/debian/patches/pve/0024-PVE-Compat-4.0-used-balloon-qemu-4-0-config-size-fal.patch b/debian/patches/pve/0024-PVE-Compat-4.0-used-balloon-qemu-4-0-config-size-fal.patch
index a7b4c00..e183b57 100644
--- a/debian/patches/pve/0024-PVE-Compat-4.0-used-balloon-qemu-4-0-config-size-fal.patch
+++ b/debian/patches/pve/0024-PVE-Compat-4.0-used-balloon-qemu-4-0-config-size-fal.patch
@@ -26,10 +26,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
  1 file changed, 2 insertions(+), 1 deletion(-)
 
 diff --git a/hw/core/machine.c b/hw/core/machine.c
-index 8d1a90c6cf..413902777e 100644
+index d0408049b5..5b38cf9356 100644
 --- a/hw/core/machine.c
 +++ b/hw/core/machine.c
-@@ -66,7 +66,8 @@ GlobalProperty hw_compat_4_0[] = {
+@@ -78,7 +78,8 @@ GlobalProperty hw_compat_4_0[] = {
      { "virtio-vga",     "edid", "false" },
      { "virtio-gpu-device", "edid", "false" },
      { "virtio-device", "use-started", "false" },
diff --git a/debian/patches/pve/0025-PVE-Allow-version-code-in-machine-type.patch b/debian/patches/pve/0025-PVE-Allow-version-code-in-machine-type.patch
index 3cf1e2f..d4b350b 100644
--- a/debian/patches/pve/0025-PVE-Allow-version-code-in-machine-type.patch
+++ b/debian/patches/pve/0025-PVE-Allow-version-code-in-machine-type.patch
@@ -13,12 +13,12 @@ Signed-off-by: Stefan Reiter <s.reiter at proxmox.com>
 ---
  hw/core/machine-qmp-cmds.c |  6 ++++++
  include/hw/boards.h        |  2 ++
- qapi/machine.json          |  3 ++-
+ qapi/machine.json          |  4 +++-
  softmmu/vl.c               | 15 ++++++++++++++-
- 4 files changed, 24 insertions(+), 2 deletions(-)
+ 4 files changed, 25 insertions(+), 2 deletions(-)
 
 diff --git a/hw/core/machine-qmp-cmds.c b/hw/core/machine-qmp-cmds.c
-index 32f630549e..71e19db4e1 100644
+index 3fcb82ce2f..7868241bd5 100644
 --- a/hw/core/machine-qmp-cmds.c
 +++ b/hw/core/machine-qmp-cmds.c
 @@ -238,6 +238,12 @@ MachineInfoList *qmp_query_machines(Error **errp)
@@ -35,10 +35,10 @@ index 32f630549e..71e19db4e1 100644
  
          if (mc->default_cpu_type) {
 diff --git a/include/hw/boards.h b/include/hw/boards.h
-index 426ce5f625..3bce25a25f 100644
+index a49e3a6b44..8e0a8c5571 100644
 --- a/include/hw/boards.h
 +++ b/include/hw/boards.h
-@@ -170,6 +170,8 @@ struct MachineClass {
+@@ -165,6 +165,8 @@ struct MachineClass {
      const char *desc;
      const char *deprecation_reason;
  
@@ -48,24 +48,32 @@ index 426ce5f625..3bce25a25f 100644
      void (*reset)(MachineState *state);
      void (*wakeup)(MachineState *state);
 diff --git a/qapi/machine.json b/qapi/machine.json
-index 268044a34b..7a811a5860 100644
+index dfc1a49d3c..32fc674042 100644
 --- a/qapi/machine.json
 +++ b/qapi/machine.json
-@@ -365,7 +365,8 @@
-   'data': { 'name': 'str', '*alias': 'str',
+@@ -337,6 +337,8 @@
+ #
+ # @default-ram-id: the default ID of initial RAM memory backend (since 5.2)
+ #
++# @pve-version: custom PVE version suffix specified as 'machine+pveN'
++#
+ # Since: 1.2.0
+ ##
+ { 'struct': 'MachineInfo',
+@@ -344,7 +346,7 @@
              '*is-default': 'bool', '*is-current': 'bool', 'cpu-max': 'int',
              'hotpluggable-cpus': 'bool',  'numa-mem-supported': 'bool',
--            'deprecated': 'bool', '*default-cpu-type': 'str' } }
-+            'deprecated': 'bool', '*default-cpu-type': 'str',
-+            '*pve-version': 'str' } }
+             'deprecated': 'bool', '*default-cpu-type': 'str',
+-            '*default-ram-id': 'str' } }
++            '*default-ram-id': 'str', '*pve-version': 'str' } }
  
  ##
  # @query-machines:
 diff --git a/softmmu/vl.c b/softmmu/vl.c
-index 366e30e594..16aa2186b0 100644
+index da204d24f0..5b5512128e 100644
 --- a/softmmu/vl.c
 +++ b/softmmu/vl.c
-@@ -2322,6 +2322,8 @@ static MachineClass *machine_parse(const char *name, GSList *machines)
+@@ -2325,6 +2325,8 @@ static MachineClass *machine_parse(const char *name, GSList *machines)
  {
      MachineClass *mc;
      GSList *el;
@@ -74,7 +82,7 @@ index 366e30e594..16aa2186b0 100644
  
      if (is_help_option(name)) {
          printf("Supported machines are:\n");
-@@ -2338,12 +2340,23 @@ static MachineClass *machine_parse(const char *name, GSList *machines)
+@@ -2341,12 +2343,23 @@ static MachineClass *machine_parse(const char *name, GSList *machines)
          exit(0);
      }
  
diff --git a/debian/patches/pve/0026-PVE-Backup-add-vma-backup-format-code.patch b/debian/patches/pve/0026-PVE-Backup-add-vma-backup-format-code.patch
index bbc4562..14d4da2 100644
--- a/debian/patches/pve/0026-PVE-Backup-add-vma-backup-format-code.patch
+++ b/debian/patches/pve/0026-PVE-Backup-add-vma-backup-format-code.patch
@@ -4,51 +4,68 @@ Date: Mon, 6 Apr 2020 12:16:57 +0200
 Subject: [PATCH] PVE-Backup: add vma backup format code
 
 ---
- Makefile      |   3 +-
- Makefile.objs |   1 +
- vma-reader.c  | 857 ++++++++++++++++++++++++++++++++++++++++++++++++++
- vma-writer.c  | 790 ++++++++++++++++++++++++++++++++++++++++++++++
- vma.c         | 839 ++++++++++++++++++++++++++++++++++++++++++++++++
- vma.h         | 150 +++++++++
- 6 files changed, 2639 insertions(+), 1 deletion(-)
+ block/meson.build   |   2 +
+ meson.build         |   5 +
+ qapi/migration.json |   2 +-
+ vma-reader.c        | 857 ++++++++++++++++++++++++++++++++++++++++++++
+ vma-writer.c        | 790 ++++++++++++++++++++++++++++++++++++++++
+ vma.c               | 839 +++++++++++++++++++++++++++++++++++++++++++
+ vma.h               | 150 ++++++++
+ 7 files changed, 2644 insertions(+), 1 deletion(-)
  create mode 100644 vma-reader.c
  create mode 100644 vma-writer.c
  create mode 100644 vma.c
  create mode 100644 vma.h
 
-diff --git a/Makefile b/Makefile
-index 13dd708c4a..7b8c17ce2d 100644
---- a/Makefile
-+++ b/Makefile
-@@ -479,7 +479,7 @@ dummy := $(call unnest-vars,, \
+diff --git a/block/meson.build b/block/meson.build
+index c10d544864..feffbc8623 100644
+--- a/block/meson.build
++++ b/block/meson.build
+@@ -42,6 +42,8 @@ block_ss.add(files(
+   'zeroinit.c',
+ ), zstd, zlib)
  
- include $(SRC_PATH)/tests/Makefile.include
++block_ss.add(files('../vma-writer.c'), libuuid)
++
+ softmmu_ss.add(when: 'CONFIG_TCG', if_true: files('blkreplay.c'))
  
--all: $(DOCS) $(if $(BUILD_DOCS),sphinxdocs) $(TOOLS) $(HELPERS-y) recurse-all modules $(vhost-user-json-y)
-+all: $(DOCS) $(if $(BUILD_DOCS),sphinxdocs) $(TOOLS) vma$(EXESUF) $(HELPERS-y) recurse-all modules $(vhost-user-json-y)
+ block_ss.add(when: 'CONFIG_QCOW1', if_true: files('qcow.c'))
+diff --git a/meson.build b/meson.build
+index e3386196ba..d5b660516b 100644
+--- a/meson.build
++++ b/meson.build
+@@ -725,6 +725,8 @@ keyutils = dependency('libkeyutils', required: false,
  
- qemu-version.h: FORCE
- 	$(call quiet-command, \
-@@ -602,6 +602,7 @@ qemu-img$(EXESUF): qemu-img.o $(authz-obj-y) $(block-obj-y) $(crypto-obj-y) $(io
- qemu-nbd$(EXESUF): qemu-nbd.o $(authz-obj-y) $(block-obj-y) $(crypto-obj-y) $(io-obj-y) $(qom-obj-y) $(COMMON_LDADDS)
- qemu-io$(EXESUF): qemu-io.o $(authz-obj-y) $(block-obj-y) $(crypto-obj-y) $(io-obj-y) $(qom-obj-y) $(COMMON_LDADDS)
- qemu-storage-daemon$(EXESUF): qemu-storage-daemon.o $(authz-obj-y) $(block-obj-y) $(crypto-obj-y) $(chardev-obj-y) $(io-obj-y) $(qom-obj-y) $(storage-daemon-obj-y) $(COMMON_LDADDS)
-+vma$(EXESUF): vma.o vma-reader.o $(authz-obj-y) $(block-obj-y) $(crypto-obj-y) $(io-obj-y) $(qom-obj-y) $(COMMON_LDADDS)
+ has_gettid = cc.has_function('gettid')
  
- qemu-bridge-helper$(EXESUF): qemu-bridge-helper.o $(COMMON_LDADDS)
++libuuid = cc.find_library('uuid', required: true)
++
+ # Malloc tests
  
-diff --git a/Makefile.objs b/Makefile.objs
-index a1307c12a8..ade7b17a69 100644
---- a/Makefile.objs
-+++ b/Makefile.objs
-@@ -17,6 +17,7 @@ block-obj-y = block/ nbd/ scsi/
- block-obj-y += block.o blockjob.o job.o
- block-obj-y += qemu-io-cmds.o
- block-obj-$(CONFIG_REPLICATION) += replication.o
-+block-obj-y += vma-writer.o
- 
- block-obj-m = block/
+ malloc = []
+@@ -1907,6 +1909,9 @@ if have_tools
+   qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
+                dependencies: [blockdev, qemuutil], install: true)
  
++  vma = executable('vma', files('vma.c', 'vma-reader.c'),
++                   dependencies: [authz, block, crypto, io, qom], install: true)
++
+   subdir('storage-daemon')
+   subdir('contrib/rdmacm-mux')
+   subdir('contrib/elf2dmp')
+diff --git a/qapi/migration.json b/qapi/migration.json
+index 72cc490697..cb3627884c 100644
+--- a/qapi/migration.json
++++ b/qapi/migration.json
+@@ -255,7 +255,7 @@
+ # @error: string containing error message is status is failed.
+ #
+ # @total-time: total amount of milliseconds since savevm started.
+-#        If savevm has ended, it returns the total save time
++#              If savevm has ended, it returns the total save time
+ #
+ # @bytes: total amount of data transfered
+ #
 diff --git a/vma-reader.c b/vma-reader.c
 new file mode 100644
 index 0000000000..2b1d1cdab3
@@ -914,7 +931,7 @@ index 0000000000..2b1d1cdab3
 +
 diff --git a/vma-writer.c b/vma-writer.c
 new file mode 100644
-index 0000000000..f5d2c5d23c
+index 0000000000..11d8321ffd
 --- /dev/null
 +++ b/vma-writer.c
 @@ -0,0 +1,790 @@
@@ -1213,20 +1230,20 @@ index 0000000000..f5d2c5d23c
 +
 +        if ((stat(filename, &st) == 0) && S_ISFIFO(st.st_mode)) {
 +            oflags = O_NONBLOCK|O_WRONLY;
-+            vmaw->fd = qemu_open(filename, oflags, 0644);
++            vmaw->fd = qemu_open(filename, oflags, errp);
 +        } else if (strstart(filename, "/dev/fdset/", &tmp_id_str)) {
 +            oflags = O_NONBLOCK|O_WRONLY;
-+            vmaw->fd = qemu_open(filename, oflags, 0644);
++            vmaw->fd = qemu_open(filename, oflags, errp);
 +        } else if (strstart(filename, "/dev/fdname/", &tmp_id_str)) {
-+            vmaw->fd = monitor_get_fd(cur_mon, tmp_id_str, errp);
++            vmaw->fd = monitor_get_fd(monitor_cur(), tmp_id_str, errp);
 +            if (vmaw->fd < 0) {
 +                goto err;
 +            }
 +            /* try to use O_NONBLOCK */
 +            fcntl(vmaw->fd, F_SETFL, fcntl(vmaw->fd, F_GETFL)|O_NONBLOCK);
 +        } else  {
-+            oflags = O_NONBLOCK|O_DIRECT|O_WRONLY|O_CREAT|O_EXCL;
-+            vmaw->fd = qemu_open(filename, oflags, 0644);
++            oflags = O_NONBLOCK|O_DIRECT|O_WRONLY|O_EXCL;
++            vmaw->fd = qemu_create(filename, oflags, 0644, errp);
 +        }
 +
 +        if (vmaw->fd < 0) {
diff --git a/debian/patches/pve/0027-PVE-Backup-add-backup-dump-block-driver.patch b/debian/patches/pve/0027-PVE-Backup-add-backup-dump-block-driver.patch
index cfd297b..8692f8e 100644
--- a/debian/patches/pve/0027-PVE-Backup-add-backup-dump-block-driver.patch
+++ b/debian/patches/pve/0027-PVE-Backup-add-backup-dump-block-driver.patch
@@ -8,26 +8,14 @@ Subject: [PATCH] PVE-Backup: add backup-dump block driver
 - block/backup.c - backup-job-create: also consider source cluster size
 - job.c: make job_should_pause non-static
 ---
- block/Makefile.objs       |   1 +
  block/backup-dump.c       | 168 ++++++++++++++++++++++++++++++++++++++
  block/backup.c            |  23 ++----
+ block/meson.build         |   1 +
  include/block/block_int.h |  30 +++++++
  job.c                     |   3 +-
  5 files changed, 206 insertions(+), 19 deletions(-)
  create mode 100644 block/backup-dump.c
 
-diff --git a/block/Makefile.objs b/block/Makefile.objs
-index d1a9227b8f..9ea0477d0b 100644
---- a/block/Makefile.objs
-+++ b/block/Makefile.objs
-@@ -33,6 +33,7 @@ block-obj-$(CONFIG_CURL) += curl.o
- block-obj-$(CONFIG_RBD) += rbd.o
- block-obj-$(CONFIG_GLUSTERFS) += gluster.o
- block-obj-$(CONFIG_LIBSSH) += ssh.o
-+block-obj-y += backup-dump.o
- block-obj-y += accounting.o dirty-bitmap.o
- block-obj-y += write-threshold.o
- block-obj-y += backup.o
 diff --git a/block/backup-dump.c b/block/backup-dump.c
 new file mode 100644
 index 0000000000..93d7f46950
@@ -203,7 +191,7 @@ index 0000000000..93d7f46950
 +    return bs;
 +}
 diff --git a/block/backup.c b/block/backup.c
-index 4f13bb20a5..cd42236b79 100644
+index 9afa0bf3b4..3df3d532d5 100644
 --- a/block/backup.c
 +++ b/block/backup.c
 @@ -32,24 +32,6 @@
@@ -231,7 +219,7 @@ index 4f13bb20a5..cd42236b79 100644
  static const BlockJobDriver backup_job_driver;
  
  static void backup_progress_bytes_callback(int64_t bytes, void *opaque)
-@@ -422,6 +404,11 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
+@@ -423,6 +405,11 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
          goto error;
      }
  
@@ -243,11 +231,23 @@ index 4f13bb20a5..cd42236b79 100644
      /*
       * If source is in backing chain of target assume that target is going to be
       * used for "image fleecing", i.e. it should represent a kind of snapshot of
+diff --git a/block/meson.build b/block/meson.build
+index feffbc8623..2507af1168 100644
+--- a/block/meson.build
++++ b/block/meson.build
+@@ -4,6 +4,7 @@ block_ss.add(files(
+   'aio_task.c',
+   'amend.c',
+   'backup.c',
++  'backup-dump.c',
+   'backup-top.c',
+   'blkdebug.c',
+   'blklogwrites.c',
 diff --git a/include/block/block_int.h b/include/block/block_int.h
-index 38dec0275b..1efb1f527c 100644
+index 95d9333be1..2645e53282 100644
 --- a/include/block/block_int.h
 +++ b/include/block/block_int.h
-@@ -62,6 +62,36 @@
+@@ -63,6 +63,36 @@
  
  #define BLOCK_PROBE_BUF_SIZE        512
  
@@ -285,7 +285,7 @@ index 38dec0275b..1efb1f527c 100644
      BDRV_TRACKED_READ,
      BDRV_TRACKED_WRITE,
 diff --git a/job.c b/job.c
-index 53be57a3a0..b8139c80a4 100644
+index 8fecf38960..f9884e7d9d 100644
 --- a/job.c
 +++ b/job.c
 @@ -269,7 +269,8 @@ static bool job_started(Job *job)
diff --git a/debian/patches/pve/0028-PVE-Backup-proxmox-backup-patches-for-qemu.patch b/debian/patches/pve/0028-PVE-Backup-proxmox-backup-patches-for-qemu.patch
index 7896692..f34f70e 100644
--- a/debian/patches/pve/0028-PVE-Backup-proxmox-backup-patches-for-qemu.patch
+++ b/debian/patches/pve/0028-PVE-Backup-proxmox-backup-patches-for-qemu.patch
@@ -4,77 +4,47 @@ Date: Mon, 6 Apr 2020 12:16:59 +0200
 Subject: [PATCH] PVE-Backup: proxmox backup patches for qemu
 
 ---
- Makefile                       |   1 +
- Makefile.objs                  |   2 +
- Makefile.target                |   2 +-
+ block/meson.build              |   5 +
  block/monitor/block-hmp-cmds.c |  33 ++
  blockdev.c                     |   1 +
  hmp-commands-info.hx           |  13 +
  hmp-commands.hx                |  29 +
  include/block/block_int.h      |   2 +-
  include/monitor/hmp.h          |   3 +
+ meson.build                    |   1 +
  monitor/hmp-cmds.c             |  44 ++
  proxmox-backup-client.c        | 176 ++++++
  proxmox-backup-client.h        |  59 ++
  pve-backup.c                   | 955 +++++++++++++++++++++++++++++++++
  qapi/block-core.json           | 109 ++++
  qapi/common.json               |  13 +
- qapi/misc.json                 |  13 -
- 16 files changed, 1440 insertions(+), 15 deletions(-)
+ qapi/machine.json              |  15 +-
+ 15 files changed, 1444 insertions(+), 14 deletions(-)
  create mode 100644 proxmox-backup-client.c
  create mode 100644 proxmox-backup-client.h
  create mode 100644 pve-backup.c
 
-diff --git a/Makefile b/Makefile
-index 7b8c17ce2d..aec216968d 100644
---- a/Makefile
-+++ b/Makefile
-@@ -602,6 +602,7 @@ qemu-img$(EXESUF): qemu-img.o $(authz-obj-y) $(block-obj-y) $(crypto-obj-y) $(io
- qemu-nbd$(EXESUF): qemu-nbd.o $(authz-obj-y) $(block-obj-y) $(crypto-obj-y) $(io-obj-y) $(qom-obj-y) $(COMMON_LDADDS)
- qemu-io$(EXESUF): qemu-io.o $(authz-obj-y) $(block-obj-y) $(crypto-obj-y) $(io-obj-y) $(qom-obj-y) $(COMMON_LDADDS)
- qemu-storage-daemon$(EXESUF): qemu-storage-daemon.o $(authz-obj-y) $(block-obj-y) $(crypto-obj-y) $(chardev-obj-y) $(io-obj-y) $(qom-obj-y) $(storage-daemon-obj-y) $(COMMON_LDADDS)
-+qemu-storage-daemon$(EXESUF): LIBS += -lproxmox_backup_qemu
- vma$(EXESUF): vma.o vma-reader.o $(authz-obj-y) $(block-obj-y) $(crypto-obj-y) $(io-obj-y) $(qom-obj-y) $(COMMON_LDADDS)
+diff --git a/block/meson.build b/block/meson.build
+index 2507af1168..dfae565db3 100644
+--- a/block/meson.build
++++ b/block/meson.build
+@@ -44,6 +44,11 @@ block_ss.add(files(
+ ), zstd, zlib)
  
- qemu-bridge-helper$(EXESUF): qemu-bridge-helper.o $(COMMON_LDADDS)
-diff --git a/Makefile.objs b/Makefile.objs
-index ade7b17a69..240eb503f2 100644
---- a/Makefile.objs
-+++ b/Makefile.objs
-@@ -33,6 +33,7 @@ endif # CONFIG_SOFTMMU or CONFIG_TOOLS
+ block_ss.add(files('../vma-writer.c'), libuuid)
++block_ss.add(files(
++  '../proxmox-backup-client.c',
++  '../pve-backup.c',
++), libproxmox_backup_qemu)
++
  
- storage-daemon-obj-y = block/ monitor/ qapi/ qom/ storage-daemon/
- storage-daemon-obj-y += blockdev.o blockdev-nbd.o iothread.o job-qmp.o
-+storage-daemon-obj-y += proxmox-backup-client.o pve-backup.o
- storage-daemon-obj-$(CONFIG_WIN32) += os-win32.o
- storage-daemon-obj-$(CONFIG_POSIX) += os-posix.o
+ softmmu_ss.add(when: 'CONFIG_TCG', if_true: files('blkreplay.c'))
  
-@@ -44,6 +45,7 @@ storage-daemon-obj-$(CONFIG_POSIX) += os-posix.o
- ifeq ($(CONFIG_SOFTMMU),y)
- common-obj-y = blockdev.o blockdev-nbd.o block/
- common-obj-y += bootdevice.o iothread.o
-+common-obj-y += proxmox-backup-client.o pve-backup.o
- common-obj-y += dump/
- common-obj-y += job-qmp.o
- common-obj-y += monitor/
-diff --git a/Makefile.target b/Makefile.target
-index ffa2657269..fd3fd6d2a7 100644
---- a/Makefile.target
-+++ b/Makefile.target
-@@ -159,7 +159,7 @@ obj-y += hw/
- obj-y += monitor/
- obj-y += qapi/
- obj-y += migration/ram.o
--LIBS := $(libs_softmmu) $(LIBS)
-+LIBS := $(libs_softmmu) $(LIBS)  -lproxmox_backup_qemu
- 
- # Hardware support
- ifeq ($(TARGET_NAME), sparc64)
 diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
-index 4c8c375172..d485c3ac79 100644
+index d15a2be827..9ba7c774a2 100644
 --- a/block/monitor/block-hmp-cmds.c
 +++ b/block/monitor/block-hmp-cmds.c
-@@ -1011,3 +1011,36 @@ void hmp_info_snapshots(Monitor *mon, const QDict *qdict)
+@@ -1012,3 +1012,36 @@ void hmp_info_snapshots(Monitor *mon, const QDict *qdict)
      g_free(sn_tab);
      g_free(global_snapshots);
  }
@@ -112,7 +82,7 @@ index 4c8c375172..d485c3ac79 100644
 +    hmp_handle_error(mon, error);
 +}
 diff --git a/blockdev.c b/blockdev.c
-index 3848a9c8ab..681da7c8b6 100644
+index fe6fb5dc1d..bae80b9177 100644
 --- a/blockdev.c
 +++ b/blockdev.c
 @@ -36,6 +36,7 @@
@@ -124,7 +94,7 @@ index 3848a9c8ab..681da7c8b6 100644
  #include "monitor/monitor.h"
  #include "qemu/error-report.h"
 diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx
-index ae8ff21789..da16499f8d 100644
+index b3b797ca28..295e14e64f 100644
 --- a/hmp-commands-info.hx
 +++ b/hmp-commands-info.hx
 @@ -513,6 +513,19 @@ SRST
@@ -148,10 +118,10 @@ index ae8ff21789..da16499f8d 100644
      {
          .name       = "usernet",
 diff --git a/hmp-commands.hx b/hmp-commands.hx
-index 2b58ac4a1c..9e58b6a5fc 100644
+index d18b911969..70257ef7ca 100644
 --- a/hmp-commands.hx
 +++ b/hmp-commands.hx
-@@ -97,6 +97,35 @@ ERST
+@@ -98,6 +98,35 @@ ERST
  SRST
  ``block_stream``
    Copy data from a backing file into a block device.
@@ -188,10 +158,10 @@ index 2b58ac4a1c..9e58b6a5fc 100644
  
      {
 diff --git a/include/block/block_int.h b/include/block/block_int.h
-index 1efb1f527c..8dda6f769d 100644
+index 2645e53282..9fa282ff54 100644
 --- a/include/block/block_int.h
 +++ b/include/block/block_int.h
-@@ -64,7 +64,7 @@
+@@ -65,7 +65,7 @@
  
  typedef int BackupDumpFunc(void *opaque, uint64_t offset, uint64_t bytes, const void *buf);
  
@@ -201,7 +171,7 @@ index 1efb1f527c..8dda6f769d 100644
      uint64_t byte_size,
      BackupDumpFunc *dump_cb,
 diff --git a/include/monitor/hmp.h b/include/monitor/hmp.h
-index 243952d32f..892a6064be 100644
+index 4e06f89e8e..10f52bd92a 100644
 --- a/include/monitor/hmp.h
 +++ b/include/monitor/hmp.h
 @@ -30,6 +30,7 @@ void hmp_info_migrate(Monitor *mon, const QDict *qdict);
@@ -221,11 +191,23 @@ index 243952d32f..892a6064be 100644
  void hmp_migrate(Monitor *mon, const QDict *qdict);
  void hmp_device_add(Monitor *mon, const QDict *qdict);
  void hmp_device_del(Monitor *mon, const QDict *qdict);
+diff --git a/meson.build b/meson.build
+index d5b660516b..3094f98c47 100644
+--- a/meson.build
++++ b/meson.build
+@@ -726,6 +726,7 @@ keyutils = dependency('libkeyutils', required: false,
+ has_gettid = cc.has_function('gettid')
+ 
+ libuuid = cc.find_library('uuid', required: true)
++libproxmox_backup_qemu = cc.find_library('proxmox_backup_qemu', required: true)
+ 
+ # Malloc tests
+ 
 diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
-index 280bb447a6..0e2d166552 100644
+index e71e4f2929..b830d3701c 100644
 --- a/monitor/hmp-cmds.c
 +++ b/monitor/hmp-cmds.c
-@@ -192,6 +192,50 @@ void hmp_info_mice(Monitor *mon, const QDict *qdict)
+@@ -195,6 +195,50 @@ void hmp_info_mice(Monitor *mon, const QDict *qdict)
      qapi_free_MouseInfoList(mice_list);
  }
  
@@ -1485,10 +1467,10 @@ index 0000000000..55441eb9d1
 +    return task.result;
 +}
 diff --git a/qapi/block-core.json b/qapi/block-core.json
-index ea5fae22ae..69db270b1a 100644
+index 7957b9867d..be67dc3376 100644
 --- a/qapi/block-core.json
 +++ b/qapi/block-core.json
-@@ -754,6 +754,115 @@
+@@ -745,6 +745,115 @@
  { 'command': 'query-block', 'returns': ['BlockInfo'] }
  
  
@@ -1544,12 +1526,12 @@ index ea5fae22ae..69db270b1a 100644
 +# @format: format of the backup file
 +#
 +# @config-file: a configuration file to include into
-+# the backup archive.
++#               the backup archive.
 +#
 +# @speed: the maximum speed, in bytes per second
 +#
 +# @devlist: list of block device names (separated by ',', ';'
-+# or ':'). By default the backup includes all writable block devices.
++#           or ':'). By default the backup includes all writable block devices.
 +#
 +# @password: backup server passsword (required for format 'pbs')
 +#
@@ -1625,13 +1607,22 @@ index 716712d4b3..556dab79e1 100644
 +# Notes: If no UUID was specified for the guest, a null UUID is returned.
 +##
 +{ 'struct': 'UuidInfo', 'data': {'UUID': 'str'} }
-diff --git a/qapi/misc.json b/qapi/misc.json
-index 9895899f8b..75dff1b306 100644
---- a/qapi/misc.json
-+++ b/qapi/misc.json
-@@ -130,19 +130,6 @@
+diff --git a/qapi/machine.json b/qapi/machine.json
+index 32fc674042..145f1a4fa2 100644
+--- a/qapi/machine.json
++++ b/qapi/machine.json
+@@ -4,6 +4,8 @@
+ # This work is licensed under the terms of the GNU GPL, version 2 or later.
+ # See the COPYING file in the top-level directory.
+ 
++{ 'include': 'common.json' }
++
  ##
- { 'command': 'query-kvm', 'returns': 'KvmInfo' }
+ # = Machines
+ ##
+@@ -406,19 +408,6 @@
+ ##
+ { 'command': 'query-target', 'returns': 'TargetInfo' }
  
 -##
 -# @UuidInfo:
diff --git a/debian/patches/pve/0029-PVE-Backup-pbs-restore-new-command-to-restore-from-p.patch b/debian/patches/pve/0029-PVE-Backup-pbs-restore-new-command-to-restore-from-p.patch
index 02e78c5..d7b0f39 100644
--- a/debian/patches/pve/0029-PVE-Backup-pbs-restore-new-command-to-restore-from-p.patch
+++ b/debian/patches/pve/0029-PVE-Backup-pbs-restore-new-command-to-restore-from-p.patch
@@ -6,33 +6,26 @@ Subject: [PATCH] PVE-Backup: pbs-restore - new command to restore from proxmox
 
 Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
 ---
- Makefile      |   4 +-
+ meson.build   |   4 +
  pbs-restore.c | 217 ++++++++++++++++++++++++++++++++++++++++++++++++++
- 2 files changed, 220 insertions(+), 1 deletion(-)
+ 2 files changed, 221 insertions(+)
  create mode 100644 pbs-restore.c
 
-diff --git a/Makefile b/Makefile
-index aec216968d..b73da29f24 100644
---- a/Makefile
-+++ b/Makefile
-@@ -479,7 +479,7 @@ dummy := $(call unnest-vars,, \
- 
- include $(SRC_PATH)/tests/Makefile.include
- 
--all: $(DOCS) $(if $(BUILD_DOCS),sphinxdocs) $(TOOLS) vma$(EXESUF) $(HELPERS-y) recurse-all modules $(vhost-user-json-y)
-+all: $(DOCS) $(if $(BUILD_DOCS),sphinxdocs) $(TOOLS) vma$(EXESUF) pbs-restore$(EXESUF) $(HELPERS-y) recurse-all modules $(vhost-user-json-y)
- 
- qemu-version.h: FORCE
- 	$(call quiet-command, \
-@@ -604,6 +604,8 @@ qemu-io$(EXESUF): qemu-io.o $(authz-obj-y) $(block-obj-y) $(crypto-obj-y) $(io-o
- qemu-storage-daemon$(EXESUF): qemu-storage-daemon.o $(authz-obj-y) $(block-obj-y) $(crypto-obj-y) $(chardev-obj-y) $(io-obj-y) $(qom-obj-y) $(storage-daemon-obj-y) $(COMMON_LDADDS)
- qemu-storage-daemon$(EXESUF): LIBS += -lproxmox_backup_qemu
- vma$(EXESUF): vma.o vma-reader.o $(authz-obj-y) $(block-obj-y) $(crypto-obj-y) $(io-obj-y) $(qom-obj-y) $(COMMON_LDADDS)
-+pbs-restore$(EXESUF): pbs-restore.o $(authz-obj-y) $(block-obj-y) $(crypto-obj-y) $(io-obj-y) $(qom-obj-y) $(COMMON_LDADDS)
-+pbs-restore$(EXESUF): LIBS += -lproxmox_backup_qemu
- 
- qemu-bridge-helper$(EXESUF): qemu-bridge-helper.o $(COMMON_LDADDS)
+diff --git a/meson.build b/meson.build
+index 3094f98c47..6f1fafee14 100644
+--- a/meson.build
++++ b/meson.build
+@@ -1913,6 +1913,10 @@ if have_tools
+   vma = executable('vma', files('vma.c', 'vma-reader.c'),
+                    dependencies: [authz, block, crypto, io, qom], install: true)
  
++  pbs_restore = executable('pbs-restore', files('pbs-restore.c'),
++                  dependencies: [authz, block, crypto, io, qom,
++                    libproxmox_backup_qemu], install: true)
++
+   subdir('storage-daemon')
+   subdir('contrib/rdmacm-mux')
+   subdir('contrib/elf2dmp')
 diff --git a/pbs-restore.c b/pbs-restore.c
 new file mode 100644
 index 0000000000..4bf37ef1fa
diff --git a/debian/patches/pve/0031-drive-mirror-add-support-for-sync-bitmap-mode-never.patch b/debian/patches/pve/0031-drive-mirror-add-support-for-sync-bitmap-mode-never.patch
index f09b953..3e324a3 100644
--- a/debian/patches/pve/0031-drive-mirror-add-support-for-sync-bitmap-mode-never.patch
+++ b/debian/patches/pve/0031-drive-mirror-add-support-for-sync-bitmap-mode-never.patch
@@ -35,10 +35,10 @@ Signed-off-by: Fabian Grünbichler <f.gruenbichler at proxmox.com>
  5 files changed, 145 insertions(+), 29 deletions(-)
 
 diff --git a/block/mirror.c b/block/mirror.c
-index e8e8844afc..100e828639 100644
+index 8e1ad6eceb..97843992c2 100644
 --- a/block/mirror.c
 +++ b/block/mirror.c
-@@ -49,7 +49,7 @@ typedef struct MirrorBlockJob {
+@@ -50,7 +50,7 @@ typedef struct MirrorBlockJob {
      BlockDriverState *to_replace;
      /* Used to block operations on the drive-mirror-replace target */
      Error *replace_blocker;
@@ -47,7 +47,7 @@ index e8e8844afc..100e828639 100644
      BlockMirrorBackingMode backing_mode;
      /* Whether the target image requires explicit zero-initialization */
      bool zero_target;
-@@ -64,6 +64,8 @@ typedef struct MirrorBlockJob {
+@@ -65,6 +65,8 @@ typedef struct MirrorBlockJob {
      size_t buf_size;
      int64_t bdev_length;
      unsigned long *cow_bitmap;
@@ -56,17 +56,17 @@ index e8e8844afc..100e828639 100644
      BdrvDirtyBitmap *dirty_bitmap;
      BdrvDirtyBitmapIter *dbi;
      uint8_t *buf;
-@@ -676,7 +678,8 @@ static int mirror_exit_common(Job *job)
+@@ -677,7 +679,8 @@ static int mirror_exit_common(Job *job)
      bdrv_child_refresh_perms(mirror_top_bs, mirror_top_bs->backing,
                               &error_abort);
      if (!abort && s->backing_mode == MIRROR_SOURCE_BACKING_CHAIN) {
 -        BlockDriverState *backing = s->is_none_mode ? src : s->base;
 +        BlockDriverState *backing;
 +        backing = s->sync_mode == MIRROR_SYNC_MODE_NONE ? src : s->base;
-         if (backing_bs(target_bs) != backing) {
-             bdrv_set_backing_hd(target_bs, backing, &local_err);
-             if (local_err) {
-@@ -771,6 +774,16 @@ static void mirror_abort(Job *job)
+         BlockDriverState *unfiltered_target = bdrv_skip_filters(target_bs);
+ 
+         if (bdrv_cow_bs(unfiltered_target) != backing) {
+@@ -774,6 +777,16 @@ static void mirror_abort(Job *job)
      assert(ret == 0);
  }
  
@@ -83,7 +83,7 @@ index e8e8844afc..100e828639 100644
  static void coroutine_fn mirror_throttle(MirrorBlockJob *s)
  {
      int64_t now = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
-@@ -952,7 +965,8 @@ static int coroutine_fn mirror_run(Job *job, Error **errp)
+@@ -955,7 +968,8 @@ static int coroutine_fn mirror_run(Job *job, Error **errp)
      mirror_free_init(s);
  
      s->last_pause_ns = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
@@ -93,7 +93,7 @@ index e8e8844afc..100e828639 100644
          ret = mirror_dirty_init(s);
          if (ret < 0 || job_is_cancelled(&s->common.job)) {
              goto immediate_exit;
-@@ -1184,6 +1198,7 @@ static const BlockJobDriver mirror_job_driver = {
+@@ -1188,6 +1202,7 @@ static const BlockJobDriver mirror_job_driver = {
          .run                    = mirror_run,
          .prepare                = mirror_prepare,
          .abort                  = mirror_abort,
@@ -101,7 +101,7 @@ index e8e8844afc..100e828639 100644
          .pause                  = mirror_pause,
          .complete               = mirror_complete,
      },
-@@ -1199,6 +1214,7 @@ static const BlockJobDriver commit_active_job_driver = {
+@@ -1203,6 +1218,7 @@ static const BlockJobDriver commit_active_job_driver = {
          .run                    = mirror_run,
          .prepare                = mirror_prepare,
          .abort                  = mirror_abort,
@@ -109,7 +109,7 @@ index e8e8844afc..100e828639 100644
          .pause                  = mirror_pause,
          .complete               = mirror_complete,
      },
-@@ -1547,7 +1563,10 @@ static BlockJob *mirror_start_job(
+@@ -1550,7 +1566,10 @@ static BlockJob *mirror_start_job(
                               BlockCompletionFunc *cb,
                               void *opaque,
                               const BlockJobDriver *driver,
@@ -121,7 +121,7 @@ index e8e8844afc..100e828639 100644
                               bool auto_complete, const char *filter_node_name,
                               bool is_mirror, MirrorCopyMode copy_mode,
                               Error **errp)
-@@ -1560,10 +1579,39 @@ static BlockJob *mirror_start_job(
+@@ -1563,10 +1582,39 @@ static BlockJob *mirror_start_job(
      Error *local_err = NULL;
      int ret;
  
@@ -163,7 +163,7 @@ index e8e8844afc..100e828639 100644
      assert(is_power_of_2(granularity));
  
      if (buf_size < 0) {
-@@ -1667,7 +1715,9 @@ static BlockJob *mirror_start_job(
+@@ -1705,7 +1753,9 @@ static BlockJob *mirror_start_job(
      s->replaces = g_strdup(replaces);
      s->on_source_error = on_source_error;
      s->on_target_error = on_target_error;
@@ -174,7 +174,7 @@ index e8e8844afc..100e828639 100644
      s->backing_mode = backing_mode;
      s->zero_target = zero_target;
      s->copy_mode = copy_mode;
-@@ -1687,6 +1737,18 @@ static BlockJob *mirror_start_job(
+@@ -1726,6 +1776,18 @@ static BlockJob *mirror_start_job(
          bdrv_disable_dirty_bitmap(s->dirty_bitmap);
      }
  
@@ -193,7 +193,7 @@ index e8e8844afc..100e828639 100644
      ret = block_job_add_bdrv(&s->common, "source", bs, 0,
                               BLK_PERM_WRITE_UNCHANGED | BLK_PERM_WRITE |
                               BLK_PERM_CONSISTENT_READ,
-@@ -1740,6 +1802,9 @@ fail:
+@@ -1803,6 +1865,9 @@ fail:
          if (s->dirty_bitmap) {
              bdrv_release_dirty_bitmap(s->dirty_bitmap);
          }
@@ -203,7 +203,7 @@ index e8e8844afc..100e828639 100644
          job_early_fail(&s->common.job);
      }
  
-@@ -1757,29 +1822,23 @@ void mirror_start(const char *job_id, BlockDriverState *bs,
+@@ -1820,29 +1885,23 @@ void mirror_start(const char *job_id, BlockDriverState *bs,
                    BlockDriverState *target, const char *replaces,
                    int creation_flags, int64_t speed,
                    uint32_t granularity, int64_t buf_size,
@@ -227,7 +227,7 @@ index e8e8844afc..100e828639 100644
 -        return;
 -    }
 -    is_none_mode = mode == MIRROR_SYNC_MODE_NONE;
-     base = mode == MIRROR_SYNC_MODE_TOP ? backing_bs(bs) : NULL;
+     base = mode == MIRROR_SYNC_MODE_TOP ? bdrv_backing_chain_next(bs) : NULL;
      mirror_start_job(job_id, bs, creation_flags, target, replaces,
                       speed, granularity, buf_size, backing_mode, zero_target,
                       on_source_error, on_target_error, unmap, NULL, NULL,
@@ -238,7 +238,7 @@ index e8e8844afc..100e828639 100644
  }
  
  BlockJob *commit_active_start(const char *job_id, BlockDriverState *bs,
-@@ -1805,7 +1864,8 @@ BlockJob *commit_active_start(const char *job_id, BlockDriverState *bs,
+@@ -1868,7 +1927,8 @@ BlockJob *commit_active_start(const char *job_id, BlockDriverState *bs,
                       job_id, bs, creation_flags, base, NULL, speed, 0, 0,
                       MIRROR_LEAVE_BACKING_CHAIN, false,
                       on_error, on_error, true, cb, opaque,
@@ -249,10 +249,10 @@ index e8e8844afc..100e828639 100644
                       &local_err);
      if (local_err) {
 diff --git a/blockdev.c b/blockdev.c
-index 681da7c8b6..02d58e7645 100644
+index bae80b9177..c79e081f57 100644
 --- a/blockdev.c
 +++ b/blockdev.c
-@@ -2876,6 +2876,10 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
+@@ -2931,6 +2931,10 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
                                     BlockDriverState *target,
                                     bool has_replaces, const char *replaces,
                                     enum MirrorSyncMode sync,
@@ -263,15 +263,15 @@ index 681da7c8b6..02d58e7645 100644
                                     BlockMirrorBackingMode backing_mode,
                                     bool zero_target,
                                     bool has_speed, int64_t speed,
-@@ -2894,6 +2898,7 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
-                                    Error **errp)
+@@ -2950,6 +2954,7 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
  {
+     BlockDriverState *unfiltered_bs;
      int job_flags = JOB_DEFAULT;
 +    BdrvDirtyBitmap *bitmap = NULL;
  
      if (!has_speed) {
          speed = 0;
-@@ -2948,6 +2953,29 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
+@@ -3004,6 +3009,29 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
          sync = MIRROR_SYNC_MODE_FULL;
      }
  
@@ -298,10 +298,10 @@ index 681da7c8b6..02d58e7645 100644
 +        }
 +    }
 +
-     if (has_replaces) {
-         BlockDriverState *to_replace_bs;
-         AioContext *replace_aio_context;
-@@ -2985,8 +3013,8 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
+     if (!has_replaces) {
+         /* We want to mirror from @bs, but keep implicit filters on top */
+         unfiltered_bs = bdrv_skip_implicit_filters(bs);
+@@ -3050,8 +3078,8 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
       * and will allow to check whether the node still exist at mirror completion
       */
      mirror_start(job_id, bs, target,
@@ -312,7 +312,7 @@ index 681da7c8b6..02d58e7645 100644
                   on_source_error, on_target_error, unmap, filter_node_name,
                   copy_mode, errp);
  }
-@@ -3127,6 +3155,8 @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp)
+@@ -3196,6 +3224,8 @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp)
  
      blockdev_mirror_common(arg->has_job_id ? arg->job_id : NULL, bs, target_bs,
                             arg->has_replaces, arg->replaces, arg->sync,
@@ -321,7 +321,7 @@ index 681da7c8b6..02d58e7645 100644
                             backing_mode, zero_target,
                             arg->has_speed, arg->speed,
                             arg->has_granularity, arg->granularity,
-@@ -3148,6 +3178,8 @@ void qmp_blockdev_mirror(bool has_job_id, const char *job_id,
+@@ -3217,6 +3247,8 @@ void qmp_blockdev_mirror(bool has_job_id, const char *job_id,
                           const char *device, const char *target,
                           bool has_replaces, const char *replaces,
                           MirrorSyncMode sync,
@@ -330,7 +330,7 @@ index 681da7c8b6..02d58e7645 100644
                           bool has_speed, int64_t speed,
                           bool has_granularity, uint32_t granularity,
                           bool has_buf_size, int64_t buf_size,
-@@ -3197,7 +3229,8 @@ void qmp_blockdev_mirror(bool has_job_id, const char *job_id,
+@@ -3266,7 +3298,8 @@ void qmp_blockdev_mirror(bool has_job_id, const char *job_id,
      }
  
      blockdev_mirror_common(has_job_id ? job_id : NULL, bs, target_bs,
@@ -341,10 +341,10 @@ index 681da7c8b6..02d58e7645 100644
                             has_granularity, granularity,
                             has_buf_size, buf_size,
 diff --git a/include/block/block_int.h b/include/block/block_int.h
-index 8dda6f769d..279bd4ab61 100644
+index 9fa282ff54..1bd4b64522 100644
 --- a/include/block/block_int.h
 +++ b/include/block/block_int.h
-@@ -1245,7 +1245,9 @@ void mirror_start(const char *job_id, BlockDriverState *bs,
+@@ -1260,7 +1260,9 @@ void mirror_start(const char *job_id, BlockDriverState *bs,
                    BlockDriverState *target, const char *replaces,
                    int creation_flags, int64_t speed,
                    uint32_t granularity, int64_t buf_size,
@@ -356,10 +356,10 @@ index 8dda6f769d..279bd4ab61 100644
                    BlockdevOnError on_source_error,
                    BlockdevOnError on_target_error,
 diff --git a/qapi/block-core.json b/qapi/block-core.json
-index 69db270b1a..9db8e26517 100644
+index be67dc3376..9054db608c 100644
 --- a/qapi/block-core.json
 +++ b/qapi/block-core.json
-@@ -2064,10 +2064,19 @@
+@@ -2080,10 +2080,19 @@
  #        (all the disk, only the sectors allocated in the topmost image, or
  #        only new I/O).
  #
@@ -380,7 +380,7 @@ index 69db270b1a..9db8e26517 100644
  #
  # @buf-size: maximum amount of data in flight from source to
  #            target (since 1.4).
-@@ -2105,7 +2114,9 @@
+@@ -2121,7 +2130,9 @@
  { 'struct': 'DriveMirror',
    'data': { '*job-id': 'str', 'device': 'str', 'target': 'str',
              '*format': 'str', '*node-name': 'str', '*replaces': 'str',
@@ -391,7 +391,7 @@ index 69db270b1a..9db8e26517 100644
              '*speed': 'int', '*granularity': 'uint32',
              '*buf-size': 'int', '*on-source-error': 'BlockdevOnError',
              '*on-target-error': 'BlockdevOnError',
-@@ -2372,10 +2383,19 @@
+@@ -2389,10 +2400,19 @@
  #        (all the disk, only the sectors allocated in the topmost image, or
  #        only new I/O).
  #
@@ -412,7 +412,7 @@ index 69db270b1a..9db8e26517 100644
  #
  # @buf-size: maximum amount of data in flight from source to
  #            target
-@@ -2424,7 +2444,8 @@
+@@ -2441,7 +2461,8 @@
  { 'command': 'blockdev-mirror',
    'data': { '*job-id': 'str', 'device': 'str', 'target': 'str',
              '*replaces': 'str',
diff --git a/debian/patches/pve/0032-drive-mirror-add-support-for-conditional-and-always-.patch b/debian/patches/pve/0032-drive-mirror-add-support-for-conditional-and-always-.patch
index 63753d5..5a87360 100644
--- a/debian/patches/pve/0032-drive-mirror-add-support-for-conditional-and-always-.patch
+++ b/debian/patches/pve/0032-drive-mirror-add-support-for-conditional-and-always-.patch
@@ -23,10 +23,10 @@ Signed-off-by: Fabian Grünbichler <f.gruenbichler at proxmox.com>
  1 file changed, 18 insertions(+), 6 deletions(-)
 
 diff --git a/block/mirror.c b/block/mirror.c
-index 100e828639..7d3c3252f3 100644
+index 97843992c2..d1cce079da 100644
 --- a/block/mirror.c
 +++ b/block/mirror.c
-@@ -653,8 +653,6 @@ static int mirror_exit_common(Job *job)
+@@ -654,8 +654,6 @@ static int mirror_exit_common(Job *job)
          bdrv_unfreeze_backing_chain(mirror_top_bs, target_bs);
      }
  
@@ -35,7 +35,7 @@ index 100e828639..7d3c3252f3 100644
      /* Make sure that the source BDS doesn't go away during bdrv_replace_node,
       * before we can call bdrv_drained_end */
      bdrv_ref(src);
-@@ -752,6 +750,18 @@ static int mirror_exit_common(Job *job)
+@@ -755,6 +753,18 @@ static int mirror_exit_common(Job *job)
      blk_set_perm(bjob->blk, 0, BLK_PERM_ALL, &error_abort);
      blk_insert_bs(bjob->blk, mirror_top_bs, &error_abort);
  
@@ -54,7 +54,7 @@ index 100e828639..7d3c3252f3 100644
      bs_opaque->job = NULL;
  
      bdrv_drained_end(src);
-@@ -1589,10 +1599,6 @@ static BlockJob *mirror_start_job(
+@@ -1592,10 +1602,6 @@ static BlockJob *mirror_start_job(
                         " sync mode",
                         MirrorSyncMode_str(sync_mode));
              return NULL;
@@ -65,7 +65,7 @@ index 100e828639..7d3c3252f3 100644
          }
      } else if (bitmap) {
          error_setg(errp,
-@@ -1609,6 +1615,12 @@ static BlockJob *mirror_start_job(
+@@ -1612,6 +1618,12 @@ static BlockJob *mirror_start_job(
              return NULL;
          }
          granularity = bdrv_dirty_bitmap_granularity(bitmap);
diff --git a/debian/patches/pve/0033-mirror-add-check-for-bitmap-mode-without-bitmap.patch b/debian/patches/pve/0033-mirror-add-check-for-bitmap-mode-without-bitmap.patch
index 607c90b..97077f3 100644
--- a/debian/patches/pve/0033-mirror-add-check-for-bitmap-mode-without-bitmap.patch
+++ b/debian/patches/pve/0033-mirror-add-check-for-bitmap-mode-without-bitmap.patch
@@ -15,10 +15,10 @@ Signed-off-by: Fabian Grünbichler <f.gruenbichler at proxmox.com>
  1 file changed, 3 insertions(+)
 
 diff --git a/blockdev.c b/blockdev.c
-index 02d58e7645..0d480f02c7 100644
+index c79e081f57..827f004069 100644
 --- a/blockdev.c
 +++ b/blockdev.c
-@@ -2974,6 +2974,9 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
+@@ -3030,6 +3030,9 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
          if (bdrv_dirty_bitmap_check(bitmap, BDRV_BITMAP_ALLOW_RO, errp)) {
              return;
          }
@@ -27,4 +27,4 @@ index 02d58e7645..0d480f02c7 100644
 +        return;
      }
  
-     if (has_replaces) {
+     if (!has_replaces) {
diff --git a/debian/patches/pve/0034-mirror-switch-to-bdrv_dirty_bitmap_merge_internal.patch b/debian/patches/pve/0034-mirror-switch-to-bdrv_dirty_bitmap_merge_internal.patch
index 1ea8b1e..8b3c1e2 100644
--- a/debian/patches/pve/0034-mirror-switch-to-bdrv_dirty_bitmap_merge_internal.patch
+++ b/debian/patches/pve/0034-mirror-switch-to-bdrv_dirty_bitmap_merge_internal.patch
@@ -15,10 +15,10 @@ Signed-off-by: Fabian Grünbichler <f.gruenbichler at proxmox.com>
  1 file changed, 4 insertions(+), 4 deletions(-)
 
 diff --git a/block/mirror.c b/block/mirror.c
-index 7d3c3252f3..fb12ccb932 100644
+index d1cce079da..e6140cf018 100644
 --- a/block/mirror.c
 +++ b/block/mirror.c
-@@ -756,8 +756,8 @@ static int mirror_exit_common(Job *job)
+@@ -759,8 +759,8 @@ static int mirror_exit_common(Job *job)
               job->ret == 0 && ret == 0)) {
              /* Success; synchronize copy back to sync. */
              bdrv_clear_dirty_bitmap(s->sync_bitmap, NULL);
@@ -29,7 +29,7 @@ index 7d3c3252f3..fb12ccb932 100644
          }
      }
      bdrv_release_dirty_bitmap(s->dirty_bitmap);
-@@ -1754,8 +1754,8 @@ static BlockJob *mirror_start_job(
+@@ -1793,8 +1793,8 @@ static BlockJob *mirror_start_job(
      }
  
      if (s->sync_mode == MIRROR_SYNC_MODE_BITMAP) {
diff --git a/debian/patches/pve/0035-iotests-add-test-for-bitmap-mirror.patch b/debian/patches/pve/0035-iotests-add-test-for-bitmap-mirror.patch
index f7ac056..07a66d6 100644
--- a/debian/patches/pve/0035-iotests-add-test-for-bitmap-mirror.patch
+++ b/debian/patches/pve/0035-iotests-add-test-for-bitmap-mirror.patch
@@ -3434,7 +3434,7 @@ index 0000000000..9b7408b6d6
 +{"error": {"class": "GenericError", "desc": "bitmap-mode must be specified if a bitmap is provided"}}
 +
 diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
-index 025ed5238d..bee527c012 100644
+index 2960dff728..952dceba1f 100644
 --- a/tests/qemu-iotests/group
 +++ b/tests/qemu-iotests/group
 @@ -270,6 +270,7 @@
diff --git a/debian/patches/pve/0036-mirror-move-some-checks-to-qmp.patch b/debian/patches/pve/0036-mirror-move-some-checks-to-qmp.patch
index cd96a02..bfbb49f 100644
--- a/debian/patches/pve/0036-mirror-move-some-checks-to-qmp.patch
+++ b/debian/patches/pve/0036-mirror-move-some-checks-to-qmp.patch
@@ -18,10 +18,10 @@ Signed-off-by: Fabian Grünbichler <f.gruenbichler at proxmox.com>
  3 files changed, 70 insertions(+), 59 deletions(-)
 
 diff --git a/block/mirror.c b/block/mirror.c
-index fb12ccb932..dfce442e97 100644
+index e6140cf018..3a08239a78 100644
 --- a/block/mirror.c
 +++ b/block/mirror.c
-@@ -1589,31 +1589,13 @@ static BlockJob *mirror_start_job(
+@@ -1592,31 +1592,13 @@ static BlockJob *mirror_start_job(
      Error *local_err = NULL;
      int ret;
  
@@ -59,10 +59,10 @@ index fb12ccb932..dfce442e97 100644
  
          if (bitmap_mode != BITMAP_SYNC_MODE_NEVER) {
 diff --git a/blockdev.c b/blockdev.c
-index 0d480f02c7..be87d65c02 100644
+index 827f004069..e2f826ca62 100644
 --- a/blockdev.c
 +++ b/blockdev.c
-@@ -2953,7 +2953,36 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
+@@ -3009,7 +3009,36 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
          sync = MIRROR_SYNC_MODE_FULL;
      }
  
diff --git a/debian/patches/pve/0037-PVE-Backup-Add-dirty-bitmap-tracking-for-incremental.patch b/debian/patches/pve/0037-PVE-Backup-Add-dirty-bitmap-tracking-for-incremental.patch
index c974060..f375b70 100644
--- a/debian/patches/pve/0037-PVE-Backup-Add-dirty-bitmap-tracking-for-incremental.patch
+++ b/debian/patches/pve/0037-PVE-Backup-Add-dirty-bitmap-tracking-for-incremental.patch
@@ -29,10 +29,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
  6 files changed, 134 insertions(+), 23 deletions(-)
 
 diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
-index d485c3ac79..fdc85a5c0e 100644
+index 9ba7c774a2..056d14deee 100644
 --- a/block/monitor/block-hmp-cmds.c
 +++ b/block/monitor/block-hmp-cmds.c
-@@ -1038,6 +1038,7 @@ void hmp_backup(Monitor *mon, const QDict *qdict)
+@@ -1039,6 +1039,7 @@ void hmp_backup(Monitor *mon, const QDict *qdict)
          false, NULL, // PBS fingerprint
          false, NULL, // PBS backup-id
          false, 0, // PBS backup-time
@@ -41,10 +41,10 @@ index d485c3ac79..fdc85a5c0e 100644
          false, NULL, false, NULL, !!devlist,
          devlist, qdict_haskey(qdict, "speed"), speed, &error);
 diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
-index 0e2d166552..3ff014d32a 100644
+index b830d3701c..bc8e92c134 100644
 --- a/monitor/hmp-cmds.c
 +++ b/monitor/hmp-cmds.c
-@@ -218,19 +218,42 @@ void hmp_info_backup(Monitor *mon, const QDict *qdict)
+@@ -221,19 +221,42 @@ void hmp_info_backup(Monitor *mon, const QDict *qdict)
              monitor_printf(mon, "End time: %s", ctime(&info->end_time));
          }
  
@@ -397,10 +397,10 @@ index d40f3f2fd6..d50f03a050 100644
      qemu_mutex_unlock(&backup_state.stat.lock);
  
 diff --git a/qapi/block-core.json b/qapi/block-core.json
-index 9db8e26517..6cad1e0e38 100644
+index 9054db608c..aadd5329b3 100644
 --- a/qapi/block-core.json
 +++ b/qapi/block-core.json
-@@ -767,8 +767,13 @@
+@@ -758,8 +758,13 @@
  #
  # @total: total amount of bytes involved in the backup process
  #
@@ -414,7 +414,7 @@ index 9db8e26517..6cad1e0e38 100644
  # @zero-bytes: amount of 'zero' bytes detected.
  #
  # @start-time: time (epoch) when backup job started.
-@@ -781,8 +786,8 @@
+@@ -772,8 +777,8 @@
  #
  ##
  { 'struct': 'BackupStatus',
@@ -425,7 +425,7 @@ index 9db8e26517..6cad1e0e38 100644
             '*start-time': 'int', '*end-time': 'int',
             '*backup-file': 'str', '*uuid': 'str' } }
  
-@@ -825,6 +830,8 @@
+@@ -816,6 +821,8 @@
  #
  # @backup-time: backup timestamp (Unix epoch, required for format 'pbs')
  #
@@ -434,7 +434,7 @@ index 9db8e26517..6cad1e0e38 100644
  # Returns: the uuid of the backup job
  #
  ##
-@@ -835,6 +842,7 @@
+@@ -826,6 +833,7 @@
                                      '*fingerprint': 'str',
                                      '*backup-id': 'str',
                                      '*backup-time': 'int',
diff --git a/debian/patches/pve/0038-PVE-backup-rename-incremental-to-use-dirty-bitmap.patch b/debian/patches/pve/0038-PVE-backup-rename-incremental-to-use-dirty-bitmap.patch
index f1e2f55..56b9c32 100644
--- a/debian/patches/pve/0038-PVE-backup-rename-incremental-to-use-dirty-bitmap.patch
+++ b/debian/patches/pve/0038-PVE-backup-rename-incremental-to-use-dirty-bitmap.patch
@@ -94,10 +94,10 @@ index d50f03a050..7bf54b4c5d 100644
          .format = format,
          .has_config_file = has_config_file,
 diff --git a/qapi/block-core.json b/qapi/block-core.json
-index 6cad1e0e38..e00e577c6c 100644
+index aadd5329b3..d4e1c98c50 100644
 --- a/qapi/block-core.json
 +++ b/qapi/block-core.json
-@@ -767,7 +767,7 @@
+@@ -758,7 +758,7 @@
  #
  # @total: total amount of bytes involved in the backup process
  #
@@ -106,7 +106,7 @@ index 6cad1e0e38..e00e577c6c 100644
  #         in the backup process which are marked dirty.
  #
  # @transferred: amount of bytes already backed up.
-@@ -830,7 +830,7 @@
+@@ -821,7 +821,7 @@
  #
  # @backup-time: backup timestamp (Unix epoch, required for format 'pbs')
  #
@@ -115,7 +115,7 @@ index 6cad1e0e38..e00e577c6c 100644
  #
  # Returns: the uuid of the backup job
  #
-@@ -842,7 +842,7 @@
+@@ -833,7 +833,7 @@
                                      '*fingerprint': 'str',
                                      '*backup-id': 'str',
                                      '*backup-time': 'int',
diff --git a/debian/patches/pve/0042-PVE-fixup-pbs-backup-add-compress-and-encrypt-option.patch b/debian/patches/pve/0042-PVE-fixup-pbs-backup-add-compress-and-encrypt-option.patch
index 90cb3e1..601df5c 100644
--- a/debian/patches/pve/0042-PVE-fixup-pbs-backup-add-compress-and-encrypt-option.patch
+++ b/debian/patches/pve/0042-PVE-fixup-pbs-backup-add-compress-and-encrypt-option.patch
@@ -10,10 +10,10 @@ Subject: [PATCH] PVE: fixup pbs backup, add compress and encrypt options
  3 files changed, 21 insertions(+), 2 deletions(-)
 
 diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
-index fdc85a5c0e..43aa87487b 100644
+index 056d14deee..46c63b1cf9 100644
 --- a/block/monitor/block-hmp-cmds.c
 +++ b/block/monitor/block-hmp-cmds.c
-@@ -1038,7 +1038,9 @@ void hmp_backup(Monitor *mon, const QDict *qdict)
+@@ -1039,7 +1039,9 @@ void hmp_backup(Monitor *mon, const QDict *qdict)
          false, NULL, // PBS fingerprint
          false, NULL, // PBS backup-id
          false, 0, // PBS backup-time
@@ -78,10 +78,10 @@ index 1cd9d31d7c..bfb648d6b5 100644
          .speed = speed,
          .errp = errp,
 diff --git a/qapi/block-core.json b/qapi/block-core.json
-index e00e577c6c..a177fea6cd 100644
+index d4e1c98c50..0fda1e3fd3 100644
 --- a/qapi/block-core.json
 +++ b/qapi/block-core.json
-@@ -832,6 +832,10 @@
+@@ -823,6 +823,10 @@
  #
  # @use-dirty-bitmap: use dirty bitmap to detect incremental changes since last job (optional for format 'pbs')
  #
@@ -92,7 +92,7 @@ index e00e577c6c..a177fea6cd 100644
  # Returns: the uuid of the backup job
  #
  ##
-@@ -843,6 +847,8 @@
+@@ -834,6 +838,8 @@
                                      '*backup-id': 'str',
                                      '*backup-time': 'int',
                                      '*use-dirty-bitmap': 'bool',
diff --git a/debian/patches/pve/0043-PVE-Add-PBS-block-driver-to-map-backup-archives-into.patch b/debian/patches/pve/0043-PVE-Add-PBS-block-driver-to-map-backup-archives-into.patch
index 0ff3b1f..4c31eaa 100644
--- a/debian/patches/pve/0043-PVE-Add-PBS-block-driver-to-map-backup-archives-into.patch
+++ b/debian/patches/pve/0043-PVE-Add-PBS-block-driver-to-map-backup-archives-into.patch
@@ -7,30 +7,28 @@ Signed-off-by: Stefan Reiter <s.reiter at proxmox.com>
 [error cleanups, file_open implementation]
 Signed-off-by: Dietmar Maurer <dietmar at proxmox.com>
 ---
- block/Makefile.objs  |   2 +
+ block/meson.build    |   3 +
  block/pbs.c          | 271 +++++++++++++++++++++++++++++++++++++++++++
- configure            |  10 ++
+ configure            |   9 ++
+ meson.build          |   1 +
  qapi/block-core.json |  14 ++-
- 4 files changed, 296 insertions(+), 1 deletion(-)
+ 5 files changed, 297 insertions(+), 1 deletion(-)
  create mode 100644 block/pbs.c
 
-diff --git a/block/Makefile.objs b/block/Makefile.objs
-index 9ea0477d0b..28fb3b7f7c 100644
---- a/block/Makefile.objs
-+++ b/block/Makefile.objs
-@@ -5,6 +5,7 @@ block-obj-$(CONFIG_CLOOP) += cloop.o
- block-obj-$(CONFIG_BOCHS) += bochs.o
- block-obj-$(CONFIG_VVFAT) += vvfat.o
- block-obj-$(CONFIG_DMG) += dmg.o
-+block-obj-$(CONFIG_PBS_BDRV) += pbs.o
+diff --git a/block/meson.build b/block/meson.build
+index dfae565db3..a070060e53 100644
+--- a/block/meson.build
++++ b/block/meson.build
+@@ -49,6 +49,9 @@ block_ss.add(files(
+   '../pve-backup.c',
+ ), libproxmox_backup_qemu)
+ 
++block_ss.add(when: 'CONFIG_PBS_BDRV', if_true: files('pbs.c'))
++block_ss.add(when: 'CONFIG_PBS_BDRV', if_true: libproxmox_backup_qemu)
++
+ 
+ softmmu_ss.add(when: 'CONFIG_TCG', if_true: files('blkreplay.c'))
  
- block-obj-y += qcow2.o qcow2-refcount.o qcow2-cluster.o qcow2-snapshot.o qcow2-cache.o qcow2-bitmap.o qcow2-threads.o
- block-obj-$(CONFIG_QED) += qed.o qed-l2-cache.o qed-table.o qed-cluster.o
-@@ -75,3 +76,4 @@ io_uring.o-cflags  := $(LINUX_IO_URING_CFLAGS)
- io_uring.o-libs    := $(LINUX_IO_URING_LIBS)
- parallels.o-cflags := $(LIBXML2_CFLAGS)
- parallels.o-libs   := $(LIBXML2_LIBS)
-+pbs.o-libs         := -lproxmox_backup_qemu
 diff --git a/block/pbs.c b/block/pbs.c
 new file mode 100644
 index 0000000000..1481a2bfd1
@@ -309,18 +307,18 @@ index 0000000000..1481a2bfd1
 +
 +block_init(bdrv_pbs_init);
 diff --git a/configure b/configure
-index 2acc4d1465..3fc80d0c2c 100755
+index 18c26e0389..33d9933871 100755
 --- a/configure
 +++ b/configure
-@@ -510,6 +510,7 @@ vvfat="yes"
+@@ -436,6 +436,7 @@ vvfat="yes"
  qed="yes"
  parallels="yes"
- sheepdog="yes"
+ sheepdog="no"
 +pbs_bdrv="yes"
  libxml2=""
  debug_mutex="no"
  libpmem=""
-@@ -1576,6 +1577,10 @@ for opt do
+@@ -1461,6 +1462,10 @@ for opt do
    ;;
    --enable-sheepdog) sheepdog="yes"
    ;;
@@ -331,24 +329,16 @@ index 2acc4d1465..3fc80d0c2c 100755
    --disable-vhost-user) vhost_user="no"
    ;;
    --enable-vhost-user) vhost_user="yes"
-@@ -1936,6 +1941,7 @@ disabled with --disable-FEATURE, default is enabled if available:
+@@ -1843,6 +1848,7 @@ disabled with --disable-FEATURE, default is enabled if available:
    qed             qed image format support
    parallels       parallels image format support
-   sheepdog        sheepdog block driver support
+   sheepdog        sheepdog block driver support (deprecated)
 +  pbs-bdrv        Proxmox backup server read-only block driver support
    crypto-afalg    Linux AF_ALG crypto backend driver
    capstone        capstone disassembler support
    debug-mutex     mutex debugging support
-@@ -7009,6 +7015,7 @@ echo "vvfat support     $vvfat"
- echo "qed support       $qed"
- echo "parallels support $parallels"
- echo "sheepdog support  $sheepdog"
-+echo "pbs-bdrv support  $pbs_bdrv"
- echo "capstone          $capstone"
- echo "libpmem support   $libpmem"
- echo "libdaxctl support $libdaxctl"
-@@ -7885,6 +7892,9 @@ fi
- if test "$sheepdog" = "yes" ; then
+@@ -6682,6 +6688,9 @@ if test "$sheepdog" = "yes" ; then
+   add_to deprecated_features "sheepdog"
    echo "CONFIG_SHEEPDOG=y" >> $config_host_mak
  fi
 +if test "$pbs_bdrv" = "yes" ; then
@@ -357,11 +347,23 @@ index 2acc4d1465..3fc80d0c2c 100755
  if test "$pty_h" = "yes" ; then
    echo "HAVE_PTY_H=y" >> $config_host_mak
  fi
+diff --git a/meson.build b/meson.build
+index 6f1fafee14..4d156d35ce 100644
+--- a/meson.build
++++ b/meson.build
+@@ -2199,6 +2199,7 @@ summary_info += {'vvfat support':     config_host.has_key('CONFIG_VVFAT')}
+ summary_info += {'qed support':       config_host.has_key('CONFIG_QED')}
+ summary_info += {'parallels support': config_host.has_key('CONFIG_PARALLELS')}
+ summary_info += {'sheepdog support':  config_host.has_key('CONFIG_SHEEPDOG')}
++summary_info += {'PBS bdrv support':  config_host.has_key('CONFIG_PBS_BDRV')}
+ summary_info += {'capstone':          capstone_opt == 'disabled' ? false : capstone_opt}
+ summary_info += {'libpmem support':   config_host.has_key('CONFIG_LIBPMEM')}
+ summary_info += {'libdaxctl support': config_host.has_key('CONFIG_LIBDAXCTL')}
 diff --git a/qapi/block-core.json b/qapi/block-core.json
-index a177fea6cd..f782c2cf96 100644
+index 0fda1e3fd3..553112d998 100644
 --- a/qapi/block-core.json
 +++ b/qapi/block-core.json
-@@ -2951,7 +2951,7 @@
+@@ -2975,7 +2975,7 @@
              'luks', 'nbd', 'nfs', 'null-aio', 'null-co', 'nvme', 'parallels',
              'qcow', 'qcow2', 'qed', 'quorum', 'raw', 'rbd',
              { 'name': 'replication', 'if': 'defined(CONFIG_REPLICATION)' },
@@ -370,7 +372,7 @@ index a177fea6cd..f782c2cf96 100644
              'ssh', 'throttle', 'vdi', 'vhdx', 'vmdk', 'vpc', 'vvfat' ] }
  
  ##
-@@ -3015,6 +3015,17 @@
+@@ -3039,6 +3039,17 @@
  { 'struct': 'BlockdevOptionsNull',
    'data': { '*size': 'int', '*latency-ns': 'uint64', '*read-zeroes': 'bool' } }
  
@@ -388,7 +390,7 @@ index a177fea6cd..f782c2cf96 100644
  ##
  # @BlockdevOptionsNVMe:
  #
-@@ -4121,6 +4132,7 @@
+@@ -4148,6 +4159,7 @@
        'nfs':        'BlockdevOptionsNfs',
        'null-aio':   'BlockdevOptionsNull',
        'null-co':    'BlockdevOptionsNull',
diff --git a/debian/patches/pve/0044-PVE-add-query_proxmox_support-QMP-command.patch b/debian/patches/pve/0044-PVE-add-query_proxmox_support-QMP-command.patch
index e2dc20f..a9cbe84 100644
--- a/debian/patches/pve/0044-PVE-add-query_proxmox_support-QMP-command.patch
+++ b/debian/patches/pve/0044-PVE-add-query_proxmox_support-QMP-command.patch
@@ -16,7 +16,7 @@ Signed-off-by: Stefan Reiter <s.reiter at proxmox.com>
  2 files changed, 33 insertions(+)
 
 diff --git a/pve-backup.c b/pve-backup.c
-index bfb648d6b5..6bf138cfc6 100644
+index bfb648d6b5..ba9d0d8a86 100644
 --- a/pve-backup.c
 +++ b/pve-backup.c
 @@ -1051,3 +1051,11 @@ BackupStatus *qmp_query_backup(Error **errp)
@@ -32,10 +32,10 @@ index bfb648d6b5..6bf138cfc6 100644
 +    return ret;
 +}
 diff --git a/qapi/block-core.json b/qapi/block-core.json
-index f782c2cf96..1ed5987c88 100644
+index 553112d998..e0a0a60354 100644
 --- a/qapi/block-core.json
 +++ b/qapi/block-core.json
-@@ -877,6 +877,31 @@
+@@ -868,6 +868,31 @@
  ##
  { 'command': 'backup-cancel' }
  
diff --git a/debian/patches/pve/0045-pbs-fix-missing-crypt-and-compress-parameters.patch b/debian/patches/pve/0045-pbs-fix-missing-crypt-and-compress-parameters.patch
index 34b0f51..d4a03be 100644
--- a/debian/patches/pve/0045-pbs-fix-missing-crypt-and-compress-parameters.patch
+++ b/debian/patches/pve/0045-pbs-fix-missing-crypt-and-compress-parameters.patch
@@ -9,7 +9,7 @@ Signed-off-by: Wolfgang Bumiller <w.bumiller at proxmox.com>
  1 file changed, 6 insertions(+), 2 deletions(-)
 
 diff --git a/pve-backup.c b/pve-backup.c
-index 6bf138cfc6..cd3a132d8b 100644
+index ba9d0d8a86..e1dcf10a45 100644
 --- a/pve-backup.c
 +++ b/pve-backup.c
 @@ -958,6 +958,8 @@ UuidInfo *qmp_backup(
diff --git a/debian/patches/pve/0046-PVE-handle-PBS-write-callback-with-big-blocks-correc.patch b/debian/patches/pve/0046-PVE-handle-PBS-write-callback-with-big-blocks-correc.patch
index d45a455..7457eb6 100644
--- a/debian/patches/pve/0046-PVE-handle-PBS-write-callback-with-big-blocks-correc.patch
+++ b/debian/patches/pve/0046-PVE-handle-PBS-write-callback-with-big-blocks-correc.patch
@@ -17,7 +17,7 @@ Signed-off-by: Stefan Reiter <s.reiter at proxmox.com>
  1 file changed, 22 insertions(+), 8 deletions(-)
 
 diff --git a/pve-backup.c b/pve-backup.c
-index cd3a132d8b..f14273645a 100644
+index e1dcf10a45..3eba85506a 100644
 --- a/pve-backup.c
 +++ b/pve-backup.c
 @@ -67,6 +67,7 @@ opts_init(pvebackup_init);
diff --git a/debian/patches/pve/0047-PVE-add-zero-block-handling-to-PBS-dump-callback.patch b/debian/patches/pve/0047-PVE-add-zero-block-handling-to-PBS-dump-callback.patch
index 930ec8f..3bb6b35 100644
--- a/debian/patches/pve/0047-PVE-add-zero-block-handling-to-PBS-dump-callback.patch
+++ b/debian/patches/pve/0047-PVE-add-zero-block-handling-to-PBS-dump-callback.patch
@@ -20,7 +20,7 @@ Signed-off-by: Stefan Reiter <s.reiter at proxmox.com>
  1 file changed, 9 insertions(+), 5 deletions(-)
 
 diff --git a/pve-backup.c b/pve-backup.c
-index f14273645a..bd802c6205 100644
+index 3eba85506a..40c2697b37 100644
 --- a/pve-backup.c
 +++ b/pve-backup.c
 @@ -8,6 +8,7 @@
diff --git a/debian/patches/pve/0048-PVE-add-query-pbs-bitmap-info-QMP-call.patch b/debian/patches/pve/0048-PVE-add-query-pbs-bitmap-info-QMP-call.patch
index 54f1dfa..165f7c1 100644
--- a/debian/patches/pve/0048-PVE-add-query-pbs-bitmap-info-QMP-call.patch
+++ b/debian/patches/pve/0048-PVE-add-query-pbs-bitmap-info-QMP-call.patch
@@ -14,10 +14,10 @@ Signed-off-by: Stefan Reiter <s.reiter at proxmox.com>
  3 files changed, 159 insertions(+), 42 deletions(-)
 
 diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
-index 3ff014d32a..c3227a1498 100644
+index bc8e92c134..f47fc01c10 100644
 --- a/monitor/hmp-cmds.c
 +++ b/monitor/hmp-cmds.c
-@@ -195,6 +195,7 @@ void hmp_info_mice(Monitor *mon, const QDict *qdict)
+@@ -198,6 +198,7 @@ void hmp_info_mice(Monitor *mon, const QDict *qdict)
  void hmp_info_backup(Monitor *mon, const QDict *qdict)
  {
      BackupStatus *info;
@@ -25,7 +25,7 @@ index 3ff014d32a..c3227a1498 100644
  
      info = qmp_query_backup(NULL);
  
-@@ -225,26 +226,29 @@ void hmp_info_backup(Monitor *mon, const QDict *qdict)
+@@ -228,26 +229,29 @@ void hmp_info_backup(Monitor *mon, const QDict *qdict)
              // this should not happen normally
              monitor_printf(mon, "Total size: %d\n", 0);
          } else {
@@ -68,7 +68,7 @@ index 3ff014d32a..c3227a1498 100644
                             info->zero_bytes, zero_per);
  
 diff --git a/pve-backup.c b/pve-backup.c
-index bd802c6205..2db4a62580 100644
+index 40c2697b37..1e7b92a950 100644
 --- a/pve-backup.c
 +++ b/pve-backup.c
 @@ -46,6 +46,7 @@ static struct PVEBackupState {
@@ -357,10 +357,10 @@ index bd802c6205..2db4a62580 100644
      return ret;
  }
 diff --git a/qapi/block-core.json b/qapi/block-core.json
-index 1ed5987c88..03fc0af99b 100644
+index e0a0a60354..b368371e8e 100644
 --- a/qapi/block-core.json
 +++ b/qapi/block-core.json
-@@ -885,11 +885,14 @@
+@@ -876,11 +876,14 @@
  # @pbs-dirty-bitmap: True if dirty-bitmap-incremental backups to PBS are
  #                    supported.
  #
@@ -375,7 +375,7 @@ index 1ed5987c88..03fc0af99b 100644
              'pbs-library-version': 'str' } }
  
  ##
-@@ -902,6 +905,59 @@
+@@ -893,6 +896,59 @@
  ##
  { 'command': 'query-proxmox-support', 'returns': 'ProxmoxSupportStatus' }
  
diff --git a/debian/patches/pve/0049-PVE-redirect-stderr-to-journal-when-daemonized.patch b/debian/patches/pve/0049-PVE-redirect-stderr-to-journal-when-daemonized.patch
index 1d54282..7fb3c4f 100644
--- a/debian/patches/pve/0049-PVE-redirect-stderr-to-journal-when-daemonized.patch
+++ b/debian/patches/pve/0049-PVE-redirect-stderr-to-journal-when-daemonized.patch
@@ -1,6 +1,6 @@
 From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
 From: Stefan Reiter <s.reiter at proxmox.com>
-Date: Tue, 30 Jun 2020 13:10:10 +0200
+Date: Tue, 12 Jan 2021 14:12:20 +0100
 Subject: [PATCH] PVE: redirect stderr to journal when daemonized
 
 QEMU uses the logging for error messages usually, so LOG_ERR is most
@@ -8,24 +8,32 @@ fitting.
 
 Signed-off-by: Stefan Reiter <s.reiter at proxmox.com>
 ---
- Makefile.objs | 1 +
- os-posix.c    | 7 +++++--
- 2 files changed, 6 insertions(+), 2 deletions(-)
+ meson.build | 2 ++
+ os-posix.c  | 7 +++++--
+ 2 files changed, 7 insertions(+), 2 deletions(-)
 
-diff --git a/Makefile.objs b/Makefile.objs
-index 240eb503f2..c7ba4e11e7 100644
---- a/Makefile.objs
-+++ b/Makefile.objs
-@@ -54,6 +54,7 @@ common-obj-y += net/
- common-obj-y += qdev-monitor.o
- common-obj-$(CONFIG_WIN32) += os-win32.o
- common-obj-$(CONFIG_POSIX) += os-posix.o
-+os-posix.o-libs := -lsystemd
+diff --git a/meson.build b/meson.build
+index 4d156d35ce..737ea9e5d7 100644
+--- a/meson.build
++++ b/meson.build
+@@ -726,6 +726,7 @@ keyutils = dependency('libkeyutils', required: false,
+ has_gettid = cc.has_function('gettid')
  
- common-obj-$(CONFIG_LINUX) += fsdev/
+ libuuid = cc.find_library('uuid', required: true)
++libsystemd = cc.find_library('systemd', required: true)
+ libproxmox_backup_qemu = cc.find_library('proxmox_backup_qemu', required: true)
  
+ # Malloc tests
+@@ -1539,6 +1540,7 @@ blockdev_ss.add(files(
+ # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
+ # os-win32.c does not
+ blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
++blockdev_ss.add(when: 'CONFIG_POSIX', if_true: libsystemd)
+ softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
+ 
+ common_ss.add(files('cpus-common.c'))
 diff --git a/os-posix.c b/os-posix.c
-index 3572db3f44..b45dde63ac 100644
+index 1de2839554..ac4f652923 100644
 --- a/os-posix.c
 +++ b/os-posix.c
 @@ -28,6 +28,8 @@
@@ -37,7 +45,7 @@ index 3572db3f44..b45dde63ac 100644
  
  #include "qemu-common.h"
  /* Needed early for CONFIG_BSD etc. */
-@@ -312,9 +314,10 @@ void os_setup_post(void)
+@@ -288,9 +290,10 @@ void os_setup_post(void)
  
          dup2(fd, 0);
          dup2(fd, 1);
diff --git a/debian/patches/pve/0050-PVE-Add-sequential-job-transaction-support.patch b/debian/patches/pve/0050-PVE-Add-sequential-job-transaction-support.patch
index 20531d3..24f8bfb 100644
--- a/debian/patches/pve/0050-PVE-Add-sequential-job-transaction-support.patch
+++ b/debian/patches/pve/0050-PVE-Add-sequential-job-transaction-support.patch
@@ -33,7 +33,7 @@ index 32aabb1c60..f7a6a0926a 100644
   * Release a reference that was previously acquired with job_txn_add_job or
   * job_txn_new. If it's the last reference to the object, it will be freed.
 diff --git a/job.c b/job.c
-index b8139c80a4..97ee97a192 100644
+index f9884e7d9d..8f06e05fbf 100644
 --- a/job.c
 +++ b/job.c
 @@ -72,6 +72,8 @@ struct JobTxn {
diff --git a/debian/patches/pve/0051-PVE-Backup-Use-a-transaction-to-synchronize-job-stat.patch b/debian/patches/pve/0051-PVE-Backup-Use-a-transaction-to-synchronize-job-stat.patch
index daa2498..bb3b026 100644
--- a/debian/patches/pve/0051-PVE-Backup-Use-a-transaction-to-synchronize-job-stat.patch
+++ b/debian/patches/pve/0051-PVE-Backup-Use-a-transaction-to-synchronize-job-stat.patch
@@ -16,7 +16,7 @@ Signed-off-by: Stefan Reiter <s.reiter at proxmox.com>
  1 file changed, 49 insertions(+), 118 deletions(-)
 
 diff --git a/pve-backup.c b/pve-backup.c
-index 2db4a62580..b52f4a9364 100644
+index 1e7b92a950..f3df43eb8c 100644
 --- a/pve-backup.c
 +++ b/pve-backup.c
 @@ -52,6 +52,7 @@ static struct PVEBackupState {
diff --git a/debian/patches/pve/0052-PVE-Backup-Use-more-coroutines-and-don-t-block-on-fi.patch b/debian/patches/pve/0052-PVE-Backup-Use-more-coroutines-and-don-t-block-on-fi.patch
index 49213d9..b215d3d 100644
--- a/debian/patches/pve/0052-PVE-Backup-Use-more-coroutines-and-don-t-block-on-fi.patch
+++ b/debian/patches/pve/0052-PVE-Backup-Use-more-coroutines-and-don-t-block-on-fi.patch
@@ -38,7 +38,7 @@ Signed-off-by: Stefan Reiter <s.reiter at proxmox.com>
  2 files changed, 95 insertions(+), 58 deletions(-)
 
 diff --git a/pve-backup.c b/pve-backup.c
-index b52f4a9364..4402c0cb17 100644
+index f3df43eb8c..f3b8ce1f3a 100644
 --- a/pve-backup.c
 +++ b/pve-backup.c
 @@ -33,7 +33,9 @@ const char *PBS_BITMAP_NAME = "pbs-incremental-dirty-bitmap";
@@ -359,10 +359,10 @@ index b52f4a9364..4402c0cb17 100644
      qemu_mutex_unlock(&backup_state.stat.lock);
  
 diff --git a/qapi/block-core.json b/qapi/block-core.json
-index 03fc0af99b..29650896e2 100644
+index b368371e8e..b90d6abe64 100644
 --- a/qapi/block-core.json
 +++ b/qapi/block-core.json
-@@ -784,12 +784,15 @@
+@@ -775,12 +775,15 @@
  #
  # @uuid: uuid for this backup job
  #
diff --git a/debian/patches/pve/0053-PVE-fix-and-clean-up-error-handling-for-create_backu.patch b/debian/patches/pve/0053-PVE-fix-and-clean-up-error-handling-for-create_backu.patch
index 873fd37..92dc3e0 100644
--- a/debian/patches/pve/0053-PVE-fix-and-clean-up-error-handling-for-create_backu.patch
+++ b/debian/patches/pve/0053-PVE-fix-and-clean-up-error-handling-for-create_backu.patch
@@ -22,7 +22,7 @@ Signed-off-by: Stefan Reiter <s.reiter at proxmox.com>
  1 file changed, 54 insertions(+), 25 deletions(-)
 
 diff --git a/pve-backup.c b/pve-backup.c
-index 4402c0cb17..c7cde0fb0e 100644
+index f3b8ce1f3a..ded90cb822 100644
 --- a/pve-backup.c
 +++ b/pve-backup.c
 @@ -50,6 +50,7 @@ static struct PVEBackupState {
diff --git a/debian/patches/pve/0055-PVE-Migrate-dirty-bitmap-state-via-savevm.patch b/debian/patches/pve/0054-PVE-Migrate-dirty-bitmap-state-via-savevm.patch
similarity index 90%
rename from debian/patches/pve/0055-PVE-Migrate-dirty-bitmap-state-via-savevm.patch
rename to debian/patches/pve/0054-PVE-Migrate-dirty-bitmap-state-via-savevm.patch
index 1c64645..a4ee6bc 100644
--- a/debian/patches/pve/0055-PVE-Migrate-dirty-bitmap-state-via-savevm.patch
+++ b/debian/patches/pve/0054-PVE-Migrate-dirty-bitmap-state-via-savevm.patch
@@ -14,12 +14,12 @@ safe migration is possible and makes sense.
 Signed-off-by: Stefan Reiter <s.reiter at proxmox.com>
 ---
  include/migration/misc.h |   3 ++
- migration/Makefile.objs  |   1 +
+ migration/meson.build    |   2 +
  migration/pbs-state.c    | 106 +++++++++++++++++++++++++++++++++++++++
  pve-backup.c             |   1 +
  qapi/block-core.json     |   6 +++
  softmmu/vl.c             |   1 +
- 6 files changed, 118 insertions(+)
+ 6 files changed, 119 insertions(+)
  create mode 100644 migration/pbs-state.c
 
 diff --git a/include/migration/misc.h b/include/migration/misc.h
@@ -34,18 +34,21 @@ index 34e7d75713..f83816dd3c 100644
 +void pbs_state_mig_init(void);
 +
  #endif
-diff --git a/migration/Makefile.objs b/migration/Makefile.objs
-index 0fc619e380..20b3792599 100644
---- a/migration/Makefile.objs
-+++ b/migration/Makefile.objs
-@@ -9,6 +9,7 @@ common-obj-y += qjson.o
- common-obj-y += block-dirty-bitmap.o
- common-obj-y += multifd.o
- common-obj-y += multifd-zlib.o
-+common-obj-y += pbs-state.o
- common-obj-$(CONFIG_ZSTD) += multifd-zstd.o
+diff --git a/migration/meson.build b/migration/meson.build
+index e62b79b60f..b90a04aa75 100644
+--- a/migration/meson.build
++++ b/migration/meson.build
+@@ -7,8 +7,10 @@ migration_files = files(
+   'qemu-file-channel.c',
+   'qemu-file.c',
+   'qjson.c',
++  'pbs-state.c',
+ )
+ softmmu_ss.add(migration_files)
++softmmu_ss.add(libproxmox_backup_qemu)
  
- common-obj-$(CONFIG_RDMA) += rdma.o
+ softmmu_ss.add(files(
+   'block-dirty-bitmap.c',
 diff --git a/migration/pbs-state.c b/migration/pbs-state.c
 new file mode 100644
 index 0000000000..29f2b3860d
@@ -159,7 +162,7 @@ index 0000000000..29f2b3860d
 +                         NULL);
 +}
 diff --git a/pve-backup.c b/pve-backup.c
-index c7cde0fb0e..f65f1dda26 100644
+index ded90cb822..6b25292ba1 100644
 --- a/pve-backup.c
 +++ b/pve-backup.c
 @@ -1130,5 +1130,6 @@ ProxmoxSupportStatus *qmp_query_proxmox_support(Error **errp)
@@ -170,10 +173,10 @@ index c7cde0fb0e..f65f1dda26 100644
      return ret;
  }
 diff --git a/qapi/block-core.json b/qapi/block-core.json
-index 29650896e2..0da4b35028 100644
+index b90d6abe64..dee3d87efe 100644
 --- a/qapi/block-core.json
 +++ b/qapi/block-core.json
-@@ -890,12 +890,18 @@
+@@ -881,12 +881,18 @@
  #
  # @query-bitmap-info: True if the 'query-pbs-bitmap-info' QMP call is supported.
  #
@@ -193,10 +196,10 @@ index 29650896e2..0da4b35028 100644
  
  ##
 diff --git a/softmmu/vl.c b/softmmu/vl.c
-index 16aa2186b0..88b13871fd 100644
+index 5b5512128e..6721889fee 100644
 --- a/softmmu/vl.c
 +++ b/softmmu/vl.c
-@@ -4288,6 +4288,7 @@ void qemu_init(int argc, char **argv, char **envp)
+@@ -4304,6 +4304,7 @@ void qemu_init(int argc, char **argv, char **envp)
      blk_mig_init();
      ram_mig_init();
      dirty_bitmap_mig_init();
diff --git a/debian/patches/pve/0054-migration-block-dirty-bitmap-fix-larger-granularity-.patch b/debian/patches/pve/0054-migration-block-dirty-bitmap-fix-larger-granularity-.patch
deleted file mode 100644
index a05478b..0000000
--- a/debian/patches/pve/0054-migration-block-dirty-bitmap-fix-larger-granularity-.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Stefan Reiter <s.reiter at proxmox.com>
-Date: Thu, 22 Oct 2020 17:34:17 +0200
-Subject: [PATCH] migration/block-dirty-bitmap: fix larger granularity bitmaps
-
-sectors_per_chunk is a 64 bit integer, but the calculation would be done
-in 32 bits, leading to an overflow for coarse bitmap granularities.
-
-If that results in the value 0, it leads to a hang where no progress is
-made but send_bitmap_bits is constantly called with nr_sectors being 0.
-
-Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov at virtuozzo.com>
-Reviewed-by: Eric Blake <eblake at redhat.com>
-Signed-off-by: Stefan Reiter <s.reiter at proxmox.com>
----
- migration/block-dirty-bitmap.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/migration/block-dirty-bitmap.c b/migration/block-dirty-bitmap.c
-index 784330ebe1..5bf0d9fbc6 100644
---- a/migration/block-dirty-bitmap.c
-+++ b/migration/block-dirty-bitmap.c
-@@ -334,8 +334,9 @@ static int add_bitmaps_to_list(DBMSaveState *s, BlockDriverState *bs,
-         dbms->node_name = bs_name;
-         dbms->bitmap = bitmap;
-         dbms->total_sectors = bdrv_nb_sectors(bs);
--        dbms->sectors_per_chunk = CHUNK_SIZE * 8 *
-+        dbms->sectors_per_chunk = CHUNK_SIZE * 8LLU *
-             bdrv_dirty_bitmap_granularity(bitmap) >> BDRV_SECTOR_BITS;
-+        assert(dbms->sectors_per_chunk != 0);
-         if (bdrv_dirty_bitmap_enabled(bitmap)) {
-             dbms->flags |= DIRTY_BITMAP_MIG_START_FLAG_ENABLED;
-         }
diff --git a/debian/patches/pve/0056-migration-block-dirty-bitmap-migrate-other-bitmaps-e.patch b/debian/patches/pve/0055-migration-block-dirty-bitmap-migrate-other-bitmaps-e.patch
similarity index 89%
rename from debian/patches/pve/0056-migration-block-dirty-bitmap-migrate-other-bitmaps-e.patch
rename to debian/patches/pve/0055-migration-block-dirty-bitmap-migrate-other-bitmaps-e.patch
index 3154291..775f992 100644
--- a/debian/patches/pve/0056-migration-block-dirty-bitmap-migrate-other-bitmaps-e.patch
+++ b/debian/patches/pve/0055-migration-block-dirty-bitmap-migrate-other-bitmaps-e.patch
@@ -18,10 +18,10 @@ Signed-off-by: Stefan Reiter <s.reiter at proxmox.com>
  1 file changed, 1 insertion(+), 1 deletion(-)
 
 diff --git a/migration/block-dirty-bitmap.c b/migration/block-dirty-bitmap.c
-index 5bf0d9fbc6..1070c19181 100644
+index c61d382be8..26e4e5c99c 100644
 --- a/migration/block-dirty-bitmap.c
 +++ b/migration/block-dirty-bitmap.c
-@@ -323,7 +323,7 @@ static int add_bitmaps_to_list(DBMSaveState *s, BlockDriverState *bs,
+@@ -534,7 +534,7 @@ static int add_bitmaps_to_list(DBMSaveState *s, BlockDriverState *bs,
  
          if (bdrv_dirty_bitmap_check(bitmap, BDRV_BITMAP_DEFAULT, &local_err)) {
              error_report_err(local_err);
@@ -29,4 +29,4 @@ index 5bf0d9fbc6..1070c19181 100644
 +            continue;
          }
  
-         bdrv_ref(bs);
+         if (bitmap_aliases) {
diff --git a/debian/patches/pve/0057-PVE-fix-aborting-multiple-CREATED-jobs-in-sequential.patch b/debian/patches/pve/0056-PVE-fix-aborting-multiple-CREATED-jobs-in-sequential.patch
similarity index 97%
rename from debian/patches/pve/0057-PVE-fix-aborting-multiple-CREATED-jobs-in-sequential.patch
rename to debian/patches/pve/0056-PVE-fix-aborting-multiple-CREATED-jobs-in-sequential.patch
index 0b5e601..0e30326 100644
--- a/debian/patches/pve/0057-PVE-fix-aborting-multiple-CREATED-jobs-in-sequential.patch
+++ b/debian/patches/pve/0056-PVE-fix-aborting-multiple-CREATED-jobs-in-sequential.patch
@@ -20,7 +20,7 @@ Signed-off-by: Wolfgang Bumiller <w.bumiller at proxmox.com>
  1 file changed, 7 insertions(+)
 
 diff --git a/job.c b/job.c
-index 97ee97a192..51984e557c 100644
+index 8f06e05fbf..05b7797e82 100644
 --- a/job.c
 +++ b/job.c
 @@ -1035,6 +1035,13 @@ int job_finish_sync(Job *job, void (*finish)(Job *, Error **errp), Error **errp)
diff --git a/debian/patches/pve/0057-PVE-Use-coroutine-QMP-for-backup-cancel_backup.patch b/debian/patches/pve/0057-PVE-Use-coroutine-QMP-for-backup-cancel_backup.patch
new file mode 100644
index 0000000..0cead60
--- /dev/null
+++ b/debian/patches/pve/0057-PVE-Use-coroutine-QMP-for-backup-cancel_backup.patch
@@ -0,0 +1,595 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Stefan Reiter <s.reiter at proxmox.com>
+Date: Tue, 26 Jan 2021 15:45:30 +0100
+Subject: [PATCH] PVE: Use coroutine QMP for backup/cancel_backup
+
+Finally turn backup QMP calls into coroutines, now that it's possible.
+This has the benefit that calls are asynchronous to the main loop, i.e.
+long running operations like connecting to a PBS server will no longer
+hang the VM.
+
+Additionally, it allows us to get rid of block_on_coroutine_fn, which
+was always a hacky workaround.
+
+While we're already spring cleaning, also remove the QmpBackupTask
+struct, since we can now put the 'prepare' function directly into
+qmp_backup and thus no longer need those giant walls of text.
+
+(Note that for our patches to work with 5.2.0 this change is actually
+required, otherwise monitor_get_fd() fails as we're not in a QMP
+coroutine, but one we start ourselves - we could of course set the
+monitor for that coroutine ourselves, but let's just fix it the right
+way instead)
+---
+ block/monitor/block-hmp-cmds.c |   4 +-
+ hmp-commands.hx                |   2 +
+ proxmox-backup-client.c        |  31 -----
+ pve-backup.c                   | 232 ++++++++++-----------------------
+ qapi/block-core.json           |   4 +-
+ 5 files changed, 77 insertions(+), 196 deletions(-)
+
+diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
+index 46c63b1cf9..11c84d5508 100644
+--- a/block/monitor/block-hmp-cmds.c
++++ b/block/monitor/block-hmp-cmds.c
+@@ -1013,7 +1013,7 @@ void hmp_info_snapshots(Monitor *mon, const QDict *qdict)
+     g_free(global_snapshots);
+ }
+ 
+-void hmp_backup_cancel(Monitor *mon, const QDict *qdict)
++void coroutine_fn hmp_backup_cancel(Monitor *mon, const QDict *qdict)
+ {
+     Error *error = NULL;
+ 
+@@ -1022,7 +1022,7 @@ void hmp_backup_cancel(Monitor *mon, const QDict *qdict)
+     hmp_handle_error(mon, error);
+ }
+ 
+-void hmp_backup(Monitor *mon, const QDict *qdict)
++void coroutine_fn hmp_backup(Monitor *mon, const QDict *qdict)
+ {
+     Error *error = NULL;
+ 
+diff --git a/hmp-commands.hx b/hmp-commands.hx
+index 70257ef7ca..b7639d189d 100644
+--- a/hmp-commands.hx
++++ b/hmp-commands.hx
+@@ -108,6 +108,7 @@ ERST
+ 		    "\n\t\t\t Use -d to dump data into a directory instead"
+ 		    "\n\t\t\t of using VMA format.",
+         .cmd = hmp_backup,
++        .coroutine  = true,
+     },
+ 
+ SRST
+@@ -121,6 +122,7 @@ ERST
+         .params     = "",
+         .help       = "cancel the current VM backup",
+         .cmd        = hmp_backup_cancel,
++        .coroutine  = true,
+     },
+ 
+ SRST
+diff --git a/proxmox-backup-client.c b/proxmox-backup-client.c
+index 4ce7bc0b5e..0923037dec 100644
+--- a/proxmox-backup-client.c
++++ b/proxmox-backup-client.c
+@@ -5,37 +5,6 @@
+ 
+ /* Proxmox Backup Server client bindings using coroutines */
+ 
+-typedef struct BlockOnCoroutineWrapper {
+-    AioContext *ctx;
+-    CoroutineEntry *entry;
+-    void *entry_arg;
+-    bool finished;
+-} BlockOnCoroutineWrapper;
+-
+-static void coroutine_fn block_on_coroutine_wrapper(void *opaque)
+-{
+-    BlockOnCoroutineWrapper *wrapper = opaque;
+-    wrapper->entry(wrapper->entry_arg);
+-    wrapper->finished = true;
+-    aio_wait_kick();
+-}
+-
+-void block_on_coroutine_fn(CoroutineEntry *entry, void *entry_arg)
+-{
+-    assert(!qemu_in_coroutine());
+-
+-    AioContext *ctx = qemu_get_current_aio_context();
+-    BlockOnCoroutineWrapper wrapper = {
+-        .finished = false,
+-        .entry = entry,
+-        .entry_arg = entry_arg,
+-        .ctx = ctx,
+-    };
+-    Coroutine *wrapper_co = qemu_coroutine_create(block_on_coroutine_wrapper, &wrapper);
+-    aio_co_enter(ctx, wrapper_co);
+-    AIO_WAIT_WHILE(ctx, !wrapper.finished);
+-}
+-
+ // This is called from another thread, so we use aio_co_schedule()
+ static void proxmox_backup_schedule_wake(void *data) {
+     CoCtxData *waker = (CoCtxData *)data;
+diff --git a/pve-backup.c b/pve-backup.c
+index 6b25292ba1..f7597ae55c 100644
+--- a/pve-backup.c
++++ b/pve-backup.c
+@@ -357,7 +357,7 @@ static void job_cancel_bh(void *opaque) {
+     aio_co_enter(data->ctx, data->co);
+ }
+ 
+-static void coroutine_fn pvebackup_co_cancel(void *opaque)
++void coroutine_fn qmp_backup_cancel(Error **errp)
+ {
+     Error *cancel_err = NULL;
+     error_setg(&cancel_err, "backup canceled");
+@@ -394,11 +394,6 @@ static void coroutine_fn pvebackup_co_cancel(void *opaque)
+     qemu_co_mutex_unlock(&backup_state.backup_mutex);
+ }
+ 
+-void qmp_backup_cancel(Error **errp)
+-{
+-    block_on_coroutine_fn(pvebackup_co_cancel, NULL);
+-}
+-
+ // assumes the caller holds backup_mutex
+ static int coroutine_fn pvebackup_co_add_config(
+     const char *file,
+@@ -531,50 +526,27 @@ static void create_backup_jobs_bh(void *opaque) {
+     aio_co_enter(data->ctx, data->co);
+ }
+ 
+-typedef struct QmpBackupTask {
+-    const char *backup_file;
+-    bool has_password;
+-    const char *password;
+-    bool has_keyfile;
+-    const char *keyfile;
+-    bool has_key_password;
+-    const char *key_password;
+-    bool has_backup_id;
+-    const char *backup_id;
+-    bool has_backup_time;
+-    const char *fingerprint;
+-    bool has_fingerprint;
+-    int64_t backup_time;
+-    bool has_use_dirty_bitmap;
+-    bool use_dirty_bitmap;
+-    bool has_format;
+-    BackupFormat format;
+-    bool has_config_file;
+-    const char *config_file;
+-    bool has_firewall_file;
+-    const char *firewall_file;
+-    bool has_devlist;
+-    const char *devlist;
+-    bool has_compress;
+-    bool compress;
+-    bool has_encrypt;
+-    bool encrypt;
+-    bool has_speed;
+-    int64_t speed;
+-    Error **errp;
+-    UuidInfo *result;
+-} QmpBackupTask;
+-
+-static void coroutine_fn pvebackup_co_prepare(void *opaque)
++UuidInfo coroutine_fn *qmp_backup(
++    const char *backup_file,
++    bool has_password, const char *password,
++    bool has_keyfile, const char *keyfile,
++    bool has_key_password, const char *key_password,
++    bool has_fingerprint, const char *fingerprint,
++    bool has_backup_id, const char *backup_id,
++    bool has_backup_time, int64_t backup_time,
++    bool has_use_dirty_bitmap, bool use_dirty_bitmap,
++    bool has_compress, bool compress,
++    bool has_encrypt, bool encrypt,
++    bool has_format, BackupFormat format,
++    bool has_config_file, const char *config_file,
++    bool has_firewall_file, const char *firewall_file,
++    bool has_devlist, const char *devlist,
++    bool has_speed, int64_t speed, Error **errp)
+ {
+     assert(qemu_in_coroutine());
+ 
+     qemu_co_mutex_lock(&backup_state.backup_mutex);
+ 
+-    QmpBackupTask *task = opaque;
+-
+-    task->result = NULL; // just to be sure
+-
+     BlockBackend *blk;
+     BlockDriverState *bs = NULL;
+     const char *backup_dir = NULL;
+@@ -591,17 +563,17 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
+     const char *firewall_name = "qemu-server.fw";
+ 
+     if (backup_state.di_list) {
+-        error_set(task->errp, ERROR_CLASS_GENERIC_ERROR,
++        error_set(errp, ERROR_CLASS_GENERIC_ERROR,
+                   "previous backup not finished");
+         qemu_co_mutex_unlock(&backup_state.backup_mutex);
+-        return;
++        return NULL;
+     }
+ 
+     /* Todo: try to auto-detect format based on file name */
+-    BackupFormat format = task->has_format ? task->format : BACKUP_FORMAT_VMA;
++    format = has_format ? format : BACKUP_FORMAT_VMA;
+ 
+-    if (task->has_devlist) {
+-        devs = g_strsplit_set(task->devlist, ",;:", -1);
++    if (has_devlist) {
++        devs = g_strsplit_set(devlist, ",;:", -1);
+ 
+         gchar **d = devs;
+         while (d && *d) {
+@@ -609,14 +581,14 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
+             if (blk) {
+                 bs = blk_bs(blk);
+                 if (!bdrv_is_inserted(bs)) {
+-                    error_setg(task->errp, QERR_DEVICE_HAS_NO_MEDIUM, *d);
++                    error_setg(errp, QERR_DEVICE_HAS_NO_MEDIUM, *d);
+                     goto err;
+                 }
+                 PVEBackupDevInfo *di = g_new0(PVEBackupDevInfo, 1);
+                 di->bs = bs;
+                 di_list = g_list_append(di_list, di);
+             } else {
+-                error_set(task->errp, ERROR_CLASS_DEVICE_NOT_FOUND,
++                error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
+                           "Device '%s' not found", *d);
+                 goto err;
+             }
+@@ -639,7 +611,7 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
+     }
+ 
+     if (!di_list) {
+-        error_set(task->errp, ERROR_CLASS_GENERIC_ERROR, "empty device list");
++        error_set(errp, ERROR_CLASS_GENERIC_ERROR, "empty device list");
+         goto err;
+     }
+ 
+@@ -649,13 +621,13 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
+     while (l) {
+         PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
+         l = g_list_next(l);
+-        if (bdrv_op_is_blocked(di->bs, BLOCK_OP_TYPE_BACKUP_SOURCE, task->errp)) {
++        if (bdrv_op_is_blocked(di->bs, BLOCK_OP_TYPE_BACKUP_SOURCE, errp)) {
+             goto err;
+         }
+ 
+         ssize_t size = bdrv_getlength(di->bs);
+         if (size < 0) {
+-            error_setg_errno(task->errp, -di->size, "bdrv_getlength failed");
++            error_setg_errno(errp, -di->size, "bdrv_getlength failed");
+             goto err;
+         }
+         di->size = size;
+@@ -682,47 +654,44 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
+     }
+ 
+     if (format == BACKUP_FORMAT_PBS) {
+-        if (!task->has_password) {
+-            error_set(task->errp, ERROR_CLASS_GENERIC_ERROR, "missing parameter 'password'");
++        if (!has_password) {
++            error_set(errp, ERROR_CLASS_GENERIC_ERROR, "missing parameter 'password'");
+             goto err_mutex;
+         }
+-        if (!task->has_backup_id) {
+-            error_set(task->errp, ERROR_CLASS_GENERIC_ERROR, "missing parameter 'backup-id'");
++        if (!has_backup_id) {
++            error_set(errp, ERROR_CLASS_GENERIC_ERROR, "missing parameter 'backup-id'");
+             goto err_mutex;
+         }
+-        if (!task->has_backup_time) {
+-            error_set(task->errp, ERROR_CLASS_GENERIC_ERROR, "missing parameter 'backup-time'");
++        if (!has_backup_time) {
++            error_set(errp, ERROR_CLASS_GENERIC_ERROR, "missing parameter 'backup-time'");
+             goto err_mutex;
+         }
+ 
+         int dump_cb_block_size = PROXMOX_BACKUP_DEFAULT_CHUNK_SIZE; // Hardcoded (4M)
+         firewall_name = "fw.conf";
+ 
+-        bool use_dirty_bitmap = task->has_use_dirty_bitmap && task->use_dirty_bitmap;
+-
+-
+         char *pbs_err = NULL;
+         pbs = proxmox_backup_new(
+-            task->backup_file,
+-            task->backup_id,
+-            task->backup_time,
++            backup_file,
++            backup_id,
++            backup_time,
+             dump_cb_block_size,
+-            task->has_password ? task->password : NULL,
+-            task->has_keyfile ? task->keyfile : NULL,
+-            task->has_key_password ? task->key_password : NULL,
+-            task->has_compress ? task->compress : true,
+-            task->has_encrypt ? task->encrypt : task->has_keyfile,
+-            task->has_fingerprint ? task->fingerprint : NULL,
++            has_password ? password : NULL,
++            has_keyfile ? keyfile : NULL,
++            has_key_password ? key_password : NULL,
++            has_compress ? compress : true,
++            has_encrypt ? encrypt : has_keyfile,
++            has_fingerprint ? fingerprint : NULL,
+              &pbs_err);
+ 
+         if (!pbs) {
+-            error_set(task->errp, ERROR_CLASS_GENERIC_ERROR,
++            error_set(errp, ERROR_CLASS_GENERIC_ERROR,
+                       "proxmox_backup_new failed: %s", pbs_err);
+             proxmox_backup_free_error(pbs_err);
+             goto err_mutex;
+         }
+ 
+-        int connect_result = proxmox_backup_co_connect(pbs, task->errp);
++        int connect_result = proxmox_backup_co_connect(pbs, errp);
+         if (connect_result < 0)
+             goto err_mutex;
+ 
+@@ -741,9 +710,9 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
+             BdrvDirtyBitmap *bitmap = bdrv_find_dirty_bitmap(di->bs, PBS_BITMAP_NAME);
+             bool expect_only_dirty = false;
+ 
+-            if (use_dirty_bitmap) {
++            if (has_use_dirty_bitmap && use_dirty_bitmap) {
+                 if (bitmap == NULL) {
+-                    bitmap = bdrv_create_dirty_bitmap(di->bs, dump_cb_block_size, PBS_BITMAP_NAME, task->errp);
++                    bitmap = bdrv_create_dirty_bitmap(di->bs, dump_cb_block_size, PBS_BITMAP_NAME, errp);
+                     if (!bitmap) {
+                         goto err_mutex;
+                     }
+@@ -773,12 +742,12 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
+                 }
+             }
+ 
+-            int dev_id = proxmox_backup_co_register_image(pbs, devname, di->size, expect_only_dirty, task->errp);
++            int dev_id = proxmox_backup_co_register_image(pbs, devname, di->size, expect_only_dirty, errp);
+             if (dev_id < 0) {
+                 goto err_mutex;
+             }
+ 
+-            if (!(di->target = bdrv_backup_dump_create(dump_cb_block_size, di->size, pvebackup_co_dump_pbs_cb, di, task->errp))) {
++            if (!(di->target = bdrv_backup_dump_create(dump_cb_block_size, di->size, pvebackup_co_dump_pbs_cb, di, errp))) {
+                 goto err_mutex;
+             }
+ 
+@@ -792,10 +761,10 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
+             backup_state.stat.bitmap_list = g_list_append(backup_state.stat.bitmap_list, info);
+         }
+     } else if (format == BACKUP_FORMAT_VMA) {
+-        vmaw = vma_writer_create(task->backup_file, uuid, &local_err);
++        vmaw = vma_writer_create(backup_file, uuid, &local_err);
+         if (!vmaw) {
+             if (local_err) {
+-                error_propagate(task->errp, local_err);
++                error_propagate(errp, local_err);
+             }
+             goto err_mutex;
+         }
+@@ -806,25 +775,25 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
+             PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
+             l = g_list_next(l);
+ 
+-            if (!(di->target = bdrv_backup_dump_create(VMA_CLUSTER_SIZE, di->size, pvebackup_co_dump_vma_cb, di, task->errp))) {
++            if (!(di->target = bdrv_backup_dump_create(VMA_CLUSTER_SIZE, di->size, pvebackup_co_dump_vma_cb, di, errp))) {
+                 goto err_mutex;
+             }
+ 
+             const char *devname = bdrv_get_device_name(di->bs);
+             di->dev_id = vma_writer_register_stream(vmaw, devname, di->size);
+             if (di->dev_id <= 0) {
+-                error_set(task->errp, ERROR_CLASS_GENERIC_ERROR,
++                error_set(errp, ERROR_CLASS_GENERIC_ERROR,
+                           "register_stream failed");
+                 goto err_mutex;
+             }
+         }
+     } else if (format == BACKUP_FORMAT_DIR) {
+-        if (mkdir(task->backup_file, 0640) != 0) {
+-            error_setg_errno(task->errp, errno, "can't create directory '%s'\n",
+-                             task->backup_file);
++        if (mkdir(backup_file, 0640) != 0) {
++            error_setg_errno(errp, errno, "can't create directory '%s'\n",
++                             backup_file);
+             goto err_mutex;
+         }
+-        backup_dir = task->backup_file;
++        backup_dir = backup_file;
+ 
+         l = di_list;
+         while (l) {
+@@ -838,34 +807,34 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
+             bdrv_img_create(di->targetfile, "raw", NULL, NULL, NULL,
+                             di->size, flags, false, &local_err);
+             if (local_err) {
+-                error_propagate(task->errp, local_err);
++                error_propagate(errp, local_err);
+                 goto err_mutex;
+             }
+ 
+             di->target = bdrv_open(di->targetfile, NULL, NULL, flags, &local_err);
+             if (!di->target) {
+-                error_propagate(task->errp, local_err);
++                error_propagate(errp, local_err);
+                 goto err_mutex;
+             }
+         }
+     } else {
+-        error_set(task->errp, ERROR_CLASS_GENERIC_ERROR, "unknown backup format");
++        error_set(errp, ERROR_CLASS_GENERIC_ERROR, "unknown backup format");
+         goto err_mutex;
+     }
+ 
+ 
+     /* add configuration file to archive */
+-    if (task->has_config_file) {
+-        if (pvebackup_co_add_config(task->config_file, config_name, format, backup_dir,
+-                                    vmaw, pbs, task->errp) != 0) {
++    if (has_config_file) {
++        if (pvebackup_co_add_config(config_file, config_name, format, backup_dir,
++                                    vmaw, pbs, errp) != 0) {
+             goto err_mutex;
+         }
+     }
+ 
+     /* add firewall file to archive */
+-    if (task->has_firewall_file) {
+-        if (pvebackup_co_add_config(task->firewall_file, firewall_name, format, backup_dir,
+-                                    vmaw, pbs, task->errp) != 0) {
++    if (has_firewall_file) {
++        if (pvebackup_co_add_config(firewall_file, firewall_name, format, backup_dir,
++                                    vmaw, pbs, errp) != 0) {
+             goto err_mutex;
+         }
+     }
+@@ -883,7 +852,7 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
+     if (backup_state.stat.backup_file) {
+         g_free(backup_state.stat.backup_file);
+     }
+-    backup_state.stat.backup_file = g_strdup(task->backup_file);
++    backup_state.stat.backup_file = g_strdup(backup_file);
+ 
+     uuid_copy(backup_state.stat.uuid, uuid);
+     uuid_unparse_lower(uuid, backup_state.stat.uuid_str);
+@@ -898,7 +867,7 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
+ 
+     qemu_mutex_unlock(&backup_state.stat.lock);
+ 
+-    backup_state.speed = (task->has_speed && task->speed > 0) ? task->speed : 0;
++    backup_state.speed = (has_speed && speed > 0) ? speed : 0;
+ 
+     backup_state.vmaw = vmaw;
+     backup_state.pbs = pbs;
+@@ -908,8 +877,6 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
+     uuid_info = g_malloc0(sizeof(*uuid_info));
+     uuid_info->UUID = uuid_str;
+ 
+-    task->result = uuid_info;
+-
+     /* Run create_backup_jobs_bh outside of coroutine (in BH) but keep
+     * backup_mutex locked. This is fine, a CoMutex can be held across yield
+     * points, and we'll release it as soon as the BH reschedules us.
+@@ -923,7 +890,7 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
+     qemu_coroutine_yield();
+ 
+     if (local_err) {
+-        error_propagate(task->errp, local_err);
++        error_propagate(errp, local_err);
+         goto err;
+     }
+ 
+@@ -936,7 +903,7 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
+     /* start the first job in the transaction */
+     job_txn_start_seq(backup_state.txn);
+ 
+-    return;
++    return uuid_info;
+ 
+ err_mutex:
+     qemu_mutex_unlock(&backup_state.stat.lock);
+@@ -967,7 +934,7 @@ err:
+     if (vmaw) {
+         Error *err = NULL;
+         vma_writer_close(vmaw, &err);
+-        unlink(task->backup_file);
++        unlink(backup_file);
+     }
+ 
+     if (pbs) {
+@@ -978,65 +945,8 @@ err:
+         rmdir(backup_dir);
+     }
+ 
+-    task->result = NULL;
+-
+     qemu_co_mutex_unlock(&backup_state.backup_mutex);
+-    return;
+-}
+-
+-UuidInfo *qmp_backup(
+-    const char *backup_file,
+-    bool has_password, const char *password,
+-    bool has_keyfile, const char *keyfile,
+-    bool has_key_password, const char *key_password,
+-    bool has_fingerprint, const char *fingerprint,
+-    bool has_backup_id, const char *backup_id,
+-    bool has_backup_time, int64_t backup_time,
+-    bool has_use_dirty_bitmap, bool use_dirty_bitmap,
+-    bool has_compress, bool compress,
+-    bool has_encrypt, bool encrypt,
+-    bool has_format, BackupFormat format,
+-    bool has_config_file, const char *config_file,
+-    bool has_firewall_file, const char *firewall_file,
+-    bool has_devlist, const char *devlist,
+-    bool has_speed, int64_t speed, Error **errp)
+-{
+-    QmpBackupTask task = {
+-        .backup_file = backup_file,
+-        .has_password = has_password,
+-        .password = password,
+-        .has_keyfile = has_keyfile,
+-        .keyfile = keyfile,
+-        .has_key_password = has_key_password,
+-        .key_password = key_password,
+-        .has_fingerprint = has_fingerprint,
+-        .fingerprint = fingerprint,
+-        .has_backup_id = has_backup_id,
+-        .backup_id = backup_id,
+-        .has_backup_time = has_backup_time,
+-        .backup_time = backup_time,
+-        .has_use_dirty_bitmap = has_use_dirty_bitmap,
+-        .use_dirty_bitmap = use_dirty_bitmap,
+-        .has_compress = has_compress,
+-        .compress = compress,
+-        .has_encrypt = has_encrypt,
+-        .encrypt = encrypt,
+-        .has_format = has_format,
+-        .format = format,
+-        .has_config_file = has_config_file,
+-        .config_file = config_file,
+-        .has_firewall_file = has_firewall_file,
+-        .firewall_file = firewall_file,
+-        .has_devlist = has_devlist,
+-        .devlist = devlist,
+-        .has_speed = has_speed,
+-        .speed = speed,
+-        .errp = errp,
+-    };
+-
+-    block_on_coroutine_fn(pvebackup_co_prepare, &task);
+-
+-    return task.result;
++    return NULL;
+ }
+ 
+ BackupStatus *qmp_query_backup(Error **errp)
+diff --git a/qapi/block-core.json b/qapi/block-core.json
+index dee3d87efe..82133e2bee 100644
+--- a/qapi/block-core.json
++++ b/qapi/block-core.json
+@@ -847,7 +847,7 @@
+                                     '*config-file': 'str',
+                                     '*firewall-file': 'str',
+                                     '*devlist': 'str', '*speed': 'int' },
+-  'returns': 'UuidInfo' }
++  'returns': 'UuidInfo', 'coroutine': true }
+ 
+ ##
+ # @query-backup:
+@@ -869,7 +869,7 @@
+ # Notes: This command succeeds even if there is no backup process running.
+ #
+ ##
+-{ 'command': 'backup-cancel' }
++{ 'command': 'backup-cancel', 'coroutine': true }
+ 
+ ##
+ # @ProxmoxSupportStatus:
diff --git a/debian/patches/series b/debian/patches/series
index 44462c2..b64505d 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1,6 +1,4 @@
-extra/0001-block-block-copy-always-align-copied-region-to-clust.patch
-extra/0002-Revert-qemu-img-convert-Don-t-pre-zero-images.patch
-extra/0003-usb-fix-setup_len-init-CVE-2020-14364.patch
+extra/0001-Revert-qemu-img-convert-Don-t-pre-zero-images.patch
 pve/0001-PVE-Config-block-file-change-locking-default-to-off.patch
 pve/0002-PVE-Config-Adjust-network-script-path-to-etc-kvm.patch
 pve/0003-PVE-Config-set-the-CPU-model-to-kvm64-32-instead-of-.patch
@@ -54,7 +52,7 @@ pve/0050-PVE-Add-sequential-job-transaction-support.patch
 pve/0051-PVE-Backup-Use-a-transaction-to-synchronize-job-stat.patch
 pve/0052-PVE-Backup-Use-more-coroutines-and-don-t-block-on-fi.patch
 pve/0053-PVE-fix-and-clean-up-error-handling-for-create_backu.patch
-pve/0054-migration-block-dirty-bitmap-fix-larger-granularity-.patch
-pve/0055-PVE-Migrate-dirty-bitmap-state-via-savevm.patch
-pve/0056-migration-block-dirty-bitmap-migrate-other-bitmaps-e.patch
-pve/0057-PVE-fix-aborting-multiple-CREATED-jobs-in-sequential.patch
+pve/0054-PVE-Migrate-dirty-bitmap-state-via-savevm.patch
+pve/0055-migration-block-dirty-bitmap-migrate-other-bitmaps-e.patch
+pve/0056-PVE-fix-aborting-multiple-CREATED-jobs-in-sequential.patch
+pve/0057-PVE-Use-coroutine-QMP-for-backup-cancel_backup.patch
diff --git a/debian/pve-qemu-kvm.install b/debian/pve-qemu-kvm.install
index 3ac471a..723d548 100644
--- a/debian/pve-qemu-kvm.install
+++ b/debian/pve-qemu-kvm.install
@@ -1,6 +1,4 @@
 # install the userspace utilities
-vma usr/bin/
-pbs-restore usr/bin/
 debian/kvm-ifup etc/kvm/
 debian/kvm-ifdown etc/kvm/
 
diff --git a/debian/rules b/debian/rules
index 57e1c91..9e72986 100755
--- a/debian/rules
+++ b/debian/rules
@@ -23,6 +23,9 @@ destdir := $(CURDIR)/debian/$(PACKAGE)
 
 flagfile := $(destdir)/usr/share/kvm/recognized-CPUID-flags-x86_64
 
+# default QEMU out-of-tree build directory is ./build
+BUILDDIR=build
+
 CFLAGS = -Wall
 
 ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
@@ -31,7 +34,7 @@ else
 	CFLAGS += -O2
 endif
 
-config.status: configure
+${BUILDDIR}/config.status: configure
 	dh_testdir
 	# Add here commands to configure the package.
 
@@ -42,7 +45,7 @@ config.status: configure
 	--prefix=/usr \
 	--sysconfdir=/etc \
 	--target-list=$(ARCH)-softmmu,aarch64-softmmu \
-	--with-confsuffix="/kvm" \
+	--with-suffix="kvm" \
 	--with-pkgversion="${DEB_SOURCE}_${DEB_VERSION_UPSTREAM}" \
 	--audio-drv-list="alsa" \
 	--datadir=/usr/share \
@@ -73,7 +76,7 @@ config.status: configure
 
 build: build-stamp
 
-build-stamp:  config.status
+build-stamp: ${BUILDDIR}/config.status
 	dh_testdir
 
 	# Add here commands to compile the package.
@@ -121,6 +124,9 @@ install: build
 	rm $(destdir)/usr/share/kvm/u-boot.e500
 	# remove Aplha files
 	rm $(destdir)/usr/share/kvm/palcode-clipper
+	# remove RISC-V files
+	rm $(destdir)/usr/share/kvm/opensbi-riscv32-generic-fw_dynamic.elf
+	rm $(destdir)/usr/share/kvm/opensbi-riscv64-generic-fw_dynamic.elf
 
 	# Remove things we don't package at all, would be a "kvm-dev" package
 	rm -Rf $(destdir)/usr/include/linux/
diff --git a/qemu b/qemu
index d0ed6a6..553032d 160000
--- a/qemu
+++ b/qemu
@@ -1 +1 @@
-Subproject commit d0ed6a69d399ae193959225cdeaa9382746c91cc
+Subproject commit 553032db17440f8de011390e5a1cfddd13751b0b
-- 
2.20.1





More information about the pve-devel mailing list