[CRIU] [PATCH v6 1/9] restore: Use pstree_pid_cmp helper in pid_rst_prio
Cyrill Gorcunov
gorcunov at gmail.com
Mon May 21 23:05:53 MSK 2018
The pid number is absolutely not a guarantee to
introduce order relationship into pid set because
they might be reused. Instead we should consider
parent->child relationship.
Otherwise we might get
| 31964 31964 31964 epoll
| 585 31964 31964 epoll
| 586 31964 31964 epoll
|...
| (04.797121) 585: Error (criu/eventpoll.c:180): epoll: Unexpected state for tfd (id 0 fd 8)
vz7 commit 1c0c47e44ec589f3782d9aa1e6e3292450550d29
Signed-off-by: Cyrill Gorcunov <gorcunov at gmail.com>
---
criu/include/pid.h | 12 +++++++++++-
criu/pstree.c | 36 ++++++++++++++++++++++++++++++++++++
2 files changed, 47 insertions(+), 1 deletion(-)
diff --git a/criu/include/pid.h b/criu/include/pid.h
index 37e39428e0d6..d8869fde0a09 100644
--- a/criu/include/pid.h
+++ b/criu/include/pid.h
@@ -69,13 +69,23 @@ static inline pid_t last_level_pid(struct pid *pid)
return pid->ns[pid->level-1].virt;
}
+extern int pstree_pid_cmp(pid_t a, pid_t b);
+
/*
* When we have to restore a shared resource, we mush select which
* task should do it, and make other(s) wait for it. In order to
* avoid deadlocks, always make task with lower pid be the restorer.
*/
-static inline bool pid_rst_prio(unsigned pid_a, unsigned pid_b)
+static inline bool pid_rst_prio(pid_t pid_a, pid_t pid_b)
{
+ int ret = pstree_pid_cmp(pid_a, pid_b);
+
+ if (ret == 1)
+ return true;
+ else if (ret == 2)
+ return false;
+
+ /* Fallback into plain pid comparision */
return pid_a < pid_b;
}
diff --git a/criu/pstree.c b/criu/pstree.c
index 6047d29ccc97..f180b9b221ed 100644
--- a/criu/pstree.c
+++ b/criu/pstree.c
@@ -655,6 +655,42 @@ int fixup_pid_for_children_ns(TaskKobjIdsEntry *ids)
return 0;
}
+/*
+ * 0 -- pids are the same
+ * 1 -- @a is a parent of @b
+ * 2 -- @b is a parent of @a
+ * 3 -- pids are not connected
+ * -1 -- pid not found
+ */
+int pstree_pid_cmp(pid_t a, pid_t b)
+{
+ struct pstree_item *pstree_a, *pstree_b, *t;
+ struct pid *pid_a, *pid_b;
+
+ if (a == b)
+ return 0;
+
+ pid_a = pstree_pid_by_virt(a);
+ pid_b = pstree_pid_by_virt(b);
+ if (!pid_a || !pid_b)
+ return -1;
+
+ pstree_a = pid_a->item;
+ pstree_b = pid_b->item;
+
+ for (t = pstree_b; t->parent; t = t->parent) {
+ if (t == pstree_a)
+ return 1;
+ }
+
+ for (t = pstree_a; t->parent; t = t->parent) {
+ if (t == pstree_b)
+ return 2;
+ }
+
+ return 3;
+}
+
static int read_pstree_ids(pid_t pid, TaskKobjIdsEntry **ids)
{
struct cr_img *img;
--
2.14.3
More information about the CRIU
mailing list