When in colo mode, call colo nic init/destroy function. Signed-off-by: zhanghailiang <zhang.zhanghaili...@huawei.com> Signed-off-by: Li Zhijian <lizhij...@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 --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()); +} -- 1.7.12.4