]> git.proxmox.com Git - pve-qemu-kvm.git/blame - debian/patches/pve/0015-backup-modify-job-api.patch
update to qemu 2.6.0
[pve-qemu-kvm.git] / debian / patches / pve / 0015-backup-modify-job-api.patch
CommitLineData
ca0fe5f5
WB
1From 2ec6f9ec8443f3389c74e8e21353d01e516c4f46 Mon Sep 17 00:00:00 2001
2From: Wolfgang Bumiller <w.bumiller@proxmox.com>
3Date: Wed, 9 Dec 2015 15:04:57 +0100
b07d35a5 4Subject: [PATCH 15/54] backup: modify job api
ca0fe5f5
WB
5
6Introduces a BackupDump function callback and a pause_count
7for backup_start. For a dump-backup the target parameter
8can now be NULL so access to target needs to be guarded now.
9---
b07d35a5
TL
10 block/backup.c | 90 ++++++++++++++++++++++++++++++-----------------
11 blockdev.c | 6 ++--
12 include/block/block_int.h | 5 +++
13 3 files changed, 65 insertions(+), 36 deletions(-)
ca0fe5f5
WB
14
15diff --git a/block/backup.c b/block/backup.c
16index 705bb77..7ac6b29 100644
17--- a/block/backup.c
18+++ b/block/backup.c
19@@ -43,6 +43,7 @@ typedef struct BackupBlockJob {
20 BdrvDirtyBitmap *sync_bitmap;
21 MirrorSyncMode sync_mode;
22 RateLimit limit;
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,
28 goto out;
29 }
30
b07d35a5 31+ int64_t start_sec = start * sectors_per_cluster;
ca0fe5f5
WB
32 if (buffer_is_zero(iov.iov_base, iov.iov_len)) {
33- ret = bdrv_co_write_zeroes(job->target,
b07d35a5 34- start * sectors_per_cluster,
ca0fe5f5
WB
35- n, BDRV_REQ_MAY_UNMAP);
36+ if (job->dump_cb) {
37+ ret = job->dump_cb(job->common.opaque, job->target, start_sec, n, NULL);
38+ }
39+ if (job->target) {
40+ ret = bdrv_co_write_zeroes(job->target, start_sec, n, BDRV_REQ_MAY_UNMAP);
41+ }
42 } else {
43- ret = bdrv_co_writev(job->target,
b07d35a5 44- start * sectors_per_cluster, n,
ca0fe5f5
WB
45- &bounce_qiov);
46+ if (job->dump_cb) {
47+ ret = job->dump_cb(job->common.opaque, job->target, start_sec, n, bounce_buffer);
48+ }
49+ if (job->target) {
50+ ret = bdrv_co_writev(job->target, start_sec, n, &bounce_qiov);
51+ }
52 }
53 if (ret < 0) {
54 trace_backup_do_cow_write_fail(job, start, ret);
55@@ -216,7 +224,7 @@ static void backup_iostatus_reset(BlockJob *job)
56 {
57 BackupBlockJob *s = container_of(job, BackupBlockJob, common);
58
59- if (s->target->blk) {
60+ if (s->target && s->target->blk) {
61 blk_iostatus_reset(s->target->blk);
62 }
63 }
64@@ -268,9 +276,11 @@ static BlockErrorAction backup_error_action(BackupBlockJob *job,
65 if (read) {
66 return block_job_error_action(&job->common, job->common.bs,
67 job->on_source_error, true, error);
68- } else {
69+ } else if (job->target) {
70 return block_job_error_action(&job->common, job->target,
71 job->on_target_error, false, error);
72+ } else {
73+ return BLOCK_ERROR_ACTION_REPORT;
74 }
75 }
76
b07d35a5 77@@ -404,9 +414,12 @@ static void coroutine_fn backup_run(void *opaque)
ca0fe5f5 78
b07d35a5 79 job->done_bitmap = bitmap_new(end);
ca0fe5f5 80
ca0fe5f5
WB
81- if (target->blk) {
82- blk_set_on_error(target->blk, on_target_error, on_target_error);
83- blk_iostatus_enable(target->blk);
84+ if (target) {
85+ bdrv_set_enable_write_cache(target, true);
86+ if (target->blk) {
87+ blk_set_on_error(target->blk, on_target_error, on_target_error);
88+ blk_iostatus_enable(target->blk);
89+ }
90 }
91
92 bdrv_add_before_write_notifier(bs, &before_write);
b07d35a5 93@@ -484,10 +497,12 @@ static void coroutine_fn backup_run(void *opaque)
ca0fe5f5 94 qemu_co_rwlock_unlock(&job->flush_rwlock);
b07d35a5 95 g_free(job->done_bitmap);
ca0fe5f5
WB
96
97- if (target->blk) {
98- blk_iostatus_disable(target->blk);
99+ if (target) {
100+ if (target->blk) {
101+ blk_iostatus_disable(target->blk);
102+ }
103+ bdrv_op_unblock_all(target, job->common.blocker);
104 }
105- bdrv_op_unblock_all(target, job->common.blocker);
106
107 data = g_malloc(sizeof(*data));
108 data->ret = ret;
b07d35a5 109@@ -499,7 +514,9 @@ void backup_start(BlockDriverState *bs, BlockDriverState *target,
ca0fe5f5
WB
110 BdrvDirtyBitmap *sync_bitmap,
111 BlockdevOnError on_source_error,
112 BlockdevOnError on_target_error,
113+ BackupDumpFunc *dump_cb,
114 BlockCompletionFunc *cb, void *opaque,
115+ int pause_count,
116 BlockJobTxn *txn, Error **errp)
117 {
118 int64_t len;
b07d35a5
TL
119@@ -507,7 +524,7 @@ void backup_start(BlockDriverState *bs, BlockDriverState *target,
120 int ret;
ca0fe5f5
WB
121
122 assert(bs);
123- assert(target);
124+ assert(target || dump_cb);
125 assert(cb);
126
127 if (bs == target) {
128@@ -519,7 +535,7 @@ void backup_start(BlockDriverState *bs, BlockDriverState *target,
129 return;
130 }
131
132- if (!bdrv_is_inserted(target)) {
133+ if (target && !bdrv_is_inserted(target)) {
134 error_setg(errp, "Device is not inserted: %s",
135 bdrv_get_device_name(target));
136 return;
137@@ -529,7 +545,7 @@ void backup_start(BlockDriverState *bs, BlockDriverState *target,
138 return;
139 }
140
141- if (bdrv_op_is_blocked(target, BLOCK_OP_TYPE_BACKUP_TARGET, errp)) {
142+ if (target && bdrv_op_is_blocked(target, BLOCK_OP_TYPE_BACKUP_TARGET, errp)) {
143 return;
144 }
145
b07d35a5 146@@ -574,6 +591,7 @@ void backup_start(BlockDriverState *bs, BlockDriverState *target,
ca0fe5f5
WB
147 goto error;
148 }
149
ca0fe5f5
WB
150+ job->dump_cb = dump_cb;
151 job->on_source_error = on_source_error;
152 job->on_target_error = on_target_error;
153 job->target = target;
b07d35a5 154@@ -581,25 +599,31 @@ void backup_start(BlockDriverState *bs, BlockDriverState *target,
ca0fe5f5
WB
155 job->sync_bitmap = sync_mode == MIRROR_SYNC_MODE_INCREMENTAL ?
156 sync_bitmap : NULL;
b07d35a5
TL
157
158- /* If there is no backing file on the target, we cannot rely on COW if our
159- * backup cluster size is smaller than the target cluster size. Even for
160- * targets with a backing file, try to avoid COW if possible. */
161- ret = bdrv_get_info(job->target, &bdi);
162- if (ret < 0 && !target->backing) {
163- error_setg_errno(errp, -ret,
164- "Couldn't determine the cluster size of the target image, "
165- "which has no backing file");
166- error_append_hint(errp,
167- "Aborting, since this may create an unusable destination image\n");
168- goto error;
169- } else if (ret < 0 && target->backing) {
170- /* Not fatal; just trudge on ahead. */
171- job->cluster_size = BACKUP_CLUSTER_SIZE_DEFAULT;
172+ if (target) {
173+ /* If there is no backing file on the target, we cannot rely on COW if our
174+ * backup cluster size is smaller than the target cluster size. Even for
175+ * targets with a backing file, try to avoid COW if possible. */
176+ ret = bdrv_get_info(job->target, &bdi);
177+ if (ret < 0 && !target->backing) {
178+ error_setg_errno(errp, -ret,
179+ "Couldn't determine the cluster size of the target image, "
180+ "which has no backing file");
181+ error_append_hint(errp,
182+ "Aborting, since this may create an unusable destination image\n");
183+ goto error;
184+ } else if (ret < 0 && target->backing) {
185+ /* Not fatal; just trudge on ahead. */
186+ job->cluster_size = BACKUP_CLUSTER_SIZE_DEFAULT;
187+ } else {
188+ job->cluster_size = MAX(BACKUP_CLUSTER_SIZE_DEFAULT, bdi.cluster_size);
189+ }
190+
191+ bdrv_op_block_all(target, job->common.blocker);
192 } else {
193- job->cluster_size = MAX(BACKUP_CLUSTER_SIZE_DEFAULT, bdi.cluster_size);
194+ job->cluster_size = BACKUP_CLUSTER_SIZE_DEFAULT;
195 }
196
197- bdrv_op_block_all(target, job->common.blocker);
ca0fe5f5
WB
198+ job->common.pause_count = pause_count;
199 job->common.len = len;
200 job->common.co = qemu_coroutine_create(backup_run);
201 block_job_txn_add_job(txn, &job->common);
202diff --git a/blockdev.c b/blockdev.c
203index 80932e8..1796eaf 100644
204--- a/blockdev.c
205+++ b/blockdev.c
206@@ -3178,8 +3178,8 @@ static void do_drive_backup(const char *device, const char *target,
207 }
208
209 backup_start(bs, target_bs, speed, sync, bmap,
210- on_source_error, on_target_error,
211- block_job_cb, bs, txn, &local_err);
212+ on_source_error, on_target_error, NULL,
213+ block_job_cb, bs, 0, txn, &local_err);
214 if (local_err != NULL) {
215 bdrv_unref(target_bs);
216 error_propagate(errp, local_err);
217@@ -3268,7 +3268,7 @@ void do_blockdev_backup(const char *device, const char *target,
218 bdrv_ref(target_bs);
219 bdrv_set_aio_context(target_bs, aio_context);
220 backup_start(bs, target_bs, speed, sync, NULL, on_source_error,
221- on_target_error, block_job_cb, bs, txn, &local_err);
222+ on_target_error, NULL, block_job_cb, bs, 0, txn, &local_err);
223 if (local_err != NULL) {
224 bdrv_unref(target_bs);
225 error_propagate(errp, local_err);
226diff --git a/include/block/block_int.h b/include/block/block_int.h
227index 4012e36..f4b6ecd 100644
228--- a/include/block/block_int.h
229+++ b/include/block/block_int.h
230@@ -60,6 +60,9 @@
231
232 #define BLOCK_PROBE_BUF_SIZE 512
233
234+typedef int BackupDumpFunc(void *opaque, BlockDriverState *bs,
235+ int64_t sector_num, int n_sectors, unsigned char *buf);
236+
237 enum BdrvTrackedRequestType {
238 BDRV_TRACKED_READ,
239 BDRV_TRACKED_WRITE,
240@@ -679,7 +682,9 @@ void backup_start(BlockDriverState *bs, BlockDriverState *target,
241 BdrvDirtyBitmap *sync_bitmap,
242 BlockdevOnError on_source_error,
243 BlockdevOnError on_target_error,
244+ BackupDumpFunc *dump_cb,
245 BlockCompletionFunc *cb, void *opaque,
246+ int pause_count,
247 BlockJobTxn *txn, Error **errp);
248
b07d35a5 249 void hmp_drive_add_node(Monitor *mon, const char *optstr);
ca0fe5f5
WB
250--
2512.1.4
252