mirror of
https://github.com/checkpoint-restore/criu
synced 2025-08-31 22:35:33 +00:00
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: Andrew Vagin <avagin@virtuozzo.com> Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
This commit is contained in:
committed by
Pavel Emelyanov
parent
04f7131ad3
commit
9d60724eca
19
cr-restore.c
19
cr-restore.c
@@ -1520,9 +1520,6 @@ static int restore_task_with_children(void *_arg)
|
||||
if (mount_proc())
|
||||
goto err_fini_mnt;
|
||||
|
||||
if (close_old_fds(current))
|
||||
goto err_fini_mnt;
|
||||
|
||||
if (root_prepare_shared())
|
||||
goto err_fini_mnt;
|
||||
|
||||
@@ -1530,14 +1527,11 @@ static int restore_task_with_children(void *_arg)
|
||||
goto err_fini_mnt;
|
||||
}
|
||||
|
||||
if (prepare_mappings())
|
||||
if (restore_task_mnt_ns(current))
|
||||
goto err_fini_mnt;
|
||||
|
||||
if (!(ca->clone_flags & CLONE_FILES)) {
|
||||
ret = close_old_fds(current);
|
||||
if (ret)
|
||||
goto err_fini_mnt;
|
||||
}
|
||||
if (prepare_mappings())
|
||||
goto err_fini_mnt;
|
||||
|
||||
/*
|
||||
* Call this _before_ forking to optimize cgroups
|
||||
@@ -1559,8 +1553,11 @@ static int restore_task_with_children(void *_arg)
|
||||
if (create_children_and_session())
|
||||
goto err_fini_mnt;
|
||||
|
||||
if (restore_task_mnt_ns(current))
|
||||
goto err_fini_mnt;
|
||||
if (!(ca->clone_flags & CLONE_FILES)) {
|
||||
ret = close_old_fds(current);
|
||||
if (ret)
|
||||
goto err_fini_mnt;
|
||||
}
|
||||
|
||||
if (unmap_guard_pages())
|
||||
goto err_fini_mnt;
|
||||
|
@@ -37,6 +37,7 @@ struct ns_id {
|
||||
struct {
|
||||
struct mount_info *mntinfo_list;
|
||||
struct mount_info *mntinfo_tree;
|
||||
int ns_fd;
|
||||
} mnt;
|
||||
|
||||
struct {
|
||||
|
78
mount.c
78
mount.c
@@ -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)
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
|
||||
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");
|
||||
if (setns(nsid->mnt.ns_fd, CLONE_NEWNS)) {
|
||||
pr_perror("Can't restore mntns");
|
||||
return -1;
|
||||
}
|
||||
|
||||
path[0] = '/';
|
||||
print_ns_root(nsid, path + 1, sizeof(path) - 1);
|
||||
if (cr_pivot_root(path))
|
||||
return -1;
|
||||
|
||||
futex_set_and_wake(&nsid->ns_created, 1);
|
||||
if (nsid->ns_pid == current->pid.virt)
|
||||
futex_set_and_wake(&nsid->ns_created, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -2639,7 +2616,7 @@ int restore_task_mnt_ns(struct pstree_item *current)
|
||||
* already there, otherwise it will have to do
|
||||
* setns().
|
||||
*/
|
||||
if (root_item->ids->mnt_ns_id == id)
|
||||
if (!current->parent || id == current->parent->ids->mnt_ns_id)
|
||||
return 0;
|
||||
|
||||
nsid = lookup_ns_by_id(id, &mnt_ns_desc);
|
||||
@@ -2762,9 +2739,10 @@ void cleanup_mnt_ns(void)
|
||||
|
||||
int prepare_mnt_ns(void)
|
||||
{
|
||||
int ret = -1;
|
||||
int ret = -1, rst = -1;
|
||||
struct mount_info *old;
|
||||
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))
|
||||
return rst_collect_local_mntns();
|
||||
@@ -2842,7 +2820,49 @@ int prepare_mnt_ns(void)
|
||||
if (!ret && opts.root)
|
||||
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;
|
||||
err:
|
||||
if (rst)
|
||||
restore_ns(rst, &mnt_ns_desc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int __mntns_get_root_fd(pid_t pid)
|
||||
|
Reference in New Issue
Block a user