Commit 96a355ab authored by Andrew Vagin's avatar Andrew Vagin Committed by Pavel Emelyanov

files: dump file descriptors by portions (v2)

Currently criu can't handle a processes with more than 1024
file descriptors.

In this patch, criu dumps file descriptors for a few iterations.

Fixes https://github.com/xemul/criu/issues/145

v2: don't move the collect stage
Signed-off-by: 's avatarAndrew Vagin <avagin@virtuozzo.com>
Reviewed-by: 's avatarCyrill Gorcunov <gorcunov@openvz.org>
Signed-off-by: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
parent a249869d
......@@ -204,9 +204,6 @@ static int collect_fds(pid_t pid, struct parasite_drain_fd **dfds)
if (dir_dots(de))
continue;
if (n > PARASITE_MAX_FDS - 1)
return -ENOMEM;
if (sizeof(struct parasite_drain_fd) + sizeof(int) * (n + 1) > size) {
struct parasite_drain_fd *t;
......
......@@ -459,46 +459,52 @@ static int dump_one_file(struct parasite_ctl *ctl, int fd, int lfd, struct fd_op
int dump_task_files_seized(struct parasite_ctl *ctl, struct pstree_item *item,
struct parasite_drain_fd *dfds)
{
int *lfds;
struct cr_img *img;
struct fd_opts *opts;
int *lfds = NULL;
struct cr_img *img = NULL;
struct fd_opts *opts = NULL;
int i, ret = -1;
int off, nr_fds = min((int) PARASITE_MAX_FDS, dfds->nr_fds);
pr_info("\n");
pr_info("Dumping opened files (pid: %d)\n", ctl->pid.real);
pr_info("----------------------------------------\n");
lfds = xmalloc(dfds->nr_fds * sizeof(int));
lfds = xmalloc(nr_fds * sizeof(int));
if (!lfds)
goto err;
opts = xmalloc(dfds->nr_fds * sizeof(struct fd_opts));
opts = xmalloc(nr_fds * sizeof(struct fd_opts));
if (!opts)
goto err1;
ret = parasite_drain_fds_seized(ctl, dfds, lfds, opts);
if (ret)
goto err2;
goto err;
img = open_image(CR_FD_FDINFO, O_DUMP, item->ids->files_id);
if (!img)
goto err2;
goto err;
for (off = 0; off < dfds->nr_fds; off += nr_fds) {
if (nr_fds + off > dfds->nr_fds)
nr_fds = dfds->nr_fds - off;
for (i = 0; i < dfds->nr_fds; i++) {
ret = dump_one_file(ctl, dfds->fds[i], lfds[i], opts + i, img);
ret = parasite_drain_fds_seized(ctl, dfds, nr_fds,
off, lfds, opts);
if (ret)
goto err;
for (i = 0; i < nr_fds; i++) {
ret = dump_one_file(ctl, dfds->fds[i + off],
lfds[i], opts + i, img);
close(lfds[i]);
if (ret)
break;
}
close_image(img);
}
pr_info("----------------------------------------\n");
err2:
err:
if (img)
close_image(img);
xfree(opts);
err1:
xfree(lfds);
err:
return ret;
}
......
......@@ -91,7 +91,7 @@ extern int parasite_dump_thread_seized(struct parasite_ctl *ctl, int id,
extern int dump_thread_core(int pid, CoreEntry *core, const struct parasite_dump_thread *dt);
extern int parasite_drain_fds_seized(struct parasite_ctl *ctl,
struct parasite_drain_fd *dfds,
struct parasite_drain_fd *dfds, int nr_fds, int off,
int *lfds, struct fd_opts *flags);
extern int parasite_get_proc_fd_seized(struct parasite_ctl *ctl);
......
......@@ -231,7 +231,8 @@ struct parasite_drain_fd {
static inline int drain_fds_size(struct parasite_drain_fd *dfds)
{
return sizeof(dfds->nr_fds) + dfds->nr_fds * sizeof(dfds->fds[0]);
int nr_fds = min((int)PARASITE_MAX_FDS, dfds->nr_fds);
return sizeof(*dfds) + nr_fds * sizeof(dfds->fds[0]);
}
struct parasite_tty_args {
......
......@@ -811,14 +811,16 @@ struct parasite_tty_args *parasite_dump_tty(struct parasite_ctl *ctl, int fd, in
}
int parasite_drain_fds_seized(struct parasite_ctl *ctl,
struct parasite_drain_fd *dfds, int *lfds, struct fd_opts *opts)
struct parasite_drain_fd *dfds, int nr_fds, int off,
int *lfds, struct fd_opts *opts)
{
int ret = -1, size;
struct parasite_drain_fd *args;
size = drain_fds_size(dfds);
args = parasite_args_s(ctl, size);
memcpy(args, dfds, size);
args->nr_fds = nr_fds;
memcpy(&args->fds, dfds->fds + off, sizeof(int) * nr_fds);
ret = __parasite_execute_daemon(PARASITE_CMD_DRAIN_FDS, ctl);
if (ret) {
......@@ -826,7 +828,7 @@ int parasite_drain_fds_seized(struct parasite_ctl *ctl,
goto err;
}
ret = recv_fds(ctl->tsock, lfds, dfds->nr_fds, opts);
ret = recv_fds(ctl->tsock, lfds, nr_fds, opts);
if (ret)
pr_err("Can't retrieve FDs from socket\n");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment