diff mbox

[COLO-Frame,v5,20/29] COLO NIC : Implement colo nic init/destroy function

Message ID 1432196001-10352-21-git-send-email-zhang.zhanghailiang@huawei.com
State New
Headers show

Commit Message

Zhanghailiang May 21, 2015, 8:13 a.m. UTC
When in colo mode, call colo nic init/destroy function.

Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
Signed-off-by: Li Zhijian <lizhijian@cn.fujitsu.com>
---
 include/migration/migration-colo.h |  2 +-
 include/net/colo-nic.h             |  3 ++
 migration/colo.c                   | 15 ++++++++
 net/colo-nic.c                     | 74 ++++++++++++++++++++++++++++++++++++--
 4 files changed, 91 insertions(+), 3 deletions(-)
diff mbox

Patch

diff --git a/include/migration/migration-colo.h b/include/migration/migration-colo.h
index 63f8b45..ebc4651 100644
--- a/include/migration/migration-colo.h
+++ b/include/migration/migration-colo.h
@@ -23,7 +23,7 @@  bool colo_supported(void);
 void colo_info_mig_init(void);
 
 /* Checkpoint control, called in migration/checkpoint thread */
-enum {
+enum colo_mode {
     COLO_UNPROTECTED_MODE = 0,
     COLO_PRIMARY_MODE,
     COLO_SECONDARY_MODE,
diff --git a/include/net/colo-nic.h b/include/net/colo-nic.h
index d35ee17..809726c 100644
--- a/include/net/colo-nic.h
+++ b/include/net/colo-nic.h
@@ -13,7 +13,10 @@ 
 
 #ifndef COLO_NIC_H
 #define COLO_NIC_H
+#include "migration/migration-colo.h"
 
+int colo_proxy_init(enum colo_mode mode);
+void colo_proxy_destroy(enum colo_mode mode);
 void colo_add_nic_devices(NetClientState *nc);
 void colo_remove_nic_devices(NetClientState *nc);
 
diff --git a/migration/colo.c b/migration/colo.c
index fc30ca5..22d7df1 100644
--- a/migration/colo.c
+++ b/migration/colo.c
@@ -15,6 +15,7 @@ 
 #include "trace.h"
 #include "qemu/error-report.h"
 #include "migration/migration-failover.h"
+#include "net/colo-nic.h"
 
 enum {
     COLO_CHECPOINT_READY = 0x46,
@@ -284,6 +285,11 @@  static void *colo_thread(void *opaque)
     QEMUFile *colo_control = NULL;
     int ret;
 
+    if (colo_proxy_init(COLO_PRIMARY_MODE) != 0) {
+        error_report("Init colo proxy error");
+        goto out;
+    }
+
     colo_control = qemu_fopen_socket(qemu_get_fd(s->file), "rb");
     if (!colo_control) {
         error_report("Open colo_control failed!");
@@ -348,6 +354,8 @@  out:
     qemu_bh_schedule(s->cleanup_bh);
     qemu_mutex_unlock_iothread();
 
+    colo_proxy_destroy(COLO_PRIMARY_MODE);
+
     return NULL;
 }
 
@@ -417,6 +425,12 @@  void *colo_process_incoming_checkpoints(void *opaque)
     colo = qemu_coroutine_self();
     assert(colo != NULL);
 
+     /* configure the network */
+    if (colo_proxy_init(COLO_SECONDARY_MODE) != 0) {
+        error_report("Init colo proxy error\n");
+        goto out;
+    }
+
     ctl = qemu_fopen_socket(fd, "wb");
     if (!ctl) {
         error_report("Can't open incoming channel!");
@@ -574,5 +588,6 @@  out:
 
     loadvm_exit_colo();
 
+    colo_proxy_destroy(COLO_SECONDARY_MODE);
     return NULL;
 }
diff --git a/net/colo-nic.c b/net/colo-nic.c
index 8b678b1..fee2cfe 100644
--- a/net/colo-nic.c
+++ b/net/colo-nic.c
@@ -25,8 +25,6 @@  typedef struct nic_device {
     bool is_up;
 } nic_device;
 
-
-
 QTAILQ_HEAD(, nic_device) nic_devices = QTAILQ_HEAD_INITIALIZER(nic_devices);
 
 /*
@@ -92,6 +90,60 @@  static int colo_nic_configure(NetClientState *nc,
     return launch_colo_script(argv);
 }
 
+static int configure_one_nic(NetClientState *nc,
+             bool up, int side, int index)
+{
+    struct nic_device *nic;
+
+    assert(nc);
+
+    QTAILQ_FOREACH(nic, &nic_devices, next) {
+        if (nic->nc == nc) {
+            if (!nic->support_colo || !nic->support_colo(nic->nc)
+                || !nic->configure) {
+                return -1;
+            }
+            if (up == nic->is_up) {
+                return 0;
+            }
+
+            if (nic->configure(nic->nc, up, side, index) && up) {
+                return -1;
+            }
+            nic->is_up = up;
+            return 0;
+        }
+    }
+
+    return -1;
+}
+
+static int configure_nic(int side, int index)
+{
+    struct nic_device *nic;
+
+    if (QTAILQ_EMPTY(&nic_devices)) {
+        return -1;
+    }
+
+    QTAILQ_FOREACH(nic, &nic_devices, next) {
+        if (configure_one_nic(nic->nc, 1, side, index)) {
+            return -1;
+        }
+    }
+
+    return 0;
+}
+
+static void teardown_nic(int side, int index)
+{
+    struct nic_device *nic;
+
+    QTAILQ_FOREACH(nic, &nic_devices, next) {
+        configure_one_nic(nic->nc, 0, side, index);
+    }
+}
+
 void colo_add_nic_devices(NetClientState *nc)
 {
     struct nic_device *nic = g_malloc0(sizeof(*nic));
@@ -118,8 +170,26 @@  void colo_remove_nic_devices(NetClientState *nc)
 
     QTAILQ_FOREACH_SAFE(nic, &nic_devices, next, next_nic) {
         if (nic->nc == nc) {
+            configure_one_nic(nc, 0, get_colo_mode(), getpid());
             QTAILQ_REMOVE(&nic_devices, nic, next);
             g_free(nic);
         }
     }
 }
+
+int colo_proxy_init(enum colo_mode mode)
+{
+    int ret = -1;
+
+    ret = configure_nic(mode, getpid());
+    if (ret != 0) {
+        error_report("excute colo-proxy-script failed");
+    }
+
+    return ret;
+}
+
+void colo_proxy_destroy(enum colo_mode mode)
+{
+    teardown_nic(mode, getpid());
+}