From d917ff15bbdc0427203455e56e997841cc41f035 Mon Sep 17 00:00:00 2001 From: Andrey Vagin Date: Thu, 14 Nov 2013 01:01:56 +0400 Subject: [PATCH] tcp: save the amount of unsent data in the socket send queue TCP send queue contains two types of data: * unacknowledged data, which have been sent out * data, which have not been sent Currently only the size of all data is save, but it's not enough for proper restoring of TCP connections. Signed-off-by: Andrey Vagin Signed-off-by: Pavel Emelyanov --- cr-show.c | 2 +- include/sk-inet.h | 3 ++- protobuf/tcp-stream.proto | 4 +++- sk-tcp.c | 9 +++++++++ 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/cr-show.c b/cr-show.c index 6736ae6ce..21695f9d6 100644 --- a/cr-show.c +++ b/cr-show.c @@ -320,7 +320,7 @@ static struct show_image_info show_infos[] = { SHOW_PLAIN(RLIMIT), SHOW_PLAIN(TUNFILE), - { TCP_STREAM_MAGIC, PB_TCP_STREAM, true, show_tcp_stream, "1:%u 2:%u 3:%u 4:%u", }, + { TCP_STREAM_MAGIC, PB_TCP_STREAM, true, show_tcp_stream, "1:%u 2:%u 3:%u 4:%u 12:%u", }, { STATS_MAGIC, PB_STATS, true, NULL, "1.1:%u 1.2:%u 1.3:%u 1.4:%u 1.5:%Lu 1.6:%Lu 1.7:%Lu", }, { FDINFO_MAGIC, PB_FDINFO, false, NULL, "flags:%#o fd:%d", }, { UNIXSK_MAGIC, PB_UNIX_SK, false, NULL, "1:%#x 2:%#x 3:%d 4:%d 5:%d 6:%d 7:%d 8:%#x 11:S", }, diff --git a/include/sk-inet.h b/include/sk-inet.h index a3dff732e..8e22d151b 100644 --- a/include/sk-inet.h +++ b/include/sk-inet.h @@ -24,7 +24,8 @@ struct inet_sk_desc { unsigned int dst_port; unsigned int state; unsigned int rqlen; - unsigned int wqlen; + unsigned int wqlen; /* sent + unsent data */ + unsigned int uwqlen; /* unsent data */ unsigned int src_addr[4]; unsigned int dst_addr[4]; unsigned short shutdown; diff --git a/protobuf/tcp-stream.proto b/protobuf/tcp-stream.proto index d9d4af61b..a2db0265c 100644 --- a/protobuf/tcp-stream.proto +++ b/protobuf/tcp-stream.proto @@ -1,7 +1,7 @@ message tcp_stream_entry { required uint32 inq_len = 1; required uint32 inq_seq = 2; - required uint32 outq_len = 3; + required uint32 outq_len = 3; /* unsent and sent data in the send queue*/ required uint32 outq_seq = 4; required uint32 opt_mask = 5; /* TCPI_OPT_ bits */ @@ -12,4 +12,6 @@ message tcp_stream_entry { optional bool cork = 10; optional bool nodelay = 11; + + optional uint32 unsq_len = 12; /* unsent data in the send queue */ } diff --git a/sk-tcp.c b/sk-tcp.c index 51b2dab49..0db83a3d9 100644 --- a/sk-tcp.c +++ b/sk-tcp.c @@ -94,6 +94,13 @@ static int refresh_inet_sk(struct inet_sk_desc *sk) sk->wqlen = size; + if (ioctl(sk->rfd, SIOCOUTQNSD, &size) == -1) { + pr_perror("Unable to get size of unsent data"); + return -1; + } + + sk->uwqlen = size; + if (ioctl(sk->rfd, SIOCINQ, &size) == -1) { pr_perror("Unable to get size of recv queue"); return -1; @@ -324,6 +331,8 @@ static int dump_tcp_conn_state(struct inet_sk_desc *sk) pr_info("Reading outq for socket\n"); tse.outq_len = sk->wqlen; + tse.unsq_len = sk->uwqlen; + tse.has_unsq_len = true; ret = tcp_stream_get_queue(sk->rfd, TCP_SEND_QUEUE, &tse.outq_seq, tse.outq_len, &out_buf); if (ret < 0)