1 From 2ec6f9ec8443f3389c74e8e21353d01e516c4f46 Mon Sep 17 00:00:00 2001
2 From: Wolfgang Bumiller <w.bumiller@proxmox.com>
3 Date: Wed, 9 Dec 2015 15:04:57 +0100
4 Subject: [PATCH 15/41] backup: modify job api
6 Introduces a BackupDump function callback and a pause_count
7 for backup_start. For a dump-backup the target parameter
8 can now be NULL so access to target needs to be guarded now.
10 block/backup.c | 57 +++++++++++++++++++++++++++++++----------------
12 include/block/block_int.h | 5 +++++
13 3 files changed, 46 insertions(+), 22 deletions(-)
15 diff --git a/block/backup.c b/block/backup.c
16 index 705bb77..7ac6b29 100644
19 @@ -43,6 +43,7 @@ typedef struct BackupBlockJob {
20 BdrvDirtyBitmap *sync_bitmap;
21 MirrorSyncMode sync_mode;
23 + BackupDumpFunc *dump_cb;
24 BlockdevOnError on_source_error;
25 BlockdevOnError on_target_error;
26 CoRwlock flush_rwlock;
27 @@ -147,14 +148,21 @@ static int coroutine_fn backup_do_cow(BlockDriverState *bs,
31 + int64_t start_sec = start * BACKUP_SECTORS_PER_CLUSTER;
32 if (buffer_is_zero(iov.iov_base, iov.iov_len)) {
33 - ret = bdrv_co_write_zeroes(job->target,
34 - start * BACKUP_SECTORS_PER_CLUSTER,
35 - n, BDRV_REQ_MAY_UNMAP);
37 + ret = job->dump_cb(job->common.opaque, job->target, start_sec, n, NULL);
40 + ret = bdrv_co_write_zeroes(job->target, start_sec, n, BDRV_REQ_MAY_UNMAP);
43 - ret = bdrv_co_writev(job->target,
44 - start * BACKUP_SECTORS_PER_CLUSTER, n,
47 + ret = job->dump_cb(job->common.opaque, job->target, start_sec, n, bounce_buffer);
50 + ret = bdrv_co_writev(job->target, start_sec, n, &bounce_qiov);
54 trace_backup_do_cow_write_fail(job, start, ret);
55 @@ -216,7 +224,7 @@ static void backup_iostatus_reset(BlockJob *job)
57 BackupBlockJob *s = container_of(job, BackupBlockJob, common);
59 - if (s->target->blk) {
60 + if (s->target && s->target->blk) {
61 blk_iostatus_reset(s->target->blk);
64 @@ -268,9 +276,11 @@ static BlockErrorAction backup_error_action(BackupBlockJob *job,
66 return block_job_error_action(&job->common, job->common.bs,
67 job->on_source_error, true, error);
69 + } else if (job->target) {
70 return block_job_error_action(&job->common, job->target,
71 job->on_target_error, false, error);
73 + return BLOCK_ERROR_ACTION_REPORT;
77 @@ -396,10 +406,12 @@ static void coroutine_fn backup_run(void *opaque)
79 job->bitmap = hbitmap_alloc(end, 0);
81 - bdrv_set_enable_write_cache(target, true);
83 - blk_set_on_error(target->blk, on_target_error, on_target_error);
84 - blk_iostatus_enable(target->blk);
86 + bdrv_set_enable_write_cache(target, true);
88 + blk_set_on_error(target->blk, on_target_error, on_target_error);
89 + blk_iostatus_enable(target->blk);
93 bdrv_add_before_write_notifier(bs, &before_write);
94 @@ -477,10 +489,12 @@ static void coroutine_fn backup_run(void *opaque)
95 qemu_co_rwlock_unlock(&job->flush_rwlock);
96 hbitmap_free(job->bitmap);
99 - blk_iostatus_disable(target->blk);
102 + blk_iostatus_disable(target->blk);
104 + bdrv_op_unblock_all(target, job->common.blocker);
106 - bdrv_op_unblock_all(target, job->common.blocker);
108 data = g_malloc(sizeof(*data));
110 @@ -492,13 +506,15 @@ void backup_start(BlockDriverState *bs, BlockDriverState *target,
111 BdrvDirtyBitmap *sync_bitmap,
112 BlockdevOnError on_source_error,
113 BlockdevOnError on_target_error,
114 + BackupDumpFunc *dump_cb,
115 BlockCompletionFunc *cb, void *opaque,
117 BlockJobTxn *txn, Error **errp)
123 + assert(target || dump_cb);
127 @@ -519,7 +535,7 @@ void backup_start(BlockDriverState *bs, BlockDriverState *target,
131 - if (!bdrv_is_inserted(target)) {
132 + if (target && !bdrv_is_inserted(target)) {
133 error_setg(errp, "Device is not inserted: %s",
134 bdrv_get_device_name(target));
136 @@ -529,7 +545,7 @@ void backup_start(BlockDriverState *bs, BlockDriverState *target,
140 - if (bdrv_op_is_blocked(target, BLOCK_OP_TYPE_BACKUP_TARGET, errp)) {
141 + if (target && bdrv_op_is_blocked(target, BLOCK_OP_TYPE_BACKUP_TARGET, errp)) {
145 @@ -565,14 +581,17 @@ void backup_start(BlockDriverState *bs, BlockDriverState *target,
149 - bdrv_op_block_all(target, job->common.blocker);
151 + bdrv_op_block_all(target, job->common.blocker);
153 + job->dump_cb = dump_cb;
154 job->on_source_error = on_source_error;
155 job->on_target_error = on_target_error;
156 job->target = target;
157 job->sync_mode = sync_mode;
158 job->sync_bitmap = sync_mode == MIRROR_SYNC_MODE_INCREMENTAL ?
160 + job->common.pause_count = pause_count;
161 job->common.len = len;
162 job->common.co = qemu_coroutine_create(backup_run);
163 block_job_txn_add_job(txn, &job->common);
164 diff --git a/blockdev.c b/blockdev.c
165 index 80932e8..1796eaf 100644
168 @@ -3178,8 +3178,8 @@ static void do_drive_backup(const char *device, const char *target,
171 backup_start(bs, target_bs, speed, sync, bmap,
172 - on_source_error, on_target_error,
173 - block_job_cb, bs, txn, &local_err);
174 + on_source_error, on_target_error, NULL,
175 + block_job_cb, bs, 0, txn, &local_err);
176 if (local_err != NULL) {
177 bdrv_unref(target_bs);
178 error_propagate(errp, local_err);
179 @@ -3268,7 +3268,7 @@ void do_blockdev_backup(const char *device, const char *target,
181 bdrv_set_aio_context(target_bs, aio_context);
182 backup_start(bs, target_bs, speed, sync, NULL, on_source_error,
183 - on_target_error, block_job_cb, bs, txn, &local_err);
184 + on_target_error, NULL, block_job_cb, bs, 0, txn, &local_err);
185 if (local_err != NULL) {
186 bdrv_unref(target_bs);
187 error_propagate(errp, local_err);
188 diff --git a/include/block/block_int.h b/include/block/block_int.h
189 index 4012e36..f4b6ecd 100644
190 --- a/include/block/block_int.h
191 +++ b/include/block/block_int.h
194 #define BLOCK_PROBE_BUF_SIZE 512
196 +typedef int BackupDumpFunc(void *opaque, BlockDriverState *bs,
197 + int64_t sector_num, int n_sectors, unsigned char *buf);
199 enum BdrvTrackedRequestType {
202 @@ -679,7 +682,9 @@ void backup_start(BlockDriverState *bs, BlockDriverState *target,
203 BdrvDirtyBitmap *sync_bitmap,
204 BlockdevOnError on_source_error,
205 BlockdevOnError on_target_error,
206 + BackupDumpFunc *dump_cb,
207 BlockCompletionFunc *cb, void *opaque,
209 BlockJobTxn *txn, Error **errp);
211 void blk_set_bs(BlockBackend *blk, BlockDriverState *bs);