Commit 86c0c5fb authored by Pavel Emelyanov's avatar Pavel Emelyanov

proc: Allocate and get vma fstat in vma_get_mapfile

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: 's avatarPavel Emelyanov <xemul@parallels.com>
parent f4282b47
......@@ -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 */;
......
......@@ -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;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment