]> git.proxmox.com Git - pve-qemu-kvm.git/blob - debian/patches/pve/0014-backup-modify-job-api.patch
4a4b67134ff9e3e43287ca754ec238cb245b5ee1
[pve-qemu-kvm.git] / debian / patches / pve / 0014-backup-modify-job-api.patch
1 From 1078c0f6acc1bfba04b7d5cdfdeb02b161b5f7c4 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 14/47] backup: modify job api
5
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.
9 ---
10 block/backup.c | 82 +++++++++++++++++++++++++++++++----------------
11 blockdev.c | 6 ++--
12 include/block/block_int.h | 5 +++
13 3 files changed, 63 insertions(+), 30 deletions(-)
14
15 diff --git a/block/backup.c b/block/backup.c
16 index 2c05323..f3c0ba3 100644
17 --- a/block/backup.c
18 +++ b/block/backup.c
19 @@ -41,6 +41,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 @@ -149,12 +150,23 @@ static int coroutine_fn backup_do_cow(BackupBlockJob *job,
28 goto out;
29 }
30
31 + int64_t start_sec = start * sectors_per_cluster;
32 if (buffer_is_zero(iov.iov_base, iov.iov_len)) {
33 - ret = blk_co_pwrite_zeroes(job->target, start * job->cluster_size,
34 - bounce_qiov.size, BDRV_REQ_MAY_UNMAP);
35 + if (job->dump_cb) {
36 + ret = job->dump_cb(job->common.opaque, job->target, start_sec, n, NULL);
37 + }
38 + if (job->target) {
39 + ret = blk_co_pwrite_zeroes(job->target, start * job->cluster_size,
40 + bounce_qiov.size, BDRV_REQ_MAY_UNMAP);
41 + }
42 } else {
43 - ret = blk_co_pwritev(job->target, start * job->cluster_size,
44 - bounce_qiov.size, &bounce_qiov, 0);
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) {
49 + ret = blk_co_pwritev(job->target, start * job->cluster_size,
50 + bounce_qiov.size, &bounce_qiov, 0);
51 + }
52 }
53 if (ret < 0) {
54 trace_backup_do_cow_write_fail(job, start, ret);
55 @@ -268,9 +280,11 @@ static BlockErrorAction backup_error_action(BackupBlockJob *job,
56 if (read) {
57 return block_job_error_action(&job->common, job->on_source_error,
58 true, error);
59 - } else {
60 + } else if (job->target) {
61 return block_job_error_action(&job->common, job->on_target_error,
62 false, error);
63 + } else {
64 + return BLOCK_ERROR_ACTION_REPORT;
65 }
66 }
67
68 @@ -393,6 +407,7 @@ static void coroutine_fn backup_run(void *opaque)
69
70 job->done_bitmap = bitmap_new(end);
71
72 +
73 job->before_write.notify = backup_before_write_notify;
74 bdrv_add_before_write_notifier(bs, &job->before_write);
75
76 @@ -467,7 +482,9 @@ static void coroutine_fn backup_run(void *opaque)
77 qemu_co_rwlock_unlock(&job->flush_rwlock);
78 g_free(job->done_bitmap);
79
80 - bdrv_op_unblock_all(blk_bs(target), job->common.blocker);
81 + if (target) {
82 + bdrv_op_unblock_all(blk_bs(target), job->common.blocker);
83 + }
84
85 data = g_malloc(sizeof(*data));
86 data->ret = ret;
87 @@ -479,7 +496,9 @@ void backup_start(const char *job_id, BlockDriverState *bs,
88 MirrorSyncMode sync_mode, BdrvDirtyBitmap *sync_bitmap,
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;
97 @@ -488,7 +507,7 @@ void backup_start(const char *job_id, BlockDriverState *bs,
98 int ret;
99
100 assert(bs);
101 - assert(target);
102 + assert(target || dump_cb);
103
104 if (bs == target) {
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,
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;
115 @@ -511,7 +530,7 @@ void backup_start(const char *job_id, BlockDriverState *bs,
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
124 @@ -547,34 +566,43 @@ void backup_start(const char *job_id, BlockDriverState *bs,
125 goto error;
126 }
127
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
135 + job->dump_cb = dump_cb;
136 job->on_source_error = on_source_error;
137 job->on_target_error = on_target_error;
138 job->sync_mode = sync_mode;
139 job->sync_bitmap = sync_mode == MIRROR_SYNC_MODE_INCREMENTAL ?
140 sync_bitmap : NULL;
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. */
145 - ret = bdrv_get_info(target, &bdi);
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. */
160 + ret = bdrv_get_info(target, &bdi);
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);
182 + job->common.pause_count = pause_count;
183 job->common.len = len;
184 job->common.co = qemu_coroutine_create(backup_run, job);
185 block_job_txn_add_job(txn, &job->common);
186 diff --git a/blockdev.c b/blockdev.c
187 index 2161400..5e3707d 100644
188 --- a/blockdev.c
189 +++ b/blockdev.c
190 @@ -3277,8 +3277,8 @@ static void do_drive_backup(const char *job_id, const char *device,
191 }
192
193 backup_start(job_id, bs, target_bs, speed, sync, bmap,
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);
198 bdrv_unref(target_bs);
199 if (local_err != NULL) {
200 error_propagate(errp, local_err);
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,
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) {
208 error_propagate(errp, local_err);
209 }
210 diff --git a/include/block/block_int.h b/include/block/block_int.h
211 index 1e939de..db4650e 100644
212 --- a/include/block/block_int.h
213 +++ b/include/block/block_int.h
214 @@ -59,6 +59,9 @@
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,
224 @@ -767,7 +770,9 @@ void backup_start(const char *job_id, BlockDriverState *bs,
225 MirrorSyncMode sync_mode, BdrvDirtyBitmap *sync_bitmap,
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
233 void hmp_drive_add_node(Monitor *mon, const char *optstr);
234 --
235 2.1.4
236