[04/12] sk-queue: Allow to dump a skb sender

Submitted by Kirill Tkhai on April 29, 2016, 2:36 p.m.

Details

Message ID 146194056029.9179.3616211648197688521.stgit@pro
State Rejected
Series "Support for packet's msg_name in receive queue of promiscous DGRAM sockets"
Headers show

Commit Message

Kirill Tkhai April 29, 2016, 2:36 p.m.
Add a possibility to dump a packet sender using a method get_sender,
passed by caller.

If there is the only sender of all pending socket's packets, its inode
is returned as result in (*sender_ino). Otherwise, 0 is there (inode 0
can't exist in real world).

Signed-off-by: Kirill Tkhai <ktkhai@virtuozzo.com>
---
 criu/include/image.h    |    2 ++
 criu/include/sk-queue.h |    4 +++-
 criu/sk-queue.c         |   48 +++++++++++++++++++++++++++++++++++++++++------
 criu/sk-unix.c          |    2 +-
 4 files changed, 48 insertions(+), 8 deletions(-)

Patch hide | download patch | download mbox

diff --git a/criu/include/image.h b/criu/include/image.h
index 305febf..feb359c 100644
--- a/criu/include/image.h
+++ b/criu/include/image.h
@@ -42,6 +42,8 @@ 
 #define USK_SERVICE	(1 << 1)
 #define USK_CALLBACK	(1 << 2)
 #define USK_INHERIT	(1 << 3)
+#define USK_EMPTY_Q	(1 << 4)
+#define USK_NONAME_SND	(1 << 5)
 
 /*
  * VMA_AREA status:
diff --git a/criu/include/sk-queue.h b/criu/include/sk-queue.h
index e0a47af..93498e3 100644
--- a/criu/include/sk-queue.h
+++ b/criu/include/sk-queue.h
@@ -1,8 +1,10 @@ 
 #ifndef __CR_SK_QUEUE_H__
 #define __CR_SK_QUEUE_H__
 
+#define SK_NONAME_SENDER	(~0ULL)
+
 extern struct collect_image_info sk_queues_cinfo;
-extern int dump_sk_queue(int sock_fd, int sock_id);
+extern int dump_sk_queue(int sock_fd, int sock_id, u32 (*get_sender)(const char *, int), u64 *sender_ino);
 extern int restore_sk_queue(int fd, unsigned int peer_id);
 
 #endif /* __CR_SK_QUEUE_H__ */
diff --git a/criu/sk-queue.c b/criu/sk-queue.c
index 50854d7..d0cbf2a 100644
--- a/criu/sk-queue.c
+++ b/criu/sk-queue.c
@@ -59,12 +59,17 @@  struct collect_image_info sk_queues_cinfo = {
 	.collect = collect_one_packet,
 };
 
-int dump_sk_queue(int sock_fd, int sock_id)
+/* Currently known the longest possible sender name of all socket types */
+#define MAX_MSG_NAME_LEN	UNIX_PATH_MAX
+
+int dump_sk_queue(int sock_fd, int sock_id, u32 (*get_sender)(const char *, int), u64 *sender_ino)
 {
 	SkPacketEntry pe = SK_PACKET_ENTRY__INIT;
-	int ret, size, orig_peek_off;
-	void *data;
+	int ret, size, orig_peek_off, first = 1;
+	bool only_sender = true;
+	void *data, *mem;
 	socklen_t tmp;
+	u64 next;
 
 	/*
 	 * Save original peek offset.
@@ -87,16 +92,22 @@  int dump_sk_queue(int sock_fd, int sock_id)
 		return ret;
 	}
 
+	if (get_sender)
+		size += MAX_MSG_NAME_LEN;
+
 	/* Note: 32 bytes will be used by kernel for protocol header. */
 	size -= 32;
 
 	/*
 	 * Allocate data for a stream.
 	 */
-	data = xmalloc(size);
-	if (!data)
+	mem = data = xmalloc(size);
+	if (!mem)
 		return -1;
 
+	if (get_sender)
+		data += MAX_MSG_NAME_LEN;
+
 	/*
 	 * Enable peek offset incrementation.
 	 */
@@ -118,6 +129,11 @@  int dump_sk_queue(int sock_fd, int sock_id)
 			.msg_iovlen	= 1,
 		};
 
+		if (get_sender) {
+			msg.msg_name	= mem;
+			msg.msg_namelen	= MAX_MSG_NAME_LEN;
+		}
+
 		ret = pe.length = recvmsg(sock_fd, &msg, MSG_DONTWAIT | MSG_PEEK);
 		if (!ret)
 			/*
@@ -141,6 +157,25 @@  int dump_sk_queue(int sock_fd, int sock_id)
 			goto err_set_sock;
 		}
 
+		if (get_sender) {
+			next = get_sender(msg.msg_name, msg.msg_namelen);
+			if (next) {
+				pe.has_sender_ino = true;
+				pe.sender_ino = next;
+			} else
+				next = SK_NONAME_SENDER;
+
+			if (only_sender) {
+				if (first)
+					*sender_ino = next;
+				else if (*sender_ino != next)
+					only_sender = false;
+			}
+
+			if (!only_sender)
+				*sender_ino = 0;
+		}
+
 		ret = pb_write_one(img_from_set(glob_imgset, CR_FD_SK_QUEUES), &pe, PB_SK_QUEUES);
 		if (ret < 0) {
 			ret = -EIO;
@@ -152,6 +187,7 @@  int dump_sk_queue(int sock_fd, int sock_id)
 			ret = -EIO;
 			goto err_set_sock;
 		}
+		first = 0;
 	}
 	ret = 0;
 
@@ -164,7 +200,7 @@  int dump_sk_queue(int sock_fd, int sock_id)
 		ret = -1;
 	}
 err_brk:
-	xfree(data);
+	xfree(mem);
 	return ret;
 }
 
diff --git a/criu/sk-unix.c b/criu/sk-unix.c
index d1f4c33..e519d01 100644
--- a/criu/sk-unix.c
+++ b/criu/sk-unix.c
@@ -445,7 +445,7 @@  static int dump_one_unix_fd(int lfd, u32 id, const struct fd_parms *p)
 	 */
 	if (sk->rqlen != 0 && !(sk->type == SOCK_STREAM &&
 				sk->state == TCP_LISTEN))
-		if (dump_sk_queue(lfd, id))
+		if (dump_sk_queue(lfd, id, NULL, NULL))
 			goto err;
 
 	pr_info("Dumping unix socket at %d\n", p->fd);