[CRIU] [PATCH v3 5/8] dump: hide local opened fd into fd params

Kinsbursky Stanislav skinsbursky at openvz.org
Mon Mar 5 13:01:10 EST 2012


This is a part of fd info. So open and set it with other params.

Signed-off-by: Stanislav Kinsbursky <skinsbursky at openvz.org>

---
 cr-dump.c |   69 +++++++++++++++++++++++++++++++++++--------------------------
 1 files changed, 40 insertions(+), 29 deletions(-)

diff --git a/cr-dump.c b/cr-dump.c
index 51237a6..a5a7810 100644
--- a/cr-dump.c
+++ b/cr-dump.c
@@ -93,12 +93,13 @@ struct fd_parms {
 	unsigned int	flags;
 	unsigned int	type;
 	ino_t		ino;
+	int		lfd;
 
 	u64		id;
 	pid_t		pid;
 };
 
-static int dump_one_reg_file(struct fd_parms *p, int lfd,
+static int dump_one_reg_file(struct fd_parms *p,
 			     struct cr_fdset *cr_fdset,
 			     bool do_close_lfd)
 {
@@ -107,7 +108,7 @@ static int dump_one_reg_file(struct fd_parms *p, int lfd,
 	int len;
 	int ret = -1;
 
-	snprintf(fd_str, sizeof(fd_str), "/proc/self/fd/%d", lfd);
+	snprintf(fd_str, sizeof(fd_str), "/proc/self/fd/%d", p->lfd);
 	len = readlink(fd_str, big_buffer, sizeof(big_buffer) - 1);
 	if (len < 0) {
 		pr_perror("Can't readlink %s", fd_str);
@@ -116,10 +117,10 @@ static int dump_one_reg_file(struct fd_parms *p, int lfd,
 
 	big_buffer[len] = '\0';
 	pr_info("Dumping path for %lx fd via self %d [%s]\n",
-		p->fd_name, lfd, big_buffer);
+		p->fd_name, p->lfd, big_buffer);
 
 	if (do_close_lfd)
-		close(lfd);
+		close(p->lfd);
 
 	e.type	= p->type;
 	e.len	= len;
@@ -163,20 +164,25 @@ static int dump_task_special_files(pid_t pid, struct cr_fdset *cr_fdset)
 	struct fd_parms params;
 	int fd, ret;
 
+	fd = open_proc(pid, "cwd");
+	if (fd < 0)
+		return -1;
+
 	/* Dump /proc/pid/cwd */
 	params = (struct fd_parms) {
 		.fd_name	= FDINFO_CWD,
 		.id		= FD_ID_INVALID,
 		.pid		= FD_PID_INVALID,
 		.type		= FDINFO_FD,
+		.lfd		= fd,
 	};
+	ret = dump_one_reg_file(&params, cr_fdset, 1);
+	if (ret)
+		return ret;
 
-	fd = open_proc(pid, "cwd");
+	fd = open_proc(pid, "exe");
 	if (fd < 0)
 		return -1;
-	ret = dump_one_reg_file(&params, fd, cr_fdset, 1);
-	if (ret)
-		return ret;
 
 	/* Dump /proc/pid/exe */
 	params = (struct fd_parms) {
@@ -184,12 +190,9 @@ static int dump_task_special_files(pid_t pid, struct cr_fdset *cr_fdset)
 		.id		= FD_ID_INVALID,
 		.pid		= FD_PID_INVALID,
 		.type		= FDINFO_FD,
+		.lfd		= fd,
 	};
-
-	fd = open_proc(pid, "exe");
-	if (fd < 0)
-		return -1;
-	ret = dump_one_reg_file(&params, fd, cr_fdset, 1);
+	ret = dump_one_reg_file(&params, cr_fdset, 1);
 
 	return ret;
 }
@@ -249,20 +252,20 @@ err:
 	return ret;
 }
 
-static int dump_one_pipe(struct fd_parms *p, int lfd, struct cr_fdset *cr_fdset)
+static int dump_one_pipe(struct fd_parms *p, struct cr_fdset *cr_fdset)
 {
 	struct pipe_entry e;
 	int ret = -1;
 	struct statfs stfs_buf;
 
-	if (fstatfs(lfd, &stfs_buf) < 0) {
+	if (fstatfs(p->lfd, &stfs_buf) < 0) {
 		pr_perror("Can't fstatfs on %ld", p->fd_name);
-		return -1;
+		goto out;
 	}
 
 	if (stfs_buf.f_type != PIPEFS_MAGIC) {
 		pr_err("Dumping of FIFO's is not supported: %ld\n", p->fd_name);
-		return -1;
+		goto out;
 	}
 
 	pr_info("Dumping pipe %ld/%lx flags %x\n", p->fd_name, p->ino, p->flags);
@@ -275,7 +278,7 @@ static int dump_one_pipe(struct fd_parms *p, int lfd, struct cr_fdset *cr_fdset)
 		e.bytes = 0;
 		ret = write_img(cr_fdset->fds[CR_FD_PIPES], &e);
 	} else
-		ret = dump_pipe_and_data(lfd, &e, cr_fdset);
+		ret = dump_pipe_and_data(p->lfd, &e, cr_fdset);
 
 err:
 	if (!ret)
@@ -283,14 +286,17 @@ err:
 			e.fd, e.pipeid, e.flags, e.bytes);
 	else
 		pr_err("Dumping pipe %ld/%lx flags %x\n", p->fd_name, p->ino, p->flags);
-
+out:
+	close_safe(&p->lfd);
 	return ret;
 }
 
-static int read_fd_params(pid_t pid, char *fd, struct stat *fd_stat, struct fd_parms *p)
+static int read_fd_params(pid_t pid, int pid_fd_dir, char *fd,
+			  struct stat *fd_stat, struct fd_parms *p)
 {
 	FILE *file;
 	int ret;
+	char d_name[32];
 
 	file = fopen_proc(pid, "fdinfo/%s", fd);
 	if (!file)
@@ -312,11 +318,19 @@ static int read_fd_params(pid_t pid, char *fd, struct stat *fd_stat, struct fd_p
 	p->id	= FD_ID_INVALID;
 	p->type = 0;
 	p->ino	= fd_stat->st_ino;
+	p->lfd = -1;
 
 	switch (fd_stat->st_mode & S_IFMT) {
 	case S_IFREG:
 	case S_IFDIR:
 	case S_IFCHR:
+	case S_IFIFO:
+		sprintf(d_name, "%ld", p->fd_name);
+		p->lfd = openat(pid_fd_dir, d_name, O_RDONLY);
+		if (p->lfd < 0) {
+			pr_perror("Failed to fstatat %d/%s", pid_fd_dir, d_name);
+			return -1;
+		}
 		p->id = MAKE_FD_GENID(fd_stat->st_dev, fd_stat->st_ino, p->pos);
 		p->type = FDINFO_FD;
 	}
@@ -329,7 +343,6 @@ static int dump_one_fd(pid_t pid, int pid_fd_dir, char *d_name, struct cr_fdset
 	struct stat fd_stat;
 	int err;
 	struct fd_parms p;
-	int lfd;
 
 	err = fstatat(pid_fd_dir, d_name, &fd_stat, 0);
 	if (err < 0) {
@@ -337,11 +350,9 @@ static int dump_one_fd(pid_t pid, int pid_fd_dir, char *d_name, struct cr_fdset
 		return -1;
 	}
 
-	if (read_fd_params(pid, d_name, &fd_stat, &p))
+	if (read_fd_params(pid, pid_fd_dir, d_name, &fd_stat, &p))
 		return -1;
 
-	lfd = openat(pid_fd_dir, d_name, O_RDONLY);
-
 	switch (fd_stat.st_mode & S_IFMT) {
 	case S_IFCHR:
 		if (major(fd_stat.st_rdev) != MEM_MAJOR) {
@@ -362,17 +373,17 @@ static int dump_one_fd(pid_t pid, int pid_fd_dir, char *d_name, struct cr_fdset
 		 */
 	case S_IFREG:
 	case S_IFDIR:
-		err = dump_one_reg_file(&p, lfd, cr_fdset, 0);
+		err = dump_one_reg_file(&p, cr_fdset, 1);
 		break;
 	case S_IFIFO:
-		err = dump_one_pipe(&p, lfd, cr_fdset);
+		err = dump_one_pipe(&p, cr_fdset);
 		break;
 	case S_IFSOCK:
 		err = try_dump_socket(pid, p.fd_name, cr_fdset, sk_queue);
 		if (err != 1)
 			return err;
 
-		pr_perror("Failed to open %d/%s", pid_fd_dir, d_name);
+		pr_perror("Failed to open %d/%ld", pid_fd_dir, p.fd_name);
 		return -1;
 	case S_IFLNK:
 	case S_IFBLK:
@@ -383,7 +394,6 @@ static int dump_one_fd(pid_t pid, int pid_fd_dir, char *d_name, struct cr_fdset
 	}
 	if (err)
 		pr_err("Can't dump file %ld of that type [%x]\n", p.fd_name, fd_stat.st_mode);
-	close_safe(&lfd);
 	return err;
 }
 
@@ -466,6 +476,7 @@ static int dump_task_mappings(pid_t pid, struct list_head *vma_area_list, struct
 				.id		= FD_ID_INVALID,
 				.pid		= pid,
 				.type		= FDINFO_MAP,
+				.lfd		= vma_area->vm_file_fd,
 			};
 
 			if (vma->prot & PROT_WRITE &&
@@ -474,7 +485,7 @@ static int dump_task_mappings(pid_t pid, struct list_head *vma_area_list, struct
 			else
 				p.flags = O_RDONLY;
 
-			ret = dump_one_reg_file(&p, vma_area->vm_file_fd, cr_fdset, 0);
+			ret = dump_one_reg_file(&p, cr_fdset, 0);
 			if (ret)
 				goto err;
 		}



More information about the CRIU mailing list