[CRIU] [PATCH 1/2] tcp: save the amount of unsent data in the socket send queue

Andrey Vagin avagin at openvz.org
Wed Nov 13 13:01:56 PST 2013


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 <avagin at openvz.org>
---
 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 6736ae6..21695f9 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 a3dff73..8e22d15 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 d9d4af6..a2db026 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 51b2dab..0db83a3 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)
-- 
1.8.3.1



More information about the CRIU mailing list