summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzhanghailiang <zhang.zhanghailiang@huawei.com>2016-10-27 14:43:04 +0800
committerAmit Shah <amit@amitshah.net>2016-10-30 15:17:39 +0530
commitaef060850bd0e35aa7128e0ae3cef9d62c328314 (patch)
tree00d1c224767ef8cf90e230ad56000683b999718e
parentd89e666e0666a0023e4aa6b6b4c4d25d049c5215 (diff)
downloadqemu-aef060850bd0e35aa7128e0ae3cef9d62c328314.zip
COLO: Introduce state to record failover process
When handling failover, COLO processes differently according to the different stage of failover process, here we introduce a global atomic variable to record the status of failover. We add four failover status to indicate the different stage of failover process. You should use the helpers to get and set the value. Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com> Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com> Reviewed-by: Amit Shah <amit.shah@redhat.com> Signed-off-by: Amit Shah <amit@amitshah.net>
-rw-r--r--include/migration/failover.h5
-rw-r--r--migration/colo-failover.c41
-rw-r--r--migration/colo.c4
-rw-r--r--migration/trace-events1
-rw-r--r--qapi-schema.json18
5 files changed, 69 insertions, 0 deletions
diff --git a/include/migration/failover.h b/include/migration/failover.h
index 3274735068..7e0f36a274 100644
--- a/include/migration/failover.h
+++ b/include/migration/failover.h
@@ -14,7 +14,12 @@
#define QEMU_FAILOVER_H
#include "qemu-common.h"
+#include "qapi-types.h"
+void failover_init_state(void);
+FailoverStatus failover_set_state(FailoverStatus old_state,
+ FailoverStatus new_state);
+FailoverStatus failover_get_state(void);
void failover_request_active(Error **errp);
#endif
diff --git a/migration/colo-failover.c b/migration/colo-failover.c
index e31fc10c82..6cca039eb9 100644
--- a/migration/colo-failover.c
+++ b/migration/colo-failover.c
@@ -15,22 +15,63 @@
#include "migration/failover.h"
#include "qmp-commands.h"
#include "qapi/qmp/qerror.h"
+#include "qemu/error-report.h"
+#include "trace.h"
static QEMUBH *failover_bh;
+static FailoverStatus failover_state;
static void colo_failover_bh(void *opaque)
{
+ int old_state;
+
qemu_bh_delete(failover_bh);
failover_bh = NULL;
+
+ old_state = failover_set_state(FAILOVER_STATUS_REQUIRE,
+ FAILOVER_STATUS_ACTIVE);
+ if (old_state != FAILOVER_STATUS_REQUIRE) {
+ error_report("Unknown error for failover, old_state = %s",
+ FailoverStatus_lookup[old_state]);
+ return;
+ }
+
/* TODO: Do failover work */
}
void failover_request_active(Error **errp)
{
+ if (failover_set_state(FAILOVER_STATUS_NONE,
+ FAILOVER_STATUS_REQUIRE) != FAILOVER_STATUS_NONE) {
+ error_setg(errp, "COLO failover is already actived");
+ return;
+ }
failover_bh = qemu_bh_new(colo_failover_bh, NULL);
qemu_bh_schedule(failover_bh);
}
+void failover_init_state(void)
+{
+ failover_state = FAILOVER_STATUS_NONE;
+}
+
+FailoverStatus failover_set_state(FailoverStatus old_state,
+ FailoverStatus new_state)
+{
+ FailoverStatus old;
+
+ old = atomic_cmpxchg(&failover_state, old_state, new_state);
+ if (old == old_state) {
+ trace_colo_failover_set_state(FailoverStatus_lookup[new_state]);
+ }
+ return old;
+}
+
+FailoverStatus failover_get_state(void)
+{
+ return atomic_read(&failover_state);
+}
+
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 12fa0b4111..6b32c9183c 100644
--- a/migration/colo.c
+++ b/migration/colo.c
@@ -232,6 +232,8 @@ static void colo_process_checkpoint(MigrationState *s)
Error *local_err = NULL;
int ret;
+ failover_init_state();
+
s->rp_state.from_dst_file = qemu_file_get_return_path(s->to_dst_file);
if (!s->rp_state.from_dst_file) {
error_report("Open QEMUFile from_dst_file failed");
@@ -332,6 +334,8 @@ void *colo_process_incoming_thread(void *opaque)
migrate_set_state(&mis->state, MIGRATION_STATUS_ACTIVE,
MIGRATION_STATUS_COLO);
+ failover_init_state();
+
mis->to_src_file = qemu_file_get_return_path(mis->from_src_file);
if (!mis->to_src_file) {
error_report("COLO incoming thread: Open QEMUFile to_src_file failed");
diff --git a/migration/trace-events b/migration/trace-events
index f374c8cf27..94134f700b 100644
--- a/migration/trace-events
+++ b/migration/trace-events
@@ -212,3 +212,4 @@ migration_tls_incoming_handshake_complete(void) ""
colo_vm_state_change(const char *old, const char *new) "Change '%s' => '%s'"
colo_send_message(const char *msg) "Send '%s' message"
colo_receive_message(const char *msg) "Receive '%s' message"
+colo_failover_set_state(const char *new_state) "new state %s"
diff --git a/qapi-schema.json b/qapi-schema.json
index a18484115f..8a7b527091 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -840,6 +840,24 @@
'data': [ 'unknown', 'primary', 'secondary'] }
##
+# @FailoverStatus
+#
+# An enumeration of COLO failover status
+#
+# @none: no failover has ever happened
+#
+# @require: got failover requirement but not handled
+#
+# @active: in the process of doing failover
+#
+# @completed: finish the process of failover
+#
+# Since: 2.8
+##
+{ 'enum': 'FailoverStatus',
+ 'data': [ 'none', 'require', 'active', 'completed'] }
+
+##
# @x-colo-lost-heartbeat
#
# Tell qemu that heartbeat is lost, request it to do takeover procedures.