qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

colo-failover.c (2240B)


      1 /*
      2  * COarse-grain LOck-stepping Virtual Machines for Non-stop Service (COLO)
      3  * (a.k.a. Fault Tolerance or Continuous Replication)
      4  *
      5  * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD.
      6  * Copyright (c) 2016 FUJITSU LIMITED
      7  * Copyright (c) 2016 Intel Corporation
      8  *
      9  * This work is licensed under the terms of the GNU GPL, version 2 or
     10  * later.  See the COPYING file in the top-level directory.
     11  */
     12 
     13 #include "qemu/osdep.h"
     14 #include "migration/colo.h"
     15 #include "migration/failover.h"
     16 #include "qemu/main-loop.h"
     17 #include "migration.h"
     18 #include "qapi/error.h"
     19 #include "qapi/qapi-commands-migration.h"
     20 #include "qapi/qmp/qerror.h"
     21 #include "qemu/error-report.h"
     22 #include "trace.h"
     23 
     24 static QEMUBH *failover_bh;
     25 static FailoverStatus failover_state;
     26 
     27 static void colo_failover_bh(void *opaque)
     28 {
     29     int old_state;
     30 
     31     qemu_bh_delete(failover_bh);
     32     failover_bh = NULL;
     33 
     34     old_state = failover_set_state(FAILOVER_STATUS_REQUIRE,
     35                                    FAILOVER_STATUS_ACTIVE);
     36     if (old_state != FAILOVER_STATUS_REQUIRE) {
     37         error_report("Unknown error for failover, old_state = %s",
     38                     FailoverStatus_str(old_state));
     39         return;
     40     }
     41 
     42     colo_do_failover();
     43 }
     44 
     45 void failover_request_active(Error **errp)
     46 {
     47    if (failover_set_state(FAILOVER_STATUS_NONE,
     48         FAILOVER_STATUS_REQUIRE) != FAILOVER_STATUS_NONE) {
     49         error_setg(errp, "COLO failover is already activated");
     50         return;
     51     }
     52     failover_bh = qemu_bh_new(colo_failover_bh, NULL);
     53     qemu_bh_schedule(failover_bh);
     54 }
     55 
     56 void failover_init_state(void)
     57 {
     58     failover_state = FAILOVER_STATUS_NONE;
     59 }
     60 
     61 FailoverStatus failover_set_state(FailoverStatus old_state,
     62                     FailoverStatus new_state)
     63 {
     64     FailoverStatus old;
     65 
     66     old = qatomic_cmpxchg(&failover_state, old_state, new_state);
     67     if (old == old_state) {
     68         trace_colo_failover_set_state(FailoverStatus_str(new_state));
     69     }
     70     return old;
     71 }
     72 
     73 FailoverStatus failover_get_state(void)
     74 {
     75     return qatomic_read(&failover_state);
     76 }
     77 
     78 void qmp_x_colo_lost_heartbeat(Error **errp)
     79 {
     80     if (get_colo_mode() == COLO_MODE_NONE) {
     81         error_setg(errp, QERR_FEATURE_DISABLED, "colo");
     82         return;
     83     }
     84 
     85     failover_request_active(errp);
     86 }