[CRIU] [PATCH 8/9] net: add a way to get a network namespace for a socket

Andrei Vagin avagin at openvz.org
Tue Feb 14 15:59:31 PST 2017


From: Andrei Vagin <avagin at virtuozzo.com>

Each sockets belongs to one network namespace and operates
in this network namespace.

socket_diag reports informations about sockets from
one network namespace, but it doesn't report sockets which
are not bound or connected to somewhere. So we need to have
a way to get network namespaces for such sockets.

Signed-off-by: Andrei Vagin <avagin at virtuozzo.com>
---
 criu/include/namespaces.h |  1 +
 criu/namespaces.c         |  2 +-
 criu/net.c                | 28 ++++++++++++++++++++++++----
 3 files changed, 26 insertions(+), 5 deletions(-)

diff --git a/criu/include/namespaces.h b/criu/include/namespaces.h
index 5b39cbd..1b454e0 100644
--- a/criu/include/namespaces.h
+++ b/criu/include/namespaces.h
@@ -187,5 +187,6 @@ extern int __userns_call(const char *func_name, uns_call_t call, int flags,
 extern int add_ns_shared_cb(int (*actor)(void *data), void *data);
 
 extern struct ns_id *get_socket_ns(int lfd);
+extern struct ns_id *lookup_ns_by_kid(unsigned int kid, struct ns_desc *nd);
 
 #endif /* __CR_NS_H__ */
diff --git a/criu/namespaces.c b/criu/namespaces.c
index d796888..9e61c94 100644
--- a/criu/namespaces.c
+++ b/criu/namespaces.c
@@ -327,7 +327,7 @@ int rst_add_ns_id(unsigned int id, struct pstree_item *i, struct ns_desc *nd)
 	return 0;
 }
 
-static struct ns_id *lookup_ns_by_kid(unsigned int kid, struct ns_desc *nd)
+struct ns_id *lookup_ns_by_kid(unsigned int kid, struct ns_desc *nd)
 {
 	struct ns_id *nsid;
 
diff --git a/criu/net.c b/criu/net.c
index 7000923..2001998 100644
--- a/criu/net.c
+++ b/criu/net.c
@@ -2054,11 +2054,31 @@ static struct ns_id *get_root_netns()
  */
 struct ns_id *get_socket_ns(int lfd)
 {
-	if (netns_nr == 1)
-		return get_root_netns();
+	struct ns_id *ns;
+	struct stat st;
+	int ns_fd;
 
-	pr_perror("Unable to get a socket net namespace");
-	return NULL;
+	ns_fd = ioctl(lfd, SIOCGSKNS);
+	if (ns_fd < 0) {
+		/* backward compatiblity with old kernels */
+		if (netns_nr == 1)
+			return get_root_netns();
+
+		pr_perror("Unable to get a socket net namespace");
+		return NULL;
+	}
+	if (fstat(ns_fd, &st)) {
+		pr_perror("Unable to stat a network namespace");
+		return NULL;
+	}
+
+	ns = lookup_ns_by_kid(st.st_ino, &net_ns_desc);
+	if (ns == NULL) {
+		pr_err("Unable to dump a socket from an external network namespace\n");
+		return NULL;
+	}
+
+	return ns;
 }
 
 int kerndat_socket_netns(void)
-- 
2.7.4



More information about the CRIU mailing list