[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