From patchwork Fri Apr 8 06:26:21 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zhanghailiang X-Patchwork-Id: 8781081 Return-Path: X-Original-To: patchwork-qemu-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 12B289FBEA for ; Fri, 8 Apr 2016 06:35:46 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 4D5AE2024D for ; Fri, 8 Apr 2016 06:35:45 +0000 (UTC) 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.kernel.org (Postfix) with ESMTPS id 57C1B2026D for ; Fri, 8 Apr 2016 06:35:44 +0000 (UTC) Received: from localhost ([::1]:54261 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aoQ19-00074j-C5 for patchwork-qemu-devel@patchwork.kernel.org; Fri, 08 Apr 2016 02:35:43 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39648) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aoPty-0000xE-6T for qemu-devel@nongnu.org; Fri, 08 Apr 2016 02:28:19 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1aoPtu-00072D-Qc for qemu-devel@nongnu.org; Fri, 08 Apr 2016 02:28:17 -0400 Received: from szxga01-in.huawei.com ([58.251.152.64]:30183) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aoPtq-00070p-HF for qemu-devel@nongnu.org; Fri, 08 Apr 2016 02:28:14 -0400 Received: from 172.24.1.60 (EHLO SZXEML424-HUB.china.huawei.com) ([172.24.1.60]) by szxrg01-dlp.huawei.com (MOS 4.3.7-GA FastPath queued) with ESMTP id DII24242; Fri, 08 Apr 2016 14:27:59 +0800 (CST) Received: from localhost (10.177.24.212) by SZXEML424-HUB.china.huawei.com (10.82.67.153) with Microsoft SMTP Server id 14.3.235.1; Fri, 8 Apr 2016 14:27:48 +0800 From: zhanghailiang To: Date: Fri, 8 Apr 2016 14:26:21 +0800 Message-ID: <1460096797-14916-20-git-send-email-zhang.zhanghailiang@huawei.com> X-Mailer: git-send-email 2.7.2.windows.1 In-Reply-To: <1460096797-14916-1-git-send-email-zhang.zhanghailiang@huawei.com> References: <1460096797-14916-1-git-send-email-zhang.zhanghailiang@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.177.24.212] X-CFilter-Loop: Reflected X-Mirapoint-Virus-RAPID-Raw: score=unknown(0), refid=str=0001.0A020201.57074F70.003E, ss=1, re=0.000, recu=0.000, reip=0.000, cl=1, cld=1, fgs=0, ip=0.0.0.0, so=2013-06-18 04:22:30, dmn=2013-03-21 17:37:32 X-Mirapoint-Loop-Id: 59191f915edc60be483c61fd06d9662a X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.4.x-2.6.x [generic] X-Received-From: 58.251.152.64 Subject: [Qemu-devel] [PATCH COLO-Frame v16 19/35] COLO: Implement failover work for Primary VM 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, lizhijian@cn.fujitsu.com, quintela@redhat.com, armbru@redhat.com, yunhong.jiang@intel.com, eddie.dong@intel.com, peter.huangpeng@huawei.com, dgilbert@redhat.com, zhanghailiang , arei.gonglei@huawei.com, stefanha@redhat.com, amit.shah@redhat.com, zhangchen.fnst@cn.fujitsu.com, hongyang.yang@easystack.cn Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP For PVM, if there is failover request from users. The colo thread will exit the loop while the failover BH does the cleanup work and resumes VM. Signed-off-by: zhanghailiang Signed-off-by: Li Zhijian Reviewed-by: Dr. David Alan Gilbert --- v13: - Add Reviewed-by tag v12: - Fix error report and remove unnecessary check in primary_vm_do_failover() (Dave's suggestion) v11: - Don't call migration_end() in primary_vm_do_failover(), The cleanup work will be done in migration_thread(). - Remove vm_start() in primary_vm_do_failover() which also been done in migraiton_thread() v10: - Call migration_end() in primary_vm_do_failover() --- include/migration/colo.h | 3 +++ include/migration/failover.h | 1 + migration/colo-failover.c | 7 +++++- migration/colo.c | 53 +++++++++++++++++++++++++++++++++++++++++--- 4 files changed, 60 insertions(+), 4 deletions(-) diff --git a/include/migration/colo.h b/include/migration/colo.h index e9ac2c3..e32eef4 100644 --- a/include/migration/colo.h +++ b/include/migration/colo.h @@ -32,4 +32,7 @@ void *colo_process_incoming_thread(void *opaque); bool migration_incoming_in_colo_state(void); COLOMode get_colo_mode(void); + +/* failover */ +void colo_do_failover(MigrationState *s); #endif diff --git a/include/migration/failover.h b/include/migration/failover.h index fe71bb4..c4bd81e 100644 --- a/include/migration/failover.h +++ b/include/migration/failover.h @@ -26,5 +26,6 @@ void failover_init_state(void); int failover_set_state(int old_state, int new_state); int failover_get_state(void); void failover_request_active(Error **errp); +bool failover_request_is_active(void); #endif diff --git a/migration/colo-failover.c b/migration/colo-failover.c index 69aac55..fa84172 100644 --- a/migration/colo-failover.c +++ b/migration/colo-failover.c @@ -33,7 +33,7 @@ static void colo_failover_bh(void *opaque) error_report("Unkown error for failover, old_state=%d", old_state); return; } - /*TODO: Do failover work */ + colo_do_failover(NULL); } void failover_request_active(Error **errp) @@ -68,6 +68,11 @@ int failover_get_state(void) return atomic_read(&failover_state); } +bool failover_request_is_active(void) +{ + return failover_get_state() != FAILOVER_STATUS_NONE; +} + void qmp_x_colo_lost_heartbeat(Error **errp) { if (get_colo_mode() == COLO_MODE_UNKNOWN) { diff --git a/migration/colo.c b/migration/colo.c index af1f8c2..bdde182 100644 --- a/migration/colo.c +++ b/migration/colo.c @@ -41,6 +41,40 @@ bool migration_incoming_in_colo_state(void) return mis && (mis->state == MIGRATION_STATUS_COLO); } +static bool colo_runstate_is_stopped(void) +{ + return runstate_check(RUN_STATE_COLO) || !runstate_is_running(); +} + +static void primary_vm_do_failover(void) +{ + MigrationState *s = migrate_get_current(); + int old_state; + + migrate_set_state(&s->state, MIGRATION_STATUS_COLO, + MIGRATION_STATUS_COMPLETED); + + old_state = failover_set_state(FAILOVER_STATUS_HANDLING, + FAILOVER_STATUS_COMPLETED); + if (old_state != FAILOVER_STATUS_HANDLING) { + error_report("Incorrect state (%d) while doing failover for Primary VM", + old_state); + return; + } +} + +void colo_do_failover(MigrationState *s) +{ + /* Make sure vm stopped while failover */ + if (!colo_runstate_is_stopped()) { + vm_stop_force_state(RUN_STATE_COLO); + } + + if (get_colo_mode() == COLO_MODE_PRIMARY) { + primary_vm_do_failover(); + } +} + static void colo_send_message(QEMUFile *f, COLOMessage msg, Error **errp) { @@ -167,9 +201,20 @@ static int colo_do_checkpoint_transaction(MigrationState *s, } qemu_mutex_lock_iothread(); + if (failover_request_is_active()) { + qemu_mutex_unlock_iothread(); + goto out; + } vm_stop_force_state(RUN_STATE_COLO); qemu_mutex_unlock_iothread(); trace_colo_vm_state_change("run", "stop"); + /* + * failover request bh could be called after + * vm_stop_force_state so we check failover_request_is_active() again. + */ + if (failover_request_is_active()) { + goto out; + } /* Disable block migration */ s->params.blk = 0; @@ -267,6 +312,11 @@ static void colo_process_checkpoint(MigrationState *s) trace_colo_vm_state_change("stop", "run"); while (s->state == MIGRATION_STATUS_COLO) { + if (failover_request_is_active()) { + error_report("failover request"); + goto out; + } + current_time = qemu_clock_get_ms(QEMU_CLOCK_HOST); if (current_time - checkpoint_time < s->parameters[MIGRATION_PARAMETER_X_CHECKPOINT_DELAY]) { @@ -289,9 +339,6 @@ out: if (local_err) { error_report_err(local_err); } - migrate_set_state(&s->state, MIGRATION_STATUS_COLO, - MIGRATION_STATUS_COMPLETED); - qsb_free(buffer); buffer = NULL;