]> git.proxmox.com Git - pve-qemu-kvm.git/blame - debian/patches/pve/0014-backup-modify-job-api.patch
update upload target
[pve-qemu-kvm.git] / debian / patches / pve / 0014-backup-modify-job-api.patch
CommitLineData
9c3bec39 1From 1078c0f6acc1bfba04b7d5cdfdeb02b161b5f7c4 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---
68a30562 10 block/backup.c | 82 +++++++++++++++++++++++++++++++----------------
b07d35a5
TL
11 blockdev.c | 6 ++--
12 include/block/block_int.h | 5 +++
68a30562 13 3 files changed, 63 insertions(+), 30 deletions(-)
ca0fe5f5
WB
14
15diff --git a/block/backup.c b/block/backup.c
68a30562 16index 2c05323..f3c0ba3 100644
ca0fe5f5
WB
17--- a/block/backup.c
18+++ b/block/backup.c
6fb04df7 19@@ -41,6 +41,7 @@ typedef struct BackupBlockJob {
ca0fe5f5
WB
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;
68a30562 27@@ -149,12 +150,23 @@ static int coroutine_fn backup_do_cow(BackupBlockJob *job,
ca0fe5f5
WB
28 goto out;
29 }
30
b07d35a5 31+ int64_t start_sec = start * sectors_per_cluster;
ca0fe5f5 32 if (buffer_is_zero(iov.iov_base, iov.iov_len)) {
68a30562
WB
33- ret = blk_co_pwrite_zeroes(job->target, start * job->cluster_size,
34- bounce_qiov.size, BDRV_REQ_MAY_UNMAP);
ca0fe5f5
WB
35+ if (job->dump_cb) {
36+ ret = job->dump_cb(job->common.opaque, job->target, start_sec, n, NULL);
37+ }
38+ if (job->target) {
68a30562
WB
39+ ret = blk_co_pwrite_zeroes(job->target, start * job->cluster_size,
40+ bounce_qiov.size, BDRV_REQ_MAY_UNMAP);
ca0fe5f5
WB
41+ }
42 } else {
68a30562
WB
43- ret = blk_co_pwritev(job->target, start * job->cluster_size,
44- bounce_qiov.size, &bounce_qiov, 0);
ca0fe5f5
WB
45+ if (job->dump_cb) {
46+ ret = job->dump_cb(job->common.opaque, job->target, start_sec, n, bounce_buffer);
47+ }
48+ if (job->target) {
68a30562
WB
49+ ret = blk_co_pwritev(job->target, start * job->cluster_size,
50+ bounce_qiov.size, &bounce_qiov, 0);
ca0fe5f5
WB
51+ }
52 }
53 if (ret < 0) {
54 trace_backup_do_cow_write_fail(job, start, ret);
68a30562 55@@ -268,9 +280,11 @@ static BlockErrorAction backup_error_action(BackupBlockJob *job,
ca0fe5f5 56 if (read) {
68a30562
WB
57 return block_job_error_action(&job->common, job->on_source_error,
58 true, error);
ca0fe5f5
WB
59- } else {
60+ } else if (job->target) {
68a30562
WB
61 return block_job_error_action(&job->common, job->on_target_error,
62 false, error);
ca0fe5f5
WB
63+ } else {
64+ return BLOCK_ERROR_ACTION_REPORT;
65 }
66 }
67
68a30562 68@@ -393,6 +407,7 @@ static void coroutine_fn backup_run(void *opaque)
ca0fe5f5 69
b07d35a5 70 job->done_bitmap = bitmap_new(end);
ca0fe5f5 71
68a30562
WB
72+
73 job->before_write.notify = backup_before_write_notify;
74 bdrv_add_before_write_notifier(bs, &job->before_write);
ca0fe5f5 75
68a30562 76@@ -467,7 +482,9 @@ static void coroutine_fn backup_run(void *opaque)
ca0fe5f5 77 qemu_co_rwlock_unlock(&job->flush_rwlock);
b07d35a5 78 g_free(job->done_bitmap);
ca0fe5f5 79
68a30562 80- bdrv_op_unblock_all(blk_bs(target), job->common.blocker);
ca0fe5f5 81+ if (target) {
68a30562
WB
82+ bdrv_op_unblock_all(blk_bs(target), job->common.blocker);
83+ }
ca0fe5f5
WB
84
85 data = g_malloc(sizeof(*data));
86 data->ret = ret;
68a30562
WB
87@@ -479,7 +496,9 @@ void backup_start(const char *job_id, BlockDriverState *bs,
88 MirrorSyncMode sync_mode, BdrvDirtyBitmap *sync_bitmap,
ca0fe5f5
WB
89 BlockdevOnError on_source_error,
90 BlockdevOnError on_target_error,
91+ BackupDumpFunc *dump_cb,
92 BlockCompletionFunc *cb, void *opaque,
93+ int pause_count,
94 BlockJobTxn *txn, Error **errp)
95 {
96 int64_t len;
68a30562 97@@ -488,7 +507,7 @@ void backup_start(const char *job_id, BlockDriverState *bs,
b07d35a5 98 int ret;
ca0fe5f5
WB
99
100 assert(bs);
101- assert(target);
102+ assert(target || dump_cb);
ca0fe5f5
WB
103
104 if (bs == target) {
68a30562
WB
105 error_setg(errp, "Source and target cannot be the same");
106@@ -501,7 +520,7 @@ void backup_start(const char *job_id, BlockDriverState *bs,
ca0fe5f5
WB
107 return;
108 }
109
110- if (!bdrv_is_inserted(target)) {
111+ if (target && !bdrv_is_inserted(target)) {
112 error_setg(errp, "Device is not inserted: %s",
113 bdrv_get_device_name(target));
114 return;
68a30562 115@@ -511,7 +530,7 @@ void backup_start(const char *job_id, BlockDriverState *bs,
ca0fe5f5
WB
116 return;
117 }
118
119- if (bdrv_op_is_blocked(target, BLOCK_OP_TYPE_BACKUP_TARGET, errp)) {
120+ if (target && bdrv_op_is_blocked(target, BLOCK_OP_TYPE_BACKUP_TARGET, errp)) {
121 return;
122 }
123
68a30562 124@@ -547,34 +566,43 @@ void backup_start(const char *job_id, BlockDriverState *bs,
ca0fe5f5
WB
125 goto error;
126 }
127
68a30562
WB
128- job->target = blk_new();
129- blk_insert_bs(job->target, target);
130+ if (target) {
131+ job->target = blk_new();
132+ blk_insert_bs(job->target, target);
133+ }
134
ca0fe5f5
WB
135+ job->dump_cb = dump_cb;
136 job->on_source_error = on_source_error;
137 job->on_target_error = on_target_error;
68a30562 138 job->sync_mode = sync_mode;
ca0fe5f5
WB
139 job->sync_bitmap = sync_mode == MIRROR_SYNC_MODE_INCREMENTAL ?
140 sync_bitmap : NULL;
b07d35a5
TL
141
142- /* If there is no backing file on the target, we cannot rely on COW if our
143- * backup cluster size is smaller than the target cluster size. Even for
144- * targets with a backing file, try to avoid COW if possible. */
68a30562 145- ret = bdrv_get_info(target, &bdi);
b07d35a5
TL
146- if (ret < 0 && !target->backing) {
147- error_setg_errno(errp, -ret,
148- "Couldn't determine the cluster size of the target image, "
149- "which has no backing file");
150- error_append_hint(errp,
151- "Aborting, since this may create an unusable destination image\n");
152- goto error;
153- } else if (ret < 0 && target->backing) {
154- /* Not fatal; just trudge on ahead. */
155- job->cluster_size = BACKUP_CLUSTER_SIZE_DEFAULT;
156+ if (target) {
157+ /* If there is no backing file on the target, we cannot rely on COW if our
158+ * backup cluster size is smaller than the target cluster size. Even for
159+ * targets with a backing file, try to avoid COW if possible. */
68a30562 160+ ret = bdrv_get_info(target, &bdi);
b07d35a5
TL
161+ if (ret < 0 && !target->backing) {
162+ error_setg_errno(errp, -ret,
163+ "Couldn't determine the cluster size of the target image, "
164+ "which has no backing file");
165+ error_append_hint(errp,
166+ "Aborting, since this may create an unusable destination image\n");
167+ goto error;
168+ } else if (ret < 0 && target->backing) {
169+ /* Not fatal; just trudge on ahead. */
170+ job->cluster_size = BACKUP_CLUSTER_SIZE_DEFAULT;
171+ } else {
172+ job->cluster_size = MAX(BACKUP_CLUSTER_SIZE_DEFAULT, bdi.cluster_size);
173+ }
174+
175+ bdrv_op_block_all(target, job->common.blocker);
176 } else {
177- job->cluster_size = MAX(BACKUP_CLUSTER_SIZE_DEFAULT, bdi.cluster_size);
178+ job->cluster_size = BACKUP_CLUSTER_SIZE_DEFAULT;
179 }
180
181- bdrv_op_block_all(target, job->common.blocker);
ca0fe5f5
WB
182+ job->common.pause_count = pause_count;
183 job->common.len = len;
68a30562 184 job->common.co = qemu_coroutine_create(backup_run, job);
ca0fe5f5
WB
185 block_job_txn_add_job(txn, &job->common);
186diff --git a/blockdev.c b/blockdev.c
68a30562 187index 2161400..5e3707d 100644
ca0fe5f5
WB
188--- a/blockdev.c
189+++ b/blockdev.c
68a30562 190@@ -3277,8 +3277,8 @@ static void do_drive_backup(const char *job_id, const char *device,
ca0fe5f5
WB
191 }
192
68a30562 193 backup_start(job_id, bs, target_bs, speed, sync, bmap,
ca0fe5f5
WB
194- on_source_error, on_target_error,
195- block_job_cb, bs, txn, &local_err);
196+ on_source_error, on_target_error, NULL,
197+ block_job_cb, bs, 0, txn, &local_err);
68a30562 198 bdrv_unref(target_bs);
ca0fe5f5 199 if (local_err != NULL) {
ca0fe5f5 200 error_propagate(errp, local_err);
68a30562
WB
201@@ -3371,7 +3371,7 @@ void do_blockdev_backup(const char *job_id, const char *device,
202 }
203 }
204 backup_start(job_id, bs, target_bs, speed, sync, NULL, on_source_error,
ca0fe5f5
WB
205- on_target_error, block_job_cb, bs, txn, &local_err);
206+ on_target_error, NULL, block_job_cb, bs, 0, txn, &local_err);
207 if (local_err != NULL) {
ca0fe5f5 208 error_propagate(errp, local_err);
68a30562 209 }
ca0fe5f5 210diff --git a/include/block/block_int.h b/include/block/block_int.h
68a30562 211index 1e939de..db4650e 100644
ca0fe5f5
WB
212--- a/include/block/block_int.h
213+++ b/include/block/block_int.h
68a30562 214@@ -59,6 +59,9 @@
ca0fe5f5
WB
215
216 #define BLOCK_PROBE_BUF_SIZE 512
217
218+typedef int BackupDumpFunc(void *opaque, BlockDriverState *bs,
219+ int64_t sector_num, int n_sectors, unsigned char *buf);
220+
221 enum BdrvTrackedRequestType {
222 BDRV_TRACKED_READ,
223 BDRV_TRACKED_WRITE,
68a30562
WB
224@@ -767,7 +770,9 @@ void backup_start(const char *job_id, BlockDriverState *bs,
225 MirrorSyncMode sync_mode, BdrvDirtyBitmap *sync_bitmap,
ca0fe5f5
WB
226 BlockdevOnError on_source_error,
227 BlockdevOnError on_target_error,
228+ BackupDumpFunc *dump_cb,
229 BlockCompletionFunc *cb, void *opaque,
230+ int pause_count,
231 BlockJobTxn *txn, Error **errp);
232
b07d35a5 233 void hmp_drive_add_node(Monitor *mon, const char *optstr);
ca0fe5f5
WB
234--
2352.1.4
236