diff --git a/criu/include/pstree.h b/criu/include/pstree.h index 4223c8c74..7b6906ef8 100644 --- a/criu/include/pstree.h +++ b/criu/include/pstree.h @@ -106,8 +106,12 @@ static inline struct pid *pstree_pid_by_virt(pid_t pid) extern struct pstree_item *root_item; extern struct pstree_item *pstree_item_next(struct pstree_item *item); +extern struct pstree_item *pssubtree_item_next(struct pstree_item *item, + struct pstree_item *root, bool skip_descendants); #define for_each_pstree_item(pi) \ for (pi = root_item; pi != NULL; pi = pstree_item_next(pi)) +#define for_each_pssubtree_item(pi, root) \ + for (pi = root; pi != NULL; pi = pssubtree_item_next(pi, root, false)) extern bool restore_before_setsid(struct pstree_item *child); extern int prepare_pstree(void); diff --git a/criu/pstree.c b/criu/pstree.c index 1653606d0..66b6dd7bb 100644 --- a/criu/pstree.c +++ b/criu/pstree.c @@ -290,13 +290,14 @@ int init_pstree_helper(struct pstree_item *ret) return 0; } -/* Deep first search on children */ -struct pstree_item *pstree_item_next(struct pstree_item *item) +/* Search only root's subtree, possibly skipping descendants */ +struct pstree_item *pssubtree_item_next(struct pstree_item *item, + struct pstree_item *root, bool skip_descendants) { - if (!list_empty(&item->children)) + if (!skip_descendants && !list_empty(&item->children)) return list_first_entry(&item->children, struct pstree_item, sibling); - while (item->parent) { + while (item->parent && item != root) { if (item->sibling.next != &item->parent->children) return list_entry(item->sibling.next, struct pstree_item, sibling); item = item->parent; @@ -305,6 +306,12 @@ struct pstree_item *pstree_item_next(struct pstree_item *item) return NULL; } +/* Deep first search on children */ +struct pstree_item *pstree_item_next(struct pstree_item *item) +{ + return pssubtree_item_next(item, NULL, false); +} + /* Preorder traversal of pstree item */ int preorder_pstree_traversal(struct pstree_item *item, int (*f)(struct pstree_item *)) {