]> git.proxmox.com Git - pve-qemu.git/blob - debian/patches/pve/0028-PVE-Backup-add-backup-dump-block-driver.patch
drop patch for custom get_link_status QMP command
[pve-qemu.git] / debian / patches / pve / 0028-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 Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
12 [FE: adapt to coroutine changes]
13 Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
14 ---
15 block/backup-dump.c | 168 +++++++++++++++++++++++++++++++
16 block/backup.c | 30 ++----
17 block/meson.build | 1 +
18 include/block/block_int-common.h | 35 +++++++
19 job.c | 3 +-
20 5 files changed, 214 insertions(+), 23 deletions(-)
21 create mode 100644 block/backup-dump.c
22
23 diff --git a/block/backup-dump.c b/block/backup-dump.c
24 new file mode 100644
25 index 0000000000..232a094426
26 --- /dev/null
27 +++ b/block/backup-dump.c
28 @@ -0,0 +1,168 @@
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"
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 +
50 +static coroutine_fn int qemu_backup_dump_co_get_info(BlockDriverState *bs,
51 + BlockDriverInfo *bdi)
52 +{
53 + BDRVBackupDumpState *s = bs->opaque;
54 +
55 + bdi->cluster_size = s->dump_cb_block_size;
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 +
92 +static coroutine_fn int64_t qemu_backup_dump_co_getlength(BlockDriverState *bs)
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,
136 + BdrvChildRole role,
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,
152 + .bdrv_co_getlength = qemu_backup_dump_co_getlength,
153 + .bdrv_co_get_info = qemu_backup_dump_co_get_info,
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 +}
197 diff --git a/block/backup.c b/block/backup.c
198 index 39410dcf8d..af87fa6aa9 100644
199 --- a/block/backup.c
200 +++ b/block/backup.c
201 @@ -29,28 +29,6 @@
202
203 #include "block/copy-before-write.h"
204
205 -typedef struct BackupBlockJob {
206 - BlockJob common;
207 - BlockDriverState *cbw;
208 - BlockDriverState *source_bs;
209 - BlockDriverState *target_bs;
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;
218 - int64_t cluster_size;
219 - BackupPerf perf;
220 -
221 - BlockCopyState *bcs;
222 -
223 - bool wait;
224 - BlockCopyCallState *bg_bcs_call;
225 -} BackupBlockJob;
226 -
227 static const BlockJobDriver backup_job_driver;
228
229 static void backup_cleanup_sync_bitmap(BackupBlockJob *job, int ret)
230 @@ -457,6 +435,14 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
231 }
232
233 cluster_size = block_copy_cluster_size(bcs);
234 + if (cluster_size < 0) {
235 + goto error;
236 + }
237 +
238 + BlockDriverInfo bdi;
239 + if (bdrv_get_info(bs, &bdi) == 0) {
240 + cluster_size = MAX(cluster_size, bdi.cluster_size);
241 + }
242
243 if (perf->max_chunk && perf->max_chunk < cluster_size) {
244 error_setg(errp, "Required max-chunk (%" PRIi64 ") is less than backup "
245 diff --git a/block/meson.build b/block/meson.build
246 index 744b698a82..f580f95395 100644
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',
254 'copy-before-write.c',
255 'blkdebug.c',
256 'blklogwrites.c',
257 diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
258 index f01bb8b617..d7ffd1826e 100644
259 --- a/include/block/block_int-common.h
260 +++ b/include/block/block_int-common.h
261 @@ -26,6 +26,7 @@
262
263 #include "block/aio.h"
264 #include "block/block-common.h"
265 +#include "block/block-copy.h"
266 #include "block/block-global-state.h"
267 #include "block/snapshot.h"
268 #include "qemu/iov.h"
269 @@ -60,6 +61,40 @@
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 +
275 +BlockDriverState *bdrv_backup_dump_create(
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;
287 + BlockDriverState *cbw;
288 + BlockDriverState *source_bs;
289 + BlockDriverState *target_bs;
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;
298 + int64_t cluster_size;
299 + BackupPerf perf;
300 +
301 + BlockCopyState *bcs;
302 +
303 + bool wait;
304 + BlockCopyCallState *bg_bcs_call;
305 +} BackupBlockJob;
306 +
307 enum BdrvTrackedRequestType {
308 BDRV_TRACKED_READ,
309 BDRV_TRACKED_WRITE,
310 diff --git a/job.c b/job.c
311 index 72d57f0934..93e22d180b 100644
312 --- a/job.c
313 +++ b/job.c
314 @@ -330,7 +330,8 @@ static bool job_started_locked(Job *job)
315 }
316
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)
321 {
322 return job->pause_count > 0;
323 }