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} |