[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 26/32] mirror: implement completion
From: |
Kevin Wolf |
Subject: |
[Qemu-devel] [PATCH 26/32] mirror: implement completion |
Date: |
Wed, 24 Oct 2012 11:50:50 +0200 |
From: Paolo Bonzini <address@hidden>
Switching to the target of the migration is done mostly asynchronously,
and reported to management via the BLOCK_JOB_COMPLETED event; the only
synchronous phase is opening the backing files. bdrv_open_backing_file
can always be done, even for migration of the full image (aka sync:
'full'). In this case, qmp_drive_mirror will create the target disk
with no backing file at all, and bdrv_open_backing_file will be a no-op.
Signed-off-by: Paolo Bonzini <address@hidden>
Signed-off-by: Kevin Wolf <address@hidden>
---
block/mirror.c | 45 ++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 40 insertions(+), 5 deletions(-)
diff --git a/block/mirror.c b/block/mirror.c
index b353798..6320f6a 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -32,6 +32,8 @@ typedef struct MirrorBlockJob {
RateLimit limit;
BlockDriverState *target;
MirrorSyncMode mode;
+ bool synced;
+ bool should_complete;
int64_t sector_num;
uint8_t *buf;
} MirrorBlockJob;
@@ -70,7 +72,6 @@ static void coroutine_fn mirror_run(void *opaque)
int64_t sector_num, end;
int ret = 0;
int n;
- bool synced = false;
if (block_job_is_cancelled(&s->common)) {
goto immediate_exit;
@@ -136,9 +137,14 @@ static void coroutine_fn mirror_run(void *opaque)
* report completion. This way, block-job-cancel will leave
* the target in a consistent state.
*/
- synced = true;
s->common.offset = end * BDRV_SECTOR_SIZE;
- should_complete = block_job_is_cancelled(&s->common);
+ if (!s->synced) {
+ block_job_ready(&s->common);
+ s->synced = true;
+ }
+
+ should_complete = s->should_complete ||
+ block_job_is_cancelled(&s->common);
cnt = bdrv_get_dirty_count(bs);
}
@@ -157,8 +163,8 @@ static void coroutine_fn mirror_run(void *opaque)
}
ret = 0;
- trace_mirror_before_sleep(s, cnt, synced);
- if (!synced) {
+ trace_mirror_before_sleep(s, cnt, s->synced);
+ if (!s->synced) {
/* Publish progress */
s->common.offset = end * BDRV_SECTOR_SIZE - cnt * BLOCK_SIZE;
@@ -191,6 +197,12 @@ static void coroutine_fn mirror_run(void *opaque)
immediate_exit:
g_free(s->buf);
bdrv_set_dirty_tracking(bs, false);
+ if (s->should_complete && ret == 0) {
+ if (bdrv_get_flags(s->target) != bdrv_get_flags(s->common.bs)) {
+ bdrv_reopen(s->target, bdrv_get_flags(s->common.bs), NULL);
+ }
+ bdrv_swap(s->target, s->common.bs);
+ }
bdrv_close(s->target);
bdrv_delete(s->target);
block_job_completed(&s->common, ret);
@@ -207,10 +219,33 @@ static void mirror_set_speed(BlockJob *job, int64_t
speed, Error **errp)
ratelimit_set_speed(&s->limit, speed / BDRV_SECTOR_SIZE, SLICE_TIME);
}
+static void mirror_complete(BlockJob *job, Error **errp)
+{
+ MirrorBlockJob *s = container_of(job, MirrorBlockJob, common);
+ int ret;
+
+ ret = bdrv_open_backing_file(s->target);
+ if (ret < 0) {
+ char backing_filename[PATH_MAX];
+ bdrv_get_full_backing_filename(s->target, backing_filename,
+ sizeof(backing_filename));
+ error_set(errp, QERR_OPEN_FILE_FAILED, backing_filename);
+ return;
+ }
+ if (!s->synced) {
+ error_set(errp, QERR_BLOCK_JOB_NOT_READY, job->bs->device_name);
+ return;
+ }
+
+ s->should_complete = true;
+ block_job_resume(job);
+}
+
static BlockJobType mirror_job_type = {
.instance_size = sizeof(MirrorBlockJob),
.job_type = "mirror",
.set_speed = mirror_set_speed,
+ .complete = mirror_complete,
};
void mirror_start(BlockDriverState *bs, BlockDriverState *target,
--
1.7.6.5
- [Qemu-devel] [PATCH 18/32] block: add bdrv_open_backing_file, (continued)
- [Qemu-devel] [PATCH 18/32] block: add bdrv_open_backing_file, Kevin Wolf, 2012/10/24
- [Qemu-devel] [PATCH 20/32] block: export dirty bitmap information in query-block, Kevin Wolf, 2012/10/24
- [Qemu-devel] [PATCH 25/32] qmp: add drive-mirror command, Kevin Wolf, 2012/10/24
- [Qemu-devel] [PATCH 24/32] mirror: introduce mirror job, Kevin Wolf, 2012/10/24
- [Qemu-devel] [PATCH 23/32] block: introduce BLOCK_JOB_READY event, Kevin Wolf, 2012/10/24
- [Qemu-devel] [PATCH 31/32] qemu-iotests: add testcases for mirroring on-source-error/on-target-error, Kevin Wolf, 2012/10/24
- [Qemu-devel] [PATCH 29/32] mirror: add support for on-source-error/on-target-error, Kevin Wolf, 2012/10/24
- [Qemu-devel] [PATCH 30/32] qmp: add pull_event function, Kevin Wolf, 2012/10/24
- [Qemu-devel] [PATCH 32/32] osdep: Less restrictive F_SEFL in qemu_dup_flags(), Kevin Wolf, 2012/10/24
- [Qemu-devel] [PATCH 27/32] qemu-iotests: add mirroring test case, Kevin Wolf, 2012/10/24
- [Qemu-devel] [PATCH 26/32] mirror: implement completion,
Kevin Wolf <=
- [Qemu-devel] [PATCH 28/32] iostatus: forward block_job_iostatus_reset to block job, Kevin Wolf, 2012/10/24
- Re: [Qemu-devel] [PULL 00/32] Block patches, Anthony Liguori, 2012/10/29