summaryrefslogtreecommitdiff
path: root/net/colo-compare.c
diff options
context:
space:
mode:
authorZhang Chen <zhangchen.fnst@cn.fujitsu.com>2016-09-27 10:22:29 +0800
committerJason Wang <jasowang@redhat.com>2016-09-27 17:54:21 +0800
commitb6540d403d28d9ecbbf0ab76b82fb0fa92dc75ce (patch)
tree694b3a31130ff38dae45973ed030892c2515281c /net/colo-compare.c
parentccf0426c09f0989d9874f7c63aff58376e1d972a (diff)
downloadqemu-b6540d403d28d9ecbbf0ab76b82fb0fa92dc75ce.tar.gz
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.c53
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);