diff --git a/criu/cr-dump.c b/criu/cr-dump.c index 7c9270110..e2c9d1ae0 100644 --- a/criu/cr-dump.c +++ b/criu/cr-dump.c @@ -679,6 +679,18 @@ err: return -1; } +static int get_thread_ids(struct pstree_item *item, int id) +{ + CoreEntry *core = item->core[id]; + core->ids = xmalloc(sizeof(*core->ids)); + if (!core->ids) + return -1; + + task_kobj_ids_entry__init(core->ids); + + return dump_thread_ids(item->threads[id]->real, core->ids); +} + static int do_dump_task_ids(const struct pstree_item *item, struct cr_img *img) { return pb_write_one(img, item->ids, PB_IDS); @@ -863,10 +875,18 @@ static int collect_pstree_ids_predump() int collect_pstree_ids(void) { struct pstree_item *item; + int i; - for_each_pstree_item(item) + for_each_pstree_item(item) { if (get_task_ids(item)) return -1; + for (i = 0; i < item->nr_threads; i++) { + if (item->threads[i]->real == item->pid->real) + continue; + if (get_thread_ids(item, i)) + return -1; + } + } return set_top_pid_ns(); } diff --git a/criu/cr-restore.c b/criu/cr-restore.c index ab827a9d3..33fdde06f 100644 --- a/criu/cr-restore.c +++ b/criu/cr-restore.c @@ -3540,7 +3540,7 @@ static int sigreturn_restore(pid_t pid, struct task_restore_args *task_args, uns blkset = (void *)&tcore->thread_core->blk_sigset; } - if ((tcore->tc || tcore->ids) && thread_args[i].pid[0] != pid) { + if ((tcore->tc) && thread_args[i].pid[0] != pid) { pr_err("Thread has optional fields present %d\n", thread_args[i].pid[0]); ret = -1; diff --git a/criu/include/namespaces.h b/criu/include/namespaces.h index 1f5783317..cafb10992 100644 --- a/criu/include/namespaces.h +++ b/criu/include/namespaces.h @@ -7,6 +7,7 @@ #include "files.h" #include "common/list.h" #include "images/ns.pb-c.h" +#include "images/core.pb-c.h" #include "images/netdev.pb-c.h" #ifndef CLONE_NEWNS @@ -200,6 +201,7 @@ extern int restore_ns(int rst, struct ns_desc *nd); extern int dump_task_ns_ids(struct pstree_item *); extern int predump_task_ns_ids(struct pstree_item *); +extern int dump_thread_ids(pid_t pid, TaskKobjIdsEntry *ids); extern struct ns_id *rst_new_ns_id(unsigned int id, pid_t pid, struct ns_desc *nd, enum ns_type t); extern int rst_add_ns_id(unsigned int id, pid_t pid, struct ns_desc *nd); extern struct ns_id *lookup_ns_by_id(unsigned int id, struct ns_desc *nd); diff --git a/criu/namespaces.c b/criu/namespaces.c index 430f6c699..0fa07b28d 100644 --- a/criu/namespaces.c +++ b/criu/namespaces.c @@ -800,6 +800,14 @@ int dump_task_ns_ids(struct pstree_item *item) return 0; } +int dump_thread_ids(pid_t pid, TaskKobjIdsEntry *ids) +{ + if (get_pid_for_children_ns_id(pid, ids) < 0) + return -1; + + return 0; +} + static int set_ns_opt(int ns_fd, unsigned ioc, struct ns_id **ns, struct ns_desc *nd) { int opt_fd, ret = -1;