Commit 2749d9e6 authored by Saied Kazemi's avatar Saied Kazemi Committed by Pavel Emelyanov

Rework fixup_aufs_vma_fd() for non-AUFS links

This patch reworks fixup_aufs_vma_fd() to let symbolic links in
/proc/<pid>/map_files that are not pointing to AUFS branch names follow
the non-AUFS applcation logic.

The use case that prompted this commit was an application mapping
/dev/zero as shared and writeable which shows up in map_files as:

lrw------- ... 7fc5c5a5f000-7fc5c5a60000 -> /dev/zero (deleted)

If the AUFS support code reads the link, it will have to strip off the
" (deleted)" string added by the kernel but core CRIU code already
does this.
Signed-off-by: 's avatarSaied Kazemi <saied@google.com>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 97743f42
...@@ -275,15 +275,24 @@ static int vma_get_mapfile(char *fname, struct vma_area *vma, DIR *mfd, ...@@ -275,15 +275,24 @@ static int vma_get_mapfile(char *fname, struct vma_area *vma, DIR *mfd,
if (!vma->vmst) if (!vma->vmst)
return -1; return -1;
if (opts.aufs)
/* /*
* For AUFS support, we cannot fstat() a file descriptor that * For AUFS support, we need to check if the symbolic link
* is a symbolic link to a branch (it would return different * points to a branch. If it does, we cannot fstat() its file
* dev/ino than the real file). Instead, we stat() using the * descriptor because it would return a different dev/ino than
* full pathname that we saved before. * the real file. If fixup_aufs_vma_fd() returns positive,
* it means that it has stat()'ed using the full pathname.
* Zero return means that the symbolic link does not point to
* a branch and we can do fstat() below.
*/ */
if (opts.aufs) {
int ret;
return fixup_aufs_vma_fd(vma); ret = fixup_aufs_vma_fd(vma);
if (ret < 0)
return -1;
if (ret > 0)
return 0;
}
if (fstat(vma->vm_file_fd, vma->vmst) < 0) { if (fstat(vma->vm_file_fd, vma->vmst) < 0) {
pr_perror("Failed fstat on map %"PRIx64"", vma->e->start); pr_perror("Failed fstat on map %"PRIx64"", vma->e->start);
......
...@@ -282,21 +282,13 @@ int fixup_aufs_vma_fd(struct vma_area *vma) ...@@ -282,21 +282,13 @@ int fixup_aufs_vma_fd(struct vma_area *vma)
return -1; return -1;
len = fixup_aufs_path(&path[1], sizeof path - 1); len = fixup_aufs_path(&path[1], sizeof path - 1);
if (len < 0) if (len <= 0)
return -1; return len;
if (len == 0) {
/*
* The vma is associated with a map_files entry
* that does not expose the branch pathname
* (e.g., /dev/zero). In this case, we can use
* the path.
*/
file = &path[1];
} else {
vma->aufs_rpath = xmalloc(len + 2); vma->aufs_rpath = xmalloc(len + 2);
if (!vma->aufs_rpath) if (!vma->aufs_rpath)
return -1; return -1;
strcpy(vma->aufs_rpath, path); strcpy(vma->aufs_rpath, path);
if (opts.root) { if (opts.root) {
vma->aufs_fpath = xmalloc(strlen(opts.root) + 1 + len + 1); vma->aufs_fpath = xmalloc(strlen(opts.root) + 1 + len + 1);
...@@ -307,7 +299,6 @@ int fixup_aufs_vma_fd(struct vma_area *vma) ...@@ -307,7 +299,6 @@ int fixup_aufs_vma_fd(struct vma_area *vma)
} }
pr_debug("Saved AUFS paths %s and %s\n", vma->aufs_rpath, vma->aufs_fpath); pr_debug("Saved AUFS paths %s and %s\n", vma->aufs_rpath, vma->aufs_fpath);
file = vma->aufs_fpath; file = vma->aufs_fpath;
}
if (stat(file, vma->vmst) < 0) { if (stat(file, vma->vmst) < 0) {
pr_perror("Failed stat on map %"PRIx64" (%s)", pr_perror("Failed stat on map %"PRIx64" (%s)",
...@@ -315,7 +306,7 @@ int fixup_aufs_vma_fd(struct vma_area *vma) ...@@ -315,7 +306,7 @@ int fixup_aufs_vma_fd(struct vma_area *vma)
return -1; return -1;
} }
return 0; return len;
} }
void free_aufs_branches(void) void free_aufs_branches(void)
......
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