diff --git a/criu/include/pstree.h b/criu/include/pstree.h index 7df92db6a..85e7e231a 100644 --- a/criu/include/pstree.h +++ b/criu/include/pstree.h @@ -139,6 +139,7 @@ extern int pstree_alloc_cores(struct pstree_item *item); extern void pstree_free_cores(struct pstree_item *item); extern int collect_pstree_ids(void); +extern int fixup_pid_for_children_ns(TaskKobjIdsEntry *ids); extern int preorder_pstree_traversal(struct pstree_item *item, int (*f)(struct pstree_item *)); extern int __set_next_pid(pid_t pid); diff --git a/criu/namespaces.c b/criu/namespaces.c index 7aceddc93..430f6c699 100644 --- a/criu/namespaces.c +++ b/criu/namespaces.c @@ -690,6 +690,25 @@ struct collect_image_info nsfile_cinfo = { .collect = collect_one_nsfile, }; +static int get_pid_for_children_ns_id(pid_t pid, TaskKobjIdsEntry *ids) +{ + ids->has_pid_for_children_ns_id = false; + + if (kdat.has_pid_for_children_ns) { + ids->pid_for_children_ns_id = __get_ns_id(pid, &pid_ns_desc, true, + &ids->has_pid_for_children_ns_id, NULL); + if (!ids->pid_for_children_ns_id) { + pr_err("Can't make pid_for_children id\n"); + return -1; + } + if (ids->pid_for_children_ns_id == UINT_MAX) { + pr_err("Just unshared pid namespaces are not supported yet\n"); + return -1; + } + } + return 0; +} + /* * Same as dump_task_ns_ids(), but * a) doesn't keep IDs (don't need them) @@ -775,6 +794,9 @@ int dump_task_ns_ids(struct pstree_item *item) return -1; } + if (get_pid_for_children_ns_id(pid, ids) < 0) + return -1; + return 0; } diff --git a/criu/pstree.c b/criu/pstree.c index cb9e6e934..ac1df2200 100644 --- a/criu/pstree.c +++ b/criu/pstree.c @@ -617,6 +617,18 @@ struct pid *__pstree_pid_by_virt(struct ns_id *ns, pid_t pid) return NULL; } +int fixup_pid_for_children_ns(TaskKobjIdsEntry *ids) +{ + if (!ids->has_pid_for_children_ns_id) { + ids->has_pid_for_children_ns_id = true; + ids->pid_for_children_ns_id = ids->pid_ns_id; + } else if (!lookup_ns_by_id(ids->pid_for_children_ns_id, &pid_ns_desc)) { + pr_err("Can't find pid_for_children ns linked\n"); + return -1; + } + return 0; +} + static int read_pstree_ids(pid_t pid, TaskKobjIdsEntry **ids) { struct cr_img *img; @@ -661,6 +673,9 @@ static int read_pstree_ids(pid_t pid, TaskKobjIdsEntry **ids) ret = -1; } + if (!ret) + ret = fixup_pid_for_children_ns(*ids); + if (!ret && !top_pid_ns) { /* * If top_pid_ns is not set, this means that here is old dump,