On 11/27/2015 08:27 PM, Zhang Chen wrote: > From: zhangchen <zhangchen.f...@cn.fujitsu.com> > > Colo-proxy is a plugin of qemu netfilter > like filter-buffer and dump > > Signed-off-by: zhangchen <zhangchen.f...@cn.fujitsu.com> > --- > net/Makefile.objs | 1 + > net/colo-proxy.c | 139 > ++++++++++++++++++++++++++++++++++++++++++++++++++++++ > net/colo-proxy.h | 63 +++++++++++++++++++++++++ > 3 files changed, 203 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..98c2699 > --- /dev/null > +++ b/net/colo-proxy.c > @@ -0,0 +1,139 @@ > +/* > + * 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 <zhangchen.f...@cn.fujitsu.com> > + * > + * 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 "colo-proxy.h" > + > +#define __DEBUG__ > + > +#ifdef __DEBUG__ > +#define DEBUG(format, ...) printf(format, ##__VA_ARGS__) > +#else > +#define DEBUG(format, ...) > +#endif > + > + > +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); > + if (s->colo_mode == COLO_PRIMARY_MODE) { > + /* colo_proxy_primary_handler */ > + } else { > + /* colo_proxy_primary_handler */ > + } > + return iov_size(iov, iovcnt); > +} > + > +static void colo_proxy_cleanup(NetFilterState *nf) > +{ > + /* cleanup */ > +} > + > + > +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) { > + printf("colo need queue all packet,\
s/need/needs/ > + please startup colo-proxy with queue=all\n"); > + return; > + } > + > + s->sockfd = -1; > + s->has_failover = false; > + colo_do_checkpoint = false; > + g_queue_init(&s->unprocessed_connections); > + > + if (!strcmp(mode, PRIMARY_MODE)) { > + s->colo_mode = COLO_PRIMARY_MODE; > + } else if (!strcmp(mode, SECONDARY_MODE)) { > + s->colo_mode = COLO_SECONDARY_MODE; > + } else { > + error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "mode", > + "primary or secondary"); > + return; > + } > +} > + > +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 char *colo_proxy_get_mode(Object *obj, Error **errp) > +{ > + return g_strdup(mode); > +} > + > +static void colo_proxy_set_mode(Object *obj, const char *value, Error **errp) > +{ > + g_free(mode); > + mode = g_strdup(value); > +} > + > +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); You can parse the address here, and can find the format error as early as possible. > +} > + > +static void colo_proxy_init(Object *obj) > +{ > + object_property_add_str(obj, "mode", 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 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_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..94afbc7 > --- /dev/null > +++ b/net/colo-proxy.h > @@ -0,0 +1,63 @@ > +/* > + * 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 <zhangchen.f...@cn.fujitsu.com> > + * > + * 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 > + > +#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 <netinet/if_ether.h> > +#include "qemu/jhash.h" > +#include "qemu/coroutine.h" Don't include too many header files here. You should only include the header files which will be used in this header file. > + > +#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" > + > +typedef enum { > + COLO_PRIMARY_MODE, /* primary mode */ > + COLO_SECONDARY_MODE, /* secondary mode */ > +} mode_type; > + > +typedef struct ColoProxyState { > + NetFilterState parent_obj; > + NetQueue *incoming_queue; /* guest normal net queue */ > + NetFilterDirection direction; /* packet direction */ > + mode_type colo_mode; /* colo mode (primary or > + * secondary) > + */ > + char *addr; /* primary colo connect addr > + * or secondary server addr > + */ > + int sockfd; /* primary client socket fd or > + * secondary server socket fd > + */ > + bool has_failover; /* colo failover flag */ > + GHashTable *unprocessed_packets; /* hashtable to save connection */ > + GQueue unprocessed_connections; /* to save unprocessed_connections */ > + Coroutine *co; > +} ColoProxyState; > + > +#endif /* QEMU_COLO_PROXY_H */ >