]> git.proxmox.com Git - pve-qemu-kvm.git/blame - debian/patches/pve/0014-backup-modify-job-api.patch
update to qemu-2.9.0-rc2
[pve-qemu-kvm.git] / debian / patches / pve / 0014-backup-modify-job-api.patch
CommitLineData
1a91ab45 1From 46f9d5c97a466bc121c99d9f178a4c1bdc74e9f9 Mon Sep 17 00:00:00 2001
ca0fe5f5
WB
2From: Wolfgang Bumiller <w.bumiller@proxmox.com>
3Date: Wed, 9 Dec 2015 15:04:57 +0100
9c3bec39 4Subject: [PATCH 14/47] 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---
1a91ab45
WB
10 block/backup.c | 116 ++++++++++++++++++++++++++++------------------
11 block/replication.c | 3 +-
12 blockdev.c | 4 +-
13 include/block/block_int.h | 5 ++
14 4 files changed, 81 insertions(+), 47 deletions(-)
ca0fe5f5
WB
15
16diff --git a/block/backup.c b/block/backup.c
1a91ab45 17index a4fb288..3a230b5 100644
ca0fe5f5
WB
18--- a/block/backup.c
19+++ b/block/backup.c
1a91ab45 20@@ -36,6 +36,7 @@ typedef struct BackupBlockJob {
ca0fe5f5
WB
21 BdrvDirtyBitmap *sync_bitmap;
22 MirrorSyncMode sync_mode;
23 RateLimit limit;
24+ BackupDumpFunc *dump_cb;
25 BlockdevOnError on_source_error;
26 BlockdevOnError on_target_error;
27 CoRwlock flush_rwlock;
1a91ab45 28@@ -145,13 +146,24 @@ static int coroutine_fn backup_do_cow(BackupBlockJob *job,
ca0fe5f5
WB
29 goto out;
30 }
31
b07d35a5 32+ int64_t start_sec = start * sectors_per_cluster;
ca0fe5f5 33 if (buffer_is_zero(iov.iov_base, iov.iov_len)) {
68a30562
WB
34- ret = blk_co_pwrite_zeroes(job->target, start * job->cluster_size,
35- bounce_qiov.size, BDRV_REQ_MAY_UNMAP);
ca0fe5f5
WB
36+ if (job->dump_cb) {
37+ ret = job->dump_cb(job->common.opaque, job->target, start_sec, n, NULL);
38+ }
39+ if (job->target) {
68a30562
WB
40+ ret = blk_co_pwrite_zeroes(job->target, start * job->cluster_size,
41+ bounce_qiov.size, BDRV_REQ_MAY_UNMAP);
ca0fe5f5
WB
42+ }
43 } else {
68a30562 44- ret = blk_co_pwritev(job->target, start * job->cluster_size,
1a91ab45
WB
45- bounce_qiov.size, &bounce_qiov,
46- job->compress ? BDRV_REQ_WRITE_COMPRESSED : 0);
ca0fe5f5
WB
47+ if (job->dump_cb) {
48+ ret = job->dump_cb(job->common.opaque, job->target, start_sec, n, bounce_buffer);
49+ }
50+ if (job->target) {
68a30562 51+ ret = blk_co_pwritev(job->target, start * job->cluster_size,
1a91ab45
WB
52+ bounce_qiov.size, &bounce_qiov,
53+ job->compress ? BDRV_REQ_WRITE_COMPRESSED : 0);
ca0fe5f5
WB
54+ }
55 }
56 if (ret < 0) {
57 trace_backup_do_cow_write_fail(job, start, ret);
1a91ab45 58@@ -330,9 +342,11 @@ static BlockErrorAction backup_error_action(BackupBlockJob *job,
ca0fe5f5 59 if (read) {
68a30562
WB
60 return block_job_error_action(&job->common, job->on_source_error,
61 true, error);
ca0fe5f5
WB
62- } else {
63+ } else if (job->target) {
68a30562
WB
64 return block_job_error_action(&job->common, job->on_target_error,
65 false, error);
ca0fe5f5
WB
66+ } else {
67+ return BLOCK_ERROR_ACTION_REPORT;
68 }
69 }
70
1a91ab45 71@@ -453,6 +467,7 @@ static void coroutine_fn backup_run(void *opaque)
ca0fe5f5 72
b07d35a5 73 job->done_bitmap = bitmap_new(end);
ca0fe5f5 74
68a30562
WB
75+
76 job->before_write.notify = backup_before_write_notify;
77 bdrv_add_before_write_notifier(bs, &job->before_write);
ca0fe5f5 78
1a91ab45 79@@ -557,7 +572,9 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
ca0fe5f5
WB
80 BlockdevOnError on_source_error,
81 BlockdevOnError on_target_error,
1a91ab45 82 int creation_flags,
ca0fe5f5
WB
83+ BackupDumpFunc *dump_cb,
84 BlockCompletionFunc *cb, void *opaque,
85+ int pause_count,
86 BlockJobTxn *txn, Error **errp)
87 {
88 int64_t len;
1a91ab45 89@@ -566,7 +583,7 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
b07d35a5 90 int ret;
ca0fe5f5
WB
91
92 assert(bs);
93- assert(target);
94+ assert(target || dump_cb);
ca0fe5f5
WB
95
96 if (bs == target) {
68a30562 97 error_setg(errp, "Source and target cannot be the same");
1a91ab45
WB
98@@ -579,13 +596,13 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
99 return NULL;
ca0fe5f5
WB
100 }
101
102- if (!bdrv_is_inserted(target)) {
103+ if (target && !bdrv_is_inserted(target)) {
104 error_setg(errp, "Device is not inserted: %s",
105 bdrv_get_device_name(target));
1a91ab45
WB
106 return NULL;
107 }
108
109- if (compress && target->drv->bdrv_co_pwritev_compressed == NULL) {
110+ if (target && compress && target->drv->bdrv_co_pwritev_compressed == NULL) {
111 error_setg(errp, "Compression is not supported for this drive %s",
112 bdrv_get_device_name(target));
113 return NULL;
114@@ -595,7 +612,7 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
115 return NULL;
ca0fe5f5
WB
116 }
117
118- if (bdrv_op_is_blocked(target, BLOCK_OP_TYPE_BACKUP_TARGET, errp)) {
119+ if (target && bdrv_op_is_blocked(target, BLOCK_OP_TYPE_BACKUP_TARGET, errp)) {
1a91ab45 120 return NULL;
ca0fe5f5
WB
121 }
122
1a91ab45 123@@ -635,15 +652,18 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
ca0fe5f5
WB
124 goto error;
125 }
126
1a91ab45
WB
127- /* The target must match the source in size, so no resize here either */
128- job->target = blk_new(BLK_PERM_WRITE,
129- BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE |
130- BLK_PERM_WRITE_UNCHANGED | BLK_PERM_GRAPH_MOD);
131- ret = blk_insert_bs(job->target, target, errp);
132- if (ret < 0) {
133- goto error;
68a30562 134+ if (target) {
1a91ab45
WB
135+ /* The target must match the source in size, so no resize here either */
136+ job->target = blk_new(BLK_PERM_WRITE,
137+ BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE |
138+ BLK_PERM_WRITE_UNCHANGED | BLK_PERM_GRAPH_MOD);
139+ ret = blk_insert_bs(job->target, target, errp);
140+ if (ret < 0) {
141+ goto error;
142+ }
143 }
68a30562 144
ca0fe5f5
WB
145+ job->dump_cb = dump_cb;
146 job->on_source_error = on_source_error;
147 job->on_target_error = on_target_error;
68a30562 148 job->sync_mode = sync_mode;
1a91ab45 149@@ -651,36 +671,44 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
ca0fe5f5 150 sync_bitmap : NULL;
1a91ab45 151 job->compress = compress;
b07d35a5
TL
152
153- /* If there is no backing file on the target, we cannot rely on COW if our
154- * backup cluster size is smaller than the target cluster size. Even for
155- * targets with a backing file, try to avoid COW if possible. */
68a30562 156- ret = bdrv_get_info(target, &bdi);
1a91ab45
WB
157- if (ret == -ENOTSUP && !target->backing) {
158- /* Cluster size is not defined */
159- error_report("WARNING: The target block device doesn't provide "
160- "information about the block size and it doesn't have a "
161- "backing file. The default block size of %u bytes is "
162- "used. If the actual block size of the target exceeds "
163- "this default, the backup may be unusable",
164- BACKUP_CLUSTER_SIZE_DEFAULT);
165- job->cluster_size = BACKUP_CLUSTER_SIZE_DEFAULT;
166- } else if (ret < 0 && !target->backing) {
b07d35a5
TL
167- error_setg_errno(errp, -ret,
168- "Couldn't determine the cluster size of the target image, "
169- "which has no backing file");
170- error_append_hint(errp,
171- "Aborting, since this may create an unusable destination image\n");
172- goto error;
173- } else if (ret < 0 && target->backing) {
174- /* Not fatal; just trudge on ahead. */
175- job->cluster_size = BACKUP_CLUSTER_SIZE_DEFAULT;
176+ if (target) {
177+ /* If there is no backing file on the target, we cannot rely on COW if our
178+ * backup cluster size is smaller than the target cluster size. Even for
179+ * targets with a backing file, try to avoid COW if possible. */
68a30562 180+ ret = bdrv_get_info(target, &bdi);
1a91ab45
WB
181+ if (ret == -ENOTSUP && !target->backing) {
182+ /* Cluster size is not defined */
183+ error_report("WARNING: The target block device doesn't provide "
184+ "information about the block size and it doesn't have a "
185+ "backing file. The default block size of %u bytes is "
186+ "used. If the actual block size of the target exceeds "
187+ "this default, the backup may be unusable",
188+ BACKUP_CLUSTER_SIZE_DEFAULT);
189+ job->cluster_size = BACKUP_CLUSTER_SIZE_DEFAULT;
190+ } else if (ret < 0 && !target->backing) {
b07d35a5
TL
191+ error_setg_errno(errp, -ret,
192+ "Couldn't determine the cluster size of the target image, "
193+ "which has no backing file");
194+ error_append_hint(errp,
195+ "Aborting, since this may create an unusable destination image\n");
196+ goto error;
197+ } else if (ret < 0 && target->backing) {
198+ /* Not fatal; just trudge on ahead. */
199+ job->cluster_size = BACKUP_CLUSTER_SIZE_DEFAULT;
200+ } else {
1a91ab45 201+ job->cluster_size = BACKUP_CLUSTER_SIZE_DEFAULT;
b07d35a5 202+ }
b07d35a5
TL
203 } else {
204- job->cluster_size = MAX(BACKUP_CLUSTER_SIZE_DEFAULT, bdi.cluster_size);
205+ job->cluster_size = BACKUP_CLUSTER_SIZE_DEFAULT;
206 }
207
1a91ab45
WB
208- /* Required permissions are already taken with target's blk_new() */
209- block_job_add_bdrv(&job->common, "target", target, 0, BLK_PERM_ALL,
210- &error_abort);
211+ if (target) {
212+ /* Required permissions are already taken with target's blk_new() */
213+ block_job_add_bdrv(&job->common, "target", target, 0, BLK_PERM_ALL,
214+ &error_abort);
215+ } else {
216+ job->common.pause_count = pause_count;
217+ }
ca0fe5f5 218 job->common.len = len;
ca0fe5f5 219 block_job_txn_add_job(txn, &job->common);
1a91ab45
WB
220
221diff --git a/block/replication.c b/block/replication.c
222index bf3c395..60c6524 100644
223--- a/block/replication.c
224+++ b/block/replication.c
225@@ -531,7 +531,8 @@ static void replication_start(ReplicationState *rs, ReplicationMode mode,
226 0, MIRROR_SYNC_MODE_NONE, NULL, false,
227 BLOCKDEV_ON_ERROR_REPORT,
228 BLOCKDEV_ON_ERROR_REPORT, BLOCK_JOB_INTERNAL,
229- backup_job_completed, bs, NULL, &local_err);
230+ NULL,
231+ backup_job_completed, bs, 0, NULL, &local_err);
232 if (local_err) {
233 error_propagate(errp, local_err);
234 backup_job_cleanup(bs);
ca0fe5f5 235diff --git a/blockdev.c b/blockdev.c
1a91ab45 236index 040c152..bb3fc5b 100644
ca0fe5f5
WB
237--- a/blockdev.c
238+++ b/blockdev.c
1a91ab45
WB
239@@ -3273,7 +3273,7 @@ static BlockJob *do_drive_backup(DriveBackup *backup, BlockJobTxn *txn,
240 job = backup_job_create(backup->job_id, bs, target_bs, backup->speed,
241 backup->sync, bmap, backup->compress,
242 backup->on_source_error, backup->on_target_error,
243- BLOCK_JOB_DEFAULT, NULL, NULL, txn, &local_err);
244+ BLOCK_JOB_DEFAULT, NULL, NULL, NULL, 0, txn, &local_err);
68a30562 245 bdrv_unref(target_bs);
ca0fe5f5 246 if (local_err != NULL) {
ca0fe5f5 247 error_propagate(errp, local_err);
1a91ab45
WB
248@@ -3352,7 +3352,7 @@ BlockJob *do_blockdev_backup(BlockdevBackup *backup, BlockJobTxn *txn,
249 job = backup_job_create(backup->job_id, bs, target_bs, backup->speed,
250 backup->sync, NULL, backup->compress,
251 backup->on_source_error, backup->on_target_error,
252- BLOCK_JOB_DEFAULT, NULL, NULL, txn, &local_err);
253+ BLOCK_JOB_DEFAULT, NULL, NULL, NULL, 0, txn, &local_err);
ca0fe5f5 254 if (local_err != NULL) {
ca0fe5f5 255 error_propagate(errp, local_err);
68a30562 256 }
ca0fe5f5 257diff --git a/include/block/block_int.h b/include/block/block_int.h
1a91ab45 258index 59400bd..ec65581 100644
ca0fe5f5
WB
259--- a/include/block/block_int.h
260+++ b/include/block/block_int.h
68a30562 261@@ -59,6 +59,9 @@
ca0fe5f5
WB
262
263 #define BLOCK_PROBE_BUF_SIZE 512
264
265+typedef int BackupDumpFunc(void *opaque, BlockDriverState *bs,
266+ int64_t sector_num, int n_sectors, unsigned char *buf);
267+
268 enum BdrvTrackedRequestType {
269 BDRV_TRACKED_READ,
270 BDRV_TRACKED_WRITE,
1a91ab45
WB
271@@ -877,7 +880,9 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
272 BlockdevOnError on_source_error,
273 BlockdevOnError on_target_error,
274 int creation_flags,
275+ BackupDumpFunc *dump_cb,
276 BlockCompletionFunc *cb, void *opaque,
277+ int pause_count,
278 BlockJobTxn *txn, Error **errp);
ca0fe5f5 279
b07d35a5 280 void hmp_drive_add_node(Monitor *mon, const char *optstr);
ca0fe5f5
WB
281--
2822.1.4
283