[12/21] ns: Make possible to avoid NS_ROOT assignment

Submitted by Kirill Tkhai on May 23, 2017, 12:40 p.m.

Details

Message ID 149554321011.12386.1839669313928371573.stgit@localhost.localdomain
State New
Series "Add /proc/[pid]/ns/pid_for_children ns support (and fixes)"
Headers show

Commit Message

Kirill Tkhai May 23, 2017, 12:40 p.m.
pid_for_children_ns of root_item may differ from its pid_ns.
In this case we don't want mark such pid_for_children_ns
as NS_ROOT in nsid_add().

Also, we don't want to create fake pid ns, if pid_for_children_ns
is a just create pid_ns without child reaper (kernel returns ENOENT
in this case). Better we later add a support to kernel to pick
such namespaces. So, we return UINT_MAX and fail.

We encode both the possibilities using the only "alternative"
parameter, as it's enough for us. If anybody needs to separate
them in the future and introduce separate parameters, it'd be rather
simple.

Signed-off-by: Kirill Tkhai <ktkhai@virtuozzo.com>
---
 criu/namespaces.c |    5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

Patch hide | download patch | download mbox

diff --git a/criu/namespaces.c b/criu/namespaces.c
index 580b55197..1a03caa89 100644
--- a/criu/namespaces.c
+++ b/criu/namespaces.c
@@ -421,7 +421,7 @@  static unsigned int generate_ns_id(int pid, unsigned int kid, struct ns_desc *nd
 
 	if (pid != getpid()) {
 		type = NS_OTHER;
-		if (pid == root_item->pid->real) {
+		if (pid == root_item->pid->real && !alternative) {
 			BUG_ON(root_ns_mask & nd->cflag);
 			pr_info("Will take %s namespace in the image\n", nd->str);
 			root_ns_mask |= nd->cflag;
@@ -444,6 +444,7 @@  static unsigned int generate_ns_id(int pid, unsigned int kid, struct ns_desc *nd
 	INIT_LIST_HEAD(&nsid->children);
 	INIT_LIST_HEAD(&nsid->siblings);
 	nsid_add(nsid, nd, ns_next_id++, pid);
+	BUG_ON(nsid->id == UINT_MAX);
 
 	if (nd == &net_ns_desc) {
 		INIT_LIST_HEAD(&nsid->net.ids);
@@ -472,6 +473,8 @@  static unsigned int __get_ns_id(int pid, struct ns_desc *nd, bool alternative,
 
 	if (fstatat(proc_dir, ns_path, &st, 0)) {
 		if (errno == ENOENT) {
+			if (alternative)
+				return UINT_MAX;
 			/* The namespace is unsupported */
 			kid = 0;
 			goto out;