]>
Commit | Line | Data |
---|---|---|
cbf9030a DM |
1 | Index: new/block/backup.c |
2 | =================================================================== | |
24bb7da3 DM |
3 | --- new.orig/block/backup.c 2014-11-20 07:55:31.000000000 +0100 |
4 | +++ new/block/backup.c 2014-11-20 08:56:23.000000000 +0100 | |
cbf9030a | 5 | @@ -39,6 +39,7 @@ |
432a6eb5 | 6 | BdrvDirtyBitmap *sync_bitmap; |
cbf9030a DM |
7 | MirrorSyncMode sync_mode; |
8 | RateLimit limit; | |
9 | + BackupDumpFunc *dump_cb; | |
10 | BlockdevOnError on_source_error; | |
11 | BlockdevOnError on_target_error; | |
12 | CoRwlock flush_rwlock; | |
38f36829 | 13 | @@ -136,14 +137,21 @@ |
5cf8ed03 | 14 | goto out; |
cbf9030a DM |
15 | } |
16 | ||
5cf8ed03 | 17 | + int64_t start_sec = start * BACKUP_SECTORS_PER_CLUSTER; |
cbf9030a DM |
18 | if (buffer_is_zero(iov.iov_base, iov.iov_len)) { |
19 | - ret = bdrv_co_write_zeroes(job->target, | |
38f36829 DM |
20 | - start * BACKUP_SECTORS_PER_CLUSTER, |
21 | - n, BDRV_REQ_MAY_UNMAP); | |
cbf9030a | 22 | + if (job->dump_cb) { |
5cf8ed03 DM |
23 | + ret = job->dump_cb(job->common.opaque, job->target, start_sec, n, NULL); |
24 | + } | |
25 | + if (job->target) { | |
38f36829 | 26 | + ret = bdrv_co_write_zeroes(job->target, start_sec, n, BDRV_REQ_MAY_UNMAP); |
cbf9030a DM |
27 | + } |
28 | } else { | |
29 | - ret = bdrv_co_writev(job->target, | |
30 | - start * BACKUP_SECTORS_PER_CLUSTER, n, | |
31 | - &bounce_qiov); | |
32 | + if (job->dump_cb) { | |
5cf8ed03 DM |
33 | + ret = job->dump_cb(job->common.opaque, job->target, start_sec, n, bounce_buffer); |
34 | + } | |
35 | + if (job->target) { | |
36 | + ret = bdrv_co_writev(job->target, start_sec, n, &bounce_qiov); | |
cbf9030a DM |
37 | + } |
38 | } | |
39 | if (ret < 0) { | |
40 | trace_backup_do_cow_write_fail(job, start, ret); | |
38f36829 | 41 | @@ -205,7 +213,9 @@ |
cbf9030a DM |
42 | { |
43 | BackupBlockJob *s = container_of(job, BackupBlockJob, common); | |
44 | ||
45 | - bdrv_iostatus_reset(s->target); | |
46 | + if (s->target) { | |
47 | + bdrv_iostatus_reset(s->target); | |
48 | + } | |
49 | } | |
50 | ||
51 | static const BlockJobDriver backup_job_driver = { | |
38f36829 | 52 | @@ -221,9 +231,11 @@ |
cbf9030a DM |
53 | if (read) { |
54 | return block_job_error_action(&job->common, job->common.bs, | |
55 | job->on_source_error, true, error); | |
56 | - } else { | |
57 | + } else if (job->target) { | |
58 | return block_job_error_action(&job->common, job->target, | |
59 | job->on_target_error, false, error); | |
60 | + } else { | |
e549ff74 | 61 | + return BLOCK_ERROR_ACTION_REPORT; |
cbf9030a DM |
62 | } |
63 | } | |
64 | ||
24bb7da3 | 65 | @@ -264,9 +276,11 @@ |
cbf9030a DM |
66 | |
67 | job->bitmap = hbitmap_alloc(end, 0); | |
68 | ||
69 | - bdrv_set_enable_write_cache(target, true); | |
70 | - bdrv_set_on_error(target, on_target_error, on_target_error); | |
71 | - bdrv_iostatus_enable(target); | |
72 | + if (target) { | |
73 | + bdrv_set_enable_write_cache(target, true); | |
74 | + bdrv_set_on_error(target, on_target_error, on_target_error); | |
75 | + bdrv_iostatus_enable(target); | |
76 | + } | |
77 | ||
78 | bdrv_add_before_write_notifier(bs, &before_write); | |
79 | ||
58117ea6 | 80 | @@ -359,8 +373,10 @@ |
432a6eb5 | 81 | } |
cbf9030a DM |
82 | hbitmap_free(job->bitmap); |
83 | ||
84 | - bdrv_iostatus_disable(target); | |
58117ea6 | 85 | - bdrv_op_unblock_all(target, job->common.blocker); |
cbf9030a DM |
86 | + if (target) { |
87 | + bdrv_iostatus_disable(target); | |
58117ea6 | 88 | + bdrv_op_unblock_all(target, job->common.blocker); |
cbf9030a DM |
89 | + } |
90 | ||
24bb7da3 DM |
91 | data = g_malloc(sizeof(*data)); |
92 | data->ret = ret; | |
58117ea6 | 93 | @@ -370,13 +386,15 @@ for backup_start |
432a6eb5 | 94 | BdrvDirtyBitmap *sync_bitmap, |
cbf9030a DM |
95 | BlockdevOnError on_source_error, |
96 | BlockdevOnError on_target_error, | |
97 | + BackupDumpFunc *dump_cb, | |
24bb7da3 | 98 | BlockCompletionFunc *cb, void *opaque, |
bd240f3b | 99 | + bool paused, |
cbf9030a DM |
100 | Error **errp) |
101 | { | |
102 | int64_t len; | |
103 | ||
104 | assert(bs); | |
105 | - assert(target); | |
106 | + assert(target || dump_cb); | |
107 | assert(cb); | |
108 | ||
58117ea6 WB |
109 | if (bs == target) { |
110 | @@ -419,7 +437,7 @@ in backup_start | |
cbf9030a DM |
111 | return; |
112 | } | |
113 | ||
58117ea6 WB |
114 | - if (!bdrv_is_inserted(target)) { |
115 | + if (target && !bdrv_is_inserted(target)) { | |
116 | error_setg(errp, "Device is not inserted: %s", | |
117 | bdrv_get_device_name(target)); | |
118 | return; | |
119 | @@ -429,7 +447,7 @@ in backup_start | |
120 | return; | |
121 | } | |
122 | ||
123 | - if (bdrv_op_is_blocked(target, BLOCK_OP_TYPE_BACKUP_TARGET, errp)) { | |
124 | + if (target && bdrv_op_is_blocked(target, BLOCK_OP_TYPE_BACKUP_TARGET, errp)) { | |
125 | return; | |
126 | } | |
127 | ||
432a6eb5 WB |
128 | @@ -397,14 +415,17 @@ in backup_start |
129 | goto error; | |
58117ea6 WB |
130 | } |
131 | ||
132 | - bdrv_op_block_all(target, job->common.blocker); | |
133 | + if (target) | |
134 | + bdrv_op_block_all(target, job->common.blocker); | |
135 | ||
cbf9030a DM |
136 | + job->dump_cb = dump_cb; |
137 | job->on_source_error = on_source_error; | |
138 | job->on_target_error = on_target_error; | |
139 | job->target = target; | |
bd240f3b | 140 | job->sync_mode = sync_mode; |
432a6eb5 WB |
141 | job->sync_bitmap = sync_mode == MIRROR_SYNC_MODE_INCREMENTAL ? |
142 | sync_bitmap : NULL; | |
bd240f3b DM |
143 | + job->common.paused = paused; |
144 | job->common.len = len; | |
145 | job->common.co = qemu_coroutine_create(backup_run); | |
146 | qemu_coroutine_enter(job->common.co, job); | |
cbf9030a DM |
147 | Index: new/blockdev.c |
148 | =================================================================== | |
24bb7da3 DM |
149 | --- new.orig/blockdev.c 2014-11-20 07:55:31.000000000 +0100 |
150 | +++ new/blockdev.c 2014-11-20 08:48:02.000000000 +0100 | |
432a6eb5 WB |
151 | @@ -2223,8 +2223,8 @@ qmp_drive_backup |
152 | } | |
cbf9030a | 153 | |
432a6eb5 WB |
154 | backup_start(bs, target_bs, speed, sync, bmap, |
155 | - on_source_error, on_target_error, | |
cbf9030a | 156 | - block_job_cb, bs, &local_err); |
432a6eb5 WB |
157 | + on_source_error, on_target_error, NULL, |
158 | + block_job_cb, bs, false, &local_err); | |
58117ea6 WB |
159 | if (local_err != NULL) { |
160 | bdrv_unref(target_bs); | |
161 | error_propagate(errp, local_err); | |
162 | @@ -2284,7 +2284,7 @@ qmp_blockdev_backup | |
163 | bdrv_ref(target_bs); | |
164 | bdrv_set_aio_context(target_bs, aio_context); | |
432a6eb5 WB |
165 | backup_start(bs, target_bs, speed, sync, NULL, on_source_error, |
166 | - on_target_error, block_job_cb, bs, &local_err); | |
167 | + on_target_error, NULL, block_job_cb, bs, false, &local_err); | |
cbf9030a DM |
168 | if (local_err != NULL) { |
169 | bdrv_unref(target_bs); | |
170 | error_propagate(errp, local_err); | |
171 | Index: new/include/block/block_int.h | |
172 | =================================================================== | |
24bb7da3 DM |
173 | --- new.orig/include/block/block_int.h 2014-11-20 07:55:31.000000000 +0100 |
174 | +++ new/include/block/block_int.h 2014-11-20 08:52:59.000000000 +0100 | |
175 | @@ -57,6 +57,9 @@ | |
58117ea6 WB |
176 | |
177 | #define BLOCK_PROBE_BUF_SIZE 512 | |
cbf9030a DM |
178 | |
179 | +typedef int BackupDumpFunc(void *opaque, BlockDriverState *bs, | |
5cf8ed03 | 180 | + int64_t sector_num, int n_sectors, unsigned char *buf); |
cbf9030a DM |
181 | + |
182 | typedef struct BdrvTrackedRequest { | |
183 | BlockDriverState *bs; | |
38f36829 | 184 | int64_t offset; |
24bb7da3 | 185 | @@ -583,7 +586,9 @@ |
432a6eb5 | 186 | BdrvDirtyBitmap *sync_bitmap, |
cbf9030a DM |
187 | BlockdevOnError on_source_error, |
188 | BlockdevOnError on_target_error, | |
189 | + BackupDumpFunc *dump_cb, | |
24bb7da3 | 190 | BlockCompletionFunc *cb, void *opaque, |
bd240f3b | 191 | + bool paused, |
cbf9030a DM |
192 | Error **errp); |
193 | ||
24bb7da3 | 194 | void blk_dev_change_media_cb(BlockBackend *blk, bool load); |