diff mbox

[COLO-Frame,v7,25/34] COLO NIC: Implement colo nic init/destroy function

Message ID 1436411802-181876-26-git-send-email-zhang.zhanghailiang@huawei.com
State New
Headers show

Commit Message

Zhanghailiang July 9, 2015, 3:16 a.m. UTC
When in colo mode, call colo nic init/destroy function.

Cc: Stefan Hajnoczi <stefanha@redhat.com>
Cc: Jason Wang <jasowang@redhat.com>
Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
Signed-off-by: Li Zhijian <lizhijian@cn.fujitsu.com>
---
 include/net/colo-nic.h |  3 +++
 migration/colo.c       | 15 +++++++++++
 net/colo-nic.c         | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 87 insertions(+)
diff mbox

Patch

diff --git a/include/net/colo-nic.h b/include/net/colo-nic.h
index f1d9c25..7b8ff57 100644
--- a/include/net/colo-nic.h
+++ b/include/net/colo-nic.h
@@ -27,4 +27,7 @@  typedef struct COLONicState {
 void colo_add_nic_devices(COLONicState *cns);
 void colo_remove_nic_devices(COLONicState *cns);
 
+int colo_proxy_init(enum COLOMode mode);
+void colo_proxy_destroy(enum COLOMode mode);
+
 #endif
diff --git a/migration/colo.c b/migration/colo.c
index aab7b38..27b41fc 100644
--- a/migration/colo.c
+++ b/migration/colo.c
@@ -16,6 +16,7 @@ 
 #include "qemu/error-report.h"
 #include "migration/failover.h"
 #include "qapi-event.h"
+#include "net/colo-nic.h"
 
 enum {
     COLO_CHECPOINT_READY = 0x46,
@@ -314,6 +315,11 @@  static void *colo_thread(void *opaque)
     QEMUFile *colo_control = NULL;
     int i, ret;
 
+    if (colo_proxy_init(COLO_MODE_PRIMARY) != 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!");
@@ -387,6 +393,8 @@  out:
     qemu_bh_schedule(s->cleanup_bh);
     qemu_mutex_unlock_iothread();
 
+    colo_proxy_destroy(COLO_MODE_PRIMARY);
+
     return NULL;
 }
 
@@ -451,6 +459,12 @@  void *colo_process_incoming_checkpoints(void *opaque)
     colo = qemu_coroutine_self();
     assert(colo != NULL);
 
+     /* configure the network */
+    if (colo_proxy_init(COLO_MODE_SECONDARY) != 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!");
@@ -617,5 +631,6 @@  out:
 
     loadvm_exit_colo();
 
+    colo_proxy_destroy(COLO_MODE_SECONDARY);
     return NULL;
 }
diff --git a/net/colo-nic.c b/net/colo-nic.c
index 4b53f72..5c24169 100644
--- a/net/colo-nic.c
+++ b/net/colo-nic.c
@@ -121,6 +121,57 @@  static int colo_nic_configure(COLONicState *cns,
     return -1;
 }
 
+static int configure_one_nic(COLONicState *cns,
+             bool up, int side, int index)
+{
+    struct nic_device *nic;
+
+    assert(cns);
+
+    QTAILQ_FOREACH(nic, &nic_devices, next) {
+        if (nic->cns == cns) {
+            if (up == nic->is_up) {
+                return 0;
+            }
+
+            if (!nic->configure || (nic->configure(nic->cns, 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->cns, 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->cns, 0, side, index);
+    }
+}
+
 void colo_add_nic_devices(COLONicState *cns)
 {
     struct nic_device *nic;
@@ -151,8 +202,26 @@  void colo_remove_nic_devices(COLONicState *cns)
 
     QTAILQ_FOREACH_SAFE(nic, &nic_devices, next, next_nic) {
         if (nic->cns == cns) {
+            configure_one_nic(cns, 0, get_colo_mode(), getpid());
             QTAILQ_REMOVE(&nic_devices, nic, next);
             g_free(nic);
         }
     }
 }
+
+int colo_proxy_init(enum COLOMode 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 COLOMode mode)
+{
+    teardown_nic(mode, getpid());
+}