]> git.proxmox.com Git - pve-qemu.git/blame - debian/patches/pve/0028-PVE-Backup-add-backup-dump-block-driver.patch
cleanup: squash backup dump driver change into patch introducing the driver
[pve-qemu.git] / debian / patches / pve / 0028-PVE-Backup-add-backup-dump-block-driver.patch
CommitLineData
6402d961
TL
1From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
2From: Dietmar Maurer <dietmar@proxmox.com>
83faa3fe
TL
3Date: Mon, 6 Apr 2020 12:16:58 +0200
4Subject: [PATCH] PVE-Backup: add backup-dump block driver
6402d961
TL
5
6- add backup-dump block driver block/backup-dump.c
7- move BackupBlockJob declaration from block/backup.c to include/block/block_int.h
8- block/backup.c - backup-job-create: also consider source cluster size
6402d961 9- job.c: make job_should_pause non-static
ddbf7a87
TL
10
11Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
bf251437
FE
12[FE: adapt to coroutine changes]
13Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
6402d961 14---
862b46e3 15 block/backup-dump.c | 172 +++++++++++++++++++++++++++++++
dc9827a6
FE
16 block/backup.c | 30 ++----
17 block/meson.build | 1 +
18 include/block/block_int-common.h | 35 +++++++
19 job.c | 3 +-
862b46e3 20 5 files changed, 218 insertions(+), 23 deletions(-)
6402d961
TL
21 create mode 100644 block/backup-dump.c
22
6402d961
TL
23diff --git a/block/backup-dump.c b/block/backup-dump.c
24new file mode 100644
862b46e3 25index 0000000000..e46abf1070
6402d961
TL
26--- /dev/null
27+++ b/block/backup-dump.c
862b46e3 28@@ -0,0 +1,172 @@
6402d961
TL
29+/*
30+ * BlockDriver to send backup data stream to a callback function
31+ *
32+ * Copyright (C) 2020 Proxmox Server Solutions GmbH
33+ *
34+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
35+ * See the COPYING file in the top-level directory.
36+ *
37+ */
38+
39+#include "qemu/osdep.h"
862b46e3
FE
40+
41+#include "qapi/qmp/qdict.h"
6402d961
TL
42+#include "qom/object_interfaces.h"
43+#include "block/block_int.h"
44+
45+typedef struct {
46+ int dump_cb_block_size;
47+ uint64_t byte_size;
48+ BackupDumpFunc *dump_cb;
49+ void *dump_cb_data;
50+} BDRVBackupDumpState;
51+
bf251437
FE
52+static coroutine_fn int qemu_backup_dump_co_get_info(BlockDriverState *bs,
53+ BlockDriverInfo *bdi)
6402d961
TL
54+{
55+ BDRVBackupDumpState *s = bs->opaque;
56+
57+ bdi->cluster_size = s->dump_cb_block_size;
6402d961
TL
58+ return 0;
59+}
60+
61+static int qemu_backup_dump_check_perm(
62+ BlockDriverState *bs,
63+ uint64_t perm,
64+ uint64_t shared,
65+ Error **errp)
66+{
67+ /* Nothing to do. */
68+ return 0;
69+}
70+
71+static void qemu_backup_dump_set_perm(
72+ BlockDriverState *bs,
73+ uint64_t perm,
74+ uint64_t shared)
75+{
76+ /* Nothing to do. */
77+}
78+
79+static void qemu_backup_dump_abort_perm_update(BlockDriverState *bs)
80+{
81+ /* Nothing to do. */
82+}
83+
84+static void qemu_backup_dump_refresh_limits(BlockDriverState *bs, Error **errp)
85+{
86+ bs->bl.request_alignment = BDRV_SECTOR_SIZE; /* No sub-sector I/O */
87+}
88+
89+static void qemu_backup_dump_close(BlockDriverState *bs)
90+{
91+ /* Nothing to do. */
92+}
93+
bf251437 94+static coroutine_fn int64_t qemu_backup_dump_co_getlength(BlockDriverState *bs)
6402d961
TL
95+{
96+ BDRVBackupDumpState *s = bs->opaque;
97+
98+ return s->byte_size;
99+}
100+
101+static coroutine_fn int qemu_backup_dump_co_writev(
102+ BlockDriverState *bs,
103+ int64_t sector_num,
104+ int nb_sectors,
105+ QEMUIOVector *qiov,
106+ int flags)
107+{
108+ /* flags can be only values we set in supported_write_flags */
109+ assert(flags == 0);
110+
111+ BDRVBackupDumpState *s = bs->opaque;
112+ off_t offset = sector_num * BDRV_SECTOR_SIZE;
113+
114+ uint64_t written = 0;
115+
116+ for (int i = 0; i < qiov->niov; ++i) {
117+ const struct iovec *v = &qiov->iov[i];
118+
119+ int rc = s->dump_cb(s->dump_cb_data, offset, v->iov_len, v->iov_base);
120+ if (rc < 0) {
121+ return rc;
122+ }
123+
124+ if (rc != v->iov_len) {
125+ return -EIO;
126+ }
127+
128+ written += v->iov_len;
129+ offset += v->iov_len;
130+ }
131+
132+ return written;
133+}
134+
135+static void qemu_backup_dump_child_perm(
136+ BlockDriverState *bs,
137+ BdrvChild *c,
60ae3775 138+ BdrvChildRole role,
6402d961
TL
139+ BlockReopenQueue *reopen_queue,
140+ uint64_t perm, uint64_t shared,
141+ uint64_t *nperm, uint64_t *nshared)
142+{
143+ *nperm = BLK_PERM_ALL;
144+ *nshared = BLK_PERM_ALL;
145+}
146+
147+static BlockDriver bdrv_backup_dump_drive = {
148+ .format_name = "backup-dump-drive",
149+ .protocol_name = "backup-dump",
150+ .instance_size = sizeof(BDRVBackupDumpState),
151+
152+ .bdrv_close = qemu_backup_dump_close,
153+ .bdrv_has_zero_init = bdrv_has_zero_init_1,
bf251437
FE
154+ .bdrv_co_getlength = qemu_backup_dump_co_getlength,
155+ .bdrv_co_get_info = qemu_backup_dump_co_get_info,
6402d961
TL
156+
157+ .bdrv_co_writev = qemu_backup_dump_co_writev,
158+
159+ .bdrv_refresh_limits = qemu_backup_dump_refresh_limits,
160+ .bdrv_check_perm = qemu_backup_dump_check_perm,
161+ .bdrv_set_perm = qemu_backup_dump_set_perm,
162+ .bdrv_abort_perm_update = qemu_backup_dump_abort_perm_update,
163+ .bdrv_child_perm = qemu_backup_dump_child_perm,
164+};
165+
166+static void bdrv_backup_dump_init(void)
167+{
168+ bdrv_register(&bdrv_backup_dump_drive);
169+}
170+
171+block_init(bdrv_backup_dump_init);
172+
173+
862b46e3 174+BlockDriverState *coroutine_fn bdrv_co_backup_dump_create(
6402d961
TL
175+ int dump_cb_block_size,
176+ uint64_t byte_size,
177+ BackupDumpFunc *dump_cb,
178+ void *dump_cb_data,
179+ Error **errp)
180+{
181+ BDRVBackupDumpState *state;
6402d961 182+
862b46e3
FE
183+ QDict *options = qdict_new();
184+ qdict_put_str(options, "driver", "backup-dump-drive");
185+
186+ BlockDriverState *bs = bdrv_co_open(NULL, NULL, options, BDRV_O_RDWR, errp);
6402d961
TL
187+ if (!bs) {
188+ return NULL;
189+ }
190+
191+ bs->total_sectors = byte_size / BDRV_SECTOR_SIZE;
192+ bs->opaque = state = g_new0(BDRVBackupDumpState, 1);
193+
194+ state->dump_cb_block_size = dump_cb_block_size;
195+ state->byte_size = byte_size;
196+ state->dump_cb = dump_cb;
197+ state->dump_cb_data = dump_cb_data;
198+
199+ return bs;
200+}
201diff --git a/block/backup.c b/block/backup.c
bf251437 202index 39410dcf8d..af87fa6aa9 100644
6402d961
TL
203--- a/block/backup.c
204+++ b/block/backup.c
4567474e 205@@ -29,28 +29,6 @@
6402d961 206
4567474e 207 #include "block/copy-before-write.h"
6402d961
TL
208
209-typedef struct BackupBlockJob {
210- BlockJob common;
4567474e 211- BlockDriverState *cbw;
6402d961 212- BlockDriverState *source_bs;
8dca018b 213- BlockDriverState *target_bs;
6402d961
TL
214-
215- BdrvDirtyBitmap *sync_bitmap;
216-
217- MirrorSyncMode sync_mode;
218- BitmapSyncMode bitmap_mode;
219- BlockdevOnError on_source_error;
220- BlockdevOnError on_target_error;
221- uint64_t len;
6402d961 222- int64_t cluster_size;
8dca018b 223- BackupPerf perf;
6402d961
TL
224-
225- BlockCopyState *bcs;
8dca018b
SR
226-
227- bool wait;
228- BlockCopyCallState *bg_bcs_call;
6402d961
TL
229-} BackupBlockJob;
230-
231 static const BlockJobDriver backup_job_driver;
232
8dca018b 233 static void backup_cleanup_sync_bitmap(BackupBlockJob *job, int ret)
bf251437 234@@ -457,6 +435,14 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
6402d961
TL
235 }
236
4567474e 237 cluster_size = block_copy_cluster_size(bcs);
8dca018b
SR
238+ if (cluster_size < 0) {
239+ goto error;
240+ }
241+
6402d961
TL
242+ BlockDriverInfo bdi;
243+ if (bdrv_get_info(bs, &bdi) == 0) {
244+ cluster_size = MAX(cluster_size, bdi.cluster_size);
245+ }
4567474e
FE
246
247 if (perf->max_chunk && perf->max_chunk < cluster_size) {
248 error_setg(errp, "Required max-chunk (%" PRIi64 ") is less than backup "
817b7667 249diff --git a/block/meson.build b/block/meson.build
10e10933 250index 59b71ba9f3..6fde9f7dcd 100644
817b7667
SR
251--- a/block/meson.build
252+++ b/block/meson.build
253@@ -4,6 +4,7 @@ block_ss.add(files(
254 'aio_task.c',
255 'amend.c',
256 'backup.c',
257+ 'backup-dump.c',
4567474e 258 'copy-before-write.c',
817b7667
SR
259 'blkdebug.c',
260 'blklogwrites.c',
dc9827a6 261diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
862b46e3 262index 74195c3004..0a0339eee4 100644
dc9827a6
FE
263--- a/include/block/block_int-common.h
264+++ b/include/block/block_int-common.h
8dca018b
SR
265@@ -26,6 +26,7 @@
266
bf251437
FE
267 #include "block/aio.h"
268 #include "block/block-common.h"
8dca018b 269+#include "block/block-copy.h"
bf251437
FE
270 #include "block/block-global-state.h"
271 #include "block/snapshot.h"
272 #include "qemu/iov.h"
273@@ -60,6 +61,40 @@
6402d961
TL
274
275 #define BLOCK_PROBE_BUF_SIZE 512
276
277+typedef int BackupDumpFunc(void *opaque, uint64_t offset, uint64_t bytes, const void *buf);
278+
862b46e3 279+BlockDriverState *coroutine_fn bdrv_co_backup_dump_create(
6402d961
TL
280+ int dump_cb_block_size,
281+ uint64_t byte_size,
282+ BackupDumpFunc *dump_cb,
283+ void *dump_cb_data,
284+ Error **errp);
285+
286+// Needs to be defined here, since it's used in blockdev.c to detect PVE backup
287+// jobs with source_bs
288+typedef struct BlockCopyState BlockCopyState;
289+typedef struct BackupBlockJob {
290+ BlockJob common;
4567474e 291+ BlockDriverState *cbw;
6402d961 292+ BlockDriverState *source_bs;
8dca018b 293+ BlockDriverState *target_bs;
6402d961
TL
294+
295+ BdrvDirtyBitmap *sync_bitmap;
296+
297+ MirrorSyncMode sync_mode;
298+ BitmapSyncMode bitmap_mode;
299+ BlockdevOnError on_source_error;
300+ BlockdevOnError on_target_error;
301+ uint64_t len;
6402d961 302+ int64_t cluster_size;
8dca018b 303+ BackupPerf perf;
6402d961
TL
304+
305+ BlockCopyState *bcs;
8dca018b
SR
306+
307+ bool wait;
308+ BlockCopyCallState *bg_bcs_call;
6402d961
TL
309+} BackupBlockJob;
310+
311 enum BdrvTrackedRequestType {
312 BDRV_TRACKED_READ,
313 BDRV_TRACKED_WRITE,
314diff --git a/job.c b/job.c
d03e1b3c 315index 72d57f0934..93e22d180b 100644
6402d961
TL
316--- a/job.c
317+++ b/job.c
d03e1b3c 318@@ -330,7 +330,8 @@ static bool job_started_locked(Job *job)
6402d961
TL
319 }
320
d03e1b3c
FE
321 /* Called with job_mutex held. */
322-static bool job_should_pause_locked(Job *job)
323+bool job_should_pause_locked(Job *job);
324+bool job_should_pause_locked(Job *job)
6402d961
TL
325 {
326 return job->pause_count > 0;
327 }