diff options
author | Fam Zheng <famz@redhat.com> | 2013-12-16 14:45:31 +0800 |
---|---|---|
committer | Stefan Hajnoczi <stefanha@redhat.com> | 2013-12-20 16:26:16 +0100 |
commit | 20a63d2cec838c2dde4d246c4d7abe747d9b7a11 (patch) | |
tree | 636439f43d5e1703cd0d88e5187bdf40ac15bf78 /block/mirror.c | |
parent | 03544a6e9ecc1be115e8a29bd929f83b467d4816 (diff) |
commit: Support commit active layer
If active is top, it will be mirrored to base, (with block/mirror.c
code), then the image is switched when user completes the block job.
QMP documentation is updated.
Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Diffstat (limited to 'block/mirror.c')
-rw-r--r-- | block/mirror.c | 11 |
1 files changed, 11 insertions, 0 deletions
diff --git a/block/mirror.c b/block/mirror.c index 04af341be6..2932bab27a 100644 --- a/block/mirror.c +++ b/block/mirror.c @@ -481,6 +481,13 @@ immediate_exit: bdrv_reopen(s->target, bdrv_get_flags(s->common.bs), NULL); } bdrv_swap(s->target, s->common.bs); + if (s->common.driver->job_type == BLOCK_JOB_TYPE_COMMIT) { + /* drop the bs loop chain formed by the swap: break the loop then + * trigger the unref from the top one */ + BlockDriverState *p = s->base->backing_hd; + s->base->backing_hd = NULL; + bdrv_unref(p); + } } bdrv_unref(s->target); block_job_completed(&s->common, ret); @@ -623,6 +630,10 @@ void commit_active_start(BlockDriverState *bs, BlockDriverState *base, BlockDriverCompletionFunc *cb, void *opaque, Error **errp) { + if (bdrv_reopen(base, bs->open_flags, errp)) { + return; + } + bdrv_ref(base); mirror_start_job(bs, base, speed, 0, 0, on_error, on_error, cb, opaque, errp, &commit_active_job_driver, false, base); |