[03/10] netlink: ns_id as a generic argument to do_collect_req's receive_callback

Submitted by Andrei Vagin on Oct. 28, 2016, 5:41 p.m.

Details

Message ID 1477676516-28669-4-git-send-email-avagin@openvz.org
State Superseded
Series "Dump and restore nested network namespaces"
Headers show

Commit Message

Andrei Vagin Oct. 28, 2016, 5:41 p.m.
From: Andrei Vagin <avagin@virtuozzo.com>

ns_id will be used to collect sockets and may be other per-netns
resources

Signed-off-by: Andrei Vagin <avagin@virtuozzo.com>
---
 criu/include/libnetlink.h |  5 +++--
 criu/include/sk-packet.h  |  2 +-
 criu/include/sockets.h    |  6 +++---
 criu/libnetlink.c         | 13 +++++++------
 criu/net.c                | 16 ++++++++--------
 criu/sk-inet.c            |  2 +-
 criu/sk-netlink.c         |  2 +-
 criu/sk-packet.c          |  2 +-
 criu/sk-unix.c            |  6 +++---
 criu/sockets.c            | 31 ++++++++++++++++---------------
 10 files changed, 44 insertions(+), 41 deletions(-)

Patch hide | download patch | download mbox

diff --git a/criu/include/libnetlink.h b/criu/include/libnetlink.h
index 0549ef9..b2980ff 100644
--- a/criu/include/libnetlink.h
+++ b/criu/include/libnetlink.h
@@ -3,9 +3,10 @@ 
 
 #define CR_NLMSG_SEQ		24680	/* arbitrary chosen */
 
+struct ns_id;
 extern int do_rtnl_req(int nl, void *req, int size,
-		int (*receive_callback)(struct nlmsghdr *h, void *),
-		int (*error_callback)(int err, void *), void *);
+		int (*receive_callback)(struct nlmsghdr *h, struct ns_id *ns, void *),
+		int (*error_callback)(int err, void *), struct ns_id *ns, void *);
 
 extern int addattr_l(struct nlmsghdr *n, int maxlen, int type,
 		const void *data, int alen);
diff --git a/criu/include/sk-packet.h b/criu/include/sk-packet.h
index fda471f..a0738ae 100644
--- a/criu/include/sk-packet.h
+++ b/criu/include/sk-packet.h
@@ -15,7 +15,7 @@  extern int dump_socket_map(struct vma_area *vma);
 extern int collect_socket_map(struct vma_area *);
 
 struct nlmsghdr;
-extern int packet_receive_one(struct nlmsghdr *h, void *arg);
+extern int packet_receive_one(struct nlmsghdr *h, struct ns_id *ns, void *arg);
 
 #ifndef PACKET_VNET_HDR
 #define PACKET_VNET_HDR 15
diff --git a/criu/include/sockets.h b/criu/include/sockets.h
index 0de527c..18e20d1 100644
--- a/criu/include/sockets.h
+++ b/criu/include/sockets.h
@@ -47,9 +47,9 @@  extern const struct fdtype_ops inet6_dump_ops;
 extern const struct fdtype_ops netlink_dump_ops;
 extern const struct fdtype_ops packet_dump_ops;
 
-extern int inet_collect_one(struct nlmsghdr *h, int family, int type);
-extern int unix_receive_one(struct nlmsghdr *h, void *);
-extern int netlink_receive_one(struct nlmsghdr *hdr, void *arg);
+extern int inet_collect_one(struct nlmsghdr *h, int family, int type, struct ns_id *ns);
+extern int unix_receive_one(struct nlmsghdr *h, struct ns_id *ns, void *);
+extern int netlink_receive_one(struct nlmsghdr *hdr, struct ns_id *ns, void *arg);
 
 extern int unix_sk_id_add(unsigned int ino);
 extern int unix_sk_ids_parse(char *optarg);
diff --git a/criu/libnetlink.c b/criu/libnetlink.c
index 5f69a3d..f585f09 100644
--- a/criu/libnetlink.c
+++ b/criu/libnetlink.c
@@ -10,8 +10,9 @@ 
 #include "libnetlink.h"
 #include "util.h"
 
