From patchwork Thu Aug 28 15:03:49 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Dr. David Alan Gilbert" X-Patchwork-Id: 383925 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 6EE38140107 for ; Fri, 29 Aug 2014 01:29:49 +1000 (EST) Received: from localhost ([::1]:37399 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XN1dz-0000uT-Fs for incoming@patchwork.ozlabs.org; Thu, 28 Aug 2014 11:29:47 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42800) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XN1GI-0001YF-45 for qemu-devel@nongnu.org; Thu, 28 Aug 2014 11:05:25 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1XN1GA-0002hl-5e for qemu-devel@nongnu.org; Thu, 28 Aug 2014 11:05:18 -0400 Received: from mx1.redhat.com ([209.132.183.28]:36495) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XN1G9-0002ge-VX for qemu-devel@nongnu.org; Thu, 28 Aug 2014 11:05:10 -0400 Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s7SF55tR029617 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Thu, 28 Aug 2014 11:05:06 -0400 Received: from dgilbert-t530.home.treblig.org (vpn1-5-132.ams2.redhat.com [10.36.5.132]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s7SF44w9003726; Thu, 28 Aug 2014 11:05:03 -0400 From: "Dr. David Alan Gilbert (git)" To: qemu-devel@nongnu.org Date: Thu, 28 Aug 2014 16:03:49 +0100 Message-Id: <1409238244-31720-33-git-send-email-dgilbert@redhat.com> In-Reply-To: <1409238244-31720-1-git-send-email-dgilbert@redhat.com> References: <1409238244-31720-1-git-send-email-dgilbert@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 209.132.183.28 Cc: aarcange@redhat.com, yamahata@private.email.ne.jp, amit.shah@redhat.com, lilei@linux.vnet.ibm.com, quintela@redhat.com Subject: [Qemu-devel] [PATCH v3 32/47] Postcopy: postcopy_start X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: "Dr. David Alan Gilbert" postcopy_start: Perform all the initialisation associated with starting up postcopy mode from the source. Signed-off-by: Dr. David Alan Gilbert --- migration.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/migration.c b/migration.c index f5d9d02..1ae5b7d 100644 --- a/migration.c +++ b/migration.c @@ -899,6 +899,91 @@ static void await_outgoing_return_path_close(MigrationState *ms) DPRINTF("%s: Exit", __func__); } +/* Switch from normal iteration to postcopy + * Returns non-0 on error + */ +static int postcopy_start(MigrationState *ms) +{ + int ret; + const QEMUSizedBuffer *qsb; + migrate_set_state(ms, MIG_STATE_ACTIVE, MIG_STATE_POSTCOPY_ACTIVE); + + DPRINTF("postcopy_start\n"); + qemu_mutex_lock_iothread(); + DPRINTF("postcopy_start: setting run state\n"); + ret = vm_stop_force_state(RUN_STATE_FINISH_MIGRATE); + + if (ret < 0) { + migrate_set_state(ms, MIG_STATE_POSTCOPY_ACTIVE, MIG_STATE_ERROR); + qemu_mutex_unlock_iothread(); + return -1; + } + + /* + * in Finish migrate and with the io-lock held everything should + * be quiet, but we've potentially still got dirty pages and we + * need to tell the destination to throw any pages it's already received + * that are dirty + */ + if (postcopy_send_discard_bitmap(ms)) { + DPRINTF("postcopy send discard bitmap failed\n"); + migrate_set_state(ms, MIG_STATE_POSTCOPY_ACTIVE, MIG_STATE_ERROR); + qemu_mutex_unlock_iothread(); + return -1; + } + + DPRINTF("postcopy_start: sending req 2\n"); + qemu_savevm_send_reqack(ms->file, 2); + /* + * send rest of state - note things that are doing postcopy + * will notice we're in MIG_STATE_POSTCOPY_ACTIVE and not actually + * wrap their state up here + */ + qemu_file_set_rate_limit(ms->file, INT64_MAX); + DPRINTF("postcopy_start: do state_complete\n"); + + /* + * We need to leave the fd free for page transfers during the + * loading of the device state, so wrap all the remaining + * commands and state into a package that gets sent in one go + */ + QEMUFile *fb = qemu_bufopen("w", NULL); + + qemu_savevm_state_complete(fb); + DPRINTF("postcopy_start: sending req 3\n"); + qemu_savevm_send_reqack(fb, 3); + + qemu_savevm_send_postcopy_ram_run(fb); + + /* <><> end of stuff going into the package */ + qsb = qemu_buf_get(fb); + + /* Now send that blob */ + if (qsb_get_length(qsb) > MAX_VM_CMD_PACKAGED_SIZE) { + DPRINTF("postcopy_start: Unreasonably large packaged state: %lu\n", + (unsigned long)(qsb_get_length(qsb))); + migrate_set_state(ms, MIG_STATE_POSTCOPY_ACTIVE, MIG_STATE_ERROR); + qemu_mutex_unlock_iothread(); + qemu_fclose(fb); + return -1; + } + qemu_savevm_send_packaged(ms->file, qsb); + qemu_fclose(fb); + + qemu_mutex_unlock_iothread(); + + DPRINTF("postcopy_start not finished sending ack\n"); + qemu_savevm_send_reqack(ms->file, 4); + + ret = qemu_file_get_error(ms->file); + if (ret) { + error_report("postcopy_start: Migration stream errored"); + migrate_set_state(ms, MIG_STATE_POSTCOPY_ACTIVE, MIG_STATE_ERROR); + } + + return ret; +} + /* * Master migration thread on the source VM. * It drives the migration and pumps the data down the outgoing channel.