]> git.proxmox.com Git - pve-qemu.git/blob - debian/patches/pve/0029-PVE-Backup-add-backup-dump-block-driver.patch
import QEMU 5.0.0-rc2 and rebase patches
[pve-qemu.git] / debian / patches / pve / 0029-PVE-Backup-add-backup-dump-block-driver.patch
1 From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
2 From: Dietmar Maurer <dietmar@proxmox.com>
3 Date: Mon, 6 Apr 2020 12:16:58 +0200
4 Subject: [PATCH] PVE-Backup: add backup-dump block driver
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
9 - job.c: make job_should_pause non-static
10 ---
11 block/Makefile.objs | 1 +
12 block/backup-dump.c | 169 ++++++++++++++++++++++++++++++++++++++
13 block/backup.c | 23 ++----
14 include/block/block_int.h | 30 +++++++
15 job.c | 3 +-
16 5 files changed, 207 insertions(+), 19 deletions(-)
17 create mode 100644 block/backup-dump.c
18
19 diff --git a/block/Makefile.objs b/block/Makefile.objs
20 index 1282445672..8af7073c83 100644
21 --- a/block/Makefile.objs
22 +++ b/block/Makefile.objs
23 @@ -34,6 +34,7 @@ block-obj-$(CONFIG_RBD) += rbd.o
24 block-obj-$(CONFIG_GLUSTERFS) += gluster.o
25 block-obj-$(CONFIG_VXHS) += vxhs.o
26 block-obj-$(CONFIG_LIBSSH) += ssh.o
27 +block-obj-y += backup-dump.o
28 block-obj-y += accounting.o dirty-bitmap.o
29 block-obj-y += write-threshold.o
30 block-obj-y += backup.o
31 diff --git a/block/backup-dump.c b/block/backup-dump.c
32 new file mode 100644
33 index 0000000000..3066ab0698
34 --- /dev/null
35 +++ b/block/backup-dump.c
36 @@ -0,0 +1,169 @@
37 +/*
38 + * BlockDriver to send backup data stream to a callback function
39 + *
40 + * Copyright (C) 2020 Proxmox Server Solutions GmbH
41 + *
42 + * This work is licensed under the terms of the GNU GPL, version 2 or later.
43 + * See the COPYING file in the top-level directory.
44 + *
45 + */
46 +
47 +#include "qemu/osdep.h"
48 +#include "qemu-common.h"
49 +#include "qom/object_interfaces.h"
50 +#include "block/block_int.h"
51 +
52 +typedef struct {
53 + int dump_cb_block_size;
54 + uint64_t byte_size;
55 + BackupDumpFunc *dump_cb;
56 + void *dump_cb_data;
57 +} BDRVBackupDumpState;
58 +
59 +static int qemu_backup_dump_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
60 +{
61 + BDRVBackupDumpState *s = bs->opaque;
62 +
63 + bdi->cluster_size = s->dump_cb_block_size;
64 + bdi->unallocated_blocks_are_zero = true;
65 + return 0;
66 +}
67 +
68 +static int qemu_backup_dump_check_perm(
69 + BlockDriverState *bs,
70 + uint64_t perm,
71 + uint64_t shared,
72 + Error **errp)
73 +{
74 + /* Nothing to do. */
75 + return 0;
76 +}
77 +
78 +static void qemu_backup_dump_set_perm(
79 + BlockDriverState *bs,
80 + uint64_t perm,
81 + uint64_t shared)
82 +{
83 + /* Nothing to do. */
84 +}
85 +
86 +static void qemu_backup_dump_abort_perm_update(BlockDriverState *bs)
87 +{
88 + /* Nothing to do. */
89 +}
90 +
91 +static void qemu_backup_dump_refresh_limits(BlockDriverState *bs, Error **errp)
92 +{
93 + bs->bl.request_alignment = BDRV_SECTOR_SIZE; /* No sub-sector I/O */
94 +}
95 +
96 +static void qemu_backup_dump_close(BlockDriverState *bs)
97 +{
98 + /* Nothing to do. */
99 +}
100 +
101 +static int64_t qemu_backup_dump_getlength(BlockDriverState *bs)
102 +{
103 + BDRVBackupDumpState *s = bs->opaque;
104 +
105 + return s->byte_size;
106 +}
107 +
108 +static coroutine_fn int qemu_backup_dump_co_writev(
109 + BlockDriverState *bs,
110 + int64_t sector_num,
111 + int nb_sectors,
112 + QEMUIOVector *qiov,
113 + int flags)
114 +{
115 + /* flags can be only values we set in supported_write_flags */
116 + assert(flags == 0);
117 +
118 + BDRVBackupDumpState *s = bs->opaque;
119 + off_t offset = sector_num * BDRV_SECTOR_SIZE;
120 +
121 + uint64_t written = 0;
122 +
123 + for (int i = 0; i < qiov->niov; ++i) {
124 + const struct iovec *v = &qiov->iov[i];
125 +
126 + int rc = s->dump_cb(s->dump_cb_data, offset, v->iov_len, v->iov_base);
127 + if (rc < 0) {
128 + return rc;
129 + }
130 +
131 + if (rc != v->iov_len) {
132 + return -EIO;
133 + }
134 +
135 + written += v->iov_len;
136 + offset += v->iov_len;
137 + }
138 +
139 + return written;
140 +}
141 +
142 +static void qemu_backup_dump_child_perm(
143 + BlockDriverState *bs,
144 + BdrvChild *c,
145 + const BdrvChildRole *role,
146 + BlockReopenQueue *reopen_queue,
147 + uint64_t perm, uint64_t shared,
148 + uint64_t *nperm, uint64_t *nshared)
149 +{
150 + *nperm = BLK_PERM_ALL;
151 + *nshared = BLK_PERM_ALL;
152 +}
153 +
154 +static BlockDriver bdrv_backup_dump_drive = {
155 + .format_name = "backup-dump-drive",
156 + .protocol_name = "backup-dump",
157 + .instance_size = sizeof(BDRVBackupDumpState),
158 +
159 + .bdrv_close = qemu_backup_dump_close,
160 + .bdrv_has_zero_init = bdrv_has_zero_init_1,
161 + .bdrv_getlength = qemu_backup_dump_getlength,
162 + .bdrv_get_info = qemu_backup_dump_get_info,
163 +
164 + .bdrv_co_writev = qemu_backup_dump_co_writev,
165 +
166 + .bdrv_refresh_limits = qemu_backup_dump_refresh_limits,
167 + .bdrv_check_perm = qemu_backup_dump_check_perm,
168 + .bdrv_set_perm = qemu_backup_dump_set_perm,
169 + .bdrv_abort_perm_update = qemu_backup_dump_abort_perm_update,
170 + .bdrv_child_perm = qemu_backup_dump_child_perm,
171 +};
172 +
173 +static void bdrv_backup_dump_init(void)
174 +{
175 + bdrv_register(&bdrv_backup_dump_drive);
176 +}
177 +
178 +block_init(bdrv_backup_dump_init);
179 +
180 +
181 +BlockDriverState *bdrv_backup_dump_create(
182 + int dump_cb_block_size,
183 + uint64_t byte_size,
184 + BackupDumpFunc *dump_cb,
185 + void *dump_cb_data,
186 + Error **errp)
187 +{
188 + BDRVBackupDumpState *state;
189 + BlockDriverState *bs = bdrv_new_open_driver(
190 + &bdrv_backup_dump_drive, NULL, BDRV_O_RDWR, errp);
191 +
192 + if (!bs) {
193 + return NULL;
194 + }
195 +
196 + bs->total_sectors = byte_size / BDRV_SECTOR_SIZE;
197 + bs->opaque = state = g_new0(BDRVBackupDumpState, 1);
198 +
199 + state->dump_cb_block_size = dump_cb_block_size;
200 + state->byte_size = byte_size;
201 + state->dump_cb = dump_cb;
202 + state->dump_cb_data = dump_cb_data;
203 +
204 + return bs;
205 +}
206 diff --git a/block/backup.c b/block/backup.c
207 index ecd93e91e0..cf8f5ad25d 100644
208 --- a/block/backup.c
209 +++ b/block/backup.c
210 @@ -32,24 +32,6 @@
211
212 #define BACKUP_CLUSTER_SIZE_DEFAULT (1 << 16)
213
214 -typedef struct BackupBlockJob {
215 - BlockJob common;
216 - BlockDriverState *backup_top;
217 - BlockDriverState *source_bs;
218 -
219 - BdrvDirtyBitmap *sync_bitmap;
220 -
221 - MirrorSyncMode sync_mode;
222 - BitmapSyncMode bitmap_mode;
223 - BlockdevOnError on_source_error;
224 - BlockdevOnError on_target_error;
225 - uint64_t len;
226 - uint64_t bytes_read;
227 - int64_t cluster_size;
228 -
229 - BlockCopyState *bcs;
230 -} BackupBlockJob;
231 -
232 static const BlockJobDriver backup_job_driver;
233
234 static void backup_progress_bytes_callback(int64_t bytes, void *opaque)
235 @@ -411,6 +393,11 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
236 goto error;
237 }
238
239 + BlockDriverInfo bdi;
240 + if (bdrv_get_info(bs, &bdi) == 0) {
241 + cluster_size = MAX(cluster_size, bdi.cluster_size);
242 + }
243 +
244 /*
245 * If source is in backing chain of target assume that target is going to be
246 * used for "image fleecing", i.e. it should represent a kind of snapshot of
247 diff --git a/include/block/block_int.h b/include/block/block_int.h
248 index 336f71e69d..62e5579723 100644
249 --- a/include/block/block_int.h
250 +++ b/include/block/block_int.h
251 @@ -60,6 +60,36 @@
252
253 #define BLOCK_PROBE_BUF_SIZE 512
254
255 +typedef int BackupDumpFunc(void *opaque, uint64_t offset, uint64_t bytes, const void *buf);
256 +
257 +BlockDriverState *bdrv_backuo_dump_create(
258 + int dump_cb_block_size,
259 + uint64_t byte_size,
260 + BackupDumpFunc *dump_cb,
261 + void *dump_cb_data,
262 + Error **errp);
263 +
264 +// Needs to be defined here, since it's used in blockdev.c to detect PVE backup
265 +// jobs with source_bs
266 +typedef struct BlockCopyState BlockCopyState;
267 +typedef struct BackupBlockJob {
268 + BlockJob common;
269 + BlockDriverState *backup_top;
270 + BlockDriverState *source_bs;
271 +
272 + BdrvDirtyBitmap *sync_bitmap;
273 +
274 + MirrorSyncMode sync_mode;
275 + BitmapSyncMode bitmap_mode;
276 + BlockdevOnError on_source_error;
277 + BlockdevOnError on_target_error;
278 + uint64_t len;
279 + uint64_t bytes_read;
280 + int64_t cluster_size;
281 +
282 + BlockCopyState *bcs;
283 +} BackupBlockJob;
284 +
285 enum BdrvTrackedRequestType {
286 BDRV_TRACKED_READ,
287 BDRV_TRACKED_WRITE,
288 diff --git a/job.c b/job.c
289 index e82253e041..bcbbb0be02 100644
290 --- a/job.c
291 +++ b/job.c
292 @@ -269,7 +269,8 @@ static bool job_started(Job *job)
293 return job->co;
294 }
295
296 -static bool job_should_pause(Job *job)
297 +bool job_should_pause(Job *job);
298 +bool job_should_pause(Job *job)
299 {
300 return job->pause_count > 0;
301 }