mirror of
https://github.com/checkpoint-restore/criu
synced 2025-09-01 06:45:35 +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:
committed by
Andrei Vagin
parent
2894e24256
commit
0a2d380e6b
@@ -84,7 +84,7 @@ struct mount_info {
|
||||
struct list_head postpone;
|
||||
|
||||
int is_overmounted;
|
||||
int remounted_rw;
|
||||
int *remounted_rw;
|
||||
|
||||
void *private; /* associated filesystem data */
|
||||
};
|
||||
@@ -100,7 +100,7 @@ static inline int collect_binfmt_misc(void)
|
||||
}
|
||||
#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 int __mntns_get_root_fd(pid_t pid);
|
||||
|
32
criu/mount.c
32
criu/mount.c
@@ -27,6 +27,7 @@
|
||||
#include "external.h"
|
||||
#include "clone-noasan.h"
|
||||
#include "fdstore.h"
|
||||
#include "rst-malloc.h"
|
||||
|
||||
#include "images/mnt.pb-c.h"
|
||||
|
||||
@@ -1415,7 +1416,8 @@ err:
|
||||
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;
|
||||
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)
|
||||
return -1;
|
||||
|
||||
@@ -2723,7 +2725,7 @@ err_root:
|
||||
return exit_code;
|
||||
}
|
||||
|
||||
struct mount_info *mnt_entry_alloc()
|
||||
struct mount_info *mnt_entry_alloc(bool rst)
|
||||
{
|
||||
struct mount_info *new;
|
||||
|
||||
@@ -2734,6 +2736,13 @@ struct mount_info *mnt_entry_alloc()
|
||||
|
||||
new = xzalloc(sizeof(struct mount_info));
|
||||
if (new) {
|
||||
if (rst) {
|
||||
new->remounted_rw = shmalloc(sizeof(int));
|
||||
if (!new->remounted_rw) {
|
||||
xfree(new);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
new->fd = -1;
|
||||
new->is_overmounted = -1;
|
||||
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)
|
||||
break;
|
||||
|
||||
pm = mnt_entry_alloc();
|
||||
pm = mnt_entry_alloc(true);
|
||||
if (!pm)
|
||||
goto err;
|
||||
|
||||
@@ -3234,7 +3243,7 @@ static int populate_mnt_ns(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
root_yard_mp = mnt_entry_alloc();
|
||||
root_yard_mp = mnt_entry_alloc(true);
|
||||
if (!root_yard_mp)
|
||||
return -1;
|
||||
|
||||
@@ -3247,7 +3256,7 @@ static int populate_mnt_ns(void)
|
||||
#ifdef CONFIG_BINFMT_MISC_VIRTUALIZED
|
||||
if (!opts.has_binfmt_misc && !list_empty(&binfmt_misc_list)) {
|
||||
/* 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)
|
||||
return -1;
|
||||
}
|
||||
@@ -3697,7 +3706,7 @@ int collect_mnt_namespaces(bool for_dump)
|
||||
ret = -1;
|
||||
goto err;
|
||||
} 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;
|
||||
goto err;
|
||||
}
|
||||
@@ -3838,7 +3847,10 @@ int try_remount_writable(struct mount_info *mi, bool ns)
|
||||
if (!ns)
|
||||
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)) {
|
||||
pr_err("The mount %d is overmounted so paths are invisible\n", mi->mnt_id);
|
||||
return -1;
|
||||
@@ -3861,7 +3873,7 @@ int try_remount_writable(struct mount_info *mi, bool ns)
|
||||
if (call_helper_process(ns_remount_writable, mi))
|
||||
return -1;
|
||||
}
|
||||
mi->remounted_rw |= remounted;
|
||||
*mi->remounted_rw |= remounted;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -3876,7 +3888,7 @@ static int __remount_readonly_mounts(struct ns_id *ns)
|
||||
if (ns && mi->nsid != ns)
|
||||
continue;
|
||||
|
||||
if (!(mi->remounted_rw && REMOUNTED_RW))
|
||||
if (!(*mi->remounted_rw && REMOUNTED_RW))
|
||||
continue;
|
||||
|
||||
/*
|
||||
|
@@ -1541,7 +1541,7 @@ struct mount_info *parse_mountinfo(pid_t pid, struct ns_id *nsid, bool for_dump)
|
||||
int ret = -1;
|
||||
char *fsname = NULL;
|
||||
|
||||
new = mnt_entry_alloc();
|
||||
new = mnt_entry_alloc(false);
|
||||
if (!new)
|
||||
goto end;
|
||||
|
||||
|
Reference in New Issue
Block a user