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