@@ -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
@@ -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;
}
@@ -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());
+}