[CRIU] [PATCH 1/3] ns: Remember procfs NS entries for root task

Cyrill Gorcunov gorcunov at openvz.org
Mon Apr 29 12:19:57 EDT 2013


This will allow us to restore paths as /proc/self/ns/net
if there was not unshare call done in the dumpee (which
is a different case).

Thus we simply collect procfs NS names and inode numbers
for future use.

Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
---
 cr-dump.c            |  9 ++++++++
 include/namespaces.h | 25 +++++++++++++++++++++
 namespaces.c         | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 95 insertions(+)

diff --git a/cr-dump.c b/cr-dump.c
index 5743551..db404ef 100644
--- a/cr-dump.c
+++ b/cr-dump.c
@@ -1559,6 +1559,15 @@ int cr_dump_tasks(pid_t pid, const struct cr_options *opts)
 	if (cpu_init())
 		goto err;
 
+	/*
+	 * On dump procedure if we've been requested to dump
+	 * namespaces -- parse inode numbers associated in
+	 * procfs thus we could try to restore files opened
+	 * with NS entries.
+	 */
+	if (ns_proc_entries_init(pid))
+		goto err;
+
 	if (write_img_inventory())
 		goto err;
 
diff --git a/include/namespaces.h b/include/namespaces.h
index c0a1ff7..f77f751 100644
--- a/include/namespaces.h
+++ b/include/namespaces.h
@@ -23,4 +23,29 @@ int dump_task_ns_ids(struct pstree_item *);
 
 extern unsigned long current_ns_mask;
 
+enum {
+	PROC_NS_NET,
+	PROC_NS_UTS,
+	PROC_NS_IPC,
+	PROC_NS_PID,
+	PROC_NS_USER,
+	PROC_NS_MNT,
+
+	PROC_NS_MAX
+};
+
+struct ns_proc_entry {
+	char		*name;
+	size_t		name_len;
+	unsigned long	i_ino;
+};
+
+#define NS_PROC_ENTRY(_index, _name)			\
+	[_index] = {					\
+		.name		= _name,		\
+		.name_len	= sizeof(_name) - 1,	\
+	}
+
+extern int ns_proc_entries_init(pid_t pid);
+
 #endif /* __CR_NS_H__ */
diff --git a/namespaces.c b/namespaces.c
index 1e13077..6148166 100644
--- a/namespaces.c
+++ b/namespaces.c
@@ -10,6 +10,67 @@
 #include "namespaces.h"
 #include "net.h"
 
+static struct ns_proc_entry ns_proc_entries[PROC_NS_MAX] = {
+	NS_PROC_ENTRY(PROC_NS_NET,	"net"),
+	NS_PROC_ENTRY(PROC_NS_UTS,	"uts"),
+	NS_PROC_ENTRY(PROC_NS_IPC,	"ipc"),
+	NS_PROC_ENTRY(PROC_NS_PID,	"pid"),
+	NS_PROC_ENTRY(PROC_NS_USER,	"user"),
+	NS_PROC_ENTRY(PROC_NS_MNT,	"mnt"),
+};
+
+int ns_proc_entries_init(pid_t pid)
+{
+	int nsfd, ret = 0;
+	unsigned int i;
+	int fd = -1;
+	char buf[64];
+
+	nsfd = open_proc(pid, "ns");
+	if (nsfd < 0) {
+		pr_perror("Can't open ns proc entry");
+		return -1;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(ns_proc_entries); i++) {
+		size_t sz = ns_proc_entries[i].name_len;
+		char *end = NULL;
+
+		ret = openat(nsfd, ns_proc_entries[i].name, O_RDONLY);
+		if (ret < 0) {
+			if (errno != ENOENT) {
+				pr_perror("Can't open ns proc %s entry",
+					  ns_proc_entries[i].name);
+				break;
+			} else
+				continue;
+		}
+		fd = ret;
+
+		ret = -1;
+		if (read_fd_link(fd, buf, sizeof(buf))) {
+			pr_err("Can't read ns proc link %s\n",
+			       ns_proc_entries[i].name);
+			break;
+		}
+
+		/*
+		 * We expect `%s:[%lu]' format here.
+		 */
+		ns_proc_entries[i].i_ino = strtoul(&buf[sz + 2], &end, 10);
+		if (!end || *end != ']') {
+			pr_err("Failed parsing ns proc %s %s\n",
+			       ns_proc_entries[i].name, end);
+			break;
+		}
+		ret = 0;
+	}
+
+	close_safe(&fd);
+	close(nsfd);
+	return ret;
+}
+
 int switch_ns(int pid, struct ns_desc *nd, int *rst)
 {
 	char buf[32];
-- 
1.8.1.4



More information about the CRIU mailing list