[CRIU] [PATCH 2/4] files: dump file descriptors by portions (v2)
Andrey Vagin
avagin at openvz.org
Tue Apr 5 12:29:38 PDT 2016
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
v2: don't move the collect stage
Signed-off-by: Andrew Vagin <avagin at virtuozzo.com>
---
criu/cr-dump.c | 3 ---
criu/files.c | 46 +++++++++++++++++++++++------------------
criu/include/parasite-syscall.h | 2 +-
criu/include/parasite.h | 4 +++-
criu/parasite-syscall.c | 8 ++++---
5 files changed, 35 insertions(+), 28 deletions(-)
diff --git a/criu/cr-dump.c b/criu/cr-dump.c
index 47e114e..5ac9fd0 100644
--- a/criu/cr-dump.c
+++ b/criu/cr-dump.c
@@ -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;
diff --git a/criu/files.c b/criu/files.c
index a30dd06..79207f6 100644
--- a/criu/files.c
+++ b/criu/files.c
@@ -462,46 +462,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);
- close(lfds[i]);
+ ret = parasite_drain_fds_seized(ctl, dfds, nr_fds,
+ off, lfds, opts);
if (ret)
- break;
+ 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;
}
diff --git a/criu/include/parasite-syscall.h b/criu/include/parasite-syscall.h
index 04d2602..15a13a6 100644
--- a/criu/include/parasite-syscall.h
+++ b/criu/include/parasite-syscall.h
@@ -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);
diff --git a/criu/include/parasite.h b/criu/include/parasite.h
index 417b324..5c4aefe 100644
--- a/criu/include/parasite.h
+++ b/criu/include/parasite.h
@@ -226,12 +226,14 @@ static inline void copy_sas(ThreadSasEntry *dst, const stack_t *src)
struct parasite_drain_fd {
int nr_fds;
+ int off;
int fds[0];
};
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 {
diff --git a/criu/parasite-syscall.c b/criu/parasite-syscall.c
index 355955e..2c59995 100644
--- a/criu/parasite-syscall.c
+++ b/criu/parasite-syscall.c
@@ -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");
--
2.5.0
More information about the CRIU
mailing list