Commit a46831ae authored by Pavel Emelyanov's avatar Pavel Emelyanov

cr: Detect namespaces presence automatically

Introduce the current_ns_mask variable, that collects info about
which namespaces tasks being dumped and to be restored live in.

For simlicity all tasks are supposed to live in one set of spaces.
This should be fixed eventually.
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 2f22c688
......@@ -17,6 +17,7 @@
#include "protobuf/inventory.pb-c.h"
bool fdinfo_per_id = false;
TaskKobjIdsEntry *root_ids;
int check_img_inventory(void)
{
......@@ -35,6 +36,11 @@ int check_img_inventory(void)
fdinfo_per_id = he->has_fdinfo_per_id ? he->fdinfo_per_id : false;
ret = he->img_version;
root_ids = xmalloc(sizeof(*root_ids));
if (!root_ids)
return -1;
memcpy(root_ids, he->root_ids, sizeof(*root_ids));
inventory_entry__free_unpacked(he, NULL);
if (ret != CRTOOLS_IMAGES_V1) {
......
......@@ -21,4 +21,7 @@ extern struct ns_desc pid_ns_desc;
struct pstree_item;
int dump_task_ns_ids(struct pstree_item *);
extern unsigned long current_ns_mask;
int check_ns_ids(struct pstree_item *);
#endif /* __CR_NS_H__ */
......@@ -74,5 +74,6 @@ struct task_entries;
extern struct task_entries *task_entries;
int get_task_ids(struct pstree_item *);
extern struct _TaskKobjIdsEntry *root_ids;
#endif /* __CR_PSTREE_H__ */
......@@ -70,8 +70,9 @@ struct ns_id {
static struct ns_id *ns_ids;
static unsigned int ns_next_id = 1;
unsigned long current_ns_mask = 0;
static unsigned int generate_ns_id(unsigned int kid, struct ns_desc *nd)
static unsigned int generate_ns_id(int pid, unsigned int kid, struct ns_desc *nd)
{
struct ns_id *nsid;
......@@ -79,6 +80,18 @@ static unsigned int generate_ns_id(unsigned int kid, struct ns_desc *nd)
if (nsid->kid == kid && nsid->nd == nd)
return nsid->id;
if (pid != getpid()) {
if (pid == root_item->pid.real) {
BUG_ON(current_ns_mask & nd->cflag);
pr_info("Will take %s namespace in the image\n", nd->str);
current_ns_mask |= nd->cflag;
} else {
pr_err("Can't dump nested %s namespace for %d\n",
nd->str, pid);
return 0;
}
}
nsid = xmalloc(sizeof(*nsid));
if (!nsid)
return 0;
......@@ -113,7 +126,7 @@ static unsigned int get_ns_id(int pid, struct ns_desc *nd)
/* 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);
return generate_ns_id(pid, kid, nd);
}
int dump_task_ns_ids(struct pstree_item *item)
......@@ -247,6 +260,51 @@ int dump_namespaces(struct pid *ns_pid, unsigned int ns_flags)
return 0;
}
static unsigned long get_clone_mask(TaskKobjIdsEntry *i,
TaskKobjIdsEntry *p)
{
unsigned long mask = 0;
if (i->pid_ns_id != p->pid_ns_id)
mask |= CLONE_NEWPID;
if (i->net_ns_id != p->net_ns_id)
mask |= CLONE_NEWNET;
if (i->ipc_ns_id != p->ipc_ns_id)
mask |= CLONE_NEWIPC;
if (i->uts_ns_id != p->uts_ns_id)
mask |= CLONE_NEWUTS;
if (i->mnt_ns_id != p->mnt_ns_id)
mask |= CLONE_NEWNS;
return mask;
}
int check_ns_ids(struct pstree_item *item)
{
struct pstree_item *p = item->parent;
if (!p) {
current_ns_mask = get_clone_mask(item->ids, root_ids);
pr_info("Will restore in %lx namespaces\n", current_ns_mask);
return 0;
}
if (!item->ids)
return 0;
while (!p->ids) {
p = p->parent;
BUG_ON(!p); /* must meet the root_item */
}
if (get_clone_mask(item->ids, p->ids)) {
pr_err("Task in sub namespace\n");
return -1;
}
return 0;
}
int prepare_namespace(int pid, unsigned long clone_flags)
{
pr_info("Restoring namespaces %d flags 0x%lx\n",
......
......@@ -6,6 +6,7 @@
#include "restorer.h"
#include "util.h"
#include "lock.h"
#include "namespaces.h"
#include "protobuf.h"
#include "protobuf/pstree.pb-c.h"
......@@ -443,6 +444,9 @@ static int prepare_pstree_ids(void)
if (item->state == TASK_HELPER)
continue;
if (check_ns_ids(item))
return -1;
if (parent == NULL)
continue;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment