[CRIU] [PATCH 2/3] file: add a general approach for external files
Andrew Vagin
avagin at virtuozzo.com
Thu Feb 4 08:23:56 PST 2016
On Wed, Feb 03, 2016 at 02:08:34PM +0300, Pavel Emelyanov wrote:
> On 01/27/2016 08:58 PM, Andrew Vagin wrote:
> > On Wed, Jan 27, 2016 at 04:40:44PM +0300, Pavel Emelyanov wrote:
> >> On 01/21/2016 05:07 AM, Andrey Vagin wrote:
> >>> From: Andrew Vagin <avagin at virtuozzo.com>
> >>>
> >>> The idea is to call open_cb for /proc/self/fd/X,
> >>> where X is an externa file descriptor.
> >
> > where X is an inherit file descriptor
> >
> >>>
> >>> This approach works for files and fifo.
> >>
> >> Plz, describe how this is supposed to be used and how this correlates
> >> with the --inherit-fd one.
> >
> > This patch is about inherit-fd.
> >
> > The idea is that we use an inherit file descriptor to get a path to a
> > file. We open /proc/self/fd/X instead of using the inherit file
> > descriptor directly. In this case we don't need to worry about access
> > mode flags, what is significant in a case when we have a few users for
> > one file.
>
> So you change the behavior of --inherit-fd option, don't you?
No, I don't change the existance behaviour. I added a new type of external descriptors.
>
> > I know that this method works for files and fifos. You can find a test
> > in the third patch.
> >
> > Thanks,
> > Andrew
> >
> >>
> >>> Signed-off-by: Andrew Vagin <avagin at virtuozzo.com>
> >>> ---
> >>> crtools.c | 2 ++
> >>> files-reg.c | 29 +++++++++++++++++++++++++----
> >>> 2 files changed, 27 insertions(+), 4 deletions(-)
> >>>
> >>> diff --git a/crtools.c b/crtools.c
> >>> index 039b7a0..fa27622 100644
> >>> --- a/crtools.c
> >>> +++ b/crtools.c
> >>> @@ -781,6 +781,7 @@ usage:
> >>> " --external RES dump objects from this list as external resources:\n"
> >>> " Formats of RES:\n"
> >>> " tty[rdev:dev]\n"
> >>> +" files[mnt_id:inode]\n"
> >>> " --inherit-fd fd[<num>]:<existing>\n"
> >>> " Inherit file descriptors. This allows to treat file descriptor\n"
> >>> " <num> as being already opened via <existing> one and instead of\n"
> >>> @@ -788,6 +789,7 @@ usage:
> >>> " tty[rdev:dev]\n"
> >>> " pipe[inode]\n"
> >>> " socket[inode]\n"
> >>> +" files[mnt_id:inode]\n"
> >>> "\n"
> >>> "* Logging:\n"
> >>> " -o|--log-file FILE log file name\n"
> >>> diff --git a/files-reg.c b/files-reg.c
> >>> index ea66af0..ec74272 100644
> >>> --- a/files-reg.c
> >>> +++ b/files-reg.c
> >>> @@ -1021,6 +1021,7 @@ int dump_one_reg_file(int lfd, u32 id, const struct fd_parms *p)
> >>> struct fd_link _link, *link;
> >>> struct ns_id *nsid;
> >>> struct cr_img *rimg;
> >>> + char ext_id[64];
> >>>
> >>> RegFileEntry rfe = REG_FILE_ENTRY__INIT;
> >>>
> >>> @@ -1031,6 +1032,14 @@ int dump_one_reg_file(int lfd, u32 id, const struct fd_parms *p)
> >>> } else
> >>> link = p->link;
> >>>
> >>> +
> >>> + snprintf(ext_id, sizeof(ext_id), "@file[%x:%"PRIx64"]", p->mnt_id, p->stat.st_ino);
> >>> + if (external_lookup_id(ext_id + 1)) {
> >>> + /* the first symbol will be cut on restore to get an relative path*/
> >>> + rfe.name = xstrdup(ext_id);
> >>> + goto ext;
> >>> + }
> >>> +
> >>> nsid = lookup_nsid_by_mnt_id(p->mnt_id);
> >>> if (nsid == NULL) {
> >>> pr_err("Can't lookup mount=%d for fd=%d path=%s\n",
> >>> @@ -1056,12 +1065,12 @@ int dump_one_reg_file(int lfd, u32 id, const struct fd_parms *p)
> >>>
> >>> if (check_path_remap(link, p, lfd, id, nsid))
> >>> return -1;
> >>> -
> >>> + rfe.name = &link->name[1];
> >>> +ext:
> >>> rfe.id = id;
> >>> rfe.flags = p->flags;
> >>> rfe.pos = p->pos;
> >>> rfe.fown = (FownEntry *)&p->fown;
> >>> - rfe.name = &link->name[1];
> >>>
> >>> if (S_ISREG(p->stat.st_mode) && should_check_size(rfe.flags)) {
> >>> rfe.has_size = true;
> >>> @@ -1216,11 +1225,22 @@ int open_path(struct file_desc *d,
> >>> struct reg_file_info *rfi;
> >>> int tmp, mntns_root;
> >>> char *orig_path = NULL;
> >>> + char path[PATH_MAX];
> >>>
> >>> if (inherited_fd(d, &tmp))
> >>> return tmp;
> >>>
> >>> rfi = container_of(d, struct reg_file_info, d);
> >>> +
> >>> + tmp = inherit_fd_lookup_id(rfi->path);
> >>> + if (tmp >= 0) {
> >>> + mntns_root = open_pid_proc(PROC_SELF);
> >>> + snprintf(path, sizeof(path), "fd/%d", tmp);
> >>> + orig_path = rfi->path;
> >>> + rfi->path = path;
> >>> + goto ext;
> >>> + }
> >>> +
> >>> if (rfi->remap) {
> >>> mutex_lock(ghost_file_mutex);
> >>> if (rfi->remap->is_dir) {
> >>> @@ -1262,6 +1282,7 @@ int open_path(struct file_desc *d,
> >>> }
> >>>
> >>> mntns_root = mntns_get_root_by_mnt_id(rfi->rfe->mnt_id);
> >>> +ext:
> >>> tmp = open_cb(mntns_root, rfi, arg);
> >>> if (tmp < 0) {
> >>> pr_perror("Can't open file %s", rfi->path);
> >>> @@ -1303,10 +1324,10 @@ int open_path(struct file_desc *d,
> >>> unlinkat(mntns_root, rfi->remap->rpath, rfi->remap->is_dir ? AT_REMOVEDIR : 0);
> >>> }
> >>>
> >>> - if (orig_path)
> >>> - rfi->path = orig_path;
> >>> mutex_unlock(ghost_file_mutex);
> >>> }
> >>> + if (orig_path)
> >>> + rfi->path = orig_path;
> >>>
> >>> if (restore_fown(tmp, rfi->rfe->fown))
> >>> return -1;
> >>>
> >>
> > .
> >
>
More information about the CRIU
mailing list