[v2,05/36] core: Introduce last_pid_mutex and use it to synchronize ns_last_pid assignment

Submitted by Kirill Tkhai on Feb. 3, 2017, 4:12 p.m.

Details

Message ID 148613834095.3612.6556103061416349317.stgit@localhost.localdomain
State New
Series "Nested user namespaces support"
Headers show

Commit Message

Kirill Tkhai Feb. 3, 2017, 4:12 p.m.
This is simplier, than file lock, because it's not propagated
to child processes, and it's not need to close the fd from them.
Also we will need a comfortable synchronization for creating
child pid namespaces, and mutex will be good for that.

The patch may be applied independently from the rest of series.

Signed-off-by: Kirill Tkhai <ktkhai@virtuozzo.com>
---
 criu/cr-restore.c       |   33 +++++++++++++--------------------
 criu/include/rst_info.h |    1 +
 criu/pie/restorer.c     |   15 ++-------------
 3 files changed, 16 insertions(+), 33 deletions(-)

Patch hide | download patch | download mbox

diff --git a/criu/cr-restore.c b/criu/cr-restore.c
index ee6b84876..7ce0c6abc 100644
--- a/criu/cr-restore.c
+++ b/criu/cr-restore.c
@@ -922,7 +922,6 @@  struct cr_clone_arg {
 	char stack_ptr[0];
 	struct pstree_item *item;
 	unsigned long clone_flags;
-	int fd;
 
 	CoreEntry *core;
 };
@@ -968,6 +967,7 @@  static inline int fork_with_pid(struct pstree_item *item)
 	struct cr_clone_arg ca;
 	int ret = -1;
 	pid_t pid = item->pid->ns[0].virt;
+	bool locked;
 
 	if (item->pid->state != TASK_HELPER) {
 		if (open_core(pid, &ca.core))
@@ -1008,25 +1008,24 @@  static inline int fork_with_pid(struct pstree_item *item)
 
 	if (!(ca.clone_flags & CLONE_NEWPID)) {
 		char buf[32];
-		int len;
+		int len, fd;
 
-		ca.fd = open_proc_rw(PROC_GEN, LAST_PID_PATH);
-		if (ca.fd < 0)
+		fd = open_proc_rw(PROC_GEN, LAST_PID_PATH);
+		if (fd < 0)
 			goto err;
 
-		if (flock(ca.fd, LOCK_EX)) {
-			close(ca.fd);
-			pr_perror("%d: Can't lock %s", pid, LAST_PID_PATH);
-			goto err;
-		}
+		mutex_lock(&task_entries->last_pid_mutex);
+		locked = true;
 
 		len = snprintf(buf, sizeof(buf), "%d", pid - 1);
-		if (write(ca.fd, buf, len) != len) {
+		len -= write(fd, buf, len);
+		close(fd);
+		if (len) {
 			pr_perror("%d: Write %s to %s", pid, buf, LAST_PID_PATH);
 			goto err_unlock;
 		}
 	} else {
-		ca.fd = -1;
+		locked = false;
 		BUG_ON(pid != INIT_PID);
 	}
 
@@ -1058,12 +1057,8 @@  static inline int fork_with_pid(struct pstree_item *item)
 	}
 
 err_unlock:
-	if (ca.fd >= 0) {
-		if (flock(ca.fd, LOCK_UN))
-			pr_perror("%d: Can't unlock %s", pid, LAST_PID_PATH);
-
-		close(ca.fd);
-	}
+	if (locked)
+		mutex_unlock(&task_entries->last_pid_mutex);
 err:
 	if (ca.core)
 		core_entry__free_unpacked(ca.core, NULL);
@@ -1349,9 +1344,6 @@  static int restore_task_with_children(void *_arg)
 				current->pid->real, current->pid->ns[0].virt);
 	}
 
-	if ( !(ca->clone_flags & CLONE_FILES))
-		close_safe(&ca->fd);
-
 	if (current->pid->state != TASK_HELPER) {
 		ret = clone_service_fd(rsti(current)->service_fd_id);
 		if (ret)
@@ -2033,6 +2025,7 @@  int prepare_task_entries(void)
 	task_entries->nr_helpers = 0;
 	futex_set(&task_entries->start, CR_STATE_RESTORE_NS);
 	mutex_init(&task_entries->userns_sync_lock);
+	mutex_init(&task_entries->last_pid_mutex);
 
 	return 0;
 }
diff --git a/criu/include/rst_info.h b/criu/include/rst_info.h
index 82fbd568c..173c303fd 100644
--- a/criu/include/rst_info.h
+++ b/criu/include/rst_info.h
@@ -11,6 +11,7 @@  struct task_entries {
 	futex_t start;
 	atomic_t cr_err;
 	mutex_t userns_sync_lock;
+	mutex_t last_pid_mutex;
 };
 
 struct fdt {
diff --git a/criu/pie/restorer.c b/criu/pie/restorer.c
index e50dac84c..978050e50 100644
--- a/criu/pie/restorer.c
+++ b/criu/pie/restorer.c
@@ -1428,12 +1428,7 @@  long __export_restore_task(struct task_restore_args *args)
 			goto core_restore_end;
 		}
 
-		ret = sys_flock(fd, LOCK_EX);
-		if (ret) {
-			pr_err("Can't lock last_pid %d\n", fd);
-			sys_close(fd);
-			goto core_restore_end;
-		}
+		mutex_lock(&task_entries_local->last_pid_mutex);
 
 		for (i = 0; i < args->nr_threads; i++) {
 			char last_pid_buf[16], *s;
@@ -1462,13 +1457,7 @@  long __export_restore_task(struct task_restore_args *args)
 			RUN_CLONE_RESTORE_FN(ret, clone_flags, new_sp, parent_tid, thread_args, args->clone_restore_fn);
 		}
 
-		ret = sys_flock(fd, LOCK_UN);
-		if (ret) {
-			pr_err("Can't unlock last_pid %ld\n", ret);
-			sys_close(fd);
-			goto core_restore_end;
-		}
-
+		mutex_unlock(&task_entries_local->last_pid_mutex);
 		sys_close(fd);
 	}