[CRIU] [PATCH 2/7] files: Add fill_fdlink helper

Cyrill Gorcunov gorcunov at openvz.org
Wed May 8 09:00:36 EDT 2013


When we dump a regular file it might be a link
to opened proc/ns entry so we need to read link
first and then analyze it. But to make it in step
byt step way we at first use fill_fdlink helper
which fills the link contents for us and modify
dump_one_reg_file to escape double link reading.

Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
---
 files-reg.c | 22 +++++++++++++++++-----
 files.c     | 31 ++++++++++++++++++++++++++++++-
 2 files changed, 47 insertions(+), 6 deletions(-)

diff --git a/files-reg.c b/files-reg.c
index 684cfd3..1e441a8 100644
--- a/files-reg.c
+++ b/files-reg.c
@@ -432,15 +432,27 @@ static int check_path_remap(char *rpath, int plen, const struct stat *ost, int l
 
 int dump_one_reg_file(int lfd, u32 id, const struct fd_parms *p)
 {
-	char rpath[PATH_MAX + 1] = ".", *path = rpath + 1;
+	char buf[PATH_MAX + 1];
+	char *rpath, *path;
 	int len, rfd;
 
 	RegFileEntry rfe = REG_FILE_ENTRY__INIT;
 
-	len = read_fd_link(lfd, path, sizeof(rpath) - 1);
-	if (len < 0) {
-		pr_err("Can't read link\n");
-		return len;
+	if (!p->nmlink) {
+		path = buf + 1;
+		rpath = buf;
+
+		len = read_fd_link(lfd, path, sizeof(buf) - 1);
+		if (len < 0) {
+			pr_err("Can't read link\n");
+			return len;
+		}
+
+		rpath[0] = '.';
+	} else {
+		path = p->nmlink + 1;
+		rpath = p->nmlink;
+		len = p->nmlen;
 	}
 
 	pr_info("Dumping path for %d fd via self %d [%s]\n",
diff --git a/files.c b/files.c
index 786eca7..edaaa0e 100644
--- a/files.c
+++ b/files.c
@@ -135,6 +135,24 @@ int do_dump_gen_file(struct fd_parms *p, int lfd,
 	return pb_write_one(fdinfo, &e, PB_FDINFO);
 }
 
+static int fill_fdlink(int lfd, struct fd_parms *p)
+{
+	char *path = &p->nmlink[1];
+	size_t len;
+
+	BUG_ON(!p->nmlink || p->nmsize < 1);
+	p->nmlink[0] = '.';
+
+	len = read_fd_link(lfd, path, p->nmsize - 1);
+	if (len < 0) {
+		pr_err("Can't read link for pid %d fd %d\n", p->pid, p->fd);
+		return -1;
+	}
+
+	p->nmlen = len + 1;
+	return 0;
+}
+
 static int fill_fd_params(struct parasite_ctl *ctl, int fd, int lfd,
 				struct fd_opts *opts, struct fd_parms *p)
 {
@@ -244,8 +262,19 @@ static int dump_one_file(struct parasite_ctl *ctl, int fd, int lfd, struct fd_op
 			return dump_unsupp_fd(&p);
 	}
 
-	if (S_ISREG(p.stat.st_mode) || S_ISDIR(p.stat.st_mode))
+	if (S_ISREG(p.stat.st_mode) || S_ISDIR(p.stat.st_mode)) {
+		char path[PATH_MAX + 1];
+
+		p.nmlink = path;
+		p.nmsize = sizeof(path);
+
+		if (fill_fdlink(lfd, &p)) {
+			pr_err("Can't fill fdlink params\n");
+			return -1;
+		}
+
 		return dump_reg_file(&p, lfd, fdinfo);
+	}
 
 	if (S_ISFIFO(p.stat.st_mode)) {
 		if (statfs.f_type == PIPEFS_MAGIC)
-- 
1.8.1.4



More information about the CRIU mailing list