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