From patchwork Thu Oct 27 06:43:00 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zhanghailiang X-Patchwork-Id: 9399009 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 262EB60588 for ; Thu, 27 Oct 2016 07:06:24 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E26331FFC9 for ; Thu, 27 Oct 2016 07:06:23 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D548D2A067; Thu, 27 Oct 2016 07:06:23 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 0C4BF2A065 for ; Thu, 27 Oct 2016 07:06:23 +0000 (UTC) Received: from localhost ([::1]:39440 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bzela-0004dN-3q for patchwork-qemu-devel@patchwork.kernel.org; Thu, 27 Oct 2016 03:06:22 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33095) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bzeR9-0004dG-Jb for qemu-devel@nongnu.org; Thu, 27 Oct 2016 02:45:16 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bzeR6-0004K5-H8 for qemu-devel@nongnu.org; Thu, 27 Oct 2016 02:45:15 -0400 Received: from szxga03-in.huawei.com ([119.145.14.66]:59445) by eggs.gnu.org with esmtps (TLS1.0:RSA_ARCFOUR_SHA1:16) (Exim 4.71) (envelope-from ) id 1bzeQq-000497-0c for qemu-devel@nongnu.org; Thu, 27 Oct 2016 02:45:12 -0400 Received: from 172.24.1.136 (EHLO SZXEML423-HUB.china.huawei.com) ([172.24.1.136]) by szxrg03-dlp.huawei.com (MOS 4.4.3-GA FastPath queued) with ESMTP id CKK24310; Thu, 27 Oct 2016 14:44:23 +0800 (CST) Received: from localhost (10.177.24.212) by SZXEML423-HUB.china.huawei.com (10.82.67.154) with Microsoft SMTP Server id 14.3.235.1; Thu, 27 Oct 2016 14:44:13 +0800 From: zhanghailiang To: , Date: Thu, 27 Oct 2016 14:43:00 +0800 Message-ID: <1477550589-16288-10-git-send-email-zhang.zhanghailiang@huawei.com> X-Mailer: git-send-email 2.7.2.windows.1 In-Reply-To: <1477550589-16288-1-git-send-email-zhang.zhanghailiang@huawei.com> References: <1477550589-16288-1-git-send-email-zhang.zhanghailiang@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.177.24.212] X-CFilter-Loop: Reflected X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.4.x-2.6.x [generic] X-Received-From: 119.145.14.66 Subject: [Qemu-devel] [PATCH COLO-Frame (Base) v23 09/18] COLO: Load VMState into QIOChannelBuffer before restore it X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: xiecl.fnst@cn.fujitsu.com, zhanghailiang , lizhijian@cn.fujitsu.com, qemu-devel@nongnu.org, dgilbert@redhat.com, Gonglei Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP We should not destroy the state of SVM (Secondary VM) until we receive the complete data of PVM's state, in case the primary fails in the process of sending the state, so we cache the VM's state in secondary side before load it into SVM. Besides, we should call qemu_system_reset() before load VM state, which can ensure the data is intact. Signed-off-by: zhanghailiang Signed-off-by: Li Zhijian Signed-off-by: Gonglei Reviewed-by: Dr. David Alan Gilbert Cc: Dr. David Alan Gilbert Reviewed-by: Amit Shah --- v22: - Add Reviewed-by tag v21: - Fix building waring v19: - fix title and comments v17: - Replace the old buffer API with the new channel buffer API. v16: - Rename colo_get_cmd_value() to colo_receive_mesage_value(); v13: - Fix the define of colo_get_cmd_value() to use 'Error **errp' instead of return value. v12: - Use the new helper colo_get_cmd_value() instead of colo_ctl_get() --- migration/colo.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 65 insertions(+), 2 deletions(-) diff --git a/migration/colo.c b/migration/colo.c index 9dc54fc..bb9b870 100644 --- a/migration/colo.c +++ b/migration/colo.c @@ -115,6 +115,28 @@ static void colo_receive_check_message(QEMUFile *f, COLOMessage expect_msg, } } +static uint64_t colo_receive_message_value(QEMUFile *f, uint32_t expect_msg, + Error **errp) +{ + Error *local_err = NULL; + uint64_t value; + int ret; + + colo_receive_check_message(f, expect_msg, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return 0; + } + + value = qemu_get_be64(f); + ret = qemu_file_get_error(f); + if (ret < 0) { + error_setg_errno(errp, -ret, "Failed to get value for COLO message: %s", + COLOMessage_lookup[expect_msg]); + } + return value; +} + static int colo_do_checkpoint_transaction(MigrationState *s, QIOChannelBuffer *bioc, QEMUFile *fb) @@ -288,6 +310,10 @@ static void colo_wait_handle_message(QEMUFile *f, int *checkpoint_request, void *colo_process_incoming_thread(void *opaque) { MigrationIncomingState *mis = opaque; + QEMUFile *fb = NULL; + QIOChannelBuffer *bioc = NULL; /* Cache incoming device state */ + uint64_t total_size; + uint64_t value; Error *local_err = NULL; migrate_set_state(&mis->state, MIGRATION_STATUS_ACTIVE, @@ -306,6 +332,10 @@ void *colo_process_incoming_thread(void *opaque) */ qemu_file_set_blocking(mis->from_src_file, true); + bioc = qio_channel_buffer_new(COLO_BUFFER_BASE_SIZE); + fb = qemu_fopen_channel_input(QIO_CHANNEL(bioc)); + object_unref(OBJECT(bioc)); + colo_send_message(mis->to_src_file, COLO_MESSAGE_CHECKPOINT_READY, &local_err); if (local_err) { @@ -333,7 +363,29 @@ void *colo_process_incoming_thread(void *opaque) goto out; } - /* TODO: read migration data into colo buffer */ + value = colo_receive_message_value(mis->from_src_file, + COLO_MESSAGE_VMSTATE_SIZE, &local_err); + if (local_err) { + goto out; + } + + /* + * Read VM device state data into channel buffer, + * It's better to re-use the memory allocated. + * Here we need to handle the channel buffer directly. + */ + if (value > bioc->capacity) { + bioc->capacity = value; + bioc->data = g_realloc(bioc->data, bioc->capacity); + } + total_size = qemu_get_buffer(mis->from_src_file, bioc->data, value); + if (total_size != value) { + error_report("Got %" PRIu64 " VMState data, less than expected" + " %" PRIu64, total_size, value); + goto out; + } + bioc->usage = total_size; + qio_channel_io_seek(QIO_CHANNEL(bioc), 0, 0, NULL); colo_send_message(mis->to_src_file, COLO_MESSAGE_VMSTATE_RECEIVED, &local_err); @@ -341,7 +393,14 @@ void *colo_process_incoming_thread(void *opaque) goto out; } - /* TODO: load vm state */ + qemu_mutex_lock_iothread(); + qemu_system_reset(VMRESET_SILENT); + if (qemu_loadvm_state(fb) < 0) { + error_report("COLO: loadvm failed"); + qemu_mutex_unlock_iothread(); + goto out; + } + qemu_mutex_unlock_iothread(); colo_send_message(mis->to_src_file, COLO_MESSAGE_VMSTATE_LOADED, &local_err); @@ -356,6 +415,10 @@ out: error_report_err(local_err); } + if (fb) { + qemu_fclose(fb); + } + if (mis->to_src_file) { qemu_fclose(mis->to_src_file); }