[CRIU] [PATCH 3/5] netlink: request flags for netlink sockets

Andrey Vagin avagin at openvz.org
Mon Jun 13 16:35:33 PDT 2016


From: Andrew Vagin <avagin at virtuozzo.com>

We need to know where a socket has a running callback or not.
If it has, we can't dump its received queue, because it
contains only a part of data, other part will be generated by the callback.

Signed-off-by: Andrew Vagin <avagin at virtuozzo.com>
---
 criu/include/netlink_diag.h |  9 +++++++++
 criu/include/sockets.h      |  8 ++++++++
 criu/sk-netlink.c           | 16 +++++++++++++++-
 criu/sockets.c              |  2 +-
 4 files changed, 33 insertions(+), 2 deletions(-)

diff --git a/criu/include/netlink_diag.h b/criu/include/netlink_diag.h
index 14ca403..626f863 100644
--- a/criu/include/netlink_diag.h
+++ b/criu/include/netlink_diag.h
@@ -28,6 +28,9 @@ struct netlink_diag_msg {
 enum {
 	NETLINK_DIAG_MEMINFO,
 	NETLINK_DIAG_GROUPS,
+	NETLINK_DIAG_RX_RING,
+	NETLINK_DIAG_TX_RING,
+	NETLINK_DIAG_FLAGS,
 
 	__NETLINK_DIAG_MAX,
 };
@@ -39,4 +42,10 @@ enum {
 #define NDIAG_SHOW_MEMINFO	0x00000001 /* show memory info of a socket */
 #define NDIAG_SHOW_GROUPS	0x00000002 /* show groups of a netlink socket */
 
+
+
+#define NDIAG_SHOW_FLAGS	0x00000008 /* show flags of a netlink socket */
+
+#define NDIAG_FLAG_CB_RUNNING		0x00000001
+
 #endif /* __CR_NETLINK_DIAG_H__ */
diff --git a/criu/include/sockets.h b/criu/include/sockets.h
index b3bacb7..cabd019 100644
--- a/criu/include/sockets.h
+++ b/criu/include/sockets.h
@@ -84,4 +84,12 @@ static inline int sk_decode_shutdown(int val)
 #define NETLINK_SOCK_DIAG NETLINK_INET_DIAG
 #endif
 
+#ifndef NETLINK_REPAIR
+#define NETLINK_REPAIR                  11
+#endif
+
+#ifndef SOL_NETLINK
+#define SOL_NETLINK			270
+#endif
+
 #endif /* __CR_SOCKETS_H__ */
diff --git a/criu/sk-netlink.c b/criu/sk-netlink.c
index dc5c4a1..8268dba 100644
--- a/criu/sk-netlink.c
+++ b/criu/sk-netlink.c
@@ -12,6 +12,7 @@
 #include "images/sk-netlink.pb-c.h"
 #include "netlink_diag.h"
 #include "libnetlink.h"
+#include "sk-queue.h"
 
 struct netlink_sk_desc {
 	struct socket_desc	sd;
@@ -20,6 +21,7 @@ struct netlink_sk_desc {
 	u32			gsize;
 	u32                     dst_portid;
 	u32			dst_group;
+	u32			nl_flags;
 	u8			state;
 	u8			protocol;
 };
@@ -61,6 +63,19 @@ int netlink_receive_one(struct nlmsghdr *hdr, void *arg)
 		sd->gsize = 0;
 	}
 
+	/*
+	 * It's imossible to dump a socket queue if a callback is running now.
+	 * We have to set NDIAG_FLAG_CB_RUNNING, if a kernel doesn't report
+	 * real flags.
+	 */
+	sd->nl_flags = NDIAG_FLAG_CB_RUNNING;
+
+	if (tb[NETLINK_DIAG_FLAGS]) {
+		u64 flags = nla_get_u32(tb[NETLINK_DIAG_FLAGS]);
+
+		sd->nl_flags = flags;
+	}
+
 	return sk_collect_one(m->ndiag_ino, PF_NETLINK, &sd->sd);
 }
 
@@ -108,7 +123,6 @@ static int dump_one_netlink_fd(int lfd, u32 id, const struct fd_parms *p)
 			ne.n_groups -= 1;
 
 		if (ne.n_groups > 1) {
-			pr_err("%d %x\n", sk->gsize, sk->groups[1]);
 			pr_err("The netlink socket 0x%x has more than 32 groups\n", ne.ino);
 			return -1;
 		}
diff --git a/criu/sockets.c b/criu/sockets.c
index d8d09aa..b20c140 100644
--- a/criu/sockets.c
+++ b/criu/sockets.c
@@ -706,7 +706,7 @@ int collect_sockets(struct ns_id *ns)
 
 	req.r.n.sdiag_family	= AF_NETLINK;
 	req.r.n.sdiag_protocol	= NDIAG_PROTO_ALL;
-	req.r.n.ndiag_show	= NDIAG_SHOW_GROUPS;
+	req.r.n.ndiag_show	= NDIAG_SHOW_GROUPS | NDIAG_SHOW_FLAGS;
 	tmp = do_collect_req(nl, &req, sizeof(req), netlink_receive_one, NULL);
 	if (tmp) {
 		pr_warn("The current kernel doesn't support netlink_diag\n");
-- 
2.7.4



More information about the CRIU mailing list