]> git.proxmox.com Git - pve-qemu.git/blobdiff - debian/patches/pve/0028-PVE-Backup-add-backup-dump-block-driver.patch
update submodule and patches to 7.1.0
[pve-qemu.git] / debian / patches / pve / 0028-PVE-Backup-add-backup-dump-block-driver.patch
diff --git a/debian/patches/pve/0028-PVE-Backup-add-backup-dump-block-driver.patch b/debian/patches/pve/0028-PVE-Backup-add-backup-dump-block-driver.patch
new file mode 100644 (file)
index 0000000..548ce20
--- /dev/null
@@ -0,0 +1,320 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Dietmar Maurer <dietmar@proxmox.com>
+Date: Mon, 6 Apr 2020 12:16:58 +0200
+Subject: [PATCH] PVE-Backup: add backup-dump block driver
+
+- add backup-dump block driver block/backup-dump.c
+- move BackupBlockJob declaration from block/backup.c to include/block/block_int.h
+- block/backup.c - backup-job-create: also consider source cluster size
+- job.c: make job_should_pause non-static
+
+Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
+---
+ block/backup-dump.c              | 167 +++++++++++++++++++++++++++++++
+ block/backup.c                   |  30 ++----
+ block/meson.build                |   1 +
+ include/block/block_int-common.h |  35 +++++++
+ job.c                            |   3 +-
+ 5 files changed, 213 insertions(+), 23 deletions(-)
+ create mode 100644 block/backup-dump.c
+
+diff --git a/block/backup-dump.c b/block/backup-dump.c
+new file mode 100644
+index 0000000000..04718a94e2
+--- /dev/null
++++ b/block/backup-dump.c
+@@ -0,0 +1,167 @@
++/*
++ * BlockDriver to send backup data stream to a callback function
++ *
++ * Copyright (C) 2020 Proxmox Server Solutions GmbH
++ *
++ * 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 "qemu/osdep.h"
++#include "qom/object_interfaces.h"
++#include "block/block_int.h"
++
++typedef struct {
++    int             dump_cb_block_size;
++    uint64_t        byte_size;
++    BackupDumpFunc *dump_cb;
++    void           *dump_cb_data;
++} BDRVBackupDumpState;
++
++static int qemu_backup_dump_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
++{
++    BDRVBackupDumpState *s = bs->opaque;
++
++    bdi->cluster_size = s->dump_cb_block_size;
++    return 0;
++}
++
++static int qemu_backup_dump_check_perm(
++    BlockDriverState *bs,
++    uint64_t perm,
++    uint64_t shared,
++    Error **errp)
++{
++    /* Nothing to do. */
++    return 0;
++}
++
++static void qemu_backup_dump_set_perm(
++    BlockDriverState *bs,
++    uint64_t perm,
++    uint64_t shared)
++{
++    /* Nothing to do. */
++}
++
++static void qemu_backup_dump_abort_perm_update(BlockDriverState *bs)
++{
++    /* Nothing to do. */
++}
++
++static void qemu_backup_dump_refresh_limits(BlockDriverState *bs, Error **errp)
++{
++    bs->bl.request_alignment = BDRV_SECTOR_SIZE; /* No sub-sector I/O */
++}
++
++static void qemu_backup_dump_close(BlockDriverState *bs)
++{
++    /* Nothing to do. */
++}
++
++static int64_t qemu_backup_dump_getlength(BlockDriverState *bs)
++{
++    BDRVBackupDumpState *s = bs->opaque;
++
++    return s->byte_size;
++}
++
++static coroutine_fn int qemu_backup_dump_co_writev(
++    BlockDriverState *bs,
++    int64_t sector_num,
++    int nb_sectors,
++    QEMUIOVector *qiov,
++    int flags)
++{
++    /* flags can be only values we set in supported_write_flags */
++    assert(flags == 0);
++
++    BDRVBackupDumpState *s = bs->opaque;
++    off_t offset = sector_num * BDRV_SECTOR_SIZE;
++
++    uint64_t written = 0;
++
++    for (int i = 0; i < qiov->niov; ++i) {
++        const struct iovec *v = &qiov->iov[i];
++
++        int rc = s->dump_cb(s->dump_cb_data, offset, v->iov_len, v->iov_base);
++        if (rc < 0) {
++            return rc;
++        }
++
++        if (rc != v->iov_len) {
++            return -EIO;
++        }
++
++        written += v->iov_len;
++        offset += v->iov_len;
++    }
++
++    return written;
++}
++
++static void qemu_backup_dump_child_perm(
++    BlockDriverState *bs,
++    BdrvChild *c,
++    BdrvChildRole role,
++    BlockReopenQueue *reopen_queue,
++    uint64_t perm, uint64_t shared,
++    uint64_t *nperm, uint64_t *nshared)
++{
++    *nperm = BLK_PERM_ALL;
++    *nshared = BLK_PERM_ALL;
++}
++
++static BlockDriver bdrv_backup_dump_drive = {
++    .format_name                  = "backup-dump-drive",
++    .protocol_name                = "backup-dump",
++    .instance_size                = sizeof(BDRVBackupDumpState),
++
++    .bdrv_close                   = qemu_backup_dump_close,
++    .bdrv_has_zero_init           = bdrv_has_zero_init_1,
++    .bdrv_getlength               = qemu_backup_dump_getlength,
++    .bdrv_get_info                = qemu_backup_dump_get_info,
++
++    .bdrv_co_writev               = qemu_backup_dump_co_writev,
++
++    .bdrv_refresh_limits          = qemu_backup_dump_refresh_limits,
++    .bdrv_check_perm              = qemu_backup_dump_check_perm,
++    .bdrv_set_perm                = qemu_backup_dump_set_perm,
++    .bdrv_abort_perm_update       = qemu_backup_dump_abort_perm_update,
++    .bdrv_child_perm              = qemu_backup_dump_child_perm,
++};
++
++static void bdrv_backup_dump_init(void)
++{
++    bdrv_register(&bdrv_backup_dump_drive);
++}
++
++block_init(bdrv_backup_dump_init);
++
++
++BlockDriverState *bdrv_backup_dump_create(
++    int dump_cb_block_size,
++    uint64_t byte_size,
++    BackupDumpFunc *dump_cb,
++    void *dump_cb_data,
++    Error **errp)
++{
++    BDRVBackupDumpState *state;
++    BlockDriverState *bs = bdrv_new_open_driver(
++        &bdrv_backup_dump_drive, NULL, BDRV_O_RDWR, errp);
++
++    if (!bs) {
++        return NULL;
++    }
++
++    bs->total_sectors = byte_size / BDRV_SECTOR_SIZE;
++    bs->opaque = state = g_new0(BDRVBackupDumpState, 1);
++
++    state->dump_cb_block_size = dump_cb_block_size;
++    state->byte_size = byte_size;
++    state->dump_cb = dump_cb;
++    state->dump_cb_data = dump_cb_data;
++
++    return bs;
++}
+diff --git a/block/backup.c b/block/backup.c
+index b6fa9e8a69..789f8b7799 100644
+--- a/block/backup.c
++++ b/block/backup.c
+@@ -29,28 +29,6 @@
+ #include "block/copy-before-write.h"
+-typedef struct BackupBlockJob {
+-    BlockJob common;
+-    BlockDriverState *cbw;
+-    BlockDriverState *source_bs;
+-    BlockDriverState *target_bs;
+-
+-    BdrvDirtyBitmap *sync_bitmap;
+-
+-    MirrorSyncMode sync_mode;
+-    BitmapSyncMode bitmap_mode;
+-    BlockdevOnError on_source_error;
+-    BlockdevOnError on_target_error;
+-    uint64_t len;
+-    int64_t cluster_size;
+-    BackupPerf perf;
+-
+-    BlockCopyState *bcs;
+-
+-    bool wait;
+-    BlockCopyCallState *bg_bcs_call;
+-} BackupBlockJob;
+-
+ static const BlockJobDriver backup_job_driver;
+ static void backup_cleanup_sync_bitmap(BackupBlockJob *job, int ret)
+@@ -454,6 +432,14 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
+     }
+     cluster_size = block_copy_cluster_size(bcs);
++    if (cluster_size < 0) {
++        goto error;
++    }
++
++    BlockDriverInfo bdi;
++    if (bdrv_get_info(bs, &bdi) == 0) {
++        cluster_size = MAX(cluster_size, bdi.cluster_size);
++    }
+     if (perf->max_chunk && perf->max_chunk < cluster_size) {
+         error_setg(errp, "Required max-chunk (%" PRIi64 ") is less than backup "
+diff --git a/block/meson.build b/block/meson.build
+index 3a0b84bc11..7f22e7f177 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',
+   'copy-before-write.c',
+   'blkdebug.c',
+   'blklogwrites.c',
+diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
+index 8947abab76..f272d0d8dc 100644
+--- a/include/block/block_int-common.h
++++ b/include/block/block_int-common.h
+@@ -26,6 +26,7 @@
+ #include "block/accounting.h"
+ #include "block/block.h"
++#include "block/block-copy.h"
+ #include "block/aio-wait.h"
+ #include "qemu/queue.h"
+ #include "qemu/coroutine.h"
+@@ -64,6 +65,40 @@
+ #define BLOCK_PROBE_BUF_SIZE        512
++typedef int BackupDumpFunc(void *opaque, uint64_t offset, uint64_t bytes, const void *buf);
++
++BlockDriverState *bdrv_backup_dump_create(
++    int dump_cb_block_size,
++    uint64_t byte_size,
++    BackupDumpFunc *dump_cb,
++    void *dump_cb_data,
++    Error **errp);
++
++// Needs to be defined here, since it's used in blockdev.c to detect PVE backup
++// jobs with source_bs
++typedef struct BlockCopyState BlockCopyState;
++typedef struct BackupBlockJob {
++    BlockJob common;
++    BlockDriverState *cbw;
++    BlockDriverState *source_bs;
++    BlockDriverState *target_bs;
++
++    BdrvDirtyBitmap *sync_bitmap;
++
++    MirrorSyncMode sync_mode;
++    BitmapSyncMode bitmap_mode;
++    BlockdevOnError on_source_error;
++    BlockdevOnError on_target_error;
++    uint64_t len;
++    int64_t cluster_size;
++    BackupPerf perf;
++
++    BlockCopyState *bcs;
++
++    bool wait;
++    BlockCopyCallState *bg_bcs_call;
++} BackupBlockJob;
++
+ enum BdrvTrackedRequestType {
+     BDRV_TRACKED_READ,
+     BDRV_TRACKED_WRITE,
+diff --git a/job.c b/job.c
+index 075c6f3a20..e5699ad200 100644
+--- a/job.c
++++ b/job.c
+@@ -276,7 +276,8 @@ static bool job_started(Job *job)
+     return job->co;
+ }
+-static bool job_should_pause(Job *job)
++bool job_should_pause(Job *job);
++bool job_should_pause(Job *job)
+ {
+     return job->pause_count > 0;
+ }