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