-static int nlmsg_receive(char *buf, int len, int (*cb)(struct nlmsghdr *, void *), 
-		int (*err_cb)(int, void *), void *arg)
+static int nlmsg_receive(char *buf, int len,
+		int (*cb)(struct nlmsghdr *, struct ns_id *ns, void *),
+		int (*err_cb)(int, void *), struct ns_id *ns, void *arg)
 {
 	struct nlmsghdr *hdr;
 
@@ -42,7 +43,7 @@  static int nlmsg_receive(char *buf, int len, int (*cb)(struct nlmsghdr *, void *
 
 			return err_cb(err->error, arg);
 		}
-		if (cb(hdr, arg))
+		if (cb(hdr, ns, arg))
 			return -1;
 	}
 
@@ -56,8 +57,8 @@  static int rtnl_return_err(int err, void *arg)
 }
 
 int do_rtnl_req(int nl, void *req, int size,
-		int (*receive_callback)(struct nlmsghdr *h, void *),
-		int (*error_callback)(int err, void *), void *arg)
+		int (*receive_callback)(struct nlmsghdr *h, struct ns_id *ns, void *),
+		int (*error_callback)(int err, void *), struct ns_id *ns, void *arg)
 {
 	struct msghdr msg;
 	struct sockaddr_nl nladdr;
@@ -116,7 +117,7 @@  int do_rtnl_req(int nl, void *req, int size,
 			goto err;
 		}
 
-		err = nlmsg_receive(buf, err, receive_callback, error_callback, arg);
+		err = nlmsg_receive(buf, err, receive_callback, error_callback, ns, arg);
 		if (err < 0)
 			goto err;
 		if (err == 0)
diff --git a/criu/net.c b/criu/net.c
index f563f00..88ba85f 100644
--- a/criu/net.c
+++ b/criu/net.c
@@ -629,7 +629,7 @@  static int dump_one_gre(struct ifinfomsg *ifi, char *kind,
 	return dump_unknown_device(ifi, kind, tb, fds);
 }
 
-static int dump_one_link(struct nlmsghdr *hdr, void *arg)
+static int dump_one_link(struct nlmsghdr *hdr, struct ns_id *ns, void *arg)
 {
 	struct cr_imgset *fds = arg;
 	struct ifinfomsg *ifi;
@@ -676,7 +676,7 @@  unk:
 	return ret;
 }
 
-static int dump_one_nf(struct nlmsghdr *hdr, void *arg)
+static int dump_one_nf(struct nlmsghdr *hdr, struct ns_id *ns, void *arg)
 {
 	struct cr_img *img = arg;
 
@@ -789,7 +789,7 @@  static int restore_nf_ct(int pid, int type)
 				goto out;
 
 		nlh->nlmsg_flags = NLM_F_REQUEST|NLM_F_ACK|NLM_F_CREATE;
-		ret = do_rtnl_req(sk, nlh, nlh->nlmsg_len, NULL, NULL, NULL);
+		ret = do_rtnl_req(sk, nlh, nlh->nlmsg_len, NULL, NULL, NULL, NULL);
 		if (ret)
 			goto out;
 	}
@@ -838,7 +838,7 @@  static int dump_nf_ct(struct cr_imgset *fds, int type)
 
 	img = img_from_set(fds, type);
 
-	ret = do_rtnl_req(sk, &req, sizeof(req), dump_one_nf, NULL, img);
+	ret = do_rtnl_req(sk, &req, sizeof(req), dump_one_nf, NULL, NULL, img);
 	close(sk);
 out:
 	return ret;
@@ -869,13 +869,13 @@  static int dump_links(struct cr_imgset *fds)
 	req.nlh.nlmsg_seq = CR_NLMSG_SEQ;
 	req.g.rtgen_family = AF_PACKET;
 
-	ret = do_rtnl_req(sk, &req, sizeof(req), dump_one_link, NULL, fds);
+	ret = do_rtnl_req(sk, &req, sizeof(req), dump_one_link, NULL, NULL, fds);
 	close(sk);
 out:
 	return ret;
 }
 
