mirror of
https://github.com/checkpoint-restore/criu
synced 2025-09-01 06:45:35 +00:00
core: Save tasks' namespaces IDs in the ids image
The recent kernels allow to get namespaces IDs by reading proc-ns links. Use this to generate IDs for tasks' namespaces (I do generate them, since IDs provided by kernel look ugly :( ). Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
This commit is contained in:
@@ -913,6 +913,10 @@ static int dump_task_ids(struct pstree_item *item, const struct cr_fdset *cr_fds
|
||||
if (ret)
|
||||
goto err_free;
|
||||
|
||||
ret = dump_task_ns_ids(item);
|
||||
if (ret)
|
||||
goto err_free;
|
||||
|
||||
ret = pb_write_one(fd_ids, item->ids, PB_IDS);
|
||||
if (ret < 0)
|
||||
goto err_free;
|
||||
|
@@ -18,4 +18,7 @@ int switch_ns(int pid, struct ns_desc *nd, int *rst);
|
||||
int restore_ns(int rst, struct ns_desc *nd);
|
||||
extern struct ns_desc pid_ns_desc;
|
||||
|
||||
struct pstree_item;
|
||||
int dump_task_ns_ids(struct pstree_item *);
|
||||
|
||||
#endif /* __CR_NS_H__ */
|
||||
|
98
namespaces.c
98
namespaces.c
@@ -61,6 +61,104 @@ int restore_ns(int rst, struct ns_desc *nd)
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct ns_id {
|
||||
unsigned int kid;
|
||||
unsigned int id;
|
||||
struct ns_desc *nd;
|
||||
struct ns_id *next;
|
||||
};
|
||||
|
||||
static struct ns_id *ns_ids;
|
||||
static unsigned int ns_next_id = 1;
|
||||
|
||||
static unsigned int generate_ns_id(unsigned int kid, struct ns_desc *nd)
|
||||
{
|
||||
struct ns_id *nsid;
|
||||
|
||||
for (nsid = ns_ids; nsid != NULL; nsid = nsid->next)
|
||||
if (nsid->kid == kid && nsid->nd == nd)
|
||||
return nsid->id;
|
||||
|
||||
nsid = xmalloc(sizeof(*nsid));
|
||||
if (!nsid)
|
||||
return 0;
|
||||
|
||||
nsid->id = ns_next_id++;
|
||||
nsid->kid = kid;
|
||||
nsid->nd = nd;
|
||||
nsid->next = ns_ids;
|
||||
ns_ids = nsid;
|
||||
|
||||
pr_info("Collected %u.%s namespace\n", nsid->id, nd->str);
|
||||
|
||||
return nsid->id;
|
||||
}
|
||||
|
||||
static unsigned int get_ns_id(int pid, struct ns_desc *nd)
|
||||
{
|
||||
int proc_dir, ret;
|
||||
unsigned int kid;
|
||||
char ns_path[10], ns_id[32], *end;
|
||||
|
||||
proc_dir = open_pid_proc(pid);
|
||||
if (proc_dir < 0)
|
||||
return 0;
|
||||
|
||||
sprintf(ns_path, "ns/%s", nd->str);
|
||||
ret = readlinkat(proc_dir, ns_path, ns_id, sizeof(ns_id));
|
||||
if (ret < 0) {
|
||||
pr_perror("Can't readlink ns link");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* XXX: Does it make sence to validate kernel links to <name>:[<id>]? */
|
||||
kid = strtoul(ns_id + strlen(nd->str) + 2, &end, 10);
|
||||
return generate_ns_id(kid, nd);
|
||||
}
|
||||
|
||||
int dump_task_ns_ids(struct pstree_item *item)
|
||||
{
|
||||
int pid = item->pid.real;
|
||||
TaskKobjIdsEntry *ids = item->ids;
|
||||
|
||||
ids->has_pid_ns_id = true;
|
||||
ids->pid_ns_id = get_ns_id(pid, &pid_ns_desc);
|
||||
if (!ids->pid_ns_id) {
|
||||
pr_err("Can't make pidns id\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ids->has_net_ns_id = true;
|
||||
ids->net_ns_id = get_ns_id(pid, &net_ns_desc);
|
||||
if (!ids->net_ns_id) {
|
||||
pr_err("Can't make netns id\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ids->has_ipc_ns_id = true;
|
||||
ids->ipc_ns_id = get_ns_id(pid, &ipc_ns_desc);
|
||||
if (!ids->ipc_ns_id) {
|
||||
pr_err("Can't make ipcns id\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ids->has_uts_ns_id = true;
|
||||
ids->uts_ns_id = get_ns_id(pid, &uts_ns_desc);
|
||||
if (!ids->uts_ns_id) {
|
||||
pr_err("Can't make utsns id\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ids->has_mnt_ns_id = true;
|
||||
ids->mnt_ns_id = get_ns_id(pid, &mnt_ns_desc);
|
||||
if (!ids->mnt_ns_id) {
|
||||
pr_err("Can't make mntns id\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_dump_namespaces(struct pid *ns_pid, unsigned int ns_flags)
|
||||
{
|
||||
struct cr_fdset *fdset;
|
||||
|
@@ -70,6 +70,12 @@ message task_kobj_ids_entry {
|
||||
required uint32 files_id = 2;
|
||||
required uint32 fs_id = 3;
|
||||
required uint32 sighand_id = 4;
|
||||
|
||||
optional uint32 pid_ns_id = 5;
|
||||
optional uint32 net_ns_id = 6;
|
||||
optional uint32 ipc_ns_id = 7;
|
||||
optional uint32 uts_ns_id = 8;
|
||||
optional uint32 mnt_ns_id = 9;
|
||||
}
|
||||
|
||||
message thread_info_x86 {
|
||||
|
Reference in New Issue
Block a user