Commit cf1ce5f8 authored by Cyrill Gorcunov's avatar Cyrill Gorcunov Committed by Pavel Emelyanov

mount: Build mount tree on dump restore early, if needed

For paths resolution we will need mount tree to be parsed
and built, but it's not that simple -- the current code
implies that once parsed the tree must not be re-parsed
again, so we pass @parse argument from a caller: if a task
we're restoring do not use mount namespace, we should parse
mount tree early, otherwise defer this action until mount
tree is read from the image.
Signed-off-by: 's avatarCyrill Gorcunov <gorcunov@openvz.org>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 8e0c1037
...@@ -1703,7 +1703,7 @@ int cr_dump_tasks(pid_t pid) ...@@ -1703,7 +1703,7 @@ int cr_dump_tasks(pid_t pid)
if (collect_file_locks()) if (collect_file_locks())
goto err; goto err;
if (collect_mount_info(pid)) if (collect_mount_info(pid, true))
goto err; goto err;
if (mntns_collect_root(root_item->pid.real)) if (mntns_collect_root(root_item->pid.real))
......
...@@ -1260,7 +1260,14 @@ static int restore_task_with_children(void *_arg) ...@@ -1260,7 +1260,14 @@ static int restore_task_with_children(void *_arg)
/* Restore root task */ /* Restore root task */
if (current->parent == NULL) { if (current->parent == NULL) {
if (collect_mount_info(getpid())) /*
* For ghost file path resolving on BTRFS we will need
* parsed mount tree, but IIF we're not restoring task
* with mount namespace cloned, in this case we don't parse
* mount tree early because we will be reading mount points
* from image later and generate new mount tree.
*/
if (collect_mount_info(getpid(), !(ca->clone_flags & CLONE_NEWNS)))
exit(1); exit(1);
if (prepare_namespace(current, ca->clone_flags)) if (prepare_namespace(current, ca->clone_flags))
......
...@@ -7,7 +7,7 @@ extern int mntns_collect_root(pid_t pid); ...@@ -7,7 +7,7 @@ extern int mntns_collect_root(pid_t pid);
struct proc_mountinfo; struct proc_mountinfo;
extern int open_mount(unsigned int s_dev); extern int open_mount(unsigned int s_dev);
extern int collect_mount_info(pid_t pid); extern int collect_mount_info(pid_t pid, bool parse);
extern struct fstype *find_fstype_by_name(char *fst); extern struct fstype *find_fstype_by_name(char *fst);
struct cr_fdset; struct cr_fdset;
......
...@@ -33,6 +33,9 @@ int mntns_root = -1; ...@@ -33,6 +33,9 @@ int mntns_root = -1;
static DIR *open_mountpoint(struct mount_info *pm); static DIR *open_mountpoint(struct mount_info *pm);
static int close_mountpoint(DIR *dfd); static int close_mountpoint(DIR *dfd);
static struct mount_info *mnt_build_tree(struct mount_info *list);
static int validate_mounts(struct mount_info *info);
static inline int is_root(char *p) static inline int is_root(char *p)
{ {
return p[0] == '/' && p[1] == '\0'; return p[0] == '/' && p[1] == '\0';
...@@ -59,7 +62,7 @@ int open_mount(unsigned int s_dev) ...@@ -59,7 +62,7 @@ int open_mount(unsigned int s_dev)
return -ENOENT; return -ENOENT;
} }
int collect_mount_info(pid_t pid) int collect_mount_info(pid_t pid, bool parse)
{ {
pr_info("Collecting mountinfo\n"); pr_info("Collecting mountinfo\n");
...@@ -69,6 +72,25 @@ int collect_mount_info(pid_t pid) ...@@ -69,6 +72,25 @@ int collect_mount_info(pid_t pid)
return -1; return -1;
} }
/*
* WARN: Don't ever parse already parsed mount tree,
* this will corrupt mount lists leading to weird
* errors.
*/
if (parse) {
mntinfo_tree = mnt_build_tree(mntinfo);
if (!mntinfo_tree) {
pr_err("Building mount tree %d failed\n", getpid());
return -1;
}
if (validate_mounts(mntinfo_tree)) {
mntinfo_tree = NULL;
pr_err("Validating mount tree %d failed\n", getpid());
return -1;
}
}
return 0; return 0;
} }
......
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