[v2,36/57] pstree: Make get_free_pid() work for different pid_ns and export it

Submitted by Kirill Tkhai on March 28, 2017, 3:39 p.m.

Details

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

Commit Message

Kirill Tkhai March 28, 2017, 3:39 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.

Signed-off-by: Kirill Tkhai <ktkhai@virtuozzo.com>
---
 criu/include/pstree.h |    1 +
 criu/pstree.c         |   20 ++++++++++++--------
 2 files changed, 13 insertions(+), 8 deletions(-)

Patch hide | download patch | download mbox

diff --git a/criu/include/pstree.h b/criu/include/pstree.h
index 438ef939..b0b44022 100644
--- a/criu/include/pstree.h
+++ b/criu/include/pstree.h
@@ -85,6 +85,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(struct pstree_item *root_item);
 extern struct pstree_item *__alloc_pstree_item(bool rst, int level);
 #define alloc_pstree_item() __alloc_pstree_item(false, 1)
diff --git a/criu/pstree.c b/criu/pstree.c
index 55e5fc99..6b7daba6 100644
--- a/criu/pstree.c
+++ b/criu/pstree.c
@@ -818,25 +818,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)
+		if (next->ns[level].virt > pid)
 			return pid;
 		prev = next;
 	}
@@ -873,7 +877,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);