[CRIU] [PATCH 4/4] files: dump file descriptors by protions
Pavel Emelyanov
xemul at virtuozzo.com
Mon Apr 4 03:26:34 PDT 2016
On 04/01/2016 08:53 AM, Andrey Vagin wrote:
> From: Andrew Vagin <avagin at virtuozzo.com>
>
> Currently criu can't handle a processes with more than 1024
> file descriptors.
>
> In this patch, criu dumps file descriptors for a few iterations.
>
> https://jira.sw.ru/browse/PSBM-44887
> https://github.com/xemul/criu/issues/145
>
> Signed-off-by: Andrew Vagin <avagin at virtuozzo.com>
> ---
> criu/files.c | 69 +++++++++++++++++++++++++++----------------------
> criu/include/parasite.h | 2 +-
> 2 files changed, 39 insertions(+), 32 deletions(-)
>
> diff --git a/criu/files.c b/criu/files.c
> index eb5f3d9..4bcaf32 100644
> --- a/criu/files.c
> +++ b/criu/files.c
> @@ -459,20 +459,16 @@ static int dump_one_file(struct parasite_ctl *ctl, int fd, int lfd, struct fd_op
> return dump_unsupp_fd(&p, lfd, img, "unknown", NULL);
> }
>
> -static int collect_fds(pid_t pid, struct parasite_drain_fd *dfds, int *skip_fds, int skip_n)
> +static int collect_fds(pid_t pid, DIR *fd_dir,
> + struct parasite_drain_fd *dfds, int *skip_fds, int skip_n)
> {
> struct dirent *de;
> - DIR *fd_dir;
> int n;
>
> pr_info("\n");
> pr_info("Collecting fds (pid: %d)\n", pid);
> pr_info("----------------------------------------\n");
>
> - fd_dir = opendir_proc(pid, "fd");
> - if (!fd_dir)
> - return -1;
> -
> n = 0;
> while ((de = readdir(fd_dir))) {
> int fd, i;
> @@ -480,9 +476,6 @@ static int collect_fds(pid_t pid, struct parasite_drain_fd *dfds, int *skip_fds,
> if (dir_dots(de))
> continue;
>
> - if (n > PARASITE_MAX_FDS - 1)
> - return -ENOMEM;
> -
> fd = atoi(de->d_name);
> for (i = 0; i < skip_n; i++)
> if (skip_fds[i] == fd)
> @@ -491,14 +484,14 @@ static int collect_fds(pid_t pid, struct parasite_drain_fd *dfds, int *skip_fds,
> continue;
>
> dfds->fds[n++] = fd;
> + if (n == PARASITE_MAX_FDS)
> + break;
> }
>
> dfds->nr_fds = n;
> pr_info("Found %d file descriptors\n", n);
> pr_info("----------------------------------------\n");
>
> - closedir(fd_dir);
> -
> return 0;
> }
>
> @@ -510,51 +503,65 @@ int dump_task_files_seized(struct parasite_ctl *ctl, struct pstree_item *item)
> pid_t pid = ctl->pid.real;
> int *lfds = NULL;
> int i, ret = -1;
> + DIR *fd_dir;
> +
> + BUILD_BUG_ON(PARASITE_MAX_FDS > PAGE_SIZE / sizeof(int));
>
> pr_info("\n");
> pr_info("Dumping opened files (pid: %d)\n", ctl->pid.real);
> pr_info("----------------------------------------\n");
>
> - dfds = xmalloc(sizeof(*dfds));
> - if (!dfds)
> - goto err;
> -
> + fd_dir = opendir_proc(pid, "fd");
> + if (!fd_dir)
> + return -1;
> img = open_image(CR_FD_FDINFO, O_DUMP, item->ids->files_id);
> if (!img)
> goto err;
>
> - ret = collect_fds(pid, dfds, (int [2]) {ctl->ptsock, ctl->plogfd} , 2);
> - if (ret) {
> - pr_err("Collect fds (pid: %d) failed with %d\n", pid, ret);
> + dfds = xmalloc(sizeof(*dfds));
> + if (!dfds)
> goto err;
You've change the order of dfds = xmalloc and img = open_image to make
the reviewer work harder. Thank you.
> - }
> -
> - parasite_ensure_args_size(drain_fds_size(dfds));
>
> - lfds = xmalloc(dfds->nr_fds * sizeof(int));
> + lfds = xmalloc(PARASITE_MAX_FDS * sizeof(int));
> if (!lfds)
> goto err;
>
> - opts = xmalloc(dfds->nr_fds * sizeof(struct fd_opts));
> + opts = xmalloc(PARASITE_MAX_FDS * sizeof(struct fd_opts));
> if (!opts)
> goto err;
>
> - ret = parasite_drain_fds_seized(ctl, dfds, lfds, opts);
> - if (ret)
> - goto err;
> + while (1) {
> + ret = collect_fds(pid, fd_dir, dfds,
> + (int [2]) {ctl->ptsock, ctl->plogfd} , 2);
> + if (ret) {
> + pr_err("Collect fds (pid: %d) failed with %d\n", pid, ret);
> + goto err;
> + }
>
> - for (i = 0; i < dfds->nr_fds; i++) {
> - ret = dump_one_file(ctl, dfds->fds[i], lfds[i], opts + i, img);
> - close(lfds[i]);
> - if (ret)
> + if (dfds->nr_fds == 0)
> break;
> - }
>
> + parasite_ensure_args_size(drain_fds_size(dfds));
Same here -- this ensure_args_size() makes no sense in this place.
> +
> + ret = parasite_drain_fds_seized(ctl, dfds, lfds, opts);
> + if (ret)
> + goto err;
> +
> + for (i = 0; i < dfds->nr_fds; i++) {
> + ret = dump_one_file(ctl, dfds->fds[i], lfds[i], opts + i, img);
> + close(lfds[i]);
> + if (ret)
> + break;
> + }
> + }
>
> pr_info("----------------------------------------\n");
> +
> err:
> + closedir(fd_dir);
> if (img)
> close_image(img);
> + xfree(dfds);
> xfree(opts);
> xfree(lfds);
> return ret;
> diff --git a/criu/include/parasite.h b/criu/include/parasite.h
> index 1319cb6..c3ae644 100644
> --- a/criu/include/parasite.h
> +++ b/criu/include/parasite.h
> @@ -224,7 +224,7 @@ static inline void copy_sas(ThreadSasEntry *dst, const stack_t *src)
> dst->ss_flags = src->ss_flags;
> }
>
> -#define PARASITE_MAX_FDS (PAGE_SIZE / sizeof(int))
> +#define PARASITE_MAX_FDS CR_SCM_MAX_FD
>
> struct parasite_drain_fd {
> int nr_fds;
>
More information about the CRIU
mailing list