[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 30/47] mirror: implement completion
From: |
Paolo Bonzini |
Subject: |
[Qemu-devel] [PATCH 30/47] mirror: implement completion |
Date: |
Tue, 24 Jul 2012 13:04:08 +0200 |
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. Note that this can be
done always, even for migration of the full image, because the backing
file structure of the source and target are not in any relationship.
For full migration (aka sync: 'full') qmp_drive_mirror will create the
target disk with no backing file at all, and bdrv_ensure_backing_file
will be a no-op.
Signed-off-by: Paolo Bonzini <address@hidden>
---
block/mirror.c | 43 +++++++++++++++++++++++++++++++++++++------
1 file changed, 37 insertions(+), 6 deletions(-)
diff --git a/block/mirror.c b/block/mirror.c
index 9c8ebd4..4454ef3 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 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;
@@ -135,10 +136,13 @@ static void coroutine_fn mirror_run(void *opaque)
* I/O and report completion, so that drive-reopen can be
* used to pivot to the mirroring target.
*/
- synced = true;
s->common.offset = end * BDRV_SECTOR_SIZE;
+ if (!s->synced) {
+ block_job_ready(&s->common);
+ s->synced = true;
+ }
- should_complete = block_job_is_cancelled(&s->common);
+ should_complete = block_job_is_cancelled(&s->common) ||
s->complete;
if (should_complete) {
/* The dirty bitmap is not updated while operations are
pending.
* If we're about to exit, wait for pending operations before
@@ -155,8 +159,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;
@@ -189,7 +193,11 @@ static void coroutine_fn mirror_run(void *opaque)
immediate_exit:
g_free(s->buf);
bdrv_set_dirty_tracking(bs, false);
- bdrv_close(s->target);
+ if (s->complete && ret == 0) {
+ bdrv_swap(s->target, s->common.bs);
+ } else {
+ bdrv_close(s->target);
+ }
bdrv_delete(s->target);
block_job_completed(&s->common, ret);
}
@@ -215,11 +223,34 @@ static void mirror_query(BlockJob *job, BlockJobInfo
*info)
info->target->stats = bdrv_query_stats(s->target);
}
+static void mirror_complete(BlockJob *job, Error **errp)
+{
+ MirrorBlockJob *s = container_of(job, MirrorBlockJob, common);
+ int ret;
+
+ ret = bdrv_ensure_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->complete = true;
+ block_job_resume(job);
+}
+
static BlockJobType mirror_job_type = {
.instance_size = sizeof(MirrorBlockJob),
.job_type = "mirror",
.set_speed = mirror_set_speed,
.query = mirror_query,
+ .complete = mirror_complete,
};
void mirror_start(BlockDriverState *bs, BlockDriverState *target,
--
1.7.10.4
- [Qemu-devel] [PATCH 47/47] mirror: support arbitrarily-sized iterations, (continued)
- [Qemu-devel] [PATCH 47/47] mirror: support arbitrarily-sized iterations, Paolo Bonzini, 2012/07/24
- [Qemu-devel] [PATCH 41/47] block: return count of dirty sectors, not chunks, Paolo Bonzini, 2012/07/24
- [Qemu-devel] [PATCH 36/47] host-utils: add ffsl and flsl, Paolo Bonzini, 2012/07/24
- [Qemu-devel] [PATCH 23/47] block: add target info to QMP query-blockjobs command, Paolo Bonzini, 2012/07/24
- [Qemu-devel] [PATCH 42/47] block: allow customizing the granularity of the dirty bitmap, Paolo Bonzini, 2012/07/24
- [Qemu-devel] [PATCH 17/47] qemu-iotests: add tests for streaming error handling, Paolo Bonzini, 2012/07/24
- [Qemu-devel] [PATCH 18/47] block: live snapshot documentation tweaks, Paolo Bonzini, 2012/07/24
- [Qemu-devel] [PATCH 22/47] block: make device optional in BlockInfo, Paolo Bonzini, 2012/07/24
- [Qemu-devel] [PATCH 30/47] mirror: implement completion,
Paolo Bonzini <=
- [Qemu-devel] [PATCH 28/47] qmp: add drive-mirror command, Paolo Bonzini, 2012/07/24
- Re: [Qemu-devel] [PATCH 28/47] qmp: add drive-mirror command, Eric Blake, 2012/07/26
- Re: [Qemu-devel] [PATCH 28/47] qmp: add drive-mirror command, Kevin Wolf, 2012/07/31
- Re: [Qemu-devel] [PATCH 28/47] qmp: add drive-mirror command, Paolo Bonzini, 2012/07/31
- Re: [Qemu-devel] [PATCH 28/47] qmp: add drive-mirror command, Kevin Wolf, 2012/07/31
- Re: [Qemu-devel] [PATCH 28/47] qmp: add drive-mirror command, Paolo Bonzini, 2012/07/31
- Re: [Qemu-devel] [PATCH 28/47] qmp: add drive-mirror command, Kevin Wolf, 2012/07/31
- Re: [Qemu-devel] [PATCH 28/47] qmp: add drive-mirror command, Paolo Bonzini, 2012/07/31
- Re: [Qemu-devel] [PATCH 28/47] qmp: add drive-mirror command, Kevin Wolf, 2012/07/31