From patchwork Fri Jul 4 17:41:41 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: 367173 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 C3D2914009C for ; Sat, 5 Jul 2014 03:54:51 +1000 (EST) Received: from localhost ([::1]:37465 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1X37hC-0005xu-2X for incoming@patchwork.ozlabs.org; Fri, 04 Jul 2014 13:54:50 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:32831) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1X37Vj-0007uh-Si for qemu-devel@nongnu.org; Fri, 04 Jul 2014 13:43:06 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1X37Vd-0000SA-9K for qemu-devel@nongnu.org; Fri, 04 Jul 2014 13:42:59 -0400 Received: from mx1.redhat.com ([209.132.183.28]:42963) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1X37Vc-0000S0-Vy for qemu-devel@nongnu.org; Fri, 04 Jul 2014 13:42:53 -0400 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s64HgoQJ009974 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 4 Jul 2014 13:42:50 -0400 Received: from dgilbert-t530.home.treblig.org (vpn1-7-141.ams2.redhat.com [10.36.7.141]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s64HfvTx030576; Fri, 4 Jul 2014 13:42:48 -0400 From: "Dr. David Alan Gilbert (git)" To: qemu-devel@nongnu.org Date: Fri, 4 Jul 2014 18:41:41 +0100 Message-Id: <1404495717-4239-31-git-send-email-dgilbert@redhat.com> In-Reply-To: <1404495717-4239-1-git-send-email-dgilbert@redhat.com> References: <1404495717-4239-1-git-send-email-dgilbert@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 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, lilei@linux.vnet.ibm.com, quintela@redhat.com Subject: [Qemu-devel] [PATCH 30/46] 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 55bb767..0d567ef 100644 --- a/migration.c +++ b/migration.c @@ -890,6 +890,91 @@ static int open_outgoing_return_path(MigrationState *ms) return 0; } +/* 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.