Commit 97cfb707 authored by Andrey Vagin's avatar Andrey Vagin Committed by Pavel Emelyanov

fown: get pid and uid-s from parasite

A task may be in another pidns and crtools should get a pid from this pidns.
Signed-off-by: 's avatarAndrey Vagin <avagin@openvz.org>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 05466cc3
...@@ -184,11 +184,9 @@ static int dump_task_exe_link(pid_t pid, MmEntry *mm) ...@@ -184,11 +184,9 @@ static int dump_task_exe_link(pid_t pid, MmEntry *mm)
return ret; return ret;
} }
static int fill_fd_params(pid_t pid, int fd, int lfd, char fd_flags, struct fd_parms *p) static int fill_fd_params(pid_t pid, int fd, int lfd,
struct fd_opts *opts, struct fd_parms *p)
{ {
struct f_owner_ex owner_ex;
u32 v[2];
if (fstat(lfd, &p->stat) < 0) { if (fstat(lfd, &p->stat) < 0) {
pr_perror("Can't stat fd %d\n", lfd); pr_perror("Can't stat fd %d\n", lfd);
return -1; return -1;
...@@ -198,12 +196,12 @@ static int fill_fd_params(pid_t pid, int fd, int lfd, char fd_flags, struct fd_p ...@@ -198,12 +196,12 @@ static int fill_fd_params(pid_t pid, int fd, int lfd, char fd_flags, struct fd_p
p->pos = lseek(lfd, 0, SEEK_CUR); p->pos = lseek(lfd, 0, SEEK_CUR);
p->flags = fcntl(lfd, F_GETFL); p->flags = fcntl(lfd, F_GETFL);
p->pid = pid; p->pid = pid;
p->fd_flags = fd_flags; p->fd_flags = opts->flags;
fown_entry__init(&p->fown); fown_entry__init(&p->fown);
pr_info("%d fdinfo %d: pos: 0x%16lx flags: %16o/%#x\n", pr_info("%d fdinfo %d: pos: 0x%16lx flags: %16o/%#x\n",
pid, fd, p->pos, p->flags, (int)fd_flags); pid, fd, p->pos, p->flags, (int)p->fd_flags);
p->fown.signum = fcntl(lfd, F_GETSIG, 0); p->fown.signum = fcntl(lfd, F_GETSIG, 0);
if (p->fown.signum < 0) { if (p->fown.signum < 0) {
...@@ -211,26 +209,13 @@ static int fill_fd_params(pid_t pid, int fd, int lfd, char fd_flags, struct fd_p ...@@ -211,26 +209,13 @@ static int fill_fd_params(pid_t pid, int fd, int lfd, char fd_flags, struct fd_p
return -1; return -1;
} }
if (fcntl(lfd, F_GETOWN_EX, (long)&owner_ex)) { if (opts->fown.pid == 0)
pr_perror("Can't get owners on %d\n", lfd);
return -1;
}
/*
* Simple case -- nothing is changed.
*/
if (owner_ex.pid == 0)
return 0; return 0;
if (fcntl(lfd, F_GETOWNER_UIDS, (long)&v)) { p->fown.pid = opts->fown.pid;
pr_perror("Can't get owner uids on %d\n", lfd); p->fown.pid_type = opts->fown.pid_type;
return -1; p->fown.uid = opts->fown.uid;
} p->fown.euid = opts->fown.euid;
p->fown.uid = v[0];
p->fown.euid = v[1];
p->fown.pid_type = owner_ex.type;
p->fown.pid = owner_ex.pid;
return 0; return 0;
} }
...@@ -264,13 +249,13 @@ static int dump_chrdev(struct fd_parms *p, int lfd, const struct cr_fdset *set) ...@@ -264,13 +249,13 @@ static int dump_chrdev(struct fd_parms *p, int lfd, const struct cr_fdset *set)
#define PIPEFS_MAGIC 0x50495045 #define PIPEFS_MAGIC 0x50495045
#endif #endif
static int dump_one_file(pid_t pid, int fd, int lfd, char fd_flags, static int dump_one_file(pid_t pid, int fd, int lfd, struct fd_opts *opts,
const struct cr_fdset *cr_fdset) const struct cr_fdset *cr_fdset)
{ {
struct fd_parms p; struct fd_parms p;
struct statfs statfs; struct statfs statfs;
if (fill_fd_params(pid, fd, lfd, fd_flags, &p) < 0) { if (fill_fd_params(pid, fd, lfd, opts, &p) < 0) {
pr_perror("Can't get stat on %d", fd); pr_perror("Can't get stat on %d", fd);
return -1; return -1;
} }
...@@ -316,7 +301,7 @@ static int dump_task_files_seized(struct parasite_ctl *ctl, const struct cr_fdse ...@@ -316,7 +301,7 @@ static int dump_task_files_seized(struct parasite_ctl *ctl, const struct cr_fdse
struct parasite_drain_fd *dfds) struct parasite_drain_fd *dfds)
{ {
int *lfds; int *lfds;
char *flags; struct fd_opts *opts;
int i, ret = -1; int i, ret = -1;
pr_info("\n"); pr_info("\n");
...@@ -327,16 +312,16 @@ static int dump_task_files_seized(struct parasite_ctl *ctl, const struct cr_fdse ...@@ -327,16 +312,16 @@ static int dump_task_files_seized(struct parasite_ctl *ctl, const struct cr_fdse
if (!lfds) if (!lfds)
goto err; goto err;
flags = xmalloc(dfds->nr_fds * sizeof(char)); opts = xmalloc(dfds->nr_fds * sizeof(struct fd_opts));
if (!flags) if (!opts)
goto err1; goto err1;
ret = parasite_drain_fds_seized(ctl, dfds, lfds, flags); ret = parasite_drain_fds_seized(ctl, dfds, lfds, opts);
if (ret) if (ret)
goto err2; goto err2;
for (i = 0; i < dfds->nr_fds; i++) { for (i = 0; i < dfds->nr_fds; i++) {
ret = dump_one_file(ctl->pid, dfds->fds[i], lfds[i], flags[i], cr_fdset); ret = dump_one_file(ctl->pid, dfds->fds[i], lfds[i], opts + i, cr_fdset);
close(lfds[i]); close(lfds[i]);
if (ret) if (ret)
goto err2; goto err2;
...@@ -344,7 +329,7 @@ static int dump_task_files_seized(struct parasite_ctl *ctl, const struct cr_fdse ...@@ -344,7 +329,7 @@ static int dump_task_files_seized(struct parasite_ctl *ctl, const struct cr_fdse
pr_info("----------------------------------------\n"); pr_info("----------------------------------------\n");
err2: err2:
xfree(flags); xfree(opts);
err1: err1:
xfree(lfds); xfree(lfds);
err: err:
......
...@@ -38,8 +38,10 @@ extern int parasite_dump_thread_seized(struct parasite_ctl *ctl, pid_t pid, ...@@ -38,8 +38,10 @@ extern int parasite_dump_thread_seized(struct parasite_ctl *ctl, pid_t pid,
unsigned int **tid_add, u32 *tid); unsigned int **tid_add, u32 *tid);
struct parasite_drain_fd; struct parasite_drain_fd;
extern int parasite_drain_fds_seized(struct parasite_ctl *ctl, struct parasite_drain_fd *dfds, struct fd_opts;
int *lfds, char *flags); extern int parasite_drain_fds_seized(struct parasite_ctl *ctl,
struct parasite_drain_fd *dfds,
int *lfds, struct fd_opts *flags);
extern int parasite_cure_seized(struct parasite_ctl *ctl); extern int parasite_cure_seized(struct parasite_ctl *ctl);
extern struct parasite_ctl *parasite_infect_seized(pid_t pid, extern struct parasite_ctl *parasite_infect_seized(pid_t pid,
......
...@@ -21,16 +21,27 @@ ...@@ -21,16 +21,27 @@
#define CR_SCM_MSG_SIZE (1024) #define CR_SCM_MSG_SIZE (1024)
#define CR_SCM_MAX_FD (252) #define CR_SCM_MAX_FD (252)
struct fd_opts {
char flags;
struct {
uint32_t uid;
uint32_t euid;
uint32_t signum;
uint32_t pid_type;
uint32_t pid;
} fown;
};
struct scm_fdset { struct scm_fdset {
struct msghdr hdr; struct msghdr hdr;
struct iovec iov; struct iovec iov;
char msg_buf[CR_SCM_MSG_SIZE]; char msg_buf[CR_SCM_MSG_SIZE];
char msg[CR_SCM_MAX_FD]; struct fd_opts opts[CR_SCM_MAX_FD];
}; };
extern int send_fds(int sock, struct sockaddr_un *saddr, int saddr_len, extern int send_fds(int sock, struct sockaddr_un *saddr, int saddr_len,
int *fds, int nr_fds, bool with_flags); int *fds, int nr_fds, bool with_flags);
extern int recv_fds(int sock, int *fds, int nr_fds, char *flags); extern int recv_fds(int sock, int *fds, int nr_fds, struct fd_opts *opts);
static inline int send_fd(int sock, struct sockaddr_un *saddr, int saddr_len, int fd) static inline int send_fd(int sock, struct sockaddr_un *saddr, int saddr_len, int fd)
{ {
......
...@@ -602,7 +602,7 @@ out: ...@@ -602,7 +602,7 @@ out:
} }
int parasite_drain_fds_seized(struct parasite_ctl *ctl, int parasite_drain_fds_seized(struct parasite_ctl *ctl,
struct parasite_drain_fd *dfds, int *lfds, char *flags) struct parasite_drain_fd *dfds, int *lfds, struct fd_opts *opts)
{ {
int ret = -1; int ret = -1;
...@@ -613,7 +613,7 @@ int parasite_drain_fds_seized(struct parasite_ctl *ctl, ...@@ -613,7 +613,7 @@ int parasite_drain_fds_seized(struct parasite_ctl *ctl,
goto err; goto err;
} }
ret = recv_fds(ctl->tsock, lfds, dfds->nr_fds, flags); ret = recv_fds(ctl->tsock, lfds, dfds->nr_fds, opts);
if (ret) { if (ret) {
pr_err("Can't retrieve FDs from socket\n"); pr_err("Can't retrieve FDs from socket\n");
goto err; goto err;
......
...@@ -28,8 +28,8 @@ static int *scm_fdset_init(struct scm_fdset *fdset, struct sockaddr_un *saddr, ...@@ -28,8 +28,8 @@ static int *scm_fdset_init(struct scm_fdset *fdset, struct sockaddr_un *saddr,
BUILD_BUG_ON(CR_SCM_MAX_FD > SCM_MAX_FD); BUILD_BUG_ON(CR_SCM_MAX_FD > SCM_MAX_FD);
BUILD_BUG_ON(sizeof(fdset->msg_buf) < (CMSG_SPACE(sizeof(int) * CR_SCM_MAX_FD))); BUILD_BUG_ON(sizeof(fdset->msg_buf) < (CMSG_SPACE(sizeof(int) * CR_SCM_MAX_FD)));
fdset->iov.iov_base = &fdset->msg; fdset->iov.iov_base = fdset->opts;
fdset->iov.iov_len = with_flags ? sizeof(fdset->msg) : 1; fdset->iov.iov_len = with_flags ? sizeof(fdset->opts) : 1;
fdset->hdr.msg_iov = &fdset->iov; fdset->hdr.msg_iov = &fdset->iov;
fdset->hdr.msg_iovlen = 1; fdset->hdr.msg_iovlen = 1;
...@@ -64,13 +64,35 @@ int send_fds(int sock, struct sockaddr_un *saddr, int len, ...@@ -64,13 +64,35 @@ int send_fds(int sock, struct sockaddr_un *saddr, int len,
int j; int j;
for (j = 0; j < min_fd; j++) { for (j = 0; j < min_fd; j++) {
int flags; int flags, fd = fds[i + j];
struct fd_opts *p = fdset.opts + j;
struct f_owner_ex owner_ex;
u32 v[2];
flags = sys_fcntl(fds[i + j], F_GETFD, 0); flags = sys_fcntl(fd, F_GETFD, 0);
if (flags < 0) if (flags < 0)
return -1; return -1;
fdset.msg[j] = (char)flags; p->flags = (char)flags;
if (sys_fcntl(fd, F_GETOWN_EX, (long)&owner_ex))
return -1;
/*
* Simple case -- nothing is changed.
*/
if (owner_ex.pid == 0) {
p->fown.pid = 0;
continue;
}
if (sys_fcntl(fd, F_GETOWNER_UIDS, (long)&v))
return -1;
p->fown.uid = v[0];
p->fown.euid = v[1];
p->fown.pid_type = owner_ex.type;
p->fown.pid = owner_ex.pid;
} }
} }
...@@ -82,7 +104,7 @@ int send_fds(int sock, struct sockaddr_un *saddr, int len, ...@@ -82,7 +104,7 @@ int send_fds(int sock, struct sockaddr_un *saddr, int len,
return 0; return 0;
} }
int recv_fds(int sock, int *fds, int nr_fds, char *flags) int recv_fds(int sock, int *fds, int nr_fds, struct fd_opts *opts)
{ {
struct scm_fdset fdset; struct scm_fdset fdset;
struct cmsghdr *cmsg; struct cmsghdr *cmsg;
...@@ -90,7 +112,7 @@ int recv_fds(int sock, int *fds, int nr_fds, char *flags) ...@@ -90,7 +112,7 @@ int recv_fds(int sock, int *fds, int nr_fds, char *flags)
int ret; int ret;
int i, min_fd; int i, min_fd;
cmsg_data = scm_fdset_init(&fdset, NULL, 0, flags != NULL); cmsg_data = scm_fdset_init(&fdset, NULL, 0, opts != NULL);
for (i = 0; i < nr_fds; i += min_fd) { for (i = 0; i < nr_fds; i += min_fd) {
min_fd = min(CR_SCM_MAX_FD, nr_fds - i); min_fd = min(CR_SCM_MAX_FD, nr_fds - i);
scm_fdset_init_chunk(&fdset, min_fd); scm_fdset_init_chunk(&fdset, min_fd);
...@@ -120,8 +142,8 @@ int recv_fds(int sock, int *fds, int nr_fds, char *flags) ...@@ -120,8 +142,8 @@ int recv_fds(int sock, int *fds, int nr_fds, char *flags)
if (unlikely(min_fd <= 0)) if (unlikely(min_fd <= 0))
return -1; return -1;
builtin_memcpy(&fds[i], cmsg_data, sizeof(int) * min_fd); builtin_memcpy(&fds[i], cmsg_data, sizeof(int) * min_fd);
if (flags) if (opts)
builtin_memcpy(flags + i, fdset.msg, sizeof(char) * min_fd); builtin_memcpy(opts + i, fdset.opts, sizeof(struct fd_opts) * min_fd);
} }
return 0; 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