[CRIU] [PATCH v4 22/41] restore: Implement set_next_pid() helper

Kirill Tkhai ktkhai at virtuozzo.com
Thu May 4 09:08:42 PDT 2017


Move next pid writing functionality to separate function.
Also make set_next_pid() skip INIT_PID, as I'm going to
call this function unconditionally in next patches.

v4: Call perror() before close()

Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
---
 criu/cr-restore.c     |   37 +++++++++++++++++++++++++++++++------
 criu/include/pstree.h |    1 +
 2 files changed, 32 insertions(+), 6 deletions(-)

diff --git a/criu/cr-restore.c b/criu/cr-restore.c
index cb9beeac2..2735489c2 100644
--- a/criu/cr-restore.c
+++ b/criu/cr-restore.c
@@ -380,6 +380,31 @@ static int root_prepare_shared(void)
 	return ret;
 }
 
+int __set_next_pid(pid_t pid)
+{
+	char buf[32];
+	int len, fd;
+
+	fd = open_proc_rw(PROC_GEN, LAST_PID_PATH);
+	if (fd < 0)
+		return -1;
+
+	len = snprintf(buf, sizeof(buf), "%d", pid - 1);
+	len -= write(fd, buf, len);
+	if (len)
+		pr_perror("%d: Write %s to %s", pid, buf, LAST_PID_PATH);
+	close(fd);
+
+	return len ? -1 : 0;
+}
+
+static int set_next_pid(struct ns_id *ns, struct pid *pid)
+{
+	if (pid->ns[0].virt == INIT_PID)
+		return 0;
+	return __set_next_pid(pid->ns[0].virt);
+}
+
 static rt_sigaction_t sigchld_act;
 /*
  * If parent's sigaction has blocked SIGKILL (which is non-sence),
@@ -1122,12 +1147,16 @@ static inline int fork_with_pid(struct pstree_item *item)
 	struct cr_clone_arg ca;
 	int ret = -1;
 	pid_t pid = vpid(item);
+	struct ns_id *pid_ns;
 
 	if (item != root_item)
 		item->user_ns = current->user_ns;
 	else
 		item->user_ns = root_user_ns;
 
+	pid_ns = lookup_ns_by_id(item->ids->pid_ns_id, &pid_ns_desc);
+	BUG_ON(!pid_ns);
+
 	if (item->pid->state != TASK_HELPER) {
 		if (open_core(pid, &ca.core))
 			return -1;
@@ -1166,9 +1195,6 @@ static inline int fork_with_pid(struct pstree_item *item)
 	pr_info("Forking task with %d pid (flags 0x%lx)\n", pid, ca.clone_flags);
 
 	if (!(ca.clone_flags & CLONE_NEWPID)) {
-		char buf[32];
-		int len;
-
 		ca.fd = open_proc_rw(PROC_GEN, LAST_PID_PATH);
 		if (ca.fd < 0)
 			goto err;
@@ -1179,9 +1205,8 @@ static inline int fork_with_pid(struct pstree_item *item)
 			goto err;
 		}
 
-		len = snprintf(buf, sizeof(buf), "%d", pid - 1);
-		if (write(ca.fd, buf, len) != len) {
-			pr_perror("%d: Write %s to %s", pid, buf, LAST_PID_PATH);
+		if (set_next_pid(pid_ns, item->pid) < 0) {
+			pr_err("Can't set next pid\n");
 			goto err_unlock;
 		}
 	} else {
diff --git a/criu/include/pstree.h b/criu/include/pstree.h
index b8e16cff3..9f88983de 100644
--- a/criu/include/pstree.h
+++ b/criu/include/pstree.h
@@ -140,4 +140,5 @@ extern void pstree_free_cores(struct pstree_item *item);
 extern int collect_pstree_ids(void);
 
 extern int preorder_pstree_traversal(struct pstree_item *item, int (*f)(struct pstree_item *));
+extern int __set_next_pid(pid_t pid);
 #endif /* __CR_PSTREE_H__ */



More information about the CRIU mailing list