[CRIU] [PATCH cr] fown: get pid and uid-s from parasite
Andrey Vagin
avagin at openvz.org
Tue Sep 4 09:24:40 EDT 2012
A task may be in another pidns and crtools should get a pid from this pidns.
Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
cr-dump.c | 49 +++++++++++++++----------------------------
include/parasite-syscall.h | 6 +++-
include/util-net.h | 15 +++++++++++-
parasite-syscall.c | 4 +-
util-net.c | 40 +++++++++++++++++++++++++++--------
5 files changed, 67 insertions(+), 47 deletions(-)
diff --git a/cr-dump.c b/cr-dump.c
index 9964689..f710f44 100644
--- a/cr-dump.c
+++ b/cr-dump.c
@@ -184,11 +184,9 @@ static int dump_task_exe_link(pid_t pid, MmEntry *mm)
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) {
pr_perror("Can't stat fd %d\n", lfd);
return -1;
@@ -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->flags = fcntl(lfd, F_GETFL);
p->pid = pid;
- p->fd_flags = fd_flags;
+ p->fd_flags = opts->flags;
fown_entry__init(&p->fown);
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);
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
return -1;
}
- if (fcntl(lfd, F_GETOWN_EX, (long)&owner_ex)) {
- pr_perror("Can't get owners on %d\n", lfd);
- return -1;
- }
-
- /*
- * Simple case -- nothing is changed.
- */
- if (owner_ex.pid == 0)
+ if (opts->fown.pid == 0)
return 0;
- if (fcntl(lfd, F_GETOWNER_UIDS, (long)&v)) {
- pr_perror("Can't get owner uids on %d\n", lfd);
- 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;
+ p->fown.pid = opts->fown.pid;
+ p->fown.pid_type = opts->fown.pid_type;
+ p->fown.uid = opts->fown.uid;
+ p->fown.euid = opts->fown.euid;
return 0;
}
@@ -264,13 +249,13 @@ static int dump_chrdev(struct fd_parms *p, int lfd, const struct cr_fdset *set)
#define PIPEFS_MAGIC 0x50495045
#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)
{
struct fd_parms p;
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);
return -1;
}
@@ -316,7 +301,7 @@ static int dump_task_files_seized(struct parasite_ctl *ctl, const struct cr_fdse
struct parasite_drain_fd *dfds)
{
int *lfds;
- char *flags;
+ struct fd_opts *opts;
int i, ret = -1;
pr_info("\n");
@@ -327,16 +312,16 @@ static int dump_task_files_seized(struct parasite_ctl *ctl, const struct cr_fdse
if (!lfds)
goto err;
- flags = xmalloc(dfds->nr_fds * sizeof(char));
- if (!flags)
+ opts = xmalloc(dfds->nr_fds * sizeof(struct fd_opts));
+ if (!opts)
goto err1;
- ret = parasite_drain_fds_seized(ctl, dfds, lfds, flags);
+ ret = parasite_drain_fds_seized(ctl, dfds, lfds, opts);
if (ret)
goto err2;
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]);
if (ret)
goto err2;
@@ -344,7 +329,7 @@ static int dump_task_files_seized(struct parasite_ctl *ctl, const struct cr_fdse
pr_info("----------------------------------------\n");
err2:
- xfree(flags);
+ xfree(opts);
err1:
xfree(lfds);
err:
diff --git a/include/parasite-syscall.h b/include/parasite-syscall.h
index 7a72010..1fd0dc0 100644
--- a/include/parasite-syscall.h
+++ b/include/parasite-syscall.h
@@ -38,8 +38,10 @@ extern int parasite_dump_thread_seized(struct parasite_ctl *ctl, pid_t pid,
unsigned int **tid_add, u32 *tid);
struct parasite_drain_fd;
-extern int parasite_drain_fds_seized(struct parasite_ctl *ctl, struct parasite_drain_fd *dfds,
- int *lfds, char *flags);
+struct fd_opts;
+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 struct parasite_ctl *parasite_infect_seized(pid_t pid,
diff --git a/include/util-net.h b/include/util-net.h
index ec58881..a4c33c9 100644
--- a/include/util-net.h
+++ b/include/util-net.h
@@ -21,16 +21,27 @@
#define CR_SCM_MSG_SIZE (1024)
#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 msghdr hdr;
struct iovec iov;
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,
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)
{
diff --git a/parasite-syscall.c b/parasite-syscall.c
index 2c3dd4a..9a27470 100644
--- a/parasite-syscall.c
+++ b/parasite-syscall.c
@@ -602,7 +602,7 @@ out:
}
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;
@@ -613,7 +613,7 @@ int parasite_drain_fds_seized(struct parasite_ctl *ctl,
goto err;
}
- ret = recv_fds(ctl->tsock, lfds, dfds->nr_fds, flags);
+ ret = recv_fds(ctl->tsock, lfds, dfds->nr_fds, opts);
if (ret) {
pr_err("Can't retrieve FDs from socket\n");
goto err;
diff --git a/util-net.c b/util-net.c
index 1d5a360..0feae03 100644
--- a/util-net.c
+++ b/util-net.c
@@ -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(sizeof(fdset->msg_buf) < (CMSG_SPACE(sizeof(int) * CR_SCM_MAX_FD)));
- fdset->iov.iov_base = &fdset->msg;
- fdset->iov.iov_len = with_flags ? sizeof(fdset->msg) : 1;
+ fdset->iov.iov_base = fdset->opts;
+ fdset->iov.iov_len = with_flags ? sizeof(fdset->opts) : 1;
fdset->hdr.msg_iov = &fdset->iov;
fdset->hdr.msg_iovlen = 1;
@@ -64,13 +64,35 @@ int send_fds(int sock, struct sockaddr_un *saddr, int len,
int 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)
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,
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 cmsghdr *cmsg;
@@ -90,7 +112,7 @@ int recv_fds(int sock, int *fds, int nr_fds, char *flags)
int ret;
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) {
min_fd = min(CR_SCM_MAX_FD, nr_fds - i);
scm_fdset_init_chunk(&fdset, min_fd);
@@ -120,8 +142,8 @@ int recv_fds(int sock, int *fds, int nr_fds, char *flags)
if (unlikely(min_fd <= 0))
return -1;
builtin_memcpy(&fds[i], cmsg_data, sizeof(int) * min_fd);
- if (flags)
- builtin_memcpy(flags + i, fdset.msg, sizeof(char) * min_fd);
+ if (opts)
+ builtin_memcpy(opts + i, fdset.opts, sizeof(struct fd_opts) * min_fd);
}
return 0;
--
1.7.1
More information about the CRIU
mailing list