Commit c69be631 authored by Andrey Vagin's avatar Andrey Vagin Committed by Pavel Emelyanov

mntns: crtools: stat pathes relatively of a mntns root

If we dump tasks with mntns, we should look at pathes from point of a mntns root.

Now we support a situation when a root of an init task has the same root as the
mntns root, because we have not another way to get a root of mntns.

A path to an unix socket is copied, because the origin copy will be gone
out from the function, where it was created.
Signed-off-by: 's avatarAndrey Vagin <avagin@openvz.org>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 3a60163b
...@@ -45,6 +45,7 @@ ...@@ -45,6 +45,7 @@
#include "eventpoll.h" #include "eventpoll.h"
#include "inotify.h" #include "inotify.h"
#include "pstree.h" #include "pstree.h"
#include "mount.h"
#include "protobuf.h" #include "protobuf.h"
#include "protobuf/fdinfo.pb-c.h" #include "protobuf/fdinfo.pb-c.h"
...@@ -1474,6 +1475,9 @@ int cr_dump_tasks(pid_t pid, const struct cr_options *opts) ...@@ -1474,6 +1475,9 @@ int cr_dump_tasks(pid_t pid, const struct cr_options *opts)
* in the dump stage * in the dump stage
*/ */
if (mntns_collect_root(root_item->pid.real))
goto err;
collect_sockets(); collect_sockets();
glob_fdset = cr_glob_fdset_open(O_DUMP); glob_fdset = cr_glob_fdset_open(O_DUMP);
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "crtools.h" #include "crtools.h"
#include "mount.h"
#include "files.h" #include "files.h"
#include "image.h" #include "image.h"
#include "list.h" #include "list.h"
...@@ -257,7 +258,7 @@ dump_entry: ...@@ -257,7 +258,7 @@ dump_entry:
&rpe, remap_file_path_entry); &rpe, remap_file_path_entry);
} }
static int check_path_remap(char *path, const struct stat *ost, int lfd, u32 id) static int check_path_remap(char *rpath, const struct stat *ost, int lfd, u32 id)
{ {
int ret; int ret;
struct stat pst; struct stat pst;
...@@ -269,9 +270,9 @@ static int check_path_remap(char *path, const struct stat *ost, int lfd, u32 id) ...@@ -269,9 +270,9 @@ static int check_path_remap(char *path, const struct stat *ost, int lfd, u32 id)
* be careful whether anybody still has any of its hardlinks * be careful whether anybody still has any of its hardlinks
* also open. * also open.
*/ */
return dump_ghost_remap(path, ost, lfd, id); return dump_ghost_remap(rpath + 1, ost, lfd, id);
ret = stat(path, &pst); ret = fstatat(mntns_root, rpath, &pst, 0);
if (ret < 0) { if (ret < 0) {
/* /*
* FIXME linked file, but path is not accessible (unless any * FIXME linked file, but path is not accessible (unless any
...@@ -304,13 +305,13 @@ static int check_path_remap(char *path, const struct stat *ost, int lfd, u32 id) ...@@ -304,13 +305,13 @@ static int check_path_remap(char *path, const struct stat *ost, int lfd, u32 id)
int dump_one_reg_file(int lfd, u32 id, const struct fd_parms *p) int dump_one_reg_file(int lfd, u32 id, const struct fd_parms *p)
{ {
char fd_str[128]; char fd_str[128];
char path[PATH_MAX]; char rpath[PATH_MAX + 1] = ".", *path = rpath + 1;;
int len, rfd; int len, rfd;
RegFileEntry rfe = REG_FILE_ENTRY__INIT; RegFileEntry rfe = REG_FILE_ENTRY__INIT;
snprintf(fd_str, sizeof(fd_str), "/proc/self/fd/%d", lfd); snprintf(fd_str, sizeof(fd_str), "/proc/self/fd/%d", lfd);
len = readlink(fd_str, path, sizeof(path) - 1); len = readlink(fd_str, path, sizeof(rpath) - 2);
if (len < 0) { if (len < 0) {
pr_perror("Can't readlink %s", fd_str); pr_perror("Can't readlink %s", fd_str);
return len; return len;
...@@ -320,7 +321,7 @@ int dump_one_reg_file(int lfd, u32 id, const struct fd_parms *p) ...@@ -320,7 +321,7 @@ int dump_one_reg_file(int lfd, u32 id, const struct fd_parms *p)
pr_info("Dumping path for %d fd via self %d [%s]\n", pr_info("Dumping path for %d fd via self %d [%s]\n",
p->fd, lfd, path); p->fd, lfd, path);
if (check_path_remap(path, &p->stat, lfd, id)) if (check_path_remap(rpath, &p->stat, lfd, id))
return -1; return -1;
rfe.id = id; rfe.id = id;
......
#ifndef MOUNT_H__ #ifndef MOUNT_H__
#define MOUNT_H__ #define MOUNT_H__
extern int mntns_root;
int mntns_collect_root(pid_t pid);
struct proc_mountinfo; struct proc_mountinfo;
extern int open_mount(unsigned int s_dev); extern int open_mount(unsigned int s_dev);
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include "protobuf/mnt.pb-c.h" #include "protobuf/mnt.pb-c.h"
static struct mount_info *mntinfo; static struct mount_info *mntinfo;
int mntns_root = -1;
int open_mount(unsigned int s_dev) int open_mount(unsigned int s_dev)
{ {
...@@ -499,3 +500,37 @@ void show_mountpoints(int fd, struct cr_options *o) ...@@ -499,3 +500,37 @@ void show_mountpoints(int fd, struct cr_options *o)
{ {
pb_show_plain(fd, mnt_entry); pb_show_plain(fd, mnt_entry);
} }
int mntns_collect_root(pid_t pid)
{
int fd, pfd;
int ret;
char path[PATH_MAX + 1];
/* If /proc/pid/root links on '/', it signs that a root of the task
* and a root of mntns is the same. */
pfd = open_pid_proc(pid);
ret = readlinkat(pfd, "root", path, PATH_MAX);
if (ret < 0)
return ret;
path[ret + 1] = '\0';
if (ret != 1 || path[0] != '/') {
pr_err("The root task has another root than mntns: %s\n", path);
close_pid_proc();
return -1;
}
fd = openat(pfd, "root", O_RDONLY | O_DIRECTORY, 0);
close_pid_proc();
if (fd < 0) {
pr_perror("Can't open the task root");
return -1;
}
mntns_root = fd;
return 0;
}
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "util-net.h" #include "util-net.h"
#include "sockets.h" #include "sockets.h"
#include "sk-queue.h" #include "sk-queue.h"
#include "mount.h"
#include "protobuf.h" #include "protobuf.h"
#include "protobuf/sk-unix.pb-c.h" #include "protobuf/sk-unix.pb-c.h"
...@@ -261,6 +262,7 @@ static int unix_collect_one(const struct unix_diag_msg *m, ...@@ -261,6 +262,7 @@ static int unix_collect_one(const struct unix_diag_msg *m,
if (name[0] != '\0') { if (name[0] != '\0') {
struct unix_diag_vfs *uv; struct unix_diag_vfs *uv;
struct stat st; struct stat st;
char rpath[PATH_MAX];
if (name[0] != '/') { if (name[0] != '/') {
pr_warn("Relative bind path '%s' " pr_warn("Relative bind path '%s' "
...@@ -275,9 +277,10 @@ static int unix_collect_one(const struct unix_diag_msg *m, ...@@ -275,9 +277,10 @@ static int unix_collect_one(const struct unix_diag_msg *m,
} }
uv = RTA_DATA(tb[UNIX_DIAG_VFS]); uv = RTA_DATA(tb[UNIX_DIAG_VFS]);
if (stat(name, &st)) { snprintf(rpath, sizeof(rpath), ".%s", name);
if (fstatat(mntns_root, rpath, &st, 0)) {
pr_perror("Can't stat socket %d(%s)", pr_perror("Can't stat socket %d(%s)",
m->udiag_ino, name); m->udiag_ino, rpath);
goto skip; goto skip;
} }
......
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