diff options
author | Zhang Chen <zhangchen.fnst@cn.fujitsu.com> | 2016-09-27 10:22:29 +0800 |
---|---|---|
committer | Jason Wang <jasowang@redhat.com> | 2016-09-27 17:54:21 +0800 |
commit | b6540d403d28d9ecbbf0ab76b82fb0fa92dc75ce (patch) | |
tree | 694b3a31130ff38dae45973ed030892c2515281c /net/colo-compare.c | |
parent | ccf0426c09f0989d9874f7c63aff58376e1d972a (diff) | |
download | qemu-b6540d403d28d9ecbbf0ab76b82fb0fa92dc75ce.tar.gz qemu-b6540d403d28d9ecbbf0ab76b82fb0fa92dc75ce.tar.bz2 qemu-b6540d403d28d9ecbbf0ab76b82fb0fa92dc75ce.zip |
colo-compare: track connection and enqueue packet
In this patch we use kernel jhash table to track
connection, and then enqueue net packet like this:
+ 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 +
+--------+ +--------+ +--------+ +--------+
We use conn_list to record connection info.
When we want to enqueue a packet, firstly get the
connection from connection_track_table. then push
the packet to g_queue(pri/sec) in it's own conn.
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>
Signed-off-by: Jason Wang <jasowang@redhat.com>
Diffstat (limited to 'net/colo-compare.c')
-rw-r--r-- | net/colo-compare.c | 53 |
1 files changed, 43 insertions, 10 deletions
diff --git a/net/colo-compare.c b/net/colo-compare.c index cea9b27dd4..bcc1beb610 100644 --- a/net/colo-compare.c +++ b/net/colo-compare.c @@ -33,6 +33,8 @@ #define COLO_COMPARE(obj) \ OBJECT_CHECK(CompareState, (obj), TYPE_COLO_COMPARE) +#define MAX_QUEUE_SIZE 1024 + /* + CompareState ++ | | @@ -67,6 +69,11 @@ typedef struct CompareState { SocketReadState pri_rs; SocketReadState sec_rs; + /* connection list: the connections belonged to this NIC could be found + * in this list. + * element type: Connection + */ + GQueue conn_list; /* hashtable to save connection */ GHashTable *connection_track_table; } CompareState; @@ -94,7 +101,9 @@ static int compare_chr_send(CharDriverState *out, */ static int packet_enqueue(CompareState *s, int mode) { + ConnectionKey key; Packet *pkt = NULL; + Connection *conn; if (mode == PRIMARY_IN) { pkt = packet_new(s->pri_rs.buf, s->pri_rs.packet_len); @@ -107,17 +116,34 @@ static int packet_enqueue(CompareState *s, int mode) pkt = NULL; return -1; } - /* TODO: get connection key from pkt */ + fill_connection_key(pkt, &key); - /* - * TODO: use connection key get conn from - * connection_track_table - */ + conn = connection_get(s->connection_track_table, + &key, + &s->conn_list); - /* - * TODO: insert pkt to it's conn->primary_list - * or conn->secondary_list - */ + if (!conn->processing) { + g_queue_push_tail(&s->conn_list, conn); + conn->processing = true; + } + + if (mode == PRIMARY_IN) { + if (g_queue_get_length(&conn->primary_list) <= + MAX_QUEUE_SIZE) { + g_queue_push_tail(&conn->primary_list, pkt); + } else { + error_report("colo compare primary queue size too big," + "drop packet"); + } + } else { + if (g_queue_get_length(&conn->secondary_list) <= + MAX_QUEUE_SIZE) { + g_queue_push_tail(&conn->secondary_list, pkt); + } else { + error_report("colo compare secondary queue size too big," + "drop packet"); + } + } return 0; } @@ -308,7 +334,12 @@ 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); - /* use g_hash_table_new_full() to new a hashtable */ + g_queue_init(&s->conn_list); + + s->connection_track_table = g_hash_table_new_full(connection_key_hash, + connection_key_equal, + g_free, + connection_destroy); return; } @@ -349,6 +380,8 @@ static void colo_compare_finalize(Object *obj) qemu_chr_fe_release(s->chr_out); } + g_queue_free(&s->conn_list); + g_free(s->pri_indev); g_free(s->sec_indev); g_free(s->outdev); |