[v3,07/15] sk-queue: Allow to dump a skb sender

Submitted by Kirill Tkhai on June 1, 2016, 3:12 p.m.

Details

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

Commit Message

Kirill Tkhai June 1, 2016, 3:12 p.m.
Add a possibility to dump a packet sender using a method get_sender,
passed by caller.

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

Patch hide | download patch | download mbox

diff --git a/criu/include/sk-queue.h b/criu/include/sk-queue.h
index e0a47af..5fd2e01 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, u64 (*get_sender)(const char *, int));
 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..ded9ca9 100644
--- a/criu/sk-queue.c
+++ b/criu/sk-queue.c
@@ -59,12 +59,15 @@  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 thru all socket types */
+#define MAX_MSG_NAME_LEN	(sizeof (struct sockaddr_un))
+
+int dump_sk_queue(int sock_fd, int sock_id, u64 (*get_sender)(const char *, int))
 {
-	SkPacketEntry pe = SK_PACKET_ENTRY__INIT;
 	int ret, size, orig_peek_off;
-	void *data;
+	void *data, *mem;
 	socklen_t tmp;
+	u64 next;
 
 	/*
 	 * Save original peek offset.
@@ -87,16 +90,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.
 	 */
@@ -106,9 +115,8 @@  int dump_sk_queue(int sock_fd, int sock_id)
 		goto err_brk;
 	}
 
-	pe.id_for = sock_id;
-
 	while (1) {
+		SkPacketEntry pe = SK_PACKET_ENTRY__INIT;
 		struct iovec iov = {
 			.iov_base	= data,
 			.iov_len	= size,
@@ -118,6 +126,12 @@  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;
+		}
+
+		pe.id_for = sock_id;
 		ret = pe.length = recvmsg(sock_fd, &msg, MSG_DONTWAIT | MSG_PEEK);
 		if (!ret)
 			/*
@@ -141,6 +155,18 @@  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) {
+				pr_err("Can't find sender for skb\n");
+				ret = -ENODEV;
+				goto err_set_sock;
+			} else if (next != SK_NONAME_SENDER) {
+				pe.has_sender_ino = true;
+				pe.sender_ino = next;
+			}
+		}
+
 		ret = pb_write_one(img_from_set(glob_imgset, CR_FD_SK_QUEUES), &pe, PB_SK_QUEUES);
 		if (ret < 0) {
 			ret = -EIO;
@@ -164,7 +190,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 58aba82..9db911b 100644
--- a/criu/sk-unix.c
+++ b/criu/sk-unix.c
@@ -52,6 +52,7 @@ 
 #define USK_SERVICE	(1 << 1)
 #define USK_CALLBACK	(1 << 2)
 #define USK_INHERIT	(1 << 3)
+#define USK_EMPTY_Q	(1 << 4)
 
 typedef struct {
 	char			*dir;
@@ -462,7 +463,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))
 			goto err;
 
 	pr_info("Dumping unix socket at %d\n", p->fd);