From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([208.118.235.92]:58268) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SfY7z-0004vr-3M for qemu-devel@nongnu.org; Fri, 15 Jun 2012 11:08:03 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SfY7q-0005FA-GW for qemu-devel@nongnu.org; Fri, 15 Jun 2012 11:07:58 -0400 Received: from mail-gh0-f173.google.com ([209.85.160.173]:59531) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SfY7q-0005Ex-9f for qemu-devel@nongnu.org; Fri, 15 Jun 2012 11:07:50 -0400 Received: by ghrr14 with SMTP id r14so2584975ghr.4 for ; Fri, 15 Jun 2012 08:07:48 -0700 (PDT) Sender: Paolo Bonzini From: Paolo Bonzini Date: Fri, 15 Jun 2012 17:05:52 +0200 Message-Id: <1339772759-31004-30-git-send-email-pbonzini@redhat.com> In-Reply-To: <1339772759-31004-1-git-send-email-pbonzini@redhat.com> References: <1339772759-31004-1-git-send-email-pbonzini@redhat.com> Subject: [Qemu-devel] [RFC PATCH 29/36] mirror: implement completion List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: kwolf@redhat.com, stefanha@linux.vnet.ibm.com, lcapitulino@redhat.com 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 --- block/mirror.c | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/block/mirror.c b/block/mirror.c index bdcbe3e..346a0eb 100644 --- a/block/mirror.c +++ b/block/mirror.c @@ -34,6 +34,7 @@ typedef struct MirrorBlockJob { MirrorSyncMode mode; BlockdevOnError on_source_error, on_target_error; bool synced; + bool complete; int64_t sector_num; void *buf; } MirrorBlockJob; @@ -149,7 +150,9 @@ static void coroutine_fn mirror_run(void *opaque) s->common.offset = end * BDRV_SECTOR_SIZE; } - should_complete = s->synced && block_job_is_cancelled(&s->common); + should_complete = + s->synced && (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 @@ -203,7 +206,14 @@ immediate_exit: g_free(s->buf); bdrv_set_dirty_tracking(bs, false); bdrv_iostatus_disable(s->target); - bdrv_close(s->target); + if (s->synced && ret == 0) { + ret = bdrv_flush(s->target); + } + if (s->synced && ret == 0) { + bdrv_swap(s->target, s->common.bs); + } else { + bdrv_close(s->target); + } bdrv_delete(s->target); block_job_completed(&s->common, ret); } @@ -236,12 +246,35 @@ 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, .iostatus_reset= mirror_iostatus_reset, .query = mirror_query, + .complete = mirror_complete, }; void mirror_start(BlockDriverState *bs, BlockDriverState *target, -- 1.7.10.2