[CRIU] [PATCH v2 07/15] sk-queue: Allow to dump a skb sender
Kirill Tkhai
ktkhai at virtuozzo.com
Fri May 27 06:06:48 PDT 2016
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 at virtuozzo.com>
---
criu/include/sk-queue.h | 4 +++-
criu/sk-queue.c | 53 +++++++++++++++++++++++++++++++++++++++--------
criu/sk-unix.c | 4 +++-
3 files changed, 50 insertions(+), 11 deletions(-)
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..fa3407b 100644
--- a/criu/sk-queue.c
+++ b/criu/sk-queue.c
@@ -59,12 +59,16 @@ 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, 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 +91,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 +116,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 +127,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 +156,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 +186,7 @@ int dump_sk_queue(int sock_fd, int sock_id)
ret = -EIO;
goto err_set_sock;
}
+ first = 0;
}
ret = 0;
@@ -164,7 +199,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..d2342ff 100644
--- a/criu/sk-unix.c
+++ b/criu/sk-unix.c
@@ -52,6 +52,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)
typedef struct {
char *dir;
@@ -462,7 +464,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);
More information about the CRIU
mailing list