-static int restore_link_cb(struct nlmsghdr *hdr, void *arg)
+static int restore_link_cb(struct nlmsghdr *hdr, struct ns_id *ns, void *arg)
 {
 	pr_info("Got response on SETLINK =)\n");
 	return 0;
@@ -959,7 +959,7 @@  static int do_rtm_link_req(int msg_type, NetDeviceEntry *nde, int nlsk,
 	if (populate_newlink_req(&req, msg_type, nde, link_info, extras) < 0)
 		return -1;
 
-	return do_rtnl_req(nlsk, &req, req.h.nlmsg_len, restore_link_cb, NULL, NULL);
+	return do_rtnl_req(nlsk, &req, req.h.nlmsg_len, restore_link_cb, NULL, NULL, NULL);
 }
 
 int restore_link_parms(NetDeviceEntry *nde, int nlsk)
@@ -1113,7 +1113,7 @@  static int userns_restore_one_link(void *arg, int fd, pid_t pid)
 
 	addattr_l(&req->h, sizeof(*req), IFLA_NET_NS_FD, &fd, sizeof(fd));
 
-	ret = do_rtnl_req(nlsk, req, req->h.nlmsg_len, restore_link_cb, NULL, NULL);
+	ret = do_rtnl_req(nlsk, req, req->h.nlmsg_len, restore_link_cb, NULL, NULL, NULL);
 	close(nlsk);
 
 out:
diff --git a/criu/sk-inet.c b/criu/sk-inet.c
index 924cf8c..87e147e 100644
--- a/criu/sk-inet.c
+++ b/criu/sk-inet.c
@@ -409,7 +409,7 @@  const struct fdtype_ops inet6_dump_ops = {
 	.dump		= dump_one_inet6_fd,
 };
 
-int inet_collect_one(struct nlmsghdr *h, int family, int type)
+int inet_collect_one(struct nlmsghdr *h, int family, int type, struct ns_id *ns)
 {
 	struct inet_sk_desc *d;
 	struct inet_diag_msg *m = NLMSG_DATA(h);
diff --git a/criu/sk-netlink.c b/criu/sk-netlink.c
index dc5c4a1..540273b 100644
--- a/criu/sk-netlink.c
+++ b/criu/sk-netlink.c
@@ -24,7 +24,7 @@  struct netlink_sk_desc {
 	u8			protocol;
 };
 
-int netlink_receive_one(struct nlmsghdr *hdr, void *arg)
+int netlink_receive_one(struct nlmsghdr *hdr, struct ns_id *ns, void *arg)
 {
 	struct nlattr *tb[NETLINK_DIAG_MAX+1];
 	struct netlink_diag_msg *m;
diff --git a/criu/sk-packet.c b/criu/sk-packet.c
index 6e0ad2d..d5a17dc 100644
--- a/criu/sk-packet.c
+++ b/criu/sk-packet.c
@@ -240,7 +240,7 @@  static int packet_save_mreqs(struct packet_sock_desc *sd, struct nlattr *mc)
 	return 0;
 }
 
-int packet_receive_one(struct nlmsghdr *hdr, void *arg)
+int packet_receive_one(struct nlmsghdr *hdr, struct ns_id *ns, void *arg)
 {
 	struct packet_diag_msg *m;
 	struct nlattr *tb[PACKET_DIAG_MAX + 1];
diff --git a/criu/sk-unix.c b/criu/sk-unix.c
index 6a1a532..74e984d 100644
--- a/criu/sk-unix.c
+++ b/criu/sk-unix.c
@@ -583,7 +583,7 @@  skip:
 }
 
 static int unix_collect_one(const struct unix_diag_msg *m,
-			    struct nlattr **tb)
+			    struct nlattr **tb, struct ns_id *ns)
 {
 	struct unix_sk_desc *d;
 	int ret = 0;
@@ -674,14 +674,14 @@  skip:
 	return ret;
 }
 
-int unix_receive_one(struct nlmsghdr *h, void *arg)
+int unix_receive_one(struct nlmsghdr *h, struct ns_id *ns, void *arg)
 {
 	struct unix_diag_msg *m = NLMSG_DATA(h);
 	struct nlattr *tb[UNIX_DIAG_MAX+1];
 
 	nlmsg_parse(h, sizeof(struct unix_diag_msg), tb, UNIX_DIAG_MAX, NULL);
 
-	return unix_collect_one(m, tb);
+	return unix_collect_one(m, tb, ns);
 }
 
 static int dump_external_sockets(struct unix_sk_desc *peer)
diff --git a/criu/sockets.c b/criu/sockets.c
index b5c03fd..fbed5fe 100644
--- a/criu/sockets.c
+++ b/criu/sockets.c
@@ -116,7 +116,7 @@  bool socket_test_collect_bit(unsigned int family, unsigned int proto)
 	return test_bit(nr, socket_cl_bits) != 0;
 }
 
