2
0
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:
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;
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);

View File

@@ -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;
/*

View File

@@ -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;