[CRIU] [PATCH 08/11] link-remap: open link-remap files from correct mountpoints
Andrew Vagin
avagin at parallels.com
Tue Aug 5 05:57:00 PDT 2014
On Tue, Aug 05, 2014 at 04:39:26PM +0400, Pavel Emelyanov wrote:
> On 08/03/2014 10:31 PM, Andrey Vagin wrote:
> > Here is a problem with ghost files. Links are created on restore, but
> > they can't be created on any mount point, because a mount point can be
> > non-root bind-mount of another one. So we need to find the root mount
> > and create all links there.
> >
> > v2: clean up
> > Signed-off-by: Andrey Vagin <avagin at openvz.org>
> > ---
> > files-reg.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++-------
> > include/files-reg.h | 1 +
> > 2 files changed, 55 insertions(+), 8 deletions(-)
> >
> > diff --git a/files-reg.c b/files-reg.c
> > index 00eef60..b72c821 100644
> > --- a/files-reg.c
> > +++ b/files-reg.c
> > @@ -154,6 +154,7 @@ static int open_remap_ghost(struct reg_file_info *rfi,
> > if (!gf)
> > return -1;
> > gf->remap.path = xmalloc(PATH_MAX);
> > + gf->remap.mnt_id = rfi->rfe->mnt_id;
> > if (!gf->remap.path)
> > goto err;
> >
> > @@ -221,6 +222,7 @@ static int open_remap_linked(struct reg_file_info *rfi,
> > rm->path = rrfi->path;
> > rm->users = 0;
> > rm->is_dir = false;
> > + rm->mnt_id = rfi->rfe->mnt_id;
> > rfi->remap = rm;
> > return 0;
> > }
> > @@ -313,8 +315,12 @@ void remap_put(struct file_remap *remap)
> > {
> > mutex_lock(ghost_file_mutex);
> > if (--remap->users == 0) {
> > + int mntns_root;
> > +
> > pr_info("Unlink the ghost %s\n", remap->path);
> > - unlink(remap->path);
> > +
> > + mntns_root = mntns_get_root_by_mnt_id(remap->mnt_id);
> > + unlinkat(mntns_root, remap->path, 0);
> > }
> > mutex_unlock(ghost_file_mutex);
> > }
> > @@ -669,7 +675,48 @@ const struct fdtype_ops regfile_dump_ops = {
> >
> > static inline int rfi_remap(struct reg_file_info *rfi)
> > {
> > - return link(rfi->remap->path, rfi->path);
> > + struct mount_info *mi, *rmi, *tmi;
> > + int off, roff;
> > + char path[PATH_MAX], rpath[PATH_MAX];
> > + int mntns_root;
> > +
> > + mi = lookup_mnt_id(rfi->rfe->mnt_id);
> > +
> > + if (mi == NULL) {
> > + mntns_root = mntns_get_root_by_mnt_id(-1);
> > + return linkat(mntns_root, rfi->remap->path, mntns_root, rfi->path, 0);
> > + }
> > +
> > + /*
> > + * mi->mountpoint ./zdtm/live/static/mntns_link_ghost.test/1
> > + * + mi->rst_off /zdtm/live/static/mntns_link_ghost.test/1
> > + * rfi->path zdtm/live/static/mntns_link_ghost.test/1/F (deleted)
> > + */
> > + rmi = lookup_mnt_id(rfi->remap->mnt_id);
> > + off = strlen(mi->mountpoint + mi->rst_off + 1);
> > + roff = strlen(rmi->mountpoint + rmi->rst_off + 1);
> > +
> > + /* Find the lowest common bind-mount */
> > + for (tmi = mi; tmi->bind; tmi = tmi->bind);
> > +
> > + /* Create paths relative to this mount.
> > + * Absolute path to the mount point + difference between source
> > + * and destination roots + path relative to the mountpoint.
> > + */
^^^^ it's explained here
> > + snprintf(path, sizeof(path), "%s/%s/%s",
> > + tmi->mountpoint + tmi->rst_off + 1,
Absolute path to the mount point
> > + mi->root + strlen(tmi->root),
difference between source and destination roots
> > + rfi->path + off);
path relative to the mountpoint
> > + snprintf(rpath, sizeof(rpath), "%s/%s/%s",
> > + tmi->mountpoint + tmi->rst_off + 1,
> > + rmi->root + strlen(tmi->root),
> > + rfi->remap->path + roff);
>
> What the above path-tossing mean? Would you explain, please.
>
> > +
> > + pr_debug("%d: Link %s -> %s\n", tmi->mnt_id, path, rpath);
> > +
> > + mntns_root = mntns_get_root_by_mnt_id(tmi->mnt_id);
> > +
> > + return linkat(mntns_root, rpath, mntns_root, path, 0);
> > }
> >
> > int open_path(struct file_desc *d,
> > @@ -752,16 +799,15 @@ int open_path(struct file_desc *d,
> > }
> >
> > if (rfi->remap) {
> > - if (!rfi->remap->is_dir)
> > - unlink(rfi->path);
> > + if (!rfi->remap->is_dir) {
> > + unlinkat(mntns_root, rfi->path, 0);
> > + }
> >
> > BUG_ON(!rfi->remap->users);
> > if (--rfi->remap->users == 0) {
> > pr_info("Unlink the ghost %s\n", rfi->remap->path);
> > - if (rfi->remap->is_dir)
> > - rmdir(rfi->remap->path);
> > - else
> > - unlink(rfi->remap->path);
> > + mntns_root = mntns_get_root_by_mnt_id(rfi->remap->mnt_id);
> > + unlinkat(mntns_root, rfi->remap->path, rfi->remap->is_dir ? AT_REMOVEDIR : 0);
> > }
> >
> > if (orig_path)
> > diff --git a/include/files-reg.h b/include/files-reg.h
> > index b4a7367..bc5f5a7 100644
> > --- a/include/files-reg.h
> > +++ b/include/files-reg.h
> > @@ -14,6 +14,7 @@ struct fd_parms;
> > struct file_remap {
> > char *path;
> > bool is_dir;
> > + int mnt_id;
> > unsigned int users;
> > };
> >
> >
>
More information about the CRIU
mailing list