aboutsummaryrefslogtreecommitdiff
path: root/block/mirror.c
diff options
context:
space:
mode:
authorFam Zheng <famz@redhat.com>2013-12-16 14:45:31 +0800
committerStefan Hajnoczi <stefanha@redhat.com>2013-12-20 16:26:16 +0100
commit20a63d2cec838c2dde4d246c4d7abe747d9b7a11 (patch)
tree636439f43d5e1703cd0d88e5187bdf40ac15bf78 /block/mirror.c
parent03544a6e9ecc1be115e8a29bd929f83b467d4816 (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.c11
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);