[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [RFC PATCH v2 03/10] Colo-proxy: add colo-proxy framework
From: |
Zhang Chen |
Subject: |
[Qemu-devel] [RFC PATCH v2 03/10] Colo-proxy: add colo-proxy framework |
Date: |
Tue, 22 Dec 2015 18:42:51 +0800 |
From: zhangchen <address@hidden>
Colo-proxy is a plugin of qemu netfilter
like filter-buffer and dump
Signed-off-by: zhangchen <address@hidden>
Signed-off-by: zhanghailiang <address@hidden>
---
net/Makefile.objs | 1 +
net/colo-proxy.c | 240 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
net/colo-proxy.h | 24 ++++++
3 files changed, 265 insertions(+)
create mode 100644 net/colo-proxy.c
create mode 100644 net/colo-proxy.h
diff --git a/net/Makefile.objs b/net/Makefile.objs
index 5fa2f97..95670f2 100644
--- a/net/Makefile.objs
+++ b/net/Makefile.objs
@@ -15,3 +15,4 @@ common-obj-$(CONFIG_VDE) += vde.o
common-obj-$(CONFIG_NETMAP) += netmap.o
common-obj-y += filter.o
common-obj-y += filter-buffer.o
+common-obj-y += colo-proxy.o
diff --git a/net/colo-proxy.c b/net/colo-proxy.c
new file mode 100644
index 0000000..2e37c45
--- /dev/null
+++ b/net/colo-proxy.c
@@ -0,0 +1,240 @@
+/*
+ * COarse-grain LOck-stepping Virtual Machines for Non-stop Service (COLO)
+ * (a.k.a. Fault Tolerance or Continuous Replication)
+ *
+ * Copyright (c) 2015 HUAWEI TECHNOLOGIES CO., LTD.
+ * Copyright (c) 2015 FUJITSU LIMITED
+ * Copyright (c) 2015 Intel Corporation
+ *
+ * Author: Zhang Chen <address@hidden>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or
+ * later. See the COPYING file in the top-level directory.
+ */
+
+#include "net/filter.h"
+#include "net/queue.h"
+#include "qemu-common.h"
+#include "qemu/iov.h"
+#include "qapi/qmp/qerror.h"
+#include "qapi-visit.h"
+#include "qom/object.h"
+#include "qemu/sockets.h"
+#include "qemu/main-loop.h"
+#include "qemu/jhash.h"
+#include "qemu/coroutine.h"
+#include "net/eth.h"
+#include "slirp/slirp.h"
+#include "slirp/slirp_config.h"
+#include "slirp/ip.h"
+#include "net/net.h"
+#include "qemu/error-report.h"
+#include "net/colo-proxy.h"
+#include "trace.h"
+#include <sys/sysinfo.h>
+
+#define FILTER_COLO_PROXY(obj) \
+ OBJECT_CHECK(COLOProxyState, (obj), TYPE_FILTER_COLO_PROXY)
+
+#define TYPE_FILTER_COLO_PROXY "colo-proxy"
+#define PRIMARY_MODE "primary"
+#define SECONDARY_MODE "secondary"
+
+/*
+
+ |COLOProxyState++
+ | |
+ +---------------+ +---------------+ +---------------+
+ |conn list +--->conn +--------->conn |
+ +---------------+ +---------------+ +---------------+
+ | | | | | |
+ +---------------+ +---v----+ +---v----+ +---v----+ +---v----+
+ |primary | |secondary |primary | |secondary
+ |packet | |packet + |packet | |packet +
+ +--------+ +--------+ +--------+ +--------+
+ | | | |
+ +---v----+ +---v----+ +---v----+ +---v----+
+ |primary | |secondary |primary | |secondary
+ |packet | |packet + |packet | |packet +
+ +--------+ +--------+ +--------+ +--------+
+ | | | |
+ +---v----+ +---v----+ +---v----+ +---v----+
+ |primary | |secondary |primary | |secondary
+ |packet | |packet + |packet | |packet +
+ +--------+ +--------+ +--------+ +--------+
+
+
+*/
+
+typedef struct COLOProxyState {
+ NetFilterState parent_obj;
+ NetQueue *incoming_queue;/* guest normal net queue */
+ NetFilterDirection direction; /* packet direction */
+ /* colo mode (primary or secondary) */
+ int colo_mode;
+ /* primary colo connect address(192.168.0.100:12345)
+ * or secondary listening address(:12345)
+ */
+ char *addr;
+ int sockfd;
+
+ /* connection list: the packet belonged to this NIC
+ * could be found in this list.
+ * element type: Connection
+ */
+ GQueue conn_list;
+ int status; /* proxy is running or not */
+ ssize_t hashtable_size; /* proxy current hash size */
+ QemuEvent need_compare_ev; /* notify compare thread */
+ QemuThread thread; /* compare thread, a thread for each NIC */
+
+} COLOProxyState;
+
+enum {
+ COLO_PROXY_NONE, /* colo proxy is not started */
+ COLO_PROXY_RUNNING, /* colo proxy is running */
+ COLO_PROXY_DONE, /* colo proxyis done(failover) */
+};
+
+/* save all the connections of a vm instance in this table */
+GHashTable *colo_conn_hash;
+static bool colo_do_checkpoint;
+static ssize_t hashtable_max_size;
+
+static ssize_t colo_proxy_receive_iov(NetFilterState *nf,
+ NetClientState *sender,
+ unsigned flags,
+ const struct iovec *iov,
+ int iovcnt,
+ NetPacketSent *sent_cb)
+{
+ /*
+ * We return size when buffer a packet, the sender will take it as
+ * a already sent packet, so sent_cb should not be called later.
+ *
+ */
+ COLOProxyState *s = FILTER_COLO_PROXY(nf);
+ ssize_t ret = 0;
+
+ if (s->status != COLO_PROXY_RUNNING) {
+ /* proxy is not started or failovered */
+ return 0;
+ }
+
+ if (s->colo_mode == COLO_MODE_PRIMARY) {
+ /* colo_proxy_primary_handler */
+ } else {
+ /* colo_proxy_secondary_handler */
+ }
+ return iov_size(iov, iovcnt);
+}
+
+static void colo_proxy_cleanup(NetFilterState *nf)
+{
+ COLOProxyState *s = FILTER_COLO_PROXY(nf);
+ close(s->sockfd);
+ s->sockfd = -1;
+ qemu_event_destroy(&s->need_compare_ev);
+}
+
+static void colo_proxy_setup(NetFilterState *nf, Error **errp)
+{
+ COLOProxyState *s = FILTER_COLO_PROXY(nf);
+
+ if (!s->addr) {
+ error_setg(errp, "filter colo_proxy needs 'addr' property set!");
+ return;
+ }
+
+ if (nf->direction != NET_FILTER_DIRECTION_ALL) {
+ error_setg(errp, "colo need queue all packet,"
+ "please startup colo-proxy with queue=all\n");
+ return;
+ }
+
+ s->sockfd = -1;
+ s->hashtable_size = 0;
+ colo_do_checkpoint = false;
+ qemu_event_init(&s->need_compare_ev, false);
+
+ s->incoming_queue = qemu_new_net_queue(qemu_netfilter_pass_to_next, nf);
+ colo_conn_hash = g_hash_table_new_full(connection_key_hash,
+ connection_key_equal,
+ g_free,
+ connection_destroy);
+ g_queue_init(&s->conn_list);
+}
+
+static void colo_proxy_class_init(ObjectClass *oc, void *data)
+{
+ NetFilterClass *nfc = NETFILTER_CLASS(oc);
+
+ nfc->setup = colo_proxy_setup;
+ nfc->cleanup = colo_proxy_cleanup;
+ nfc->receive_iov = colo_proxy_receive_iov;
+}
+
+static int colo_proxy_get_mode(Object *obj, Error **errp)
+{
+ COLOProxyState *s = FILTER_COLO_PROXY(obj);
+
+ return s->colo_mode;
+}
+
+static void
+colo_proxy_set_mode(Object *obj, int mode, Error **errp)
+{
+ COLOProxyState *s = FILTER_COLO_PROXY(obj);
+
+ s->colo_mode = mode;
+}
+
+static char *colo_proxy_get_addr(Object *obj, Error **errp)
+{
+ COLOProxyState *s = FILTER_COLO_PROXY(obj);
+
+ return g_strdup(s->addr);
+}
+
+static void
+colo_proxy_set_addr(Object *obj, const char *value, Error **errp)
+{
+ COLOProxyState *s = FILTER_COLO_PROXY(obj);
+ g_free(s->addr);
+ s->addr = g_strdup(value);
+ if (!s->addr) {
+ error_setg(errp, "colo_proxy needs 'addr'"
+ "property set!");
+ return;
+ }
+}
+
+static void colo_proxy_init(Object *obj)
+{
+ object_property_add_enum(obj, "mode", "COLOMode", COLOMode_lookup,
+ colo_proxy_get_mode, colo_proxy_set_mode, NULL);
+ object_property_add_str(obj, "addr", colo_proxy_get_addr,
+ colo_proxy_set_addr, NULL);
+}
+
+static void colo_proxy_fini(Object *obj)
+{
+ COLOProxyState *s = FILTER_COLO_PROXY(obj);
+ g_free(s->addr);
+}
+
+static const TypeInfo colo_proxy_info = {
+ .name = TYPE_FILTER_COLO_PROXY,
+ .parent = TYPE_NETFILTER,
+ .class_init = colo_proxy_class_init,
+ .instance_init = colo_proxy_init,
+ .instance_finalize = colo_proxy_fini,
+ .instance_size = sizeof(COLOProxyState),
+};
+
+static void register_types(void)
+{
+ type_register_static(&colo_proxy_info);
+}
+
+type_init(register_types);
diff --git a/net/colo-proxy.h b/net/colo-proxy.h
new file mode 100644
index 0000000..affc117
--- /dev/null
+++ b/net/colo-proxy.h
@@ -0,0 +1,24 @@
+/*
+ * COarse-grain LOck-stepping Virtual Machines for Non-stop Service (COLO)
+ * (a.k.a. Fault Tolerance or Continuous Replication)
+ *
+ * Copyright (c) 2015 HUAWEI TECHNOLOGIES CO., LTD.
+ * Copyright (c) 2015 FUJITSU LIMITED
+ * Copyright (c) 2015 Intel Corporation
+ *
+ * Author: Zhang Chen <address@hidden>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or
+ * later. See the COPYING file in the top-level directory.
+ */
+
+
+#ifndef QEMU_COLO_PROXY_H
+#define QEMU_COLO_PROXY_H
+
+int colo_proxy_start(int mode);
+void colo_proxy_stop(int mode);
+int colo_proxy_do_checkpoint(int mode);
+bool colo_proxy_query_checkpoint(void);
+
+#endif /* QEMU_COLO_PROXY_H */
--
1.9.1
- [Qemu-devel] [RFC PATCH v2 00/10] Add colo-proxy based on netfilter, Zhang Chen, 2015/12/22
- [Qemu-devel] [RFC PATCH v2 02/10] Jhash: add linux kernel jhashtable in qemu, Zhang Chen, 2015/12/22
- [Qemu-devel] [RFC PATCH v2 04/10] Colo-proxy: add data structure and jhash func, Zhang Chen, 2015/12/22
- [Qemu-devel] [RFC PATCH v2 03/10] Colo-proxy: add colo-proxy framework,
Zhang Chen <=
- [Qemu-devel] [RFC PATCH v2 01/10] Init colo-proxy object based on netfilter, Zhang Chen, 2015/12/22
- [Qemu-devel] [RFC PATCH v2 06/10] net/colo-proxy: add socket used by forward func, Zhang Chen, 2015/12/22
- [Qemu-devel] [RFC PATCH v2 10/10] net/colo-proxy: Colo-proxy do checkpoint and clear, Zhang Chen, 2015/12/22
- [Qemu-devel] [RFC PATCH v2 09/10] net/colo-proxy: Compare pri pkt to sec pkt, Zhang Chen, 2015/12/22
- [Qemu-devel] [RFC PATCH v2 07/10] net/colo-proxy: Add packet enqueue & handle func, Zhang Chen, 2015/12/22
- [Qemu-devel] [RFC PATCH v2 05/10] net/colo-proxy: Add colo interface to use proxy, Zhang Chen, 2015/12/22
- [Qemu-devel] [RFC PATCH v2 08/10] net/colo-proxy: Handle packet and connection, Zhang Chen, 2015/12/22
- Re: [Qemu-devel] [RFC PATCH v2 00/10] Add colo-proxy based on netfilter, Zhang Chen, 2015/12/29