Files
pve-qemu-qoup/debian/patches/pve/0028-PVE-Backup-add-backup-dump-block-driver.patch
T

328 lines
8.9 KiB
Diff
Raw Normal View History

2020-03-10 15:12:50 +01:00
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Dietmar Maurer <dietmar@proxmox.com>
2020-04-07 16:53:19 +02:00
Date: Mon, 6 Apr 2020 12:16:58 +0200
Subject: [PATCH] PVE-Backup: add backup-dump block driver
2020-03-10 15:12:50 +01:00
- 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
2022-01-13 10:34:33 +01:00
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2023-05-15 15:39:53 +02:00
[FE: adapt to coroutine changes]
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
2020-03-10 15:12:50 +01:00
---
block/backup-dump.c | 172 +++++++++++++++++++++++++++++++
2022-06-27 13:05:40 +02:00
block/backup.c | 30 ++----
block/meson.build | 1 +
include/block/block_int-common.h | 35 +++++++
job.c | 3 +-
5 files changed, 218 insertions(+), 23 deletions(-)
2020-03-10 15:12:50 +01:00
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..e46abf1070
2020-03-10 15:12:50 +01:00
--- /dev/null
+++ b/block/backup-dump.c
@@ -0,0 +1,172 @@
2020-03-10 15:12:50 +01:00
+/*
+ * 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 "qapi/qmp/qdict.h"
2020-03-10 15:12:50 +01:00
+#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;
+
2023-05-15 15:39:53 +02:00
+static coroutine_fn int qemu_backup_dump_co_get_info(BlockDriverState *bs,
+ BlockDriverInfo *bdi)
2020-03-10 15:12:50 +01:00
+{
+ 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. */
+}
+
2023-05-15 15:39:53 +02:00
+static coroutine_fn int64_t qemu_backup_dump_co_getlength(BlockDriverState *bs)
2020-03-10 15:12:50 +01:00
+{
+ 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,
2020-08-20 10:42:45 +02:00
+ BdrvChildRole role,
2020-03-10 15:12:50 +01:00
+ 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,
2023-05-15 15:39:53 +02:00
+ .bdrv_co_getlength = qemu_backup_dump_co_getlength,
+ .bdrv_co_get_info = qemu_backup_dump_co_get_info,
2020-03-10 15:12:50 +01:00
+
+ .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 *coroutine_fn bdrv_co_backup_dump_create(
2020-03-10 15:12:50 +01:00
+ int dump_cb_block_size,
+ uint64_t byte_size,
+ BackupDumpFunc *dump_cb,
+ void *dump_cb_data,
+ Error **errp)
+{
+ BDRVBackupDumpState *state;
+
+ QDict *options = qdict_new();
+ qdict_put_str(options, "driver", "backup-dump-drive");
+
+ BlockDriverState *bs = bdrv_co_open(NULL, NULL, options, BDRV_O_RDWR, errp);
2020-03-10 15:12:50 +01:00
+ 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
2024-04-25 17:21:29 +02:00
index 270957c0cd..16d611c4ca 100644
2020-03-10 15:12:50 +01:00
--- a/block/backup.c
+++ b/block/backup.c
2022-02-11 10:24:33 +01:00
@@ -29,28 +29,6 @@
2020-03-10 15:12:50 +01:00
2022-02-11 10:24:33 +01:00
#include "block/copy-before-write.h"
2020-03-10 15:12:50 +01:00
-typedef struct BackupBlockJob {
- BlockJob common;
2022-02-11 10:24:33 +01:00
- BlockDriverState *cbw;
2020-03-10 15:12:50 +01:00
- BlockDriverState *source_bs;
2021-05-27 12:43:32 +02:00
- BlockDriverState *target_bs;
2020-03-10 15:12:50 +01:00
-
- BdrvDirtyBitmap *sync_bitmap;
-
- MirrorSyncMode sync_mode;
- BitmapSyncMode bitmap_mode;
- BlockdevOnError on_source_error;
- BlockdevOnError on_target_error;
- uint64_t len;
- int64_t cluster_size;
2021-05-27 12:43:32 +02:00
- BackupPerf perf;
2020-03-10 15:12:50 +01:00
-
- BlockCopyState *bcs;
2021-05-27 12:43:32 +02:00
-
- bool wait;
- BlockCopyCallState *bg_bcs_call;
2020-03-10 15:12:50 +01:00
-} BackupBlockJob;
-
static const BlockJobDriver backup_job_driver;
2021-05-27 12:43:32 +02:00
static void backup_cleanup_sync_bitmap(BackupBlockJob *job, int ret)
2024-04-25 17:21:28 +02:00
@@ -461,6 +439,14 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
2020-03-10 15:12:50 +01:00
}
2022-02-11 10:24:33 +01:00
cluster_size = block_copy_cluster_size(bcs);
2021-05-27 12:43:32 +02:00
+ if (cluster_size < 0) {
+ goto error;
+ }
+
2020-03-10 15:12:50 +01:00
+ BlockDriverInfo bdi;
+ if (bdrv_get_info(bs, &bdi) == 0) {
+ cluster_size = MAX(cluster_size, bdi.cluster_size);
+ }
2022-02-11 10:24:33 +01:00
if (perf->max_chunk && perf->max_chunk < cluster_size) {
error_setg(errp, "Required max-chunk (%" PRIi64 ") is less than backup "
2021-02-11 17:11:11 +01:00
diff --git a/block/meson.build b/block/meson.build
2024-04-25 17:21:29 +02:00
index b245daa98e..e99914eaa4 100644
2021-02-11 17:11:11 +01:00
--- 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',
'blkdebug.c',
'blklogwrites.c',
2024-04-25 17:21:28 +02:00
'blkverify.c',
2022-06-27 13:05:40 +02:00
diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
2024-04-25 17:21:29 +02:00
index 761276127e..b3e6697613 100644
2022-06-27 13:05:40 +02:00
--- a/include/block/block_int-common.h
+++ b/include/block/block_int-common.h
2021-05-27 12:43:32 +02:00
@@ -26,6 +26,7 @@
2023-05-15 15:39:53 +02:00
#include "block/aio.h"
#include "block/block-common.h"
2021-05-27 12:43:32 +02:00
+#include "block/block-copy.h"
2023-05-15 15:39:53 +02:00
#include "block/block-global-state.h"
#include "block/snapshot.h"
#include "qemu/iov.h"
@@ -60,6 +61,40 @@
2020-03-10 15:12:50 +01:00
#define BLOCK_PROBE_BUF_SIZE 512
+typedef int BackupDumpFunc(void *opaque, uint64_t offset, uint64_t bytes, const void *buf);
+
+BlockDriverState *coroutine_fn bdrv_co_backup_dump_create(
2020-03-10 15:12:50 +01:00
+ 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;
2022-02-11 10:24:33 +01:00
+ BlockDriverState *cbw;
2020-03-10 15:12:50 +01:00
+ BlockDriverState *source_bs;
2021-05-27 12:43:32 +02:00
+ BlockDriverState *target_bs;
2020-03-10 15:12:50 +01:00
+
+ BdrvDirtyBitmap *sync_bitmap;
+
+ MirrorSyncMode sync_mode;
+ BitmapSyncMode bitmap_mode;
+ BlockdevOnError on_source_error;
+ BlockdevOnError on_target_error;
+ uint64_t len;
+ int64_t cluster_size;
2021-05-27 12:43:32 +02:00
+ BackupPerf perf;
2020-03-10 15:12:50 +01:00
+
+ BlockCopyState *bcs;
2021-05-27 12:43:32 +02:00
+
+ bool wait;
+ BlockCopyCallState *bg_bcs_call;
2020-03-10 15:12:50 +01:00
+} BackupBlockJob;
+
enum BdrvTrackedRequestType {
BDRV_TRACKED_READ,
BDRV_TRACKED_WRITE,
diff --git a/job.c b/job.c
2024-04-25 17:21:29 +02:00
index 660ce22c56..baf54c8d60 100644
2020-03-10 15:12:50 +01:00
--- a/job.c
+++ b/job.c
2024-04-25 17:21:28 +02:00
@@ -331,7 +331,8 @@ static bool job_started_locked(Job *job)
2020-03-10 15:12:50 +01:00
}
2022-12-14 15:16:32 +01:00
/* Called with job_mutex held. */
-static bool job_should_pause_locked(Job *job)
+bool job_should_pause_locked(Job *job);
+bool job_should_pause_locked(Job *job)
2020-03-10 15:12:50 +01:00
{
return job->pause_count > 0;
}