2
0
mirror of https://github.com/checkpoint-restore/criu synced 2025-08-29 13:28:27 +00:00

ns: Reserve pid_ns helpers

Task is able to set "/proc/sys/kernel/ns_last_pid" only for
its active pid_ns. So, if we create a multi-level pid task,
we need helpers, which allow to set pids in whole pid hierarhy.

This patch reserves a helper for every pid_ns from free pids
of this ns.

Signed-off-by: Kirill Tkhai <ktkhai@virtuozzo.com>
Signed-off-by: Andrei Vagin <avagin@virtuozzo.com>
This commit is contained in:
Kirill Tkhai 2017-05-05 19:16:28 +03:00 committed by Andrei Vagin
parent a88c55f9ca
commit aa07409e0f
3 changed files with 40 additions and 0 deletions

View File

@ -264,5 +264,6 @@ static inline int pid_ns_root_off(void)
return 1;
return 0;
}
extern int reserve_pid_ns_helpers(void);
#endif /* __CR_NS_H__ */

View File

@ -2444,5 +2444,42 @@ int set_user_ns(u32 id)
return __set_user_ns(ns);
}
static int do_reserve_pid_ns_helpers(struct ns_id *ns, void *oarg)
{
struct pstree_item *helper;
struct ns_id *iter = ns;
pid_t pid[MAX_NS_NESTING], *p;
int i, level;
for (i = MAX_NS_NESTING-1; iter && i >= 0; i--, iter = iter->parent) {
pid[i] = get_free_pid(iter);
if (pid[i] < 0) {
pr_err("Can't find free pid\n");
return -1;
}
}
if (iter) {
pr_err("Too many pids levels\n");
return -1;
}
p = &pid[++i];
level = MAX_NS_NESTING - i;
helper = lookup_create_item(p, level, ns->id);
if (helper == NULL)
return -1;
ns->ns_pid = pid[MAX_NS_NESTING-1];
return 0;
}
int reserve_pid_ns_helpers(void)
{
if (!(root_ns_mask & CLONE_NEWPID))
return 0;
return walk_namespaces(&pid_ns_desc, do_reserve_pid_ns_helpers, NULL);
}
struct ns_desc pid_ns_desc = NS_DESC_ENTRY(CLONE_NEWPID, "pid");
struct ns_desc user_ns_desc = NS_DESC_ENTRY(CLONE_NEWUSER, "user");

View File

@ -1207,6 +1207,8 @@ int prepare_pstree(void)
* pstree with properly injected helper tasks.
*/
ret = prepare_pstree_ids();
if (!ret)
ret = reserve_pid_ns_helpers();
return ret;
}