2
0
mirror of https://github.com/checkpoint-restore/criu synced 2025-09-04 08:15:37 +00:00

ghost/mount: allocate remounted_rw in shmem to get info from other processes

Previousely remounted_rw was not shared between all processes on
restore, thus cleanup didn't got this info from rfi_remap and these
mounts were wrongly left writable after restore.

Cherry-picked from Virtuozzo criu:
https://src.openvz.org/projects/OVZ/repos/criu/commits/3a1a592e7

Fixes: fd0a3cd9ef ("mount: remount ro mounts writable before
ghost-file restore")
Signed-off-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
This commit is contained in:
Pavel Tikhomirov
2020-02-13 18:28:15 +03:00
committed by Andrei Vagin
parent 2894e24256
commit 0a2d380e6b
3 changed files with 25 additions and 13 deletions

View File

@@ -84,7 +84,7 @@ struct mount_info {
struct list_head postpone; struct list_head postpone;
int is_overmounted; int is_overmounted;
int remounted_rw; int *remounted_rw;
void *private; /* associated filesystem data */ void *private; /* associated filesystem data */
}; };
@@ -100,7 +100,7 @@ static inline int collect_binfmt_misc(void)
} }
#endif #endif
extern struct mount_info *mnt_entry_alloc(void); extern struct mount_info *mnt_entry_alloc(bool rst);
extern void mnt_entry_free(struct mount_info *mi); extern void mnt_entry_free(struct mount_info *mi);
extern int __mntns_get_root_fd(pid_t pid); extern int __mntns_get_root_fd(pid_t pid);

View File

@@ -27,6 +27,7 @@
#include "external.h" #include "external.h"
#include "clone-noasan.h" #include "clone-noasan.h"
#include "fdstore.h" #include "fdstore.h"
#include "rst-malloc.h"
#include "images/mnt.pb-c.h" #include "images/mnt.pb-c.h"
@@ -1415,7 +1416,8 @@ err:
return -1; return -1;
} }
static __maybe_unused int add_cr_time_mount(struct mount_info *root, char *fsname, const char *path, unsigned int s_dev) static __maybe_unused int add_cr_time_mount(struct mount_info *root, char *fsname, const char *path, unsigned int s_dev,
bool rst)
{ {
struct mount_info *mi, *t, *parent; struct mount_info *mi, *t, *parent;
bool add_slash = false; bool add_slash = false;
@@ -1434,7 +1436,7 @@ static __maybe_unused int add_cr_time_mount(struct mount_info *root, char *fsnam
} }
} }
mi = mnt_entry_alloc(); mi = mnt_entry_alloc(rst);
if (!mi) if (!mi)
return -1; return -1;
@@ -2723,7 +2725,7 @@ err_root:
return exit_code; return exit_code;
} }
struct mount_info *mnt_entry_alloc() struct mount_info *mnt_entry_alloc(bool rst)
{ {
struct mount_info *new; struct mount_info *new;
@@ -2734,6 +2736,13 @@ struct mount_info *mnt_entry_alloc()
new = xzalloc(sizeof(struct mount_info)); new = xzalloc(sizeof(struct mount_info));
if (new) { if (new) {
if (rst) {
new->remounted_rw = shmalloc(sizeof(int));
if (!new->remounted_rw) {
xfree(new);
return NULL;
}
}
new->fd = -1; new->fd = -1;
new->is_overmounted = -1; new->is_overmounted = -1;
INIT_LIST_HEAD(&new->children); INIT_LIST_HEAD(&new->children);
@@ -2956,7 +2965,7 @@ static int collect_mnt_from_image(struct mount_info **head, struct mount_info **
if (ret <= 0) if (ret <= 0)
break; break;
pm = mnt_entry_alloc(); pm = mnt_entry_alloc(true);
if (!pm) if (!pm)
goto err; goto err;
@@ -3234,7 +3243,7 @@ static int populate_mnt_ns(void)
{ {
int ret; int ret;
root_yard_mp = mnt_entry_alloc(); root_yard_mp = mnt_entry_alloc(true);
if (!root_yard_mp) if (!root_yard_mp)
return -1; return -1;
@@ -3247,7 +3256,7 @@ static int populate_mnt_ns(void)
#ifdef CONFIG_BINFMT_MISC_VIRTUALIZED #ifdef CONFIG_BINFMT_MISC_VIRTUALIZED
if (!opts.has_binfmt_misc && !list_empty(&binfmt_misc_list)) { if (!opts.has_binfmt_misc && !list_empty(&binfmt_misc_list)) {
/* Add to mount tree. Generic code will mount it later */ /* Add to mount tree. Generic code will mount it later */
ret = add_cr_time_mount(root_yard_mp, "binfmt_misc", BINFMT_MISC_HOME, 0); ret = add_cr_time_mount(root_yard_mp, "binfmt_misc", BINFMT_MISC_HOME, 0, true);
if (ret) if (ret)
return -1; return -1;
} }
@@ -3697,7 +3706,7 @@ int collect_mnt_namespaces(bool for_dump)
ret = -1; ret = -1;
goto err; goto err;
} else if (ret > 0 && add_cr_time_mount(ns->mnt.mntinfo_tree, "binfmt_misc", BINFMT_MISC_HOME, } else if (ret > 0 && add_cr_time_mount(ns->mnt.mntinfo_tree, "binfmt_misc", BINFMT_MISC_HOME,
s_dev) < 0) { s_dev, false) < 0) {
ret = -1; ret = -1;
goto err; goto err;
} }
@@ -3838,7 +3847,10 @@ int try_remount_writable(struct mount_info *mi, bool ns)
if (!ns) if (!ns)
remounted = REMOUNTED_RW_SERVICE; remounted = REMOUNTED_RW_SERVICE;
if (mi->flags & MS_RDONLY && !(mi->remounted_rw & remounted)) { /* All mounts in mntinfo list should have it on restore */
BUG_ON(mi->remounted_rw == NULL);
if (mi->flags & MS_RDONLY && !(*mi->remounted_rw & remounted)) {
if (mnt_is_overmounted(mi)) { if (mnt_is_overmounted(mi)) {
pr_err("The mount %d is overmounted so paths are invisible\n", mi->mnt_id); pr_err("The mount %d is overmounted so paths are invisible\n", mi->mnt_id);
return -1; return -1;
@@ -3861,7 +3873,7 @@ int try_remount_writable(struct mount_info *mi, bool ns)
if (call_helper_process(ns_remount_writable, mi)) if (call_helper_process(ns_remount_writable, mi))
return -1; return -1;
} }
mi->remounted_rw |= remounted; *mi->remounted_rw |= remounted;
} }
return 0; return 0;
@@ -3876,7 +3888,7 @@ static int __remount_readonly_mounts(struct ns_id *ns)
if (ns && mi->nsid != ns) if (ns && mi->nsid != ns)
continue; continue;
if (!(mi->remounted_rw && REMOUNTED_RW)) if (!(*mi->remounted_rw && REMOUNTED_RW))
continue; continue;
/* /*

View File

@@ -1541,7 +1541,7 @@ struct mount_info *parse_mountinfo(pid_t pid, struct ns_id *nsid, bool for_dump)
int ret = -1; int ret = -1;
char *fsname = NULL; char *fsname = NULL;
new = mnt_entry_alloc(); new = mnt_entry_alloc(false);
if (!new) if (!new)
goto end; goto end;