2
0
mirror of https://github.com/checkpoint-restore/criu synced 2025-08-31 06:15:24 +00:00

mount: use per-namespace mntinfo_tree (v2)

This patch removes the global mntinfo_tree and collect_mount_info where
it was constructed. The mntinfo list is filled from dump_mnt_ns,
rst_collect_local_mntns, collect_mnt_namespaces and read_mnt_ns_img.

A mountinfo entry contains a reference on a proper ns_id entry, so
we cau use mnt_id to look up a proper mount namespace.

v2: remove trash after rebasing.
Signed-off-by: Andrey Vagin <avagin@openvz.org>
Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
This commit is contained in:
Andrey Vagin
2014-04-21 18:23:45 +04:00
committed by Pavel Emelyanov
parent 03c69251ab
commit 2f4be997b6
7 changed files with 106 additions and 92 deletions

View File

@@ -23,6 +23,7 @@
#include "fs-magic.h"
#include "asm/atomic.h"
#include "namespaces.h"
#include "proc_parse.h"
#include "protobuf.h"
#include "protobuf/regfile.pb-c.h"
@@ -56,6 +57,7 @@ static mutex_t *ghost_file_mutex;
*/
struct link_remap_rlb {
struct list_head list;
pid_t pid;
char *path;
};
static LIST_HEAD(link_remaps);
@@ -72,6 +74,7 @@ static int open_remap_ghost(struct reg_file_info *rfi,
struct ghost_file *gf;
GhostFileEntry *gfe = NULL;
int gfd, ifd, ghost_flags;
char *root, path[PATH_MAX];
rfe->remap_id &= ~REMAP_GHOST;
list_for_each_entry(gf, &ghost_files, list)
@@ -86,6 +89,12 @@ static int open_remap_ghost(struct reg_file_info *rfi,
pr_info("Opening ghost file %#x for %s\n", rfe->remap_id, rfi->path);
root = rst_get_mnt_root(rfi->rfe->mnt_id);
if (root == NULL) {
pr_err("The %d mount is not found\n", rfi->rfe->mnt_id);
return -1;
}
gf = shmalloc(sizeof(*gf));
if (!gf)
return -1;
@@ -119,9 +128,10 @@ static int open_remap_ghost(struct reg_file_info *rfi,
} else
ghost_flags = O_WRONLY | O_CREAT | O_EXCL;
gfd = open(gf->remap.path, ghost_flags, gfe->mode);
snprintf(path, sizeof(path), "%s/%s", root, gf->remap.path);
gfd = open(path, ghost_flags, gfe->mode);
if (gfd < 0) {
pr_perror("Can't open ghost file %s", gf->remap.path);
pr_perror("Can't open ghost file %s", path);
goto close_ifd;
}
@@ -290,7 +300,8 @@ struct file_remap *lookup_ghost_remap(u32 dev, u32 ino)
return NULL;
}
static int dump_ghost_remap(char *path, const struct stat *st, int lfd, u32 id)
static int dump_ghost_remap(char *path, const struct stat *st,
int lfd, u32 id, struct ns_id *nsid)
{
struct ghost_file *gf;
RemapFilePathEntry rpe = REMAP_FILE_PATH_ENTRY__INIT;
@@ -304,7 +315,7 @@ static int dump_ghost_remap(char *path, const struct stat *st, int lfd, u32 id)
return -1;
}
phys_dev = phys_stat_resolve_dev(st->st_dev, path);
phys_dev = phys_stat_resolve_dev(nsid->mnt.mntinfo_tree, st->st_dev, path);
list_for_each_entry(gf, &ghost_files, list)
if ((gf->dev == phys_dev) && (gf->ino == st->st_ino))
goto dump_entry;
@@ -339,9 +350,10 @@ static void __rollback_link_remaps(bool do_unlink)
if (!opts.link_remap_ok)
return;
mntns_root = get_service_fd(ROOT_FD_OFF);
list_for_each_entry_safe(rlb, tmp, &link_remaps, list) {
mntns_root = mntns_collect_root(rlb->pid);
if (mntns_root < 0)
return;
list_del(&rlb->list);
if (do_unlink)
unlinkat(mntns_root, rlb->path, 0);
@@ -353,7 +365,8 @@ static void __rollback_link_remaps(bool do_unlink)
void delete_link_remaps(void) { __rollback_link_remaps(true); }
void free_link_remaps(void) { __rollback_link_remaps(false); }
static int create_link_remap(char *path, int len, int lfd, u32 *idp)
static int create_link_remap(char *path, int len, int lfd,
u32 *idp, struct ns_id *nsid)
{
char link_name[PATH_MAX], *tmp;
RegFileEntry rfe = REG_FILE_ENTRY__INIT;
@@ -394,7 +407,7 @@ static int create_link_remap(char *path, int len, int lfd, u32 *idp)
/* Any 'unique' name works here actually. Remap works by reg-file ids. */
snprintf(tmp + 1, sizeof(link_name) - (size_t)(tmp - link_name - 1), "link_remap.%d", rfe.id);
mntns_root = get_service_fd(ROOT_FD_OFF);
mntns_root = mntns_collect_root(nsid->pid);
if (linkat(lfd, "", mntns_root, link_name, AT_EMPTY_PATH) < 0) {
pr_perror("Can't link remap to %s", path);
@@ -411,6 +424,8 @@ static int create_link_remap(char *path, int len, int lfd, u32 *idp)
if (rlb)
rlb->path = strdup(link_name);
rlb->pid = nsid->pid;
if (!rlb || !rlb->path) {
pr_perror("Can't register rollback for %s", path);
xfree(rlb ? rlb->path : NULL);
@@ -422,12 +437,13 @@ static int create_link_remap(char *path, int len, int lfd, u32 *idp)
return pb_write_one(fdset_fd(glob_fdset, CR_FD_REG_FILES), &rfe, PB_REG_FILE);
}
static int dump_linked_remap(char *path, int len, const struct stat *ost, int lfd, u32 id)
static int dump_linked_remap(char *path, int len, const struct stat *ost,
int lfd, u32 id, struct ns_id *nsid)
{
u32 lid;
RemapFilePathEntry rpe = REMAP_FILE_PATH_ENTRY__INIT;
if (create_link_remap(path, len, lfd, &lid))
if (create_link_remap(path, len, lfd, &lid, nsid))
return -1;
rpe.orig_id = id;
@@ -471,7 +487,8 @@ static inline bool nfs_silly_rename(char *rpath, const struct fd_parms *parms)
return (parms->fs_type == NFS_SUPER_MAGIC) && is_sillyrename_name(rpath);
}
static int check_path_remap(char *rpath, int plen, const struct fd_parms *parms, int lfd, u32 id)
static int check_path_remap(char *rpath, int plen, const struct fd_parms *parms,
int lfd, u32 id, struct ns_id *nsid)
{
int ret, mntns_root;
struct stat pst;
@@ -484,7 +501,7 @@ static int check_path_remap(char *rpath, int plen, const struct fd_parms *parms,
* be careful whether anybody still has any of its hardlinks
* also open.
*/
return dump_ghost_remap(rpath + 1, ost, lfd, id);
return dump_ghost_remap(rpath + 1, ost, lfd, id, nsid);
if (nfs_silly_rename(rpath, parms)) {
/*
@@ -495,10 +512,12 @@ static int check_path_remap(char *rpath, int plen, const struct fd_parms *parms,
* links on it) to have some persistent name at hands.
*/
pr_debug("Dump silly-rename linked remap for %x\n", id);
return dump_linked_remap(rpath + 1, plen - 1, ost, lfd, id);
return dump_linked_remap(rpath + 1, plen - 1, ost, lfd, id, nsid);
}
mntns_root = get_service_fd(ROOT_FD_OFF);
mntns_root = mntns_collect_root(nsid->pid);
if (mntns_root < 0)
return -1;
ret = fstatat(mntns_root, rpath, &pst, 0);
if (ret < 0) {
@@ -510,7 +529,8 @@ static int check_path_remap(char *rpath, int plen, const struct fd_parms *parms,
*/
if (errno == ENOENT)
return dump_linked_remap(rpath + 1, plen - 1, ost, lfd, id);
return dump_linked_remap(rpath + 1, plen - 1,
ost, lfd, id, nsid);
pr_perror("Can't stat path");
return -1;
@@ -547,6 +567,7 @@ static int check_path_remap(char *rpath, int plen, const struct fd_parms *parms,
int dump_one_reg_file(int lfd, u32 id, const struct fd_parms *p)
{
struct fd_link _link, *link;
struct ns_id *nsid;
int rfd;
RegFileEntry rfe = REG_FILE_ENTRY__INIT;
@@ -568,6 +589,12 @@ int dump_one_reg_file(int lfd, u32 id, const struct fd_parms *p)
rfe.has_mnt_id = true;
}
nsid = lookup_nsid_by_mnt_id(p->mnt_id);
if (nsid == NULL) {
pr_err("Unable to look up the %d mount\n", p->mnt_id);
return -1;
}
pr_info("Dumping path for %d fd via self %d [%s]\n",
p->fd, lfd, &link->name[1]);
@@ -579,7 +606,7 @@ int dump_one_reg_file(int lfd, u32 id, const struct fd_parms *p)
return -1;
}
if (check_path_remap(link->name, link->len, p, lfd, id))
if (check_path_remap(link->name, link->len, p, lfd, id, nsid))
return -1;
rfe.id = id;
@@ -679,9 +706,16 @@ int open_path(struct file_desc *d,
static int do_open_reg_noseek_flags(struct reg_file_info *rfi, void *arg)
{
u32 flags = *(u32 *)arg;
int fd;
int fd, mntns_root;
struct ns_id *nsid;
fd = open(rfi->path, flags);
nsid = lookup_nsid_by_mnt_id(rfi->rfe->mnt_id);
if (nsid == NULL)
return -1;
mntns_root = mntns_collect_root(nsid->pid);
fd = openat(mntns_root, rfi->path, flags);
if (fd < 0) {
pr_perror("Can't open file %s on restore", rfi->path);
return fd;