[14/28] ns: Refactor top_user_ns assignment

Submitted by Kirill Tkhai on June 5, 2017, 5:25 p.m.

Details

Message ID 149668352907.25229.14337761266609904745.stgit@localhost.localdomain
State New
Series "Support sockets leaked to child user_ns task"
Headers show

Commit Message

Kirill Tkhai June 5, 2017, 5:25 p.m.
The aim is to have top_user_ns set even if !(root_ns_mask & CLONE_NEWUSER).
This allows to avoid additional comparison top_user_ns with NULL elsewhere.

Thus, move fixup for old images to generic code, to support the case above.

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

Patch hide | download patch | download mbox

diff --git a/criu/namespaces.c b/criu/namespaces.c
index 5c01491d8..b1d53b71a 100644
--- a/criu/namespaces.c
+++ b/criu/namespaces.c
@@ -1906,16 +1906,11 @@  int stop_usernsd(void)
 	return ret;
 }
 
-static int do_read_old_user_ns_img(struct ns_id *ns, void *arg)
+static int do_read_old_user_ns_img(struct ns_id *ns)
 {
-	int ret, *count = arg;
 	struct cr_img *img;
 	UsernsEntry *e;
-
-	if (++*count > 1) {
-		pr_err("More then one user_ns, img format can't be old\n");
-		return -1;
-	}
+	int ret;
 
 	img = open_image(CR_FD_USERNS, O_RSTR, ns->id);
 	if (!img)
@@ -1926,30 +1921,18 @@  static int do_read_old_user_ns_img(struct ns_id *ns, void *arg)
 		return -1;
 	ns->user.e = e;
 	userns_entry = e;
-	ns->type = NS_ROOT;
-	top_user_ns = ns;
 	return 0;
 }
 
 static int read_old_user_ns_img(void)
 {
-	int ret, count = 0;
-	struct ns_id *ns;
-
 	if (!(root_ns_mask & CLONE_NEWUSER))
 		return 0;
 	/* If new format img has already been read */
-	if (top_user_ns)
+	if (top_user_ns->user.e)
 		return 0;
-	/* Old format img is only for top_user_ns. More or less is error */
-	ret = walk_namespaces(&user_ns_desc, do_read_old_user_ns_img, &count);
-	if (ret < 0)
-		return -1;
-
-	for (ns = ns_ids; ns != NULL; ns = ns->next)
-		if (ns->nd != &user_ns_desc)
-			ns->user_ns = top_user_ns;
-	return 0;
+	/* Old format img is only for top_user_ns */
+	return do_read_old_user_ns_img(top_user_ns);
 }
 
 static int dump_ns_with_hookups(int for_dump)
@@ -2155,11 +2138,28 @@  static int mark_root_ns(uint32_t id, struct ns_desc *desc)
 int set_ns_roots(void)
 {
 	TaskKobjIdsEntry *ids = root_item->ids;
+	struct ns_id *ns;
+
 	/* Set root for all namespaces except user and pid, which are set in read_ns_with_hookups() */
 	if (MARK_ROOT_NS(ids, net) || MARK_ROOT_NS(ids, ipc) || MARK_ROOT_NS(ids, uts) ||
 	    MARK_ROOT_NS(ids, mnt) || MARK_ROOT_NS(ids, cgroup))
 		return -1;
 	top_net_ns = lookup_ns_by_id(ids->net_ns_id, &net_ns_desc);
+	if (!top_user_ns) {
+		/*
+		 * In old dumps or if !(root_ns_mask & CLONE_NEWUSER),
+		 * ns.img does not exist/contain user_ns.
+		 */
+		top_user_ns = lookup_ns_by_id(ids->user_ns_id, &user_ns_desc);
+		if (MARK_ROOT_NS(ids, user))
+			return -1;
+	}
+
+	/* Populate !(root_ns_mask & CLONE_NEWXXX) namespaces and fixup old dumps */
+	for (ns = ns_ids; ns != NULL; ns = ns->next)
+		if (ns->user_ns == NULL && ns->nd != &user_ns_desc)
+			ns->user_ns = top_user_ns;
+
 	return 0;
 }