-static int probe_recv_one(struct nlmsghdr *h, void *arg)
+static int probe_recv_one(struct nlmsghdr *h, struct ns_id *ns, void *arg)
 {
 	pr_err("PROBE RECEIVED\n");
 	return -1;
@@ -135,7 +135,7 @@  static int probe_err(int err, void *arg)
 
 static inline void probe_diag(int nl, struct sock_diag_req *req, int expected_err)
 {
-	do_rtnl_req(nl, req, req->hdr.nlmsg_len, probe_recv_one, probe_err, &expected_err);
+	do_rtnl_req(nl, req, req->hdr.nlmsg_len, probe_recv_one, probe_err, NULL, &expected_err);
 }
 
 void preload_socket_modules(void)
@@ -584,7 +584,7 @@  int dump_socket(struct fd_parms *p, int lfd, struct cr_img *img)
 	return do_dump_gen_file(p, lfd, ops, img);
 }
 
-static int inet_receive_one(struct nlmsghdr *h, void *arg)
+static int inet_receive_one(struct nlmsghdr *h, struct ns_id *ns, void *arg)
 {
 	struct inet_diag_req_v2 *i = arg;
 	int type;
@@ -602,15 +602,16 @@  static int inet_receive_one(struct nlmsghdr *h, void *arg)
 		return -1;
 	}
 
-	return inet_collect_one(h, i->sdiag_family, type);
+	return inet_collect_one(h, i->sdiag_family, type, ns);
 }
 
 static int do_collect_req(int nl, struct sock_diag_req *req, int size,
-		int (*receive_callback)(struct nlmsghdr *h, void *), void *arg)
+		int (*receive_callback)(struct nlmsghdr *h, struct ns_id *ns, void *),
+		struct ns_id *ns, void *arg)
 {
 	int tmp;
 
-	tmp = do_rtnl_req(nl, req, size, receive_callback, NULL, arg);
+	tmp = do_rtnl_req(nl, req, size, receive_callback, NULL, ns, arg);
 
 	if (tmp == 0)
 		set_collect_bit(req->r.n.sdiag_family, req->r.n.sdiag_protocol);
@@ -636,7 +637,7 @@  int collect_sockets(struct ns_id *ns)
 	req.r.u.udiag_show	= UDIAG_SHOW_NAME | UDIAG_SHOW_VFS |
 				  UDIAG_SHOW_PEER | UDIAG_SHOW_ICONS |
 				  UDIAG_SHOW_RQLEN;
-	tmp = do_collect_req(nl, &req, sizeof(req), unix_receive_one, NULL);
+	tmp = do_collect_req(nl, &req, sizeof(req), unix_receive_one, ns, NULL);
 	if (tmp)
 		err = tmp;
 
@@ -646,7 +647,7 @@  int collect_sockets(struct ns_id *ns)
 	req.r.i.idiag_ext	= 0;
 	/* Only listening and established sockets supported yet */
 	req.r.i.idiag_states	= (1 << TCP_LISTEN) | (1 << TCP_ESTABLISHED);
-	tmp = do_collect_req(nl, &req, sizeof(req), inet_receive_one, &req.r.i);
+	tmp = do_collect_req(nl, &req, sizeof(req), inet_receive_one, ns, &req.r.i);
 	if (tmp)
 		err = tmp;
 
@@ -655,7 +656,7 @@  int collect_sockets(struct ns_id *ns)
 	req.r.i.sdiag_protocol	= IPPROTO_UDP;
 	req.r.i.idiag_ext	= 0;
 	req.r.i.idiag_states	= -1; /* All */
-	tmp = do_collect_req(nl, &req, sizeof(req), inet_receive_one, &req.r.i);
+	tmp = do_collect_req(nl, &req, sizeof(req), inet_receive_one, ns, &req.r.i);
 	if (tmp)
 		err = tmp;
 
@@ -664,7 +665,7 @@  int collect_sockets(struct ns_id *ns)
 	req.r.i.sdiag_protocol	= IPPROTO_UDPLITE;
 	req.r.i.idiag_ext	= 0;
 	req.r.i.idiag_states	= -1; /* All */
-	tmp = do_collect_req(nl, &req, sizeof(req), inet_receive_one, &req.r.i);
+	tmp = do_collect_req(nl, &req, sizeof(req), inet_receive_one, ns, &req.r.i);
 	if (tmp)
 		err = tmp;
 
@@ -674,7 +675,7 @@  int collect_sockets(struct ns_id *ns)
 	req.r.i.idiag_ext	= 0;
 	/* Only listening sockets supported yet */
 	req.r.i.idiag_states	= (1 << TCP_LISTEN) | (1 << TCP_ESTABLISHED);
-	tmp = do_collect_req(nl, &req, sizeof(req), inet_receive_one, &req.r.i);
+	tmp = do_collect_req(nl, &req, sizeof(req), inet_receive_one, ns, &req.r.i);
 	if (tmp)
 		err = tmp;
 
@@ -683,7 +684,7 @@  int collect_sockets(struct ns_id *ns)
 	req.r.i.sdiag_protocol	= IPPROTO_UDP;
 	req.r.i.idiag_ext	= 0;
 	req.r.i.idiag_states	= -1; /* All */
-	tmp = do_collect_req(nl, &req, sizeof(req), inet_receive_one, &req.r.i);
+	tmp = do_collect_req(nl, &req, sizeof(req), inet_receive_one, ns, &req.r.i);
 	if (tmp)
 		err = tmp;
 
@@ -692,7 +693,7 @@  int collect_sockets(struct ns_id *ns)
 	req.r.i.sdiag_protocol	= IPPROTO_UDPLITE;
 	req.r.i.idiag_ext	= 0;
 	req.r.i.idiag_states	= -1; /* All */
-	tmp = do_collect_req(nl, &req, sizeof(req), inet_receive_one, &req.r.i);
+	tmp = do_collect_req(nl, &req, sizeof(req), inet_receive_one, ns, &req.r.i);
 	if (tmp)
 		err = tmp;
 
@@ -700,7 +701,7 @@  int collect_sockets(struct ns_id *ns)
 	req.r.p.sdiag_protocol	= 0;
 	req.r.p.pdiag_show	= PACKET_SHOW_INFO | PACKET_SHOW_MCLIST |
 					PACKET_SHOW_FANOUT | PACKET_SHOW_RING_CFG;
-	tmp = do_collect_req(nl, &req, sizeof(req), packet_receive_one, NULL);
+	tmp = do_collect_req(nl, &req, sizeof(req), packet_receive_one, ns, NULL);
 	if (tmp) {
 		pr_warn("The current kernel doesn't support packet_diag\n");
 		if (ns->ns_pid == 0 || tmp != -ENOENT) /* Fedora 19 */
@@ -710,7 +711,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;
-	tmp = do_collect_req(nl, &req, sizeof(req), netlink_receive_one, NULL);
+	tmp = do_collect_req(nl, &req, sizeof(req), netlink_receive_one, ns, NULL);
 	if (tmp) {
 		pr_warn("The current kernel doesn't support netlink_diag\n");
 		if (ns->ns_pid == 0 || tmp != -ENOENT) /* Fedora 19 */