From 2749d9e6ea02dd99bfd72f7c6d608d3d41c271bb Mon Sep 17 00:00:00 2001 From: Saied Kazemi Date: Thu, 22 Jan 2015 02:22:00 +0300 Subject: [PATCH] Rework fixup_aufs_vma_fd() for non-AUFS links This patch reworks fixup_aufs_vma_fd() to let symbolic links in /proc//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: Saied Kazemi Signed-off-by: Pavel Emelyanov --- proc_parse.c | 25 +++++++++++++++++-------- sysfs_parse.c | 37 ++++++++++++++----------------------- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/proc_parse.c b/proc_parse.c index 3da1d9eb6..76fe0daf4 100644 --- a/proc_parse.c +++ b/proc_parse.c @@ -275,15 +275,24 @@ static int vma_get_mapfile(char *fname, struct vma_area *vma, DIR *mfd, 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. - */ + /* + * For AUFS support, we need to check if the symbolic link + * points to a branch. If it does, we cannot fstat() its file + * descriptor because it would return a different dev/ino than + * 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) { pr_perror("Failed fstat on map %"PRIx64"", vma->e->start); diff --git a/sysfs_parse.c b/sysfs_parse.c index 8e236e923..743f92a82 100644 --- a/sysfs_parse.c +++ b/sysfs_parse.c @@ -282,32 +282,23 @@ int fixup_aufs_vma_fd(struct vma_area *vma) return -1; len = fixup_aufs_path(&path[1], sizeof path - 1); - if (len < 0) + if (len <= 0) + return len; + + vma->aufs_rpath = xmalloc(len + 2); + if (!vma->aufs_rpath) return -1; - 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); - if (!vma->aufs_rpath) + strcpy(vma->aufs_rpath, path); + if (opts.root) { + vma->aufs_fpath = xmalloc(strlen(opts.root) + 1 + len + 1); + if (!vma->aufs_fpath) return -1; - strcpy(vma->aufs_rpath, path); - if (opts.root) { - vma->aufs_fpath = xmalloc(strlen(opts.root) + 1 + len + 1); - if (!vma->aufs_fpath) - return -1; - /* skip ./ in path */ - sprintf(vma->aufs_fpath, "%s/%s", opts.root, &path[2]); - } - pr_debug("Saved AUFS paths %s and %s\n", vma->aufs_rpath, vma->aufs_fpath); - file = vma->aufs_fpath; + /* skip ./ in path */ + sprintf(vma->aufs_fpath, "%s/%s", opts.root, &path[2]); } + pr_debug("Saved AUFS paths %s and %s\n", vma->aufs_rpath, vma->aufs_fpath); + file = vma->aufs_fpath; if (stat(file, vma->vmst) < 0) { pr_perror("Failed stat on map %"PRIx64" (%s)", @@ -315,7 +306,7 @@ int fixup_aufs_vma_fd(struct vma_area *vma) return -1; } - return 0; + return len; } void free_aufs_branches(void)