[CRIU] [PATCH] proc: Allocate and get vma fstat in vma_get_mapfile

Pavel Emelyanov xemul at parallels.com
Fri Dec 19 04:59:08 PST 2014


We will need to detect aio mappings soon, so this is a preparation,
that makes future patching simpler.

Also move aufs stat-ing into aufs code to keep more aufs logic in
one place.

Signed-off-by: Pavel Emelyanov <xemul at parallels.com>
---
 proc_parse.c  | 58 ++++++++++++++++++++++++++++++----------------------------
 sysfs_parse.c |  7 +++++++
 2 files changed, 37 insertions(+), 28 deletions(-)

diff --git a/proc_parse.c b/proc_parse.c
index 649ecbb..7d21eb9 100644
--- a/proc_parse.c
+++ b/proc_parse.c
@@ -234,6 +234,10 @@ static int vma_get_mapfile(struct vma_area *vma, DIR *mfd,
 	 */
 	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 */
+			return 0;
+
 		if (errno == ENXIO) {
 			struct stat buf;
 
@@ -243,15 +247,34 @@ static int vma_get_mapfile(struct vma_area *vma, DIR *mfd,
 			if (!S_ISSOCK(buf.st_mode))
 				return -1;
 
-			pr_info("Found socket %"PRIu64" mapping @%"PRIx64"\n",
-					buf.st_ino, vma->e->start);
-			vma->e->status |= VMA_AREA_SOCKET | VMA_AREA_REGULAR;
 			vma->vm_socket_id = buf.st_ino;
-		} else if (errno != ENOENT)
-			return -1;
-	} else if (opts.aufs && fixup_aufs_vma_fd(vma) < 0)
+			pr_info("Found socket mapping @%"PRIx64"\n", vma->e->start);
+			vma->e->status |= VMA_AREA_SOCKET | VMA_AREA_REGULAR;
+			return 0;
+		}
+
+		return -1;
+	}
+
+	vma->vmst = xmalloc(sizeof(struct stat));
+	if (!vma->vmst)
 		return -1;
 
+	if (opts.aufs)
+		/*
+		 * For AUFS support, we cannot fstat() a file descriptor that
+		 * is a symbolic link to a branch (it would return different
+		 * dev/ino than the real file).  Instead, we stat() using the
+		 * full pathname that we saved before.
+		 */
+
+		return fixup_aufs_vma_fd(vma);
+
+	if (fstat(vma->vm_file_fd, vma->vmst) < 0) {
+		pr_perror("Failed fstat on map %"PRIx64"", vma->e->start);
+		return -1;
+	}
+
 	return 0;
 }
 
@@ -460,28 +483,7 @@ int parse_smaps(pid_t pid, struct vm_area_list *vma_area_list)
 			vma_area->vmst = prev->vmst;
 			vma_area->mnt_id = prev->mnt_id;
 		} else if (vma_area->vm_file_fd >= 0) {
-			struct stat *st_buf;
-
-			st_buf = vma_area->vmst = xmalloc(sizeof(*st_buf));
-			if (!st_buf)
-				goto err;
-
-			/*
-			 * For AUFS support, we cannot fstat() a file descriptor that
-			 * is a symbolic link to a branch (it would return different
-			 * dev/ino than the real file).  Instead, we stat() using the
-			 * full pathname that we saved before.
-			 */
-			if (vma_area->aufs_fpath) {
-				if (stat(vma_area->aufs_fpath, st_buf) < 0) {
-					pr_perror("Failed stat on %d's map %lu (%s)",
-						pid, start, vma_area->aufs_fpath);
-					goto err;
-				}
-			} else if (fstat(vma_area->vm_file_fd, st_buf) < 0) {
-				pr_perror("Failed fstat on %d's map %lu", pid, start);
-				goto err;
-			}
+			struct stat *st_buf = vma_area->vmst;
 
 			if (S_ISREG(st_buf->st_mode))
 				/* regular file mapping -- supported */;
diff --git a/sysfs_parse.c b/sysfs_parse.c
index 9b81463..771a236 100644
--- a/sysfs_parse.c
+++ b/sysfs_parse.c
@@ -6,6 +6,7 @@
 #include <errno.h>
 #include <sys/types.h>
 #include <dirent.h>
+#include <sys/stat.h>
 
 #include "cr_options.h"
 #include "criu-log.h"
@@ -298,6 +299,12 @@ int fixup_aufs_vma_fd(struct vma_area *vma)
 		pr_debug("Saved AUFS paths %s and %s\n", vma->aufs_rpath, vma->aufs_fpath);
 	}
 
+	if (stat(vma->aufs_fpath, vma->vmst) < 0) {
+		pr_perror("Failed stat on map %"PRIx64" (%s)",
+				vma->e->start, vma->aufs_fpath);
+		return -1;
+	}
+
 	return 0;
 }
 
-- 
1.8.4.2



More information about the CRIU mailing list