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