[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