Commit 9d60724e authored by Andrew Vagin's avatar Andrew Vagin Committed by Pavel Emelyanov

restore: restore mntns before creating private vma-s (v3)

We need to open a file to restore a file mapping and this file
can be from a current mntns.

v2: All namespaces are resotred from the root task and then
other tasks calls setns() to set a proper mntns.

v3: fix comments from Pavel
Signed-off-by: 's avatarAndrew Vagin <avagin@virtuozzo.com>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 04f7131a
...@@ -1520,9 +1520,6 @@ static int restore_task_with_children(void *_arg) ...@@ -1520,9 +1520,6 @@ static int restore_task_with_children(void *_arg)
if (mount_proc()) if (mount_proc())
goto err_fini_mnt; goto err_fini_mnt;
if (close_old_fds(current))
goto err_fini_mnt;
if (root_prepare_shared()) if (root_prepare_shared())
goto err_fini_mnt; goto err_fini_mnt;
...@@ -1530,14 +1527,11 @@ static int restore_task_with_children(void *_arg) ...@@ -1530,14 +1527,11 @@ static int restore_task_with_children(void *_arg)
goto err_fini_mnt; goto err_fini_mnt;
} }
if (prepare_mappings()) if (restore_task_mnt_ns(current))
goto err_fini_mnt; goto err_fini_mnt;
if (!(ca->clone_flags & CLONE_FILES)) { if (prepare_mappings())
ret = close_old_fds(current); goto err_fini_mnt;
if (ret)
goto err_fini_mnt;
}
/* /*
* Call this _before_ forking to optimize cgroups * Call this _before_ forking to optimize cgroups
...@@ -1559,8 +1553,11 @@ static int restore_task_with_children(void *_arg) ...@@ -1559,8 +1553,11 @@ static int restore_task_with_children(void *_arg)
if (create_children_and_session()) if (create_children_and_session())
goto err_fini_mnt; goto err_fini_mnt;
if (restore_task_mnt_ns(current)) if (!(ca->clone_flags & CLONE_FILES)) {
goto err_fini_mnt; ret = close_old_fds(current);
if (ret)
goto err_fini_mnt;
}
if (unmap_guard_pages()) if (unmap_guard_pages())
goto err_fini_mnt; goto err_fini_mnt;
......
...@@ -37,6 +37,7 @@ struct ns_id { ...@@ -37,6 +37,7 @@ struct ns_id {
struct { struct {
struct mount_info *mntinfo_list; struct mount_info *mntinfo_list;
struct mount_info *mntinfo_tree; struct mount_info *mntinfo_tree;
int ns_fd;
} mnt; } mnt;
struct { struct {
......
...@@ -2590,36 +2590,13 @@ int mntns_maybe_create_roots(void) ...@@ -2590,36 +2590,13 @@ int mntns_maybe_create_roots(void)
static int do_restore_task_mnt_ns(struct ns_id *nsid, struct pstree_item *current) static int do_restore_task_mnt_ns(struct ns_id *nsid, struct pstree_item *current)
{ {
char path[PATH_MAX]; if (setns(nsid->mnt.ns_fd, CLONE_NEWNS)) {
pr_perror("Can't restore mntns");
if (nsid->ns_pid != current->pid.virt) {
int fd;
futex_wait_while_eq(&nsid->ns_created, 0);
fd = open_proc(nsid->ns_pid, "ns/mnt");
if (fd < 0)
return -1;
if (setns(fd, CLONE_NEWNS)) {
pr_perror("Unable to change mount namespace");
return -1;
}
close(fd);
return 0;
}
if (unshare(CLONE_NEWNS)) {
pr_perror("Unable to unshare mount namespace");
return -1; return -1;
} }
path[0] = '/'; if (nsid->ns_pid == current->pid.virt)
print_ns_root(nsid, path + 1, sizeof(path) - 1); futex_set_and_wake(&nsid->ns_created, 1);
if (cr_pivot_root(path))
return -1;
futex_set_and_wake(&nsid->ns_created, 1);
return 0; return 0;
} }
...@@ -2639,7 +2616,7 @@ int restore_task_mnt_ns(struct pstree_item *current) ...@@ -2639,7 +2616,7 @@ int restore_task_mnt_ns(struct pstree_item *current)
* already there, otherwise it will have to do * already there, otherwise it will have to do
* setns(). * setns().
*/ */
if (root_item->ids->mnt_ns_id == id) if (!current->parent || id == current->parent->ids->mnt_ns_id)
return 0; return 0;
nsid = lookup_ns_by_id(id, &mnt_ns_desc); nsid = lookup_ns_by_id(id, &mnt_ns_desc);
...@@ -2762,9 +2739,10 @@ void cleanup_mnt_ns(void) ...@@ -2762,9 +2739,10 @@ void cleanup_mnt_ns(void)
int prepare_mnt_ns(void) int prepare_mnt_ns(void)
{ {
int ret = -1; int ret = -1, rst = -1;
struct mount_info *old; struct mount_info *old;
struct ns_id ns = { .type = NS_CRIU, .ns_pid = PROC_SELF, .nd = &mnt_ns_desc }; struct ns_id ns = { .type = NS_CRIU, .ns_pid = PROC_SELF, .nd = &mnt_ns_desc };
struct ns_id *nsid;
if (!(root_ns_mask & CLONE_NEWNS)) if (!(root_ns_mask & CLONE_NEWNS))
return rst_collect_local_mntns(); return rst_collect_local_mntns();
...@@ -2842,7 +2820,49 @@ int prepare_mnt_ns(void) ...@@ -2842,7 +2820,49 @@ int prepare_mnt_ns(void)
if (!ret && opts.root) if (!ret && opts.root)
ret = cr_pivot_root(NULL); ret = cr_pivot_root(NULL);
rst = open_proc(PROC_SELF, "ns/mnt");
if (rst < 0)
return -1;
/* resotre non-root namespaces */
for (nsid = ns_ids; nsid != NULL; nsid = nsid->next) {
char path[PATH_MAX];
if (nsid->nd != &mnt_ns_desc)
continue;
if (root_item->ids->mnt_ns_id == nsid->id)
continue;
/* Create the new mount namespace */
if (unshare(CLONE_NEWNS)) {
pr_perror("Unable to create a new mntns");
goto err;
}
/* Set its root */
path[0] = '/';
print_ns_root(nsid, path + 1, sizeof(path) - 1);
if (cr_pivot_root(path))
goto err;
/* Pin one with a file descriptor */
nsid->mnt.ns_fd = open_proc(PROC_SELF, "ns/mnt");
if (nsid->mnt.ns_fd < 0)
goto err;
/* And return back to regain the access to the roots yard */
if (setns(rst, CLONE_NEWNS)) {
pr_perror("Can't restore mntns back");
goto err;
}
}
close(rst);
return ret; return ret;
err:
if (rst)
restore_ns(rst, &mnt_ns_desc);
return -1;
} }
int __mntns_get_root_fd(pid_t pid) int __mntns_get_root_fd(pid_t pid)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment