diff mbox

[COLO-Frame,v12,37/38] colo: Use default buffer-filter to buffer and release packets

Message ID 1450167779-9960-38-git-send-email-zhang.zhanghailiang@huawei.com
State New
Headers show

Commit Message

Zhanghailiang Dec. 15, 2015, 8:22 a.m. UTC
Enable default filter to buffer packets and release the
packets after a checkpoint.

Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
Cc: Jason Wang <jasowang@redhat.com>
Cc: Yang Hongyang <hongyang.yang@easystack.cn>
---
v12:
- Add a helper function to check if all netdev supports buffer packets.
- Flush buffered packets when do failover.
v11:
- Use new helper functions to buffer and release packets.

Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
---
 include/net/net.h |  1 +
 migration/colo.c  | 24 +++++++++++++++++++++++-
 net/net.c         | 17 +++++++++++++++++
 3 files changed, 41 insertions(+), 1 deletion(-)
diff mbox

Patch

diff --git a/include/net/net.h b/include/net/net.h
index 5c65c45..2eb9451 100644
--- a/include/net/net.h
+++ b/include/net/net.h
@@ -129,6 +129,7 @@  typedef void (*qemu_netfilter_foreach)(NetFilterState *nf, void *opaque,
                                        Error **errp);
 void qemu_foreach_netfilter(qemu_netfilter_foreach func, void *opaque,
                             Error **errp);
+bool qemu_netdev_support_netfilter(void);
 int qemu_can_send_packet(NetClientState *nc);
 ssize_t qemu_sendv_packet(NetClientState *nc, const struct iovec *iov,
                           int iovcnt);
diff --git a/migration/colo.c b/migration/colo.c
index 4571359..b7a7ad6 100644
--- a/migration/colo.c
+++ b/migration/colo.c
@@ -19,6 +19,8 @@ 
 #include "qemu/sockets.h"
 #include "migration/failover.h"
 #include "qapi-event.h"
+#include "net/filter.h"
+#include "net/net.h"
 
 static bool vmstate_loading;
 
@@ -128,6 +130,10 @@  static void primary_vm_do_failover(void)
                      old_state);
         return;
     }
+    /* Don't buffer any packets while exited COLO */
+    qemu_set_default_filters_status(false);
+    /* Flush the residuary buffered packts */
+    qemu_release_default_filters_packets();
 }
 
 void colo_do_failover(MigrationState *s)
@@ -315,6 +321,8 @@  static int colo_do_checkpoint_transaction(MigrationState *s,
         goto out;
     }
 
+    qemu_release_default_filters_packets();
+
     if (colo_shutdown) {
         colo_put_cmd(s->to_dst_file, COLO_COMMAND_GUEST_SHUTDOWN);
         qemu_fflush(s->to_dst_file);
@@ -354,6 +362,17 @@  static int colo_prepare_before_save(MigrationState *s)
     return 0;
 }
 
+static int colo_init_buffer_filters(void)
+{
+    if (!qemu_netdev_support_netfilter()) {
+        return -EPERM;
+    }
+    /* Begin to buffer packets that sent by VM */
+    qemu_set_default_filters_status(true);
+
+    return 0;
+}
+
 static void colo_process_checkpoint(MigrationState *s)
 {
     QEMUSizedBuffer *buffer = NULL;
@@ -361,7 +380,10 @@  static void colo_process_checkpoint(MigrationState *s)
     int ret = 0;
 
     failover_init_state();
-
+    ret = colo_init_buffer_filters();
+    if (ret < 0) {
+        goto out;
+    }
     s->rp_state.from_dst_file = qemu_file_get_return_path(s->to_dst_file);
     if (!s->rp_state.from_dst_file) {
         ret = -EINVAL;
diff --git a/net/net.c b/net/net.c
index 75b828e..96d97ce 100644
--- a/net/net.c
+++ b/net/net.c
@@ -288,6 +288,23 @@  void qemu_foreach_netfilter(qemu_netfilter_foreach func, void *opaque,
     }
 }
 
+bool qemu_netdev_support_netfilter(void)
+{
+    NetClientState *nc;
+
+    QTAILQ_FOREACH(nc, &net_clients, next) {
+        if (nc->info->type == NET_CLIENT_OPTIONS_KIND_NIC) {
+            continue;
+        }
+        if (QTAILQ_EMPTY(&nc->filters)) {
+            error_report("netdev (%s) does not support filter", nc->name);
+            return false;
+        }
+    }
+
+    return true;
+}
+
 static void qemu_net_client_destructor(NetClientState *nc)
 {
     g_free(nc);