From patchwork Wed Oct 26 15:42:02 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zhanghailiang X-Patchwork-Id: 9397535 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 7854E60231 for ; Wed, 26 Oct 2016 15:51:05 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5A41B29B6A for ; Wed, 26 Oct 2016 15:51:05 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4F03C29B82; Wed, 26 Oct 2016 15:51:05 +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 B461629B6A for ; Wed, 26 Oct 2016 15:51:04 +0000 (UTC) Received: from localhost ([::1]:35601 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bzQTn-00068z-Tn for patchwork-qemu-devel@patchwork.kernel.org; Wed, 26 Oct 2016 11:51:03 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:54777) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bzQM2-0008Io-Hk for qemu-devel@nongnu.org; Wed, 26 Oct 2016 11:43:03 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bzQM1-0008Tm-5t for qemu-devel@nongnu.org; Wed, 26 Oct 2016 11:43:02 -0400 Received: from szxga03-in.huawei.com ([119.145.14.66]:29360) by eggs.gnu.org with esmtps (TLS1.0:RSA_ARCFOUR_SHA1:16) (Exim 4.71) (envelope-from ) id 1bzQM0-0008Ov-1j for qemu-devel@nongnu.org; Wed, 26 Oct 2016 11:43:01 -0400 Received: from 172.24.1.60 (EHLO szxeml432-hub.china.huawei.com) ([172.24.1.60]) by szxrg03-dlp.huawei.com (MOS 4.4.3-GA FastPath queued) with ESMTP id CKI07885; Wed, 26 Oct 2016 23:42:38 +0800 (CST) Received: from localhost (10.177.24.212) by szxeml432-hub.china.huawei.com (10.82.67.209) with Microsoft SMTP Server id 14.3.235.1; Wed, 26 Oct 2016 23:42:30 +0800 From: zhanghailiang To: , Date: Wed, 26 Oct 2016 23:42:02 +0800 Message-ID: <1477496530-9624-10-git-send-email-zhang.zhanghailiang@huawei.com> X-Mailer: git-send-email 2.7.2.windows.1 In-Reply-To: <1477496530-9624-1-git-send-email-zhang.zhanghailiang@huawei.com> References: <1477496530-9624-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) v22 09/17] 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 b4649fc..7519984 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, @@ -305,6 +331,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) { @@ -332,7 +362,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); @@ -340,7 +392,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); @@ -355,6 +414,10 @@ out: error_report_err(local_err); } + if (fb) { + qemu_fclose(fb); + } + if (mis->to_src_file) { qemu_fclose(mis->to_src_file); }