[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