]> Git Repo - qemu.git/commitdiff
COLO: Introduce state to record failover process
authorzhanghailiang <[email protected]>
Thu, 27 Oct 2016 06:43:04 +0000 (14:43 +0800)
committerAmit Shah <[email protected]>
Sun, 30 Oct 2016 09:47:39 +0000 (15:17 +0530)
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 <[email protected]>
Reviewed-by: Dr. David Alan Gilbert <[email protected]>
Reviewed-by: Amit Shah <[email protected]>
Signed-off-by: Amit Shah <[email protected]>
include/migration/failover.h
migration/colo-failover.c
migration/colo.c
migration/trace-events
qapi-schema.json

index 327473506874c7b0169a9e02c4b29141384d4337..7e0f36a27423dedea1a9e574a1ca98d1274d5a6f 100644 (file)
 #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
index e31fc10c826880d1c0502931df44464948d7f86a..6cca039eb99b682a72322c4dde2b485ead623ac8 100644 (file)
 #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) {
index 12fa0b411157911d4e59498602cb40a569933642..6b32c9183c6000ed021b51a496c1843ece4dec61 100644 (file)
@@ -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");
index f374c8cf274204bb8a5184bf48b07eb81bc4d248..94134f700bb2c602eb2d9c27a7627693ec2a67ac 100644 (file)
@@ -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"
index a18484115f6348538ed4f791ee1e31f65c461817..8a7b5270910277d907072fdce04e3de56971c66b 100644 (file)
 { 'enum': 'COLOMode',
   '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
 #
This page took 0.037548 seconds and 4 git commands to generate.