diff --git a/cr-dump.c b/cr-dump.c index 417e91c6a..2531beaf1 100644 --- a/cr-dump.c +++ b/cr-dump.c @@ -1705,7 +1705,7 @@ int cr_dump_tasks(pid_t pid) goto err; if (current_ns_mask) - if (dump_namespaces(&root_item->pid, current_ns_mask) < 0) + if (dump_namespaces(root_item, current_ns_mask) < 0) goto err; ret = cr_dump_shmem(); diff --git a/cr-restore.c b/cr-restore.c index 413815cdd..3debcbe44 100644 --- a/cr-restore.c +++ b/cr-restore.c @@ -1234,7 +1234,7 @@ static int restore_task_with_children(void *_arg) if (collect_mount_info(getpid())) exit(1); - if (prepare_namespace(current->pid.virt, ca->clone_flags)) + if (prepare_namespace(current, ca->clone_flags)) exit(1); /* diff --git a/image.c b/image.c index 65ce4a386..763410af2 100644 --- a/image.c +++ b/image.c @@ -19,6 +19,7 @@ #include "protobuf/pagemap.pb-c.h" bool fdinfo_per_id = false; +bool ns_per_id = false; TaskKobjIdsEntry *root_ids; int check_img_inventory(void) @@ -34,6 +35,7 @@ int check_img_inventory(void) goto out_close; fdinfo_per_id = he->has_fdinfo_per_id ? he->fdinfo_per_id : false; + ns_per_id = he->has_ns_per_id ? he->ns_per_id : false; if (he->root_ids) { root_ids = xmalloc(sizeof(*root_ids)); @@ -71,6 +73,8 @@ int write_img_inventory(void) he.img_version = CRTOOLS_IMAGES_V1; he.fdinfo_per_id = true; he.has_fdinfo_per_id = true; + he.ns_per_id = true; + he.has_ns_per_id = true; crt.state = TASK_ALIVE; crt.pid.real = getpid(); diff --git a/include/image.h b/include/image.h index 37203cb2b..862aaf044 100644 --- a/include/image.h +++ b/include/image.h @@ -63,5 +63,6 @@ #define TASK_HELPER 0x4 extern bool fdinfo_per_id; +extern bool ns_per_id; #endif /* __CR_IMAGE_H__ */ diff --git a/include/namespaces.h b/include/namespaces.h index 3a1962bc5..4b427f8b1 100644 --- a/include/namespaces.h +++ b/include/namespaces.h @@ -27,8 +27,8 @@ extern unsigned long current_ns_mask; extern const struct fdtype_ops nsfile_dump_ops; extern struct collect_image_info nsfile_cinfo; -int dump_namespaces(struct pid *pid, unsigned int ns_flags); -int prepare_namespace(int pid, unsigned long clone_flags); +int dump_namespaces(struct pstree_item *item, unsigned int ns_flags); +int prepare_namespace(struct pstree_item *item, unsigned long clone_flags); int try_show_namespaces(int pid); int switch_ns(int pid, struct ns_desc *nd, int *rst); diff --git a/namespaces.c b/namespaces.c index 1d8d61507..6bffa2a6d 100644 --- a/namespaces.c +++ b/namespaces.c @@ -348,32 +348,32 @@ int dump_task_ns_ids(struct pstree_item *item) return 0; } -static int do_dump_namespaces(struct pid *ns_pid, unsigned int ns_flags) +static int do_dump_namespaces(struct pstree_item *item, unsigned int ns_flags) { - pid_t ns_id = ns_pid->virt; + struct pid *ns_pid = &item->pid; int ret = 0; if (ns_flags & CLONE_NEWUTS) { pr_info("Dump UTS namespace\n"); - ret = dump_uts_ns(ns_pid->real, ns_id); + ret = dump_uts_ns(ns_pid->real, item->ids->uts_ns_id); if (ret < 0) goto err; } if (ns_flags & CLONE_NEWIPC) { pr_info("Dump IPC namespace\n"); - ret = dump_ipc_ns(ns_pid->real, ns_id); + ret = dump_ipc_ns(ns_pid->real, item->ids->ipc_ns_id); if (ret < 0) goto err; } if (ns_flags & CLONE_NEWNS) { pr_info("Dump MNT namespace (mountpoints)\n"); - ret = dump_mnt_ns(ns_pid->real, ns_id); + ret = dump_mnt_ns(ns_pid->real, item->ids->mnt_ns_id); if (ret < 0) goto err; } if (ns_flags & CLONE_NEWNET) { pr_info("Dump NET namespace info\n"); - ret = dump_net_ns(ns_pid->real, ns_id); + ret = dump_net_ns(ns_pid->real, item->ids->net_ns_id); if (ret < 0) goto err; } @@ -382,8 +382,9 @@ err: } -int dump_namespaces(struct pid *ns_pid, unsigned int ns_flags) +int dump_namespaces(struct pstree_item *item, unsigned int ns_flags) { + struct pid *ns_pid = &item->pid; int pid, status; int ret = 0; @@ -412,7 +413,7 @@ int dump_namespaces(struct pid *ns_pid, unsigned int ns_flags) } if (pid == 0) { - ret = do_dump_namespaces(ns_pid, ns_flags); + ret = do_dump_namespaces(item, ns_flags); exit(ret); } @@ -431,10 +432,13 @@ int dump_namespaces(struct pid *ns_pid, unsigned int ns_flags) return 0; } -int prepare_namespace(int pid, unsigned long clone_flags) +int prepare_namespace(struct pstree_item *item, unsigned long clone_flags) { + pid_t pid = item->pid.virt; + int id; + pr_info("Restoring namespaces %d flags 0x%lx\n", - pid, clone_flags); + item->pid.virt, clone_flags); /* * On netns restore we launch an IP tool, thus we @@ -442,13 +446,17 @@ int prepare_namespace(int pid, unsigned long clone_flags) * tree (i.e. -- mnt_ns restoring) */ - if ((clone_flags & CLONE_NEWNET) && prepare_net_ns(pid)) + id = ns_per_id ? item->ids->net_ns_id : pid; + if ((clone_flags & CLONE_NEWNET) && prepare_net_ns(id)) return -1; - if ((clone_flags & CLONE_NEWUTS) && prepare_utsns(pid)) + id = ns_per_id ? item->ids->uts_ns_id : pid; + if ((clone_flags & CLONE_NEWUTS) && prepare_utsns(id)) return -1; - if ((clone_flags & CLONE_NEWIPC) && prepare_ipc_ns(pid)) + id = ns_per_id ? item->ids->ipc_ns_id : pid; + if ((clone_flags & CLONE_NEWIPC) && prepare_ipc_ns(id)) return -1; - if ((clone_flags & CLONE_NEWNS) && prepare_mnt_ns(pid)) + id = ns_per_id ? item->ids->mnt_ns_id : pid; + if ((clone_flags & CLONE_NEWNS) && prepare_mnt_ns(id)) return -1; return 0; @@ -457,11 +465,21 @@ int prepare_namespace(int pid, unsigned long clone_flags) int try_show_namespaces(int ns_pid) { struct cr_fdset *fdset; - int i, fd; + int i, fd, ret; + TaskKobjIdsEntry *ids; pr_msg("Namespaces for %d:\n", ns_pid); - fdset = cr_fdset_open(ns_pid, _CR_FD_NETNS_FROM, _CR_FD_NETNS_TO, O_SHOW); + fd = open_image(CR_FD_IDS, O_RSTR, ns_pid); + if (fd < 0) + return -1; + ret = pb_read_one(fd, &ids, PB_IDS); + close(fd); + if (ret < 0) + return -1; + + fdset = cr_fdset_open(ids->net_ns_id, + _CR_FD_NETNS_FROM, _CR_FD_NETNS_TO, O_SHOW); if (fdset) { pr_msg("-------------------NETNS---------------------\n"); for (i = _CR_FD_NETNS_FROM + 1; i < _CR_FD_NETNS_TO; i++) { @@ -476,7 +494,8 @@ int try_show_namespaces(int ns_pid) close_cr_fdset(&fdset); } - fdset = cr_fdset_open(ns_pid, _CR_FD_IPCNS_FROM, _CR_FD_IPCNS_TO, O_SHOW); + fdset = cr_fdset_open(ids->ipc_ns_id, + _CR_FD_IPCNS_FROM, _CR_FD_IPCNS_TO, O_SHOW); if (fdset) { pr_msg("-------------------IPCNS---------------------\n"); for (i = _CR_FD_IPCNS_FROM + 1; i < _CR_FD_IPCNS_TO; i++) { @@ -489,14 +508,14 @@ int try_show_namespaces(int ns_pid) close_cr_fdset(&fdset); } - fd = open_image(CR_FD_UTSNS, O_SHOW, ns_pid); + fd = open_image(CR_FD_UTSNS, O_SHOW, ids->uts_ns_id); if (fd >= 0) { pr_msg("-------------------UTSNS---------------------\n"); cr_parse_fd(fd, fdset_template[CR_FD_UTSNS].magic); close(fd); } - fd = open_image(CR_FD_MNTS, O_SHOW, ns_pid); + fd = open_image(CR_FD_MNTS, O_SHOW, ids->mnt_ns_id); if (fd > 0) { pr_msg("-------------------MNTNS---------------------\n"); cr_parse_fd(fd, fdset_template[CR_FD_MNTS].magic); diff --git a/protobuf/inventory.proto b/protobuf/inventory.proto index 5d9f234bd..4b559d0d8 100644 --- a/protobuf/inventory.proto +++ b/protobuf/inventory.proto @@ -4,4 +4,5 @@ message inventory_entry { required uint32 img_version = 1; optional bool fdinfo_per_id = 2; optional task_kobj_ids_entry root_ids = 3; + optional bool ns_per_id = 4; }