[CRIU] [PATCH 2/6] cr-dump: fix dumping file locks in a mount namespace

Andrey Vagin avagin at openvz.org
Fri Jan 18 14:51:10 EST 2013


Before this patch crtools reads link /proc/pid/fd/X and
calls stat on this file. If a process is in another mount
namespace, a file will be not avaliable.

This patch reworks code to use fstat on a real descriptor.

Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
 cr-dump.c | 52 ++++++++++++++++++----------------------------------
 1 file changed, 18 insertions(+), 34 deletions(-)

diff --git a/cr-dump.c b/cr-dump.c
index 3ace532..1409ec7 100644
--- a/cr-dump.c
+++ b/cr-dump.c
@@ -675,43 +675,28 @@ err:
 }
 
 static int get_fd_by_ino(unsigned long i_no, struct parasite_drain_fd *dfds,
-			pid_t pid)
+			pid_t pid, int *lfds)
 {
-	int  i, ret = -1;
+	int  i;
 	char path[PATH_MAX];
-	char buf[40];
 	struct stat fd_stat;
 
-	i = 0;
-	while (i < dfds->nr_fds) {
-		snprintf(buf, sizeof(buf), "/proc/%d/fd/%d", pid,
-			dfds->fds[i]);
-		buf[39] = '\0';
-
-		memset(path, 0, sizeof(path));
-		ret = readlink(buf, path, sizeof(path));
-		if (ret < 0) {
-			pr_err("Read link %s failed!\n", buf);
-			goto err;
-		}
-
-		if (stat(path, &fd_stat) == -1) {
-			i++;
-			pr_msg("Could not get %s stat!\n", path);
-			continue;
+	for (i = 0; i < dfds->nr_fds; i++) {
+		if (fstat(lfds[i], &fd_stat) == -1) {
+			pr_err("Could not get %s stat!\n", path);
+			return -1;
 		}
 
 		if (fd_stat.st_ino == i_no)
 			return dfds->fds[i];
-		i++;
 	}
 
-err:
 	return -1;
 }
 
-static int dump_task_file_locks(struct parasite_ctl *ctl,
-			struct cr_fdset *fdset,	struct parasite_drain_fd *dfds)
+static int dump_task_file_locks(struct parasite_ctl *ctl, struct pstree_item *item,
+				const struct cr_fdset *fdset,
+				struct parasite_drain_fd *dfds, int *lfds)
 {
 	FileLockEntry	 fle;
 	struct file_lock *fl;
@@ -735,7 +720,7 @@ static int dump_task_file_locks(struct parasite_ctl *ctl,
 		if (ret)
 			goto err;
 
-		fle.fd = get_fd_by_ino(fl->i_no, dfds, pid);
+		fle.fd = get_fd_by_ino(fl->i_no, dfds, pid, lfds);
 		if (fle.fd < 0) {
 			ret = -1;
 			goto err;
@@ -1561,6 +1546,14 @@ static int dump_files_and_locks_seized(struct parasite_ctl *parasite_ctl,
 		}
 	}
 
+	if (opts.handle_file_locks) {
+		ret = dump_task_file_locks(parasite_ctl, item, cr_fdset, dfds, lfds);
+		if (ret) {
+			pr_err("Dump file locks failed with %d\n", ret);
+			goto err;
+		}
+	}
+
 err:
 	for (i = 0; i < dfds->nr_fds; i++)
 		close(lfds[i]);
@@ -1656,15 +1649,6 @@ static int dump_one_task(struct pstree_item *item)
 	if (ret)
 		goto err_cure;
 
-	if (opts.handle_file_locks) {
-		ret = dump_task_file_locks(parasite_ctl, cr_fdset, dfds);
-		if (ret) {
-			pr_err("Dump file locks (pid: %d) failed with %d\n",
-				pid, ret);
-			goto err_cure;
-		}
-	}
-
 	ret = parasite_dump_pages_seized(parasite_ctl, &vma_area_list, cr_fdset);
 	if (ret) {
 		pr_err("Can't dump pages (pid: %d) with parasite\n", pid);
-- 
1.7.11.7



More information about the CRIU mailing list