[CRIU] [PATCH 3/3] crtools: Start using cr-super tool
Cyrill Gorcunov
gorcunov at openvz.org
Thu Sep 24 09:37:15 PDT 2015
Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
---
cr-dump.c | 14 ++++++
crtools.c | 4 ++
include/cr_options.h | 1 +
proc_parse.c | 121 +++++++++++++++++++++++++++++----------------------
4 files changed, 88 insertions(+), 52 deletions(-)
diff --git a/cr-dump.c b/cr-dump.c
index 3af077b0b1ef..d8b3120d8053 100644
--- a/cr-dump.c
+++ b/cr-dump.c
@@ -47,6 +47,7 @@
#include "namespaces.h"
#include "image.h"
#include "proc_parse.h"
+#include "cr-super-client.h"
#include "parasite.h"
#include "parasite-syscall.h"
#include "files.h"
@@ -1368,6 +1369,11 @@ int cr_pre_dump_tasks(pid_t pid)
if (vdso_init())
goto err;
+ if (cr_super_init(opts.cr_super,
+ get_service_fd(LOG_FD_OFF),
+ log_get_loglevel()))
+ goto err;
+
if (connect_to_page_server())
goto err;
@@ -1428,6 +1434,8 @@ err:
if (bfd_flush_images())
ret = -1;
+ cr_super_fini();
+
if (ret)
pr_err("Pre-dumping FAILED.\n");
else {
@@ -1466,6 +1474,11 @@ int cr_dump_tasks(pid_t pid)
if (vdso_init())
goto err;
+ if (cr_super_init(opts.cr_super,
+ get_service_fd(LOG_FD_OFF),
+ log_get_loglevel()))
+ goto err;
+
if (parse_cg_info())
goto err;
@@ -1600,6 +1613,7 @@ err:
network_unlock();
delete_link_remaps();
}
+ cr_super_fini();
pstree_switch_state(root_item,
(ret || post_dump_ret) ?
TASK_ALIVE : opts.final_state);
diff --git a/crtools.c b/crtools.c
index ea8b889f086d..3667ef34fe43 100644
--- a/crtools.c
+++ b/crtools.c
@@ -252,6 +252,7 @@ int main(int argc, char *argv[], char *envp[])
{ "freeze-cgroup", required_argument, 0, 1068 },
{ "ghost-limit", required_argument, 0, 1069 },
{ "irmap-scan-path", required_argument, 0, 1070 },
+ { "cr-super", required_argument, 0, 1071 },
{ },
};
@@ -494,6 +495,9 @@ int main(int argc, char *argv[], char *envp[])
if (irmap_scan_path_add(optarg))
return -1;
break;
+ case 1071:
+ opts.cr_super = optarg;
+ break;
case 'M':
{
char *aux;
diff --git a/include/cr_options.h b/include/cr_options.h
index af130ddc504d..31b0cd2186e9 100644
--- a/include/cr_options.h
+++ b/include/cr_options.h
@@ -93,6 +93,7 @@ struct cr_options {
bool overlayfs;
size_t ghost_limit;
struct list_head irmap_scan_paths;
+ char *cr_super;
};
extern struct cr_options opts;
diff --git a/proc_parse.c b/proc_parse.c
index 6fdd840aa8fa..1f2ebf8221a3 100644
--- a/proc_parse.c
+++ b/proc_parse.c
@@ -31,6 +31,8 @@
#include "namespaces.h"
#include "files-reg.h"
+#include "cr-super-client.h"
+
#include "protobuf.h"
#include "protobuf/fdinfo.pb-c.h"
#include "protobuf/mnt.pb-c.h"
@@ -172,10 +174,17 @@ static inline int vfi_equal(struct vma_file_info *a, struct vma_file_info *b)
(a->dev_min ^ b->dev_min)) == 0;
}
-static int vma_get_mapfile(char *fname, struct vma_area *vma, DIR *mfd,
- struct vma_file_info *vfi, struct vma_file_info *prev_vfi)
+static int vma_get_mapfile(pid_t pid, char *fname,
+ struct vma_area *vma,
+ struct vma_file_info *vfi,
+ struct vma_file_info *prev_vfi)
{
- char path[32];
+ super_req_mfd_info_entry_t info = { };
+ int ret;
+
+ pr_debug("%d %s %lx-%lx\n", pid, fname,
+ (unsigned long)vma->e->start,
+ (unsigned long)vma->e->end);
if (prev_vfi->vma && vfi_equal(vfi, prev_vfi)) {
struct vma_area *prev = prev_vfi->vma;
@@ -205,44 +214,64 @@ static int vma_get_mapfile(char *fname, struct vma_area *vma, DIR *mfd,
return 0;
}
- /* Figure out if it's file mapping */
- snprintf(path, sizeof(path), "%"PRIx64"-%"PRIx64, vma->e->start, vma->e->end);
-
- /*
- * Note that we "open" it in dumper process space
- * so later we might refer to it via /proc/self/fd/vm_file_fd
- * if needed.
- */
- vma->vm_file_fd = openat(dirfd(mfd), path, O_RDONLY);
- if (vma->vm_file_fd < 0) {
- if (errno == ENOENT)
- /* Just mapping w/o map_files link */
+ ret = cr_super_fetch_vma_file_info(pid, vma, &info);
+ if (ret < 0) {
+ /*
+ * Mapping without map_files link
+ */
+ if (ret == -ENOENT) {
+ vma->vm_file_fd = -1;
return 0;
+ }
- if (errno == ENXIO) {
- struct stat buf;
-
- if (fstatat(dirfd(mfd), path, &buf, 0))
- return -1;
-
- if (S_ISSOCK(buf.st_mode)) {
- pr_info("Found socket mapping @%"PRIx64"\n", vma->e->start);
- vma->vm_socket_id = buf.st_ino;
- vma->e->status |= VMA_AREA_SOCKET | VMA_AREA_REGULAR;
- return 0;
- }
+ /*
+ * Anything else is plain error.
+ */
+ pr_err("Can't fetch info of %d for mapping %lx-%lx\n",
+ pid, (unsigned long)vma->e->start,
+ (unsigned long)vma->e->end);
+ return -1;
+ }
- if ((buf.st_mode & S_IFMT) == 0 && !strcmp(fname, AIO_FNAME)) {
- /* AIO ring, let's try */
- close(vma->vm_file_fd);
- vma->aio_nr_req = -1;
- vma->e->status = VMA_AREA_AIORING;
- return 0;
- }
+ if (info.o_rdonly_error == -ENOENT) {
+ /*
+ * Mapping without map_files link
+ */
+ vma->vm_file_fd = -1;
+ return 0;
+ } else if (info.o_rdonly_error == -ENXIO) {
+ if (S_ISSOCK(info.st.st_mode)) {
+ pr_info("Found socket mapping %lx-%lx\n",
+ (unsigned long)vma->e->start,
+ (unsigned long)vma->e->end);
+ vma->vm_socket_id = info.st.st_ino;
+ vma->e->status |= VMA_AREA_SOCKET | VMA_AREA_REGULAR;
+ return 0;
+ }
- pr_err("Unknown shit %o (%s)\n", buf.st_mode, fname);
+ if ((info.st.st_mode & S_IFMT) == 0 && !strcmp(fname, AIO_FNAME)) {
+ /* AIO ring, let's try */
+ close(vma->vm_file_fd);
+ vma->vm_file_fd = -1;
+ vma->aio_nr_req = -1;
+ vma->e->status = VMA_AREA_AIORING;
+ return 0;
}
+ pr_err("Unknown shit mapping %o (%s)\n", info.st.st_mode, fname);
+ return -1;
+ } else if (info.o_rdonly_error) {
+ pr_err("Unknown error %d while fetching info of %d for mapping %lx-%lx\n",
+ info.o_rdonly_error, pid, (unsigned long)vma->e->start,
+ (unsigned long)vma->e->end);
+ return -1;
+ }
+
+ vma->vm_file_fd = cr_super_open_vma_file(pid, vma);
+ if (vma->vm_file_fd < 0) {
+ pr_err("Can't fetch file of %d for mapping %lx-%lx\n",
+ pid, (unsigned long)vma->e->start,
+ (unsigned long)vma->e->end);
return -1;
}
@@ -269,11 +298,7 @@ static int vma_get_mapfile(char *fname, struct vma_area *vma, DIR *mfd,
return 0;
}
- if (fstat(vma->vm_file_fd, vma->vmst) < 0) {
- pr_perror("Failed fstat on map %"PRIx64"", vma->e->start);
- return -1;
- }
-
+ *vma->vmst = info.st;
return 0;
}
@@ -342,12 +367,12 @@ static inline int handle_vvar_vma(struct vma_area *vma)
#endif
static int handle_vma(pid_t pid, struct vma_area *vma_area,
- char *file_path, DIR *map_files_dir,
+ char *file_path,
struct vma_file_info *vfi,
struct vma_file_info *prev_vfi,
struct vm_area_list *vma_area_list)
{
- if (vma_get_mapfile(file_path, vma_area, map_files_dir, vfi, prev_vfi))
+ if (vma_get_mapfile(pid, file_path, vma_area, vfi, prev_vfi))
goto err_bogus_mapfile;
if (vma_area->e->status != 0) {
@@ -499,7 +524,6 @@ int parse_smaps(pid_t pid, struct vm_area_list *vma_area_list)
struct vma_file_info vfi;
struct vma_file_info prev_vfi = {};
- DIR *map_files_dir = NULL;
struct bfd f;
vma_area_list->nr = 0;
@@ -515,10 +539,6 @@ int parse_smaps(pid_t pid, struct vm_area_list *vma_area_list)
if (bfdopenr(&f))
goto err_n;
- map_files_dir = opendir_proc(pid, "map_files");
- if (!map_files_dir) /* old kernel? */
- goto err;
-
while (1) {
int num;
char file_path[32];
@@ -591,8 +611,8 @@ int parse_smaps(pid_t pid, struct vm_area_list *vma_area_list)
goto err;
}
- if (handle_vma(pid, vma_area, file_path, map_files_dir,
- &vfi, &prev_vfi, vma_area_list))
+ if (handle_vma(pid, vma_area, file_path,
+ &vfi, &prev_vfi, vma_area_list))
goto err;
}
@@ -602,9 +622,6 @@ int parse_smaps(pid_t pid, struct vm_area_list *vma_area_list)
err:
bclose(&f);
err_n:
- if (map_files_dir)
- closedir(map_files_dir);
-
xfree(vma_area);
return ret;
--
2.4.3
More information about the CRIU
mailing list