[CRIU] [PATCH 07/10] pstree: check that all processes see their group leader

Pavel Tikhomirov ptikhomirov at virtuozzo.com
Tue Jul 4 12:08:06 MSK 2017


We only restore process group for process if it can see the leader
of group, tricky cases when task inherits group and than enters
pidns and then forks again so that even parent can't see the leader
are not supported now, as sometimes it would leed to hard to track
restore deadlocks.

Signed-off-by: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>
---
 criu/pstree.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 59 insertions(+)

diff --git a/criu/pstree.c b/criu/pstree.c
index 9dc7d76..1d2ac2f 100644
--- a/criu/pstree.c
+++ b/criu/pstree.c
@@ -1154,6 +1154,58 @@ static int can_inherit_sid(struct pstree_item *item) {
 	return __can_inherit_sid(item, 0);
 }
 
+/*
+ * Get pid of process item in pidns of process base,
+ * base and item should have ->ids initialized.
+ */
+static pid_t get_relative_pid(struct pstree_item *base, struct pstree_item *item)
+{
+	struct ns_id *item_pidns;
+
+	/* The pidns of an item is above */
+	if (item->pid->level < base->pid->level)
+		return 0;
+
+	/* Same level fast path */
+	if (item->pid->level == base->pid->level) {
+		if (base->ids->pid_ns_id == item->ids->pid_ns_id)
+			return last_level_pid(item->pid);
+		else
+			return 0;
+	}
+
+	item_pidns = lookup_ns_by_id(item->ids->pid_ns_id, &pid_ns_desc);
+	BUG_ON(!item_pidns);
+	item_pidns = ns_nth_parent(item_pidns, item->pid->level - base->pid->level);
+	BUG_ON(!item_pidns);
+
+	/* On base's level item & base have the same pidns */
+	if (base->ids->pid_ns_id == item_pidns->id)
+		return  item->pid->ns[base->pid->level-1].virt;
+	return 0;
+}
+
+static int can_receive_pgid(struct pstree_item *item)
+{
+	struct pstree_item *leader;
+	pid_t pgid = vpgid(item);
+
+	BUG_ON(pgid == 0);
+
+	leader = pstree_item_by_virt(pgid);
+	BUG_ON(!leader || leader->pid->state == TASK_UNDEF);
+
+	/* item inherited pgid with session */
+	if (is_session_leader(leader))
+		return 1;
+
+	/* item can see it's leader */
+	if (get_relative_pid(item, leader))
+		return 1;
+
+	return 0;
+}
+
 static struct pstree_item *get_helper(int sid, unsigned int id, struct list_head *helpers)
 {
 	struct pstree_item *helper;
@@ -1290,6 +1342,13 @@ static int prepare_pstree_ids(void)
 				return -1;
 			}
 		}
+
+		if (!is_group_leader(item)) {
+			if (!can_receive_pgid(item)) {
+				pr_err("Can't find a group leader for %d\n", vsid(item));
+				return -1;
+			}
+		}
 	}
 
 	/*
-- 
2.9.4



More information about the CRIU mailing list