[CRIU] [PATCH] restore: Wait for userns being prepared before moving into cgroups

Andrey Vagin avagin at openvz.org
Wed Apr 20 13:46:54 PDT 2016


From: Andrew Vagin <avagin at virtuozzo.com>

When user namespace are stepping in we should wait for their preparation
to complete before start using userns daemon (internally the kernel
checks for uids and if uids are not set -EINVAL will be returned
when usersn calls for sendmsg()).

Thus use completion and wait for uid maps being written first.

https://jira.sw.ru/browse/PSBM-46360

Cc: Cyrill Gorcunov <gorcunov at gmail.com>
Signed-off-by: Andrew Vagin <avagin at virtuozzo.com>
---
 criu/cr-restore.c       | 18 ++++++++++++++++--
 criu/include/restorer.h |  3 ++-
 2 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/criu/cr-restore.c b/criu/cr-restore.c
index 34db7f7..d9ca9f4 100644
--- a/criu/cr-restore.c
+++ b/criu/cr-restore.c
@@ -1608,6 +1608,11 @@ static int restore_task_with_children(void *_arg)
 
 	current = ca->item;
 
+	if (ca->clone_flags & CLONE_NEWUSER) {
+		if (restore_finish_stage(CR_STATE_RESTORE_USERNS) < 0)
+			goto err;
+	}
+
 	if (current != root_item) {
 		char buf[12];
 		int fd;
@@ -1752,6 +1757,7 @@ static inline int stage_participants(int next_stage)
 	switch (next_stage) {
 	case CR_STATE_FAIL:
 		return 0;
+	case CR_STATE_RESTORE_USERNS:
 	case CR_STATE_RESTORE_NS:
 	case CR_STATE_RESTORE_SHARED:
 		return 1;
@@ -2047,6 +2053,9 @@ static int restore_root_task(struct pstree_item *init)
 	futex_set(&task_entries->nr_in_progress,
 			stage_participants(CR_STATE_RESTORE_NS));
 
+	if (root_ns_mask & CLONE_NEWUSER)
+		__restore_switch_stage(CR_STATE_RESTORE_USERNS);
+
 	ret = fork_with_pid(init);
 	if (ret < 0)
 		goto out;
@@ -2078,8 +2087,13 @@ static int restore_root_task(struct pstree_item *init)
 	 * uid_map and gid_map must be filled from a parent user namespace.
 	 * prepare_userns_creds() must be called after filling mappings.
 	 */
-	if ((root_ns_mask & CLONE_NEWUSER) && prepare_userns(init))
-		goto out_kill;
+	if (root_ns_mask & CLONE_NEWUSER) {
+		if  (prepare_userns(init))
+			goto out_kill;
+		ret = restore_switch_stage(CR_STATE_RESTORE_NS);
+		if (ret < 0)
+			goto out_kill;
+	}
 
 	pr_info("Wait until namespaces are created\n");
 	ret = restore_wait_inprogress_tasks();
diff --git a/criu/include/restorer.h b/criu/include/restorer.h
index b00c212..098c5f0 100644
--- a/criu/include/restorer.h
+++ b/criu/include/restorer.h
@@ -213,7 +213,8 @@ static inline unsigned long restorer_stack(struct thread_restore_args *a)
 
 enum {
 	CR_STATE_FAIL		= -1,
-	CR_STATE_RESTORE_NS	= 0, /* is used for executing "setup-namespace" scripts */
+	CR_STATE_RESTORE_USERNS = 0,	/* restore uid_map and gid_map */
+	CR_STATE_RESTORE_NS,		/* is used for executing "setup-namespace" scripts */
 	CR_STATE_RESTORE_SHARED,
 	CR_STATE_FORKING,
 	CR_STATE_RESTORE,
-- 
2.5.0



More information about the CRIU mailing list