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