[v5,03/11] sk-queue: Allow to dump a skb sender

Submitted by Kirill Tkhai on June 16, 2016, 1:53 p.m.

Details

Message ID 146608519996.15781.12779041331445732052.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 16, 2016, 1:53 p.m.
Add a possibility to dump a packet sender using a method get_sender,
passed by caller.

v5: Delete USK_EMPTY_Q flag

Signed-off-by: Kirill Tkhai <ktkhai@virtuozzo.com>
---
 criu/include/sk-queue.h |    4 +++-
 criu/sk-queue.c         |   42 ++++++++++++++++++++++++++++++++++--------
 criu/sk-unix.c          |    2 +-
 3 files changed, 38 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 c6381c6..bbc8bf1 100644
--- a/criu/sk-unix.c
+++ b/criu/sk-unix.c
@@ -462,7 +462,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);

Comments

Pavel Emelianov June 28, 2016, 12:21 p.m.
On 06/16/2016 04:53 PM, Kirill Tkhai wrote:
> Add a possibility to dump a packet sender using a method get_sender,
> passed by caller.
> 
> v5: Delete USK_EMPTY_Q flag
> 
> Signed-off-by: Kirill Tkhai <ktkhai@virtuozzo.com>
> ---
>  criu/include/sk-queue.h |    4 +++-
>  criu/sk-queue.c         |   42 ++++++++++++++++++++++++++++++++++--------
>  criu/sk-unix.c          |    2 +-
>  3 files changed, 38 insertions(+), 10 deletions(-)
> 
> 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))

Any reason why this is a function pointer, rather than bool dump_sender_ino ?

>  {
> -	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.
Kirill Tkhai June 28, 2016, 1:04 p.m.
On 28.06.2016 15:21, Pavel Emelyanov wrote:
> On 06/16/2016 04:53 PM, Kirill Tkhai wrote:
>> Add a possibility to dump a packet sender using a method get_sender,
>> passed by caller.
>>
>> v5: Delete USK_EMPTY_Q flag
>>
>> Signed-off-by: Kirill Tkhai <ktkhai@virtuozzo.com>
>> ---
>>  criu/include/sk-queue.h |    4 +++-
>>  criu/sk-queue.c         |   42 ++++++++++++++++++++++++++++++++++--------
>>  criu/sk-unix.c          |    2 +-
>>  3 files changed, 38 insertions(+), 10 deletions(-)
>>
>> 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))
> 
> Any reason why this is a function pointer, rather than bool dump_sender_ino ?

Just to do not export unix_sk_entry etc to sk-queue. I can get rid of that.
Are you OK with export?
 
>>  {
>> -	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.
>
Pavel Emelianov July 4, 2016, 5:27 p.m.
On 06/28/2016 04:04 PM, Kirill Tkhai wrote:
> 
> 
> On 28.06.2016 15:21, Pavel Emelyanov wrote:
>> On 06/16/2016 04:53 PM, Kirill Tkhai wrote:
>>> Add a possibility to dump a packet sender using a method get_sender,
>>> passed by caller.
>>>
>>> v5: Delete USK_EMPTY_Q flag
>>>
>>> Signed-off-by: Kirill Tkhai <ktkhai@virtuozzo.com>
>>> ---
>>>  criu/include/sk-queue.h |    4 +++-
>>>  criu/sk-queue.c         |   42 ++++++++++++++++++++++++++++++++++--------
>>>  criu/sk-unix.c          |    2 +-
>>>  3 files changed, 38 insertions(+), 10 deletions(-)
>>>
>>> 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))
>>
>> Any reason why this is a function pointer, rather than bool dump_sender_ino ?
> 
> Just to do not export unix_sk_entry etc to sk-queue. I can get rid of that.
> Are you OK with export?

Yup.

>>>  {
>>> -	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.
>>
> .
>