[v4,19/41] pstree: Make get_free_pid() work for different pid_ns and export it

Submitted by Kirill Tkhai on May 4, 2017, 4:07 p.m.

Details

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

Commit Message

Kirill Tkhai May 4, 2017, 4:07 p.m.
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@virtuozzo.com>
---
 criu/include/pstree.h |    1 +
 criu/pstree.c         |   22 +++++++++++++---------
 2 files changed, 14 insertions(+), 9 deletions(-)

Patch hide | download patch | download mbox

diff --git a/criu/include/pstree.h b/criu/include/pstree.h
index 313b77458..e30146e90 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 3306c5c75..a4b50a5d2 100644
--- a/criu/pstree.c
+++ b/criu/pstree.c
@@ -822,25 +822,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;
 	}
@@ -877,7 +881,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);