[CRIU] Re: [RFC] splitting files.c

Pavel Emelyanov xemul at parallels.com
Wed Jun 20 11:20:22 EDT 2012


On 06/20/2012 06:25 PM, Cyrill Gorcunov wrote:
> Hi guys, while mocking up with fifos and paths handling I found that our
> regular-files dumping code is a bit spread over files.c and cr-dump.c
> files. So I thought it would be good to cope reg-files in one place,
> that's how files-reg.c appeared.
> 
> What do you think, is it worth to?

Worth. Make it work and I'll commit the patch. But please -- only code move
and _required_ adds/removes. No "clean tabs/braces/spaces/names/whatever while
I am at it".

>         Cyrill
> ---
> From: Cyrill Gorcunov <gorcunov at openvz.org>
> Subject: [PATCH] files: Move regular files handling code to files-reg
> 
> Instead of spreading regular files handling code over
> files.c and cr-dump.c move it to files-reg.c.
> 
> This allows to extend regular file handling code in
> future without disturbing other source files and
> make code logically coupled, where files.c is mostly
> a place for general file handling code unrelated to
> file type specifics.
> 
> Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
> ---
>  Makefile            |    1 +
>  cr-dump.c           |  188 +----------------------
>  files-reg.c         |  433 +++++++++++++++++++++++++++++++++++++++++++++++++++
>  files.c             |  228 ---------------------------
>  include/files-reg.h |   16 ++
>  5 files changed, 451 insertions(+), 415 deletions(-)
>  create mode 100644 files-reg.c
>  create mode 100644 include/files-reg.h
> 
> diff --git a/Makefile b/Makefile
> index 44b6854..3853028 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -44,6 +44,7 @@ OBJS          += sk-tcp.o
>  OBJS           += sk-unix.o
>  OBJS           += sk-queue.o
>  OBJS           += files.o
> +OBJS           += files-reg.o
>  OBJS           += pipes.o
>  OBJS           += file-ids.o
>  OBJS           += namespaces.o
> diff --git a/cr-dump.c b/cr-dump.c
> index 9edc17c..2b2f99b 100644
> --- a/cr-dump.c
> +++ b/cr-dump.c
> @@ -35,6 +35,7 @@
>  #include "parasite.h"
>  #include "parasite-syscall.h"
>  #include "files.h"
> +#include "files-reg.h"
>  #include "pipes.h"
>  #include "shmem.h"
>  #include "sk-inet.h"
> @@ -46,7 +47,6 @@
>  # error No x86-32 support yet
>  #endif
> 
> -static char big_buffer[PATH_MAX];
>  static char loc_buf[PAGE_SIZE];
> 
>  static struct pstree_item *root_item = NULL;
> @@ -140,180 +140,6 @@ static int collect_fds(pid_t pid, int *fd, int *nr_fd)
>         return 0;
>  }
> 
> -/*
> - * Ghost files are those not visible from the FS. Dumping them is
> - * nasty and the only way we have -- just carry its contents with
> - * us. Any brave soul to implement link unlinked file back?
> - */
> -struct ghost_file {
> -       u32     dev;
> -       u32     ino;
> -       u32     id;
> -       struct list_head list;
> -};
> -
> -static u32 ghost_file_ids = 1;
> -static LIST_HEAD(ghost_files);
> -/*
> - * This constant is selected without any calculations. Just do not
> - * want to pick up too big files with us in the image.
> - */
> -#define MAX_GHOST_FILE_SIZE    (1 * 1024 * 1024)
> -
> -static int dump_ghost_file(int _fd, u32 id, const struct stat *st)
> -{
> -       int img, fd;
> -       struct ghost_file_entry gfe;
> -       char lpath[32];
> -
> -       pr_info("Dumping ghost file contents (id %#x)\n", id);
> -
> -       img = open_image(CR_FD_GHOST_FILE, O_DUMP, id);
> -       if (img < 0)
> -               return -1;
> -
> -       /*
> -        * Reopen file locally since it may have no read
> -        * permissions when drained
> -        */
> -       snprintf(lpath, sizeof(lpath), "/proc/self/fd/%d", _fd);
> -       fd = open(lpath, O_RDONLY);
> -       if (fd < 0) {
> -               pr_perror("Can't open ghost original file");
> -               return -1;
> -       }
> -
> -       gfe.uid = st->st_uid;
> -       gfe.gid = st->st_gid;
> -       gfe.mode = st->st_mode;
> -
> -       if (write_img(img, &gfe))
> -               return -1;
> -
> -       if (copy_file(fd, img, st->st_size))
> -               return -1;
> -
> -       close(fd);
> -       close(img);
> -       return 0;
> -}
> -
> -static int dump_ghost_remap(char *path, const struct stat *st, int lfd, u32 id)
> -{
> -       struct ghost_file *gf;
> -       struct remap_file_path_entry rpe;
> -
> -       pr_info("Dumping ghost file for fd %d id %#x\n", lfd, id);
> -
> -       if (st->st_size > MAX_GHOST_FILE_SIZE) {
> -               pr_err("Can't dump ghost file %s of %lu size\n",
> -                               path, st->st_size);
> -               return -1;
> -       }
> -
> -       list_for_each_entry(gf, &ghost_files, list)
> -               if ((gf->dev == st->st_dev) && (gf->ino == st->st_ino))
> -                       goto dump_entry;
> -
> -       gf = xmalloc(sizeof(*gf));
> -       if (gf == NULL)
> -               return -1;
> -
> -       gf->dev = st->st_dev;
> -       gf->ino = st->st_ino;
> -       gf->id = ghost_file_ids++;
> -       list_add_tail(&gf->list, &ghost_files);
> -
> -       if (dump_ghost_file(lfd, gf->id, st))
> -               return -1;
> -
> -dump_entry:
> -       rpe.orig_id = id;
> -       rpe.remap_id = gf->id | REMAP_GHOST;
> -
> -       return write_img(fdset_fd(glob_fdset, CR_FD_REMAP_FPATH), &rpe);
> -}
> -
> -static int check_path_remap(char *path, const struct stat *ost, int lfd, u32 id)
> -{
> -       int ret;
> -       struct stat pst;
> -
> -       if (ost->st_nlink == 0)
> -               /*
> -                * Unpleasant, but easy case. File is completely invisible
> -                * from the FS. Just dump its contents and that's it. But
> -                * be careful whether anybody still has any of its hardlinks
> -                * also open.
> -                */
> -               return dump_ghost_remap(path, ost, lfd, id);
> -
> -       ret = stat(path, &pst);
> -       if (ret < 0) {
> -               /*
> -                * FIXME linked file, but path is not accessible (unless any
> -                * other error occurred). We can create a temporary link to it
> -                * uning linkat with AT_EMPTY_PATH flag and remap it to this
> -                * name.
> -                */
> -               pr_perror("Can't stat path");
> -               return -1;
> -       }
> -
> -       if ((pst.st_ino != ost->st_ino) || (pst.st_dev != ost->st_dev)) {
> -               /*
> -                * FIXME linked file, but the name we see it by is reused
> -                * by somebody else.
> -                */
> -               pr_err("Unaccessible path opened %u:%u, need %u:%u\n",
> -                               (int)pst.st_dev, (int)pst.st_ino,
> -                               (int)ost->st_dev, (int)ost->st_ino);
> -               return -1;
> -       }
> -
> -       /*
> -        * File is linked and visible by the name it is opened by
> -        * this task. Go ahead and dump it.
> -        */
> -       return 0;
> -}
> -
> -static int dump_one_reg_file(int lfd, u32 id, const struct fd_parms *p)
> -{
> -       char fd_str[128];
> -       int len, rfd;
> -       struct reg_file_entry rfe;
> -
> -       snprintf(fd_str, sizeof(fd_str), "/proc/self/fd/%d", lfd);
> -       len = readlink(fd_str, big_buffer, sizeof(big_buffer) - 1);
> -       if (len < 0) {
> -               pr_perror("Can't readlink %s", fd_str);
> -               return len;
> -       }
> -
> -       big_buffer[len] = '\0';
> -       pr_info("Dumping path for %d fd via self %d [%s]\n",
> -                       p->fd, lfd, big_buffer);
> -
> -       if (check_path_remap(big_buffer, &p->stat, lfd, id))
> -               return -1;
> -
> -       rfe.len = len;
> -       rfe.flags = p->flags;
> -       rfe.pos = p->pos;
> -       rfe.id = id;
> -       rfe.fown = p->fown;
> -
> -       rfd = fdset_fd(glob_fdset, CR_FD_REG_FILES);
> -
> -       if (write_img(rfd, &rfe))
> -               return -1;
> -       if (write_img_buf(rfd, big_buffer, len))
> -               return -1;
> -
> -       return 0;
> -}
> -
>  u32 make_gen_id(const struct fd_parms *p)
>  {
>         return MAKE_FD_GENID(p->stat.st_dev, p->stat.st_ino, p->pos);
> @@ -348,18 +174,6 @@ err:
>         return ret;
>  }
> 
> -static const struct fdtype_ops regfile_ops = {
> -       .type           = FDINFO_REG,
> -       .make_gen_id    = make_gen_id,
> -       .dump           = dump_one_reg_file,
> -};
> -
> -static int dump_reg_file(struct fd_parms *p, int lfd,
> -                            const struct cr_fdset *cr_fdset)
> -{
> -       return do_dump_gen_file(p, lfd, &regfile_ops, cr_fdset);
> -}
> -
>  static int dump_task_exe_link(pid_t pid, struct mm_entry *mm)
>  {
>         struct fd_parms params = { };
> diff --git a/files-reg.c b/files-reg.c
> new file mode 100644
> index 0000000..3407bee
> --- /dev/null
> +++ b/files-reg.c
> @@ -0,0 +1,433 @@
> +#include <stdlib.h>
> +#include <unistd.h>
> +#include <errno.h>
> +
> +#include <sys/types.h>
> +#include <sys/stat.h>
> +
> +#include "crtools.h"
> +
> +#include "files.h"
> +#include "image.h"
> +#include "list.h"
> +#include "util.h"
> +
> +#include "files-reg.h"
> +
> +struct reg_file_info {
> +       struct file_desc        d;
> +
> +       struct reg_file_entry   rfe;
> +       char                    *remap_path;
> +       char                    *path;
> +};
> +
> +struct ghost_file {
> +       struct list_head        list;
> +       u32                     id;
> +       char                    *path;
> +};
> +
> +/*
> + * Ghost files are those not visible from the FS. Dumping them is
> + * nasty and the only way we have -- just carry its contents with
> + * us. Any brave soul to implement link unlinked file back?
> + */
> +struct ghost_file_dumpee {
> +       struct list_head        list;
> +       u32                     id;
> +       u32                     dev;
> +       u32                     ino;
> +};
> +
> +static u32 ghost_file_ids = 1;
> +static LIST_HEAD(ghost_files);
> +
> +/*
> + * This constant is selected without any calculations. Just do not
> + * want to pick up too big files with us in the image.
> + */
> +#define MAX_GHOST_FILE_SIZE    (1 * 1024 * 1024)
> +
> +void clear_ghost_files(void)
> +{
> +       struct ghost_file *gf;
> +
> +       pr_info("Unlinking ghosts\n");
> +       list_for_each_entry(gf, &ghost_files, list) {
> +               pr_info("\t`- %s\n", gf->path);
> +               unlink(gf->path);
> +       }
> +}
> +
> +static int open_remap_ghost(struct reg_file_info *rfi, struct remap_file_path_entry *rfe)
> +{
> +       struct ghost_file_entry gfe;
> +       struct ghost_file *gf;
> +       int gfd, ifd;
> +
> +       list_for_each_entry(gf, &ghost_files, list) {
> +               if (gf->id == rfe->remap_id)
> +                       goto gf_found;
> +       }
> +
> +       /*
> +        * Ghost not found. We will create one in the same dir
> +        * as the very first client of it thus resolving any
> +        * issues with cross-device links.
> +        */
> +       pr_info("Opening ghost file %#x for %s\n", rfe->remap_id, rfi->path);
> +
> +       gf = xmalloc(sizeof(*gf));
> +       if (!gf)
> +               return -1;
> +       gf->path = xmalloc(PATH_MAX);
> +       if (!gf->path)
> +               goto err;
> +
> +       ifd = open_image_ro(CR_FD_GHOST_FILE, rfe->remap_id);
> +       if (ifd < 0)
> +               goto err;
> +
> +       if (read_img(ifd, &gfe) < 0)
> +               goto err;
> +
> +       snprintf(gf->path, PATH_MAX, "%s.cr.%x.ghost", rfi->path, rfe->remap_id);
> +       gfd = open(gf->path, O_WRONLY | O_CREAT | O_EXCL, gfe.mode);
> +       if (gfd < 0) {
> +               pr_perror("Can't open ghost file");
> +               goto err;
> +       }
> +
> +       if (fchown(gfd, gfe.uid, gfe.gid) < 0) {
> +               pr_perror("Can't reset user/group on ghost %#x\n", rfe->remap_id);
> +               goto err;
> +       }
> +
> +       if (copy_file(ifd, gfd, 0) < 0)
> +               goto err;
> +
> +       close(ifd);
> +       close(gfd);
> +
> +       gf->id = rfe->remap_id;
> +       list_add_tail(&gf->list, &ghost_files);
> +
> +gf_found:
> +       rfi->remap_path = gf->path;
> +       return 0;
> +
> +err:
> +       xfree(gf->path);
> +       xfree(gf);
> +       return -1;
> +}
> +
> +static int collect_remaps(void)
> +{
> +       int fd, ret = 0;
> +
> +       fd = open_image_ro(CR_FD_REMAP_FPATH);
> +       if (fd < 0)
> +               return -1;
> +
> +       while (1) {
> +               struct remap_file_path_entry rfe;
> +               struct reg_file_info *rfi;
> +               struct file_desc *fdesc;
> +
> +               ret = read_img_eof(fd, &rfe);
> +               if (ret <= 0)
> +                       break;
> +
> +               ret = -1;
> +               if (!(rfe.remap_id & REMAP_GHOST)) {
> +                       pr_err("Non ghost remap not supported @%#x\n", rfe.orig_id);
> +                       break;
> +               }
> +
> +               fdesc = find_file_desc_raw(FDINFO_REG, rfe.orig_id);
> +               if (fdesc == NULL) {
> +                       pr_err("Remap for non existing file %#x\n",
> +                                       rfe.orig_id);
> +                       break;
> +               }
> +
> +               rfe.remap_id &= ~REMAP_GHOST;
> +               rfi = container_of(fdesc, struct reg_file_info, d);
> +               pr_info("Configuring remap %#x -> %#x\n", rfi->rfe.id, rfe.remap_id);
> +               ret = open_remap_ghost(rfi, &rfe);
> +               if (ret < 0)
> +                       break;
> +       }
> +
> +       close(fd);
> +       return ret;
> +}
> +
> +static int dump_ghost_file(int _fd, u32 id, const struct stat *st)
> +{
> +       struct ghost_file_entry gfe;
> +       char lpath[32];
> +       int img, fd;
> +
> +       pr_info("Dumping ghost file contents (id %#x)\n", id);
> +
> +       img = open_image(CR_FD_GHOST_FILE, O_DUMP, id);
> +       if (img < 0)
> +               return -1;
> +
> +       /*
> +        * Reopen file locally since it may have no read
> +        * permissions when drained
> +        */
> +       snprintf(lpath, sizeof(lpath), "/proc/self/fd/%d", _fd);
> +       fd = open(lpath, O_RDONLY);
> +       if (fd < 0) {
> +               pr_perror("Can't open ghost original file");
> +               return -1;
> +       }
> +
> +       gfe.uid = st->st_uid;
> +       gfe.gid = st->st_gid;
> +       gfe.mode= st->st_mode;
> +
> +       if (write_img(img, &gfe))
> +               return -1;
> +
> +       if (copy_file(fd, img, st->st_size))
> +               return -1;
> +
> +       close(fd);
> +       close(img);
> +       return 0;
> +}
> +
> +static int dump_ghost_remap(char *path, const struct stat *st, int lfd, u32 id)
> +{
> +       struct remap_file_path_entry rpe;
> +       struct ghost_file_dumpee *gf;
> +
> +       pr_info("Dumping ghost file for fd %d id %#x\n", lfd, id);
> +
> +       if (st->st_size > MAX_GHOST_FILE_SIZE) {
> +               pr_err("Can't dump ghost file %s of %lu size\n",
> +                      path, st->st_size);
> +               return -1;
> +       }
> +
> +       list_for_each_entry(gf, &ghost_files, list) {
> +               if ((gf->dev == st->st_dev) && (gf->ino == st->st_ino))
> +                       goto dump_entry;
> +       }
> +
> +       gf = xmalloc(sizeof(*gf));
> +       if (gf == NULL)
> +               return -1;
> +
> +       gf->dev = st->st_dev;
> +       gf->ino = st->st_ino;
> +       gf->id  = ghost_file_ids++;
> +
> +       list_add_tail(&gf->list, &ghost_files);
> +
> +       if (dump_ghost_file(lfd, gf->id, st))
> +               return -1;
> +
> +dump_entry:
> +       rpe.orig_id     = id;
> +       rpe.remap_id    = gf->id | REMAP_GHOST;
> +
> +       return write_img(fdset_fd(glob_fdset, CR_FD_REMAP_FPATH), &rpe);
> +}
> +
> +static int check_path_remap(char *path, const struct stat *ost, int lfd, u32 id)
> +{
> +       int ret;
> +       struct stat pst;
> +
> +       if (ost->st_nlink == 0) {
> +               /*
> +                * Unpleasant, but easy case. File is completely invisible
> +                * from the FS. Just dump its contents and that's it. But
> +                * be careful whether anybody still has any of its hardlinks
> +                * also open.
> +                */
> +               return dump_ghost_remap(path, ost, lfd, id);
> +       }
> +
> +       ret = stat(path, &pst);
> +       if (ret < 0) {
> +               /*
> +                * FIXME linked file, but path is not accessible (unless any
> +                * other error occurred). We can create a temporary link to it
> +                * uning linkat with AT_EMPTY_PATH flag and remap it to this
> +                * name.
> +                */
> +               pr_perror("Can't stat path");
> +               return -1;
> +       }
> +
> +       if ((pst.st_ino != ost->st_ino) || (pst.st_dev != ost->st_dev)) {
> +               /*
> +                * FIXME linked file, but the name we see it by is reused
> +                * by somebody else.
> +                */
> +               pr_err("Unaccessible path opened %u:%u, need %u:%u\n",
> +                      (int)pst.st_dev, (int)pst.st_ino,
> +                      (int)ost->st_dev, (int)ost->st_ino);
> +               return -1;
> +       }
> +
> +       /*
> +        * File is linked and visible by the name it is opened by
> +        * this task. Go ahead and dump it.
> +        */
> +       return 0;
> +}
> +
> +int dump_one_reg_file(int lfd, u32 id, const struct fd_parms *p)
> +{
> +       struct reg_file_entry rfe;
> +       char path[PATH_MAX];
> +       char fd_str[128];
> +       int len, rfd;
> +
> +       snprintf(fd_str, sizeof(fd_str), "/proc/self/fd/%d", lfd);
> +       len = readlink(fd_str, path, sizeof(path) - 1);
> +       if (len < 0) {
> +               pr_perror("Can't readlink %s", fd_str);
> +               return len;
> +       }
> +
> +       path[len] = '\0';
> +       pr_info("Dumping path for %d fd via self %d [%s]\n",
> +               p->fd, lfd, path);
> +
> +       if (check_path_remap(path, &p->stat, lfd, id))
> +               return -1;
> +
> +       rfe.id          = id;
> +       rfe.flags       = p->flags;
> +       rfe.len         = len;
> +       rfe.pos         = p->pos;
> +       rfe.fown        = p->fown;
> +
> +       rfd = fdset_fd(glob_fdset, CR_FD_REG_FILES);
> +
> +       if (write_img(rfd, &rfe))
> +               return -1;
> +       if (write_img_buf(rfd, path, len))
> +               return -1;
> +
> +       return 0;
> +}
> +
> +static const struct fdtype_ops regfile_ops = {
> +       .type           = FDINFO_REG,
> +       .make_gen_id    = make_gen_id,
> +       .dump           = dump_one_reg_file,
> +};
> +
> +int dump_reg_file(struct fd_parms *p, int lfd, const struct cr_fdset *set)
> +{
> +       return do_dump_gen_file(p, lfd, &regfile_ops, set);
> +}
> +
> +static int open_fe_fd(struct file_desc *d)
> +{
> +       struct reg_file_info *rfi;
> +       int tmp;
> +
> +       rfi = container_of(d, struct reg_file_info, d);
> +       if (rfi->remap_path) {
> +               if (link(rfi->remap_path, rfi->path) < 0) {
> +                       pr_perror("Can't link %s -> %s\n",
> +                                 rfi->remap_path, rfi->path);
> +                       return -1;
> +               }
> +       }
> +
> +       tmp = open(rfi->path, rfi->rfe.flags);
> +       if (tmp < 0) {
> +               pr_perror("Can't open file %s", rfi->path);
> +               return -1;
> +       }
> +
> +       if (rfi->remap_path)
> +               unlink(rfi->path);
> +
> +       lseek(tmp, rfi->rfe.pos, SEEK_SET);
> +
> +       if (restore_fown(tmp, &rfi->rfe.fown))
> +               return -1;
> +
> +       return tmp;
> +}
> +
> +int open_reg_by_id(u32 id)
> +{
> +       struct file_desc *d;
> +
> +       d = find_file_desc_raw(FDINFO_REG, id);
> +       if (!d) {
> +               pr_perror("Can't find regfile for %#x\n", id);
> +               return -1;
> +       }
> +
> +       return open_fe_fd(d);
> +}
> +
> +static struct file_desc_ops reg_desc_ops = {
> +       .type = FDINFO_REG,
> +       .open = open_fe_fd,
> +};
> +
> +int collect_reg_files(void)
> +{
> +       struct reg_file_info *rfi = NULL;
> +       int fd, ret = -1;
> +
> +       fd = open_image_ro(CR_FD_REG_FILES);
> +       if (fd < 0)
> +               return -1;
> +
> +       while (1) {
> +               int len;
> +
> +               rfi = xmalloc(sizeof(*rfi));
> +               ret = -1;
> +               if (rfi == NULL)
> +                       break;
> +
> +               rfi->path = NULL;
> +               ret = read_img_eof(fd, &rfi->rfe);
> +               if (ret <= 0)
> +                       break;
> +
> +               len = rfi->rfe.len;
> +               rfi->path = xmalloc(len + 1);
> +               ret = -1;
> +               if (rfi->path == NULL)
> +                       break;
> +
> +               ret = read_img_buf(fd, rfi->path, len);
> +               if (ret < 0)
> +                       break;
> +
> +               rfi->remap_path = NULL;
> +               rfi->path[len] = '\0';
> +
> +               pr_info("Collected [%s] ID %#x\n", rfi->path, rfi->rfe.id);
> +               file_desc_add(&rfi->d, rfi->rfe.id, &reg_desc_ops);
> +       }
> +
> +       if (rfi) {
> +               xfree(rfi->path);
> +               xfree(rfi);
> +       }
> +
> +       close(fd);
> +
> +       return collect_remaps();
> +}
> diff --git a/files.c b/files.c
> index 82b9fad..e504d2e 100644
> --- a/files.c
> +++ b/files.c
> @@ -81,13 +81,6 @@ struct fdinfo_list_entry *file_master(struct file_desc *d)
>                         struct fdinfo_list_entry, desc_list);
>  }
> 
> -struct reg_file_info {
> -       struct reg_file_entry rfe;
> -       char *remap_path;
> -       char *path;
> -       struct file_desc d;
> -};
> -
>  void show_saved_files(void)
>  {
>         int i;
> @@ -157,184 +150,6 @@ int rst_file_params(int fd, fown_t *fown, int flags)
>         return 0;
>  }
> 
> -static int open_fe_fd(struct file_desc *d);
> -
> -static struct file_desc_ops reg_desc_ops = {
> -       .type = FDINFO_REG,
> -       .open = open_fe_fd,
> -};
> -
> -struct ghost_file {
> -       u32 id;
> -       char *path;
> -       struct list_head list;
> -};
> -
> -static LIST_HEAD(ghost_files);
> -
> -void clear_ghost_files(void)
> -{
> -       struct ghost_file *gf;
> -
> -       pr_info("Unlinking ghosts\n");
> -
> -       list_for_each_entry(gf, &ghost_files, list) {
> -               pr_info("\t`- %s\n", gf->path);
> -               unlink(gf->path);
> -       }
> -}
> -
> -static int open_remap_ghost(struct reg_file_info *rfi,
> -               struct remap_file_path_entry *rfe)
> -{
> -       struct ghost_file *gf;
> -       struct ghost_file_entry gfe;
> -       int gfd, ifd;
> -
> -       list_for_each_entry(gf, &ghost_files, list)
> -               if (gf->id == rfe->remap_id)
> -                       goto gf_found;
> -
> -       /*
> -        * Ghost not found. We will create one in the same dir
> -        * as the very first client of it thus resolving any
> -        * issues with cross-device links.
> -        */
> -
> -       pr_info("Opening ghost file %#x for %s\n", rfe->remap_id, rfi->path);
> -
> -       gf = xmalloc(sizeof(*gf));
> -       if (!gf)
> -               return -1;
> -       gf->path = xmalloc(PATH_MAX);
> -       if (!gf->path)
> -               return -1;
> -
> -       ifd = open_image_ro(CR_FD_GHOST_FILE, rfe->remap_id);
> -       if (ifd < 0)
> -               return -1;
> -
> -       if (read_img(ifd, &gfe) < 0)
> -               return -1;
> -
> -       snprintf(gf->path, PATH_MAX, "%s.cr.%x.ghost", rfi->path, rfe->remap_id);
> -       gfd = open(gf->path, O_WRONLY | O_CREAT | O_EXCL, gfe.mode);
> -       if (gfd < 0) {
> -               pr_perror("Can't open ghost file");
> -               return -1;
> -       }
> -
> -       if (fchown(gfd, gfe.uid, gfe.gid) < 0) {
> -               pr_perror("Can't reset user/group on ghost %#x\n", rfe->remap_id);
> -               return -1;
> -       }
> -
> -       if (copy_file(ifd, gfd, 0) < 0)
> -               return -1;
> -
> -       close(ifd);
> -       close(gfd);
> -
> -       gf->id = rfe->remap_id;
> -       list_add_tail(&gf->list, &ghost_files);
> -gf_found:
> -       rfi->remap_path = gf->path;
> -       return 0;
> -}
> -
> -static int collect_remaps(void)
> -{
> -       int fd, ret = 0;
> -
> -       fd = open_image_ro(CR_FD_REMAP_FPATH);
> -       if (fd < 0)
> -               return -1;
> -
> -       while (1) {
> -               struct remap_file_path_entry rfe;
> -               struct file_desc *fdesc;
> -               struct reg_file_info *rfi;
> -
> -               ret = read_img_eof(fd, &rfe);
> -               if (ret <= 0)
> -                       break;
> -
> -               ret = -1;
> -
> -               if (!(rfe.remap_id & REMAP_GHOST)) {
> -                       pr_err("Non ghost remap not supported @%#x\n",
> -                                       rfe.orig_id);
> -                       break;
> -               }
> -
> -               fdesc = find_file_desc_raw(FDINFO_REG, rfe.orig_id);
> -               if (fdesc == NULL) {
> -                       pr_err("Remap for non existing file %#x\n",
> -                                       rfe.orig_id);
> -                       break;
> -               }
> -
> -               rfe.remap_id &= ~REMAP_GHOST;
> -               rfi = container_of(fdesc, struct reg_file_info, d);
> -               pr_info("Configuring remap %#x -> %#x\n", rfi->rfe.id, rfe.remap_id);
> -               ret = open_remap_ghost(rfi, &rfe);
> -               if (ret < 0)
> -                       break;
> -       }
> -
> -       close(fd);
> -       return ret;
> -}
> -
> -int collect_reg_files(void)
> -{
> -       struct reg_file_info *rfi = NULL;
> -       int fd, ret = -1;
> -
> -       fd = open_image_ro(CR_FD_REG_FILES);
> -       if (fd < 0)
> -               return -1;
> -
> -       while (1) {
> -               int len;
> -
> -               rfi = xmalloc(sizeof(*rfi));
> -               ret = -1;
> -               if (rfi == NULL)
> -                       break;
> -
> -               rfi->path = NULL;
> -               ret = read_img_eof(fd, &rfi->rfe);
> -               if (ret <= 0)
> -                       break;
> -
> -               len = rfi->rfe.len;
> -               rfi->path = xmalloc(len + 1);
> -               ret = -1;
> -               if (rfi->path == NULL)
> -                       break;
> -
> -               ret = read_img_buf(fd, rfi->path, len);
> -               if (ret < 0)
> -                       break;
> -
> -               rfi->remap_path = NULL;
> -               rfi->path[len] = '\0';
> -
> -               pr_info("Collected [%s] ID %#x\n", rfi->path, rfi->rfe.id);
> -               file_desc_add(&rfi->d, rfi->rfe.id, &reg_desc_ops);
> -       }
> -
> -       if (rfi) {
> -               xfree(rfi->path);
> -               xfree(rfi);
> -       }
> -
> -       close(fd);
> -
> -       return collect_remaps();
> -}
> -
>  static int collect_fd(int pid, struct fdinfo_entry *e, struct rst_info *rst_info)
>  {
>         struct fdinfo_list_entry *l, *le = &fdinfo_list[nr_fdinfo_list];
> @@ -403,49 +218,6 @@ int prepare_fd_pid(int pid, struct rst_info *rst_info)
>         return ret;
>  }
> 
> -static int open_fe_fd(struct file_desc *d)
> -{
> -       struct reg_file_info *rfi;
> -       int tmp;
> -
> -       rfi = container_of(d, struct reg_file_info, d);
> -
> -       if (rfi->remap_path)
> -               if (link(rfi->remap_path, rfi->path) < 0) {
> -                       pr_perror("Can't link %s -> %s\n",
> -                                       rfi->remap_path, rfi->path);
> -                       return -1;
> -               }
> -
> -       tmp = open(rfi->path, rfi->rfe.flags);
> -       if (tmp < 0) {
> -               pr_perror("Can't open file %s", rfi->path);
> -               return -1;
> -       }
> -
> -       if (rfi->remap_path)
> -               unlink(rfi->path);
> -
> -       lseek(tmp, rfi->rfe.pos, SEEK_SET);
> -
> -       if (restore_fown(tmp, &rfi->rfe.fown))
> -               return -1;
> -
> -       return tmp;
> -}
> -int open_reg_by_id(u32 id)
> -{
> -       struct file_desc *fd;
> -
> -       fd = find_file_desc_raw(FDINFO_REG, id);
> -       if (fd == NULL) {
> -               pr_perror("Can't find regfile for %#x\n", id);
> -               return -1;
> -       }
> -
> -       return open_fe_fd(fd);
> -}
> -
>  #define SETFL_MASK (O_APPEND | O_ASYNC | O_NONBLOCK | O_NDELAY | O_DIRECT | O_NOATIME)
>  int set_fd_flags(int fd, int flags)
>  {
> diff --git a/include/files-reg.h b/include/files-reg.h
> new file mode 100644
> index 0000000..04b2862
> --- /dev/null
> +++ b/include/files-reg.h
> @@ -0,0 +1,16 @@
> +#ifndef FILES_REG_H__
> +#define FILES_REG_H__
> +
> +#include "types.h"
> +
> +struct cr_fdset;
> +struct fd_parms;
> +
> +extern int open_reg_by_id(u32 id);
> +extern void clear_ghost_files(void);
> +extern int collect_reg_files(void);
> +
> +extern int dump_reg_file(struct fd_parms *p, int lfd, const struct cr_fdset *set);
> +extern int dump_one_reg_file(int lfd, u32 id, const struct fd_parms *p);
> +
> +#endif /* FILES_REG_H__ */
> --
> 1.7.7.6
> 
> .
> 



More information about the CRIU mailing list