[CRIU] [PATCH] reg-files: Serialize linking of ghost files

Cyrill Gorcunov gorcunov at openvz.org
Mon Sep 17 04:50:28 EDT 2012


In case if there at least two tasks with same ghost
file we've a race in open_path -- both task may enter
the open_path at same time and try to link ghost file
to same name leading to

 | 26445: Error (files-reg.c:363): Can't link
 | /home/crtools/test/zdtm/live/static/write_read10.test (deleted).cr.1.ghost ->
 | /home/crtools/test/zdtm/live/static/write_read10.test (deleted)

The both tasks have ghost files as

 | id:  0x3 flags: 0x8002 pos: 0000000000000000 ... name: "/home/crtools/test/zdtm/live/static/write_read10.test (deleted)"

and

 | id: 0x10 flags: 0x8002 pos: 0000000000000000 ... name: "/home/crtools/test/zdtm/live/static/write_read10.test (deleted)"

Thus, to serialize link/unlink procedure we use per-ghost-file mutex.

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

diff --git a/files-reg.c b/files-reg.c
index b459130..3620d23 100644
--- a/files-reg.c
+++ b/files-reg.c
@@ -38,6 +38,7 @@ struct ghost_file {
 		};
 	};
 	atomic_t users;
+	mutex_t lock;
 };
 
 static u32 ghost_file_ids = 1;
@@ -115,6 +116,7 @@ static int open_remap_ghost(struct reg_file_info *rfi,
 
 	gf->id = rfe->remap_id;
 	atomic_set(&gf->users, 0);
+	mutex_init(&gf->lock);
 	list_add_tail(&gf->list, &ghost_files);
 gf_found:
 	atomic_inc(&gf->users);
@@ -351,12 +353,14 @@ static int open_path(struct file_desc *d,
 
 	rfi = container_of(d, struct reg_file_info, d);
 
-	if (rfi->ghost)
+	if (rfi->ghost) {
+		mutex_lock(&rfi->ghost->lock);
 		if (link(rfi->ghost->path, rfi->path) < 0) {
 			pr_perror("Can't link %s -> %s\n",
 					rfi->ghost->path, rfi->path);
 			return -1;
 		}
+	}
 
 	tmp = open_cb(rfi, arg);
 	if (tmp < 0) {
@@ -370,6 +374,7 @@ static int open_path(struct file_desc *d,
 			pr_info("Unlink the ghost %s\n", rfi->ghost->path);
 			unlink(rfi->ghost->path);
 		}
+		mutex_unlock(&rfi->ghost->lock);
 	}
 
 	if (restore_fown(tmp, rfi->rfe->fown))
-- 
1.7.7.6



More information about the CRIU mailing list