2
0
mirror of https://github.com/checkpoint-restore/criu synced 2025-08-31 06:15:24 +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:
Pavel Emelyanov
2013-01-18 13:18:33 +04:00
parent 47c98c63d7
commit 2105e18eee
4 changed files with 111 additions and 0 deletions

View File

@@ -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;