Commit 3a291e33 authored by Andrey Vagin's avatar Andrey Vagin Committed by Pavel Emelyanov

crtools: restore nested mount namespaces (v2)

Known issue:
* currently only namespaces with the same root is supported
* nested namespaces can be dumped and restored only if the root task
  has own mount namespace.

All nested namespaces are restored in a root namespace in temporary
directories. All mount points restored in one tree and then they are
divided into namesaces.
The task with minimal pid for each namespaces unshared mntns and
then it makes pivot_root in a proper temporary directory. All other
tasks makes setns to enter into a mount namespace of the task with
minimal pid.

v2: clean up
Signed-off-by: 's avatarAndrey Vagin <avagin@openvz.org>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent e7e9c2ee
......@@ -1286,6 +1286,18 @@ static int restore_task_with_children(void *_arg)
if (create_children_and_session())
goto err;
if (current->ids && current->ids->has_mnt_ns_id) {
struct ns_id *nsid;
nsid = lookup_ns_by_id(current->ids->mnt_ns_id, &mnt_ns_desc);
if (nsid == NULL) {
pr_err("Can't find mount namespace %d\n", current->ids->mnt_ns_id);
goto err;
}
if (restore_task_mnt_ns(nsid, current->pid.real))
goto err;
}
if (unmap_guard_pages())
goto err;
......
......@@ -24,6 +24,8 @@ extern struct ns_desc mnt_ns_desc;
extern dev_t phys_stat_resolve_dev(dev_t st_dev, const char *path);
extern bool phys_stat_dev_match(dev_t st_dev, dev_t phys_dev, const char *path);
struct ns_id;
extern int restore_task_mnt_ns(struct ns_id *nsid, pid_t pid);
extern int fini_mnt_ns(void);
#endif /* __CR_MOUNT_H__ */
......@@ -15,6 +15,7 @@ struct ns_id {
pid_t pid;
struct ns_desc *nd;
struct ns_id *next;
futex_t created; /* boolean */
};
extern struct ns_id *ns_ids;
......
......@@ -1528,6 +1528,43 @@ err:
return NULL;
}
int restore_task_mnt_ns(struct ns_id *nsid, pid_t pid)
{
char path[PATH_MAX];
if (root_item->ids->mnt_ns_id == nsid->id)
return 0;
if (nsid->pid != getpid()) {
int fd;
futex_wait_while_eq(&nsid->created, 0);
fd = open_proc(nsid->pid, "ns/mnt");
if (fd < 0)
return -1;
if (setns(fd, CLONE_NEWNS)) {
pr_perror("Unable to change mount namespace");
return -1;
}
return 0;
}
if (unshare(CLONE_NEWNS)) {
pr_perror("Unable to unshare mount namespace");
return -1;
}
snprintf(path, sizeof(path), "%s/%d/", mnt_roots, nsid->id);
if (cr_pivot_root(path))
return -1;
futex_set_and_wake(&nsid->created, 1);
return 0;
}
/*
* All nested mount namespaces are restore as sub-trees of the root namespace.
*/
......
......@@ -136,6 +136,7 @@ int rst_add_ns_id(unsigned int id, pid_t pid, struct ns_desc *nd)
nsid->nd = nd;
nsid->id = id;
nsid->pid = pid;
futex_set(&nsid->created, 0);
nsid->next = ns_ids;
ns_ids = nsid;
......
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