stream.c (9358450e98ed4a5350df4754863d116ff2e6186c) stream.c (61b49e48b379db45f0ea91c93a61c873695549a9)
1/*
2 * Image streaming
3 *
4 * Copyright IBM, Corp. 2011
5 *
6 * Authors:
7 * Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
8 *

--- 23 unchanged lines hidden (view full) ---

32#define SLICE_TIME 100000000ULL /* ns */
33
34typedef struct StreamBlockJob {
35 BlockJob common;
36 RateLimit limit;
37 BlockDriverState *base;
38 BlockdevOnError on_error;
39 char *backing_file_str;
1/*
2 * Image streaming
3 *
4 * Copyright IBM, Corp. 2011
5 *
6 * Authors:
7 * Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
8 *

--- 23 unchanged lines hidden (view full) ---

32#define SLICE_TIME 100000000ULL /* ns */
33
34typedef struct StreamBlockJob {
35 BlockJob common;
36 RateLimit limit;
37 BlockDriverState *base;
38 BlockdevOnError on_error;
39 char *backing_file_str;
40 int bs_flags;
40} StreamBlockJob;
41
42static int coroutine_fn stream_populate(BlockBackend *blk,
43 int64_t sector_num, int nb_sectors,
44 void *buf)
45{
46 struct iovec iov = {
47 .iov_base = buf,

--- 28 unchanged lines hidden (view full) ---

76 if (base->drv) {
77 base_fmt = base->drv->format_name;
78 }
79 }
80 data->ret = bdrv_change_backing_file(bs, base_id, base_fmt);
81 bdrv_set_backing_hd(bs, base);
82 }
83
41} StreamBlockJob;
42
43static int coroutine_fn stream_populate(BlockBackend *blk,
44 int64_t sector_num, int nb_sectors,
45 void *buf)
46{
47 struct iovec iov = {
48 .iov_base = buf,

--- 28 unchanged lines hidden (view full) ---

77 if (base->drv) {
78 base_fmt = base->drv->format_name;
79 }
80 }
81 data->ret = bdrv_change_backing_file(bs, base_id, base_fmt);
82 bdrv_set_backing_hd(bs, base);
83 }
84
85 /* Reopen the image back in read-only mode if necessary */
86 if (s->bs_flags != bdrv_get_flags(bs)) {
87 bdrv_reopen(bs, s->bs_flags, NULL);
88 }
89
84 g_free(s->backing_file_str);
85 block_job_completed(&s->common, data->ret);
86 g_free(data);
87}
88
89static void coroutine_fn stream_run(void *opaque)
90{
91 StreamBlockJob *s = opaque;

--- 123 unchanged lines hidden (view full) ---

215};
216
217void stream_start(const char *job_id, BlockDriverState *bs,
218 BlockDriverState *base, const char *backing_file_str,
219 int64_t speed, BlockdevOnError on_error,
220 BlockCompletionFunc *cb, void *opaque, Error **errp)
221{
222 StreamBlockJob *s;
90 g_free(s->backing_file_str);
91 block_job_completed(&s->common, data->ret);
92 g_free(data);
93}
94
95static void coroutine_fn stream_run(void *opaque)
96{
97 StreamBlockJob *s = opaque;

--- 123 unchanged lines hidden (view full) ---

221};
222
223void stream_start(const char *job_id, BlockDriverState *bs,
224 BlockDriverState *base, const char *backing_file_str,
225 int64_t speed, BlockdevOnError on_error,
226 BlockCompletionFunc *cb, void *opaque, Error **errp)
227{
228 StreamBlockJob *s;
229 BlockDriverState *iter;
230 int orig_bs_flags;
223
224 s = block_job_create(job_id, &stream_job_driver, bs, speed,
225 cb, opaque, errp);
226 if (!s) {
227 return;
228 }
229
231
232 s = block_job_create(job_id, &stream_job_driver, bs, speed,
233 cb, opaque, errp);
234 if (!s) {
235 return;
236 }
237
238 /* Make sure that the image is opened in read-write mode */
239 orig_bs_flags = bdrv_get_flags(bs);
240 if (!(orig_bs_flags & BDRV_O_RDWR)) {
241 if (bdrv_reopen(bs, orig_bs_flags | BDRV_O_RDWR, errp) != 0) {
242 block_job_unref(&s->common);
243 return;
244 }
245 }
246
247 /* Block all intermediate nodes between bs and base, because they
248 * will disappear from the chain after this operation */
249 for (iter = backing_bs(bs); iter && iter != base; iter = backing_bs(iter)) {
250 block_job_add_bdrv(&s->common, iter);
251 }
252
230 s->base = base;
231 s->backing_file_str = g_strdup(backing_file_str);
253 s->base = base;
254 s->backing_file_str = g_strdup(backing_file_str);
255 s->bs_flags = orig_bs_flags;
232
233 s->on_error = on_error;
234 s->common.co = qemu_coroutine_create(stream_run, s);
235 trace_stream_start(bs, base, s, s->common.co, opaque);
236 qemu_coroutine_enter(s->common.co);
237}
256
257 s->on_error = on_error;
258 s->common.co = qemu_coroutine_create(stream_run, s);
259 trace_stream_start(bs, base, s, s->common.co, opaque);
260 qemu_coroutine_enter(s->common.co);
261}