[CRIU] [PATCH 11/14] files: dump fdinfo per files_id instead of pid (v2)
Andrey Vagin
avagin at openvz.org
Fri Jan 11 04:22:42 EST 2013
A few processes can share one fdtable.
v2: fix backward compatiability
Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
cr-dump.c | 26 ++++++++++++++++----------
cr-restore.c | 5 ++++-
files.c | 23 ++++++++++++++++++-----
image.c | 6 ++++++
include/crtools.h | 2 +-
include/files.h | 2 +-
include/image.h | 2 ++
protobuf/inventory.proto | 1 +
8 files changed, 49 insertions(+), 18 deletions(-)
diff --git a/cr-dump.c b/cr-dump.c
index 25ff91e..fb81bc4 100644
--- a/cr-dump.c
+++ b/cr-dump.c
@@ -354,10 +354,10 @@ static int dump_one_file(struct parasite_ctl *ctl, int fd, int lfd, struct fd_op
return dump_unsupp_fd(&p);
}
-static int dump_task_files_seized(struct parasite_ctl *ctl, const int fdinfo,
+static int dump_task_files_seized(struct parasite_ctl *ctl, struct pstree_item *item,
struct parasite_drain_fd *dfds)
{
- int *lfds;
+ int *lfds, fdinfo;
struct fd_opts *opts;
int i, ret = -1;
@@ -377,13 +377,19 @@ static int dump_task_files_seized(struct parasite_ctl *ctl, const int fdinfo,
if (ret)
goto err2;
+ fdinfo = open_image(CR_FD_FDINFO, O_DUMP, item->ids->files_id);
+ if (fdinfo < 0)
+ goto err2;
+
for (i = 0; i < dfds->nr_fds; i++) {
ret = dump_one_file(ctl, dfds->fds[i], lfds[i], opts + i, fdinfo);
close(lfds[i]);
if (ret)
- goto err2;
+ break;
}
+ close(fdinfo);
+
pr_info("----------------------------------------\n");
err2:
xfree(opts);
@@ -1422,7 +1428,13 @@ static int dump_one_task(struct pstree_item *item)
if (!cr_fdset)
goto err_cure;
- ret = dump_task_files_seized(parasite_ctl, fdset_fd(cr_fdset, CR_FD_FDINFO), dfds);
+ ret = dump_task_ids(item, cr_fdset);
+ if (ret) {
+ pr_err("Dump ids (pid: %d) failed with %d\n", pid, ret);
+ goto err_cure;
+ }
+
+ ret = dump_task_files_seized(parasite_ctl, item, dfds);
if (ret) {
pr_err("Dump files (pid: %d) failed with %d\n", pid, ret);
goto err_cure;
@@ -1453,12 +1465,6 @@ static int dump_one_task(struct pstree_item *item)
goto err_cure;
}
- ret = dump_task_ids(item, cr_fdset);
- if (ret) {
- pr_err("Dump ids (pid: %d) failed with %d\n", pid, ret);
- goto err_cure;
- }
-
ret = dump_task_threads(parasite_ctl, item);
if (ret) {
pr_err("Can't dump threads\n");
diff --git a/cr-restore.c b/cr-restore.c
index 210347e..ccc404d 100644
--- a/cr-restore.c
+++ b/cr-restore.c
@@ -155,7 +155,7 @@ static int root_prepare_shared(void)
if (ret < 0)
break;
- ret = prepare_fd_pid(pi->pid.virt, pi->rst);
+ ret = prepare_fd_pid(pi);
if (ret < 0)
break;
}
@@ -715,6 +715,9 @@ static int check_core(CoreEntry *core)
goto out;
}
+ if (!current->ids && core->ids)
+ current->ids = core->ids;
+
if (core->tc->task_state != TASK_DEAD) {
if (!current->ids) {
pr_err("Core IDS data missed for non-zombie\n");
diff --git a/files.c b/files.c
index 34eabfb..2a22c3a 100644
--- a/files.c
+++ b/files.c
@@ -217,19 +217,32 @@ int prepare_ctl_tty(int pid, struct rst_info *rst_info, u32 ctl_tty_id)
return 0;
}
-int prepare_fd_pid(int pid, struct rst_info *rst_info)
+int prepare_fd_pid(struct pstree_item *item)
{
int fdinfo_fd, ret = 0;
+ pid_t pid = item->pid.virt;
+ struct rst_info *rst_info = item->rst;
INIT_LIST_HEAD(&rst_info->fds);
INIT_LIST_HEAD(&rst_info->eventpoll);
INIT_LIST_HEAD(&rst_info->tty_slaves);
- fdinfo_fd = open_image_ro(CR_FD_FDINFO, pid);
- if (fdinfo_fd < 0) {
- if (errno == ENOENT)
+ if (!fdinfo_per_id) {
+ fdinfo_fd = open_image_ro(CR_FD_FDINFO, pid);
+ if (fdinfo_fd < 0) {
+ if (errno == ENOENT)
+ return 0;
+ return -1;
+ }
+ } else {
+ if (item->ids == NULL) /* zombie */
return 0;
- else
+
+ if (item->rst->fdt && item->rst->fdt->pid != item->pid.virt)
+ return 0;
+
+ fdinfo_fd = open_image_ro(CR_FD_FDINFO, item->ids->files_id);
+ if (fdinfo_fd < 0)
return -1;
}
diff --git a/image.c b/image.c
index d94c3de..fe85613 100644
--- a/image.c
+++ b/image.c
@@ -15,6 +15,8 @@
#include "protobuf.h"
#include "protobuf/inventory.pb-c.h"
+bool fdinfo_per_id = false;
+
int check_img_inventory(void)
{
int fd, ret;
@@ -29,6 +31,8 @@ int check_img_inventory(void)
if (ret < 0)
return ret;
+ fdinfo_per_id = he->has_fdinfo_per_id ? he->fdinfo_per_id : false;
+
ret = he->img_version;
inventory_entry__free_unpacked(he, NULL);
@@ -52,6 +56,8 @@ int write_img_inventory(void)
return -1;
he.img_version = CRTOOLS_IMAGES_V1;
+ he.fdinfo_per_id = true;
+ he.has_fdinfo_per_id = true;
if (pb_write_one(fd, &he, PB_INVENTORY) < 0)
return -1;
diff --git a/include/crtools.h b/include/crtools.h
index 0afa2a1..00c917d 100644
--- a/include/crtools.h
+++ b/include/crtools.h
@@ -24,7 +24,6 @@ enum {
*/
_CR_FD_TASK_FROM,
- CR_FD_FDINFO,
CR_FD_PAGES,
CR_FD_CORE,
CR_FD_IDS,
@@ -56,6 +55,7 @@ enum {
CR_FD_SHMEM_PAGES,
CR_FD_GHOST_FILE,
CR_FD_TCP_STREAM,
+ CR_FD_FDINFO,
_CR_FD_GLOB_FROM,
CR_FD_SK_QUEUES,
diff --git a/include/files.h b/include/files.h
index 9d829f2..f246da4 100644
--- a/include/files.h
+++ b/include/files.h
@@ -87,7 +87,7 @@ extern int rst_file_params(int fd, FownEntry *fown, int flags);
extern void show_saved_files(void);
extern int prepare_fds(struct pstree_item *me);
-extern int prepare_fd_pid(int pid, struct rst_info *rst_info);
+extern int prepare_fd_pid(struct pstree_item *me);
extern int prepare_ctl_tty(int pid, struct rst_info *rst_info, u32 ctl_tty_id);
extern int prepare_shared_fdinfo(void);
extern int get_filemap_fd(int pid, VmaEntry *vma_entry);
diff --git a/include/image.h b/include/image.h
index ee75a5d..8ba25df 100644
--- a/include/image.h
+++ b/include/image.h
@@ -134,4 +134,6 @@ struct page_entry {
#define GET_FILE_OFF(s, m) (offsetof(s,m) + MAGIC_OFFSET)
#define GET_FILE_OFF_AFTER(s) (sizeof(s) + MAGIC_OFFSET)
+extern bool fdinfo_per_id;
+
#endif /* __CR_IMAGE_H__ */
diff --git a/protobuf/inventory.proto b/protobuf/inventory.proto
index e9a40ee..9dff72c 100644
--- a/protobuf/inventory.proto
+++ b/protobuf/inventory.proto
@@ -1,3 +1,4 @@
message inventory_entry {
required uint32 img_version = 1;
+ optional bool fdinfo_per_id = 2;
}
--
1.7.11.7
More information about the CRIU
mailing list