All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jason Wang <jasowang@redhat.com>
To: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>,
	qemu devel <qemu-devel@nongnu.org>
Cc: Li Zhijian <lizhijian@cn.fujitsu.com>,
	Wen Congyang <wency@cn.fujitsu.com>,
	zhanghailiang <zhang.zhanghailiang@huawei.com>,
	"eddie . dong" <eddie.dong@intel.com>,
	"Dr . David Alan Gilbert" <dgilbert@redhat.com>
Subject: Re: [Qemu-devel] [RFC PATCH V10 2/7] colo-base: add colo-base to define and handle packet
Date: Tue, 2 Aug 2016 14:38:55 +0800	[thread overview]
Message-ID: <ad3be05e-d472-32dd-de24-b84bff059fd6@redhat.com> (raw)
In-Reply-To: <1469497794-16976-3-git-send-email-zhangchen.fnst@cn.fujitsu.com>



On 2016年07月26日 09:49, Zhang Chen wrote:
> COLO-base used by colo-compare and filter-rewriter.

s/used/is used/

> this can share common data structure like:net packet,

s/this/This/ and ':' looks unnecessary.
> and share other functions.

s/share//

>
> Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
> Signed-off-by: Li Zhijian <lizhijian@cn.fujitsu.com>
> Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
> ---
>   net/Makefile.objs  |   1 +
>   net/colo-base.c    |  74 +++++++++++++++++++++++++++++++++
>   net/colo-base.h    |  38 +++++++++++++++++
>   net/colo-compare.c | 119 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
>   trace-events       |   3 ++
>   5 files changed, 233 insertions(+), 2 deletions(-)
>   create mode 100644 net/colo-base.c
>   create mode 100644 net/colo-base.h
>
> diff --git a/net/Makefile.objs b/net/Makefile.objs
> index ba92f73..119589f 100644
> --- a/net/Makefile.objs
> +++ b/net/Makefile.objs
> @@ -17,3 +17,4 @@ common-obj-y += filter.o
>   common-obj-y += filter-buffer.o
>   common-obj-y += filter-mirror.o
>   common-obj-y += colo-compare.o
> +common-obj-y += colo-base.o
> diff --git a/net/colo-base.c b/net/colo-base.c
> new file mode 100644
> index 0000000..f5d5de9
> --- /dev/null
> +++ b/net/colo-base.c

I was thinking maybe just use colo.c is better here.

> @@ -0,0 +1,74 @@
> +/*
> + * COarse-grain LOck-stepping Virtual Machines for Non-stop Service (COLO)
> + * (a.k.a. Fault Tolerance or Continuous Replication)
> + *
> + * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD.
> + * Copyright (c) 2016 FUJITSU LIMITED
> + * Copyright (c) 2016 Intel Corporation
> + *
> + * Author: Zhang Chen <zhangchen.fnst@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 "qemu/osdep.h"
> +#include "qemu/error-report.h"
> +#include "net/colo-base.h"
> +
> +int parse_packet_early(Packet *pkt)
> +{
> +    int network_length;
> +    uint8_t *data = pkt->data;
> +    uint16_t l3_proto;
> +    ssize_t l2hdr_len = eth_get_l2_hdr_length(data);
> +
> +    if (pkt->size < ETH_HLEN) {
> +        error_report("pkt->size < ETH_HLEN");
> +        return 1;
> +    }
> +    pkt->network_layer = data + ETH_HLEN;
> +    l3_proto = eth_get_l3_proto(data, l2hdr_len);
> +    if (l3_proto != ETH_P_IP) {
> +        return 1;
> +    }
> +
> +    network_length = pkt->ip->ip_hl * 4;
> +    if (pkt->size < ETH_HLEN + network_length) {
> +        error_report("pkt->size < network_layer + network_length");
> +        return 1;
> +    }
> +    pkt->transport_layer = pkt->network_layer + network_length;
> +    if (!pkt->transport_layer) {

Looks like at least pkt->network_layer can't be zero, so I wonder how 
this condition were met.

> +        error_report("pkt->transport_layer is valid");
> +        return 1;
> +    }
> +
> +    return 0;
> +}
> +
> +Packet *packet_new(const void *data, int size)
> +{
> +    Packet *pkt = g_slice_new(Packet);
> +
> +    pkt->data = g_memdup(data, size);
> +    pkt->size = size;
> +
> +    return pkt;
> +}
> +
> +void packet_destroy(void *opaque, void *user_data)

What's the reason of using void * instead of Packet * directly? And 
user_data were not used in this function.

> +{
> +    Packet *pkt = opaque;
> +
> +    g_free(pkt->data);
> +    g_slice_free(Packet, pkt);
> +}
> +
> +/*
> + * Clear hashtable, stop this hash growing really huge
> + */
> +void connection_hashtable_reset(GHashTable *connection_track_table)
> +{
> +    g_hash_table_remove_all(connection_track_table);
> +}
> diff --git a/net/colo-base.h b/net/colo-base.h
> new file mode 100644
> index 0000000..48835e7
> --- /dev/null
> +++ b/net/colo-base.h
> @@ -0,0 +1,38 @@
> +/*
> + * COarse-grain LOck-stepping Virtual Machines for Non-stop Service (COLO)
> + * (a.k.a. Fault Tolerance or Continuous Replication)
> + *
> + * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD.
> + * Copyright (c) 2016 FUJITSU LIMITED
> + * Copyright (c) 2016 Intel Corporation
> + *
> + * Author: Zhang Chen <zhangchen.fnst@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_BASE_H
> +#define QEMU_COLO_BASE_H
> +
> +#include "slirp/slirp.h"
> +#include "qemu/jhash.h"
> +
> +#define HASHTABLE_MAX_SIZE 16384
> +
> +typedef struct Packet {
> +    void *data;
> +    union {
> +        uint8_t *network_layer;

I think it would be better to use "network_header" here.

> +        struct ip *ip;
> +    };
> +    uint8_t *transport_layer;

And "transport_header" here.

And why not union tcp header here? I'm asking since ip header were 
unioned above.

> +    int size;
> +} Packet;
> +
> +int parse_packet_early(Packet *pkt);
> +void connection_hashtable_reset(GHashTable *connection_track_table);
> +Packet *packet_new(const void *data, int size);
> +void packet_destroy(void *opaque, void *user_data);
> +
> +#endif /* QEMU_COLO_BASE_H */
> diff --git a/net/colo-compare.c b/net/colo-compare.c
> index 0402958..7c52cc8 100644
> --- a/net/colo-compare.c
> +++ b/net/colo-compare.c
> @@ -27,13 +27,38 @@
>   #include "sysemu/char.h"
>   #include "qemu/sockets.h"
>   #include "qapi-visit.h"
> +#include "net/colo-base.h"
> +#include "trace.h"
>   
>   #define TYPE_COLO_COMPARE "colo-compare"
>   #define COLO_COMPARE(obj) \
>       OBJECT_CHECK(CompareState, (obj), TYPE_COLO_COMPARE)
>   
>   #define COMPARE_READ_LEN_MAX NET_BUFSIZE
> +#define MAX_QUEUE_SIZE 1024
>   
> +/*
> +  + CompareState ++
> +  |               |
> +  +---------------+   +---------------+         +---------------+
> +  |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 CompareState {
>       Object parent;
>   
> @@ -46,12 +71,89 @@ typedef struct CompareState {
>       QTAILQ_ENTRY(CompareState) next;
>       SocketReadState pri_rs;
>       SocketReadState sec_rs;
> +
> +    /* hashtable to save connection */
> +    GHashTable *connection_track_table;
> +    /* to save unprocessed_connections */
> +    GQueue unprocessed_connections;
> +    /* proxy current hash size */
> +    uint32_t hashtable_size;
>   } CompareState;
>   
>   typedef struct CompareClass {
>       ObjectClass parent_class;
>   } CompareClass;
>   
> +enum {
> +    PRIMARY_IN = 0,
> +    SECONDARY_IN,
> +};
> +
> +static int compare_chr_send(CharDriverState *out,
> +                            const uint8_t *buf,
> +                            uint32_t size);
> +
> +/*
> + * Return 0 on success, if return -1 means the pkt
> + * is unsupported(arp and ipv6) and will be sent later
> + */
> +static int packet_enqueue(CompareState *s, int mode)
> +{
> +    Packet *pkt = NULL;
> +
> +    if (mode == PRIMARY_IN) {
> +        pkt = packet_new(s->pri_rs.buf, s->pri_rs.packet_len);
> +    } else {
> +        pkt = packet_new(s->sec_rs.buf, s->sec_rs.packet_len);
> +    }
> +
> +    if (parse_packet_early(pkt)) {
> +        packet_destroy(pkt, NULL);
> +        pkt = NULL;
> +        return -1;
> +    }
> +    /* TODO: get connection key from pkt */
> +
> +    /*
> +     * TODO: use connection key get conn from
> +     * connection_track_table
> +     */
> +
> +    /*
> +     * TODO: insert pkt to it's conn->primary_list
> +     * or conn->secondary_list
> +     */
> +
> +    return 0;
> +}
> +
> +static int compare_chr_send(CharDriverState *out,
> +                            const uint8_t *buf,
> +                            uint32_t size)
> +{
> +    int ret = 0;
> +    uint32_t len = htonl(size);
> +
> +    if (!size) {
> +        return 0;
> +    }
> +
> +    ret = qemu_chr_fe_write_all(out, (uint8_t *)&len, sizeof(len));
> +    if (ret != sizeof(len)) {
> +        goto err;
> +    }
> +
> +    ret = qemu_chr_fe_write_all(out, (uint8_t *)buf, size);
> +    if (ret != size) {
> +        goto err;
> +    }
> +
> +    return 0;
> +
> +err:
> +    return ret < 0 ? ret : -EIO;
> +}
> +
>   static char *compare_get_pri_indev(Object *obj, Error **errp)
>   {
>       CompareState *s = COLO_COMPARE(obj);
> @@ -99,12 +201,21 @@ static void compare_set_outdev(Object *obj, const char *value, Error **errp)
>   
>   static void compare_pri_rs_finalize(SocketReadState *pri_rs)
>   {
> -    /* if packet_enqueue pri pkt failed we will send unsupported packet */
> +    CompareState *s = container_of(pri_rs, CompareState, pri_rs);
> +
> +    if (packet_enqueue(s, PRIMARY_IN)) {
> +        trace_colo_compare_main("primary: unsupported packet in");
> +        compare_chr_send(s->chr_out, pri_rs->buf, pri_rs->packet_len);
> +    }
>   }
>   
>   static void compare_sec_rs_finalize(SocketReadState *sec_rs)
>   {
> -    /* if packet_enqueue sec pkt failed we will notify trace */
> +    CompareState *s = container_of(sec_rs, CompareState, sec_rs);
> +
> +    if (packet_enqueue(s, SECONDARY_IN)) {
> +        trace_colo_compare_main("secondary: unsupported packet in");
> +    }
>   }
>   
>   /*
> @@ -156,6 +267,10 @@ static void colo_compare_complete(UserCreatable *uc, Error **errp)
>       net_socket_rs_init(&s->pri_rs, compare_pri_rs_finalize);
>       net_socket_rs_init(&s->sec_rs, compare_sec_rs_finalize);
>   
> +    s->hashtable_size = 0;
> +
> +    /* use g_hash_table_new_full() to new a hashtable */
> +
>       return;
>   }
>   
> diff --git a/trace-events b/trace-events
> index ca7211b..703de1a 100644
> --- a/trace-events
> +++ b/trace-events
> @@ -1916,3 +1916,6 @@ aspeed_vic_update_fiq(int flags) "Raising FIQ: %d"
>   aspeed_vic_update_irq(int flags) "Raising IRQ: %d"
>   aspeed_vic_read(uint64_t offset, unsigned size, uint32_t value) "From 0x%" PRIx64 " of size %u: 0x%" PRIx32
>   aspeed_vic_write(uint64_t offset, unsigned size, uint32_t data) "To 0x%" PRIx64 " of size %u: 0x%" PRIx32
> +
> +# net/colo-compare.c
> +colo_compare_main(const char *chr) ": %s"

  reply	other threads:[~2016-08-02  6:39 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-07-26  1:49 [Qemu-devel] [RFC PATCH V10 0/7] Introduce COLO-compare Zhang Chen
2016-07-26  1:49 ` [Qemu-devel] [RFC PATCH V10 1/7] colo-compare: introduce colo compare initialization Zhang Chen
2016-08-02  6:26   ` Jason Wang
2016-08-03  2:51     ` Zhang Chen
2016-07-26  1:49 ` [Qemu-devel] [RFC PATCH V10 2/7] colo-base: add colo-base to define and handle packet Zhang Chen
2016-08-02  6:38   ` Jason Wang [this message]
2016-08-03  6:34     ` Zhang Chen
2016-07-26  1:49 ` [Qemu-devel] [RFC PATCH V10 3/7] Jhash: add linux kernel jhashtable in qemu Zhang Chen
2016-08-02  6:40   ` Jason Wang
2016-08-03  6:36     ` Zhang Chen
2016-07-26  1:49 ` [Qemu-devel] [RFC PATCH V10 4/7] colo-compare: track connection and enqueue packet Zhang Chen
2016-08-02  7:14   ` Jason Wang
2016-08-04  6:49     ` Zhang Chen
2016-07-26  1:49 ` [Qemu-devel] [RFC PATCH V10 5/7] qemu-char: Add qemu_chr_add_handlers_full() for GMaincontext Zhang Chen
2016-07-26  1:49 ` [Qemu-devel] [RFC PATCH V10 6/7] colo-compare: introduce packet comparison thread Zhang Chen
2016-08-02  7:52   ` Jason Wang
2016-08-05  7:45     ` Zhang Chen
2016-07-26  1:49 ` [Qemu-devel] [RFC PATCH V10 7/7] colo-compare: add TCP, UDP, ICMP packet comparison Zhang Chen
2016-08-02  8:04   ` Jason Wang
2016-08-05  8:55     ` Zhang Chen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ad3be05e-d472-32dd-de24-b84bff059fd6@redhat.com \
    --to=jasowang@redhat.com \
    --cc=dgilbert@redhat.com \
    --cc=eddie.dong@intel.com \
    --cc=lizhijian@cn.fujitsu.com \
    --cc=qemu-devel@nongnu.org \
    --cc=wency@cn.fujitsu.com \
    --cc=zhang.zhanghailiang@huawei.com \
    --cc=zhangchen.fnst@cn.fujitsu.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.