[CRIU] [PATCH v5 20/42] pstree: Make get_free_pid() work for different pid_ns and export it

Kirill Tkhai ktkhai at virtuozzo.com
Fri May 5 09:16:04 PDT 2017


Add ns argument to this function to be able to find a free pid
in speific pid_ns, not only in top_pid_ns.

v4: Use ns[level] instead of ns[0] during next dereferrence.

Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
---
 criu/include/pstree.h |    1 +
 criu/pstree.c         |   22 +++++++++++++---------
 2 files changed, 14 insertions(+), 9 deletions(-)

diff --git a/criu/include/pstree.h b/criu/include/pstree.h
index d7f052a22..270ebb6eb 100644
--- a/criu/include/pstree.h
+++ b/criu/include/pstree.h
@@ -87,6 +87,7 @@ static inline bool task_alive(struct pstree_item *i)
 	return is_alive_state(i->pid->state);
 }
 
+extern int get_free_pid(struct ns_id *ns);
 extern void free_pstree_item(struct pstree_item *item);
 extern void free_pstree(struct pstree_item *root_item);
 extern struct pstree_item *__alloc_pstree_item(bool rst, int level);
diff --git a/criu/pstree.c b/criu/pstree.c
index e4604029e..bba21d4d0 100644
--- a/criu/pstree.c
+++ b/criu/pstree.c
@@ -826,25 +826,29 @@ static int read_pstree_image(pid_t *pid_max)
 }
 
 #define RESERVED_PIDS		300
-static int get_free_pid()
+int get_free_pid(struct ns_id *ns)
 {
-	static struct pid *prev, *next;
+	struct pid *prev, *next;
+	struct ns_id *i = ns;
+	int level = 0;
 
-	if (prev == NULL)
-		prev = rb_entry(rb_first(&top_pid_ns->pid.rb_root), struct pid, ns[0].node);
+	while ((i = i->parent) != NULL)
+		level++;
+
+	prev = rb_entry(rb_first(&ns->pid.rb_root), struct pid, ns[level].node);
 
 	while (1) {
 		struct rb_node *node;
 		pid_t pid;
 
-		pid = prev->ns[0].virt + 1;
+		pid = prev->ns[level].virt + 1;
 		pid = pid < RESERVED_PIDS ? RESERVED_PIDS + 1 : pid;
 
-		node = rb_next(&prev->ns[0].node);
+		node = rb_next(&prev->ns[level].node);
 		if (node == NULL)
 			return pid;
-		next = rb_entry(node, struct pid, ns[0].node);
-		if (next->ns[0].virt > pid)
+		next = rb_entry(node, struct pid, ns[level].node);
+		if (next->ns[level].virt > pid)
 			return pid;
 		prev = next;
 	}
@@ -881,7 +885,7 @@ static int prepare_pstree_ids(void)
 		if (leader->pid->state != TASK_UNDEF) {
 			pid_t pid;
 
-			pid = get_free_pid();
+			pid = get_free_pid(top_pid_ns);
 			if (pid < 0)
 				break;
 			helper = lookup_create_item(&pid, 1, item->ids->pid_ns_id);



More information about the CRIU mailing list