Skip to content

Commit

Permalink
cgroup/restore: split prepare_task_cgroup code into two separate func…
Browse files Browse the repository at this point in the history
…tions

This does cgroup namespace creation separately from joining task
cgroups. This makes the code more logical, because creating cgroup
namespace also involves joining cgroups but these cgroups can be
different to task's cgroups as they are cgroup namespace roots
(cgns_prefix), and mixing all of them together may lead to
misunderstanding.

Another positive thing is that we consolidate !item->parent checks in
one place in restore_task_with_children.

Signed-off-by: Valeriy Vdovin <valeriy.vdovin@virtuozzo.com>
Signed-off-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
  • Loading branch information
valeriyvdovin authored and avagin committed Jun 12, 2023
1 parent 72e794c commit f392ea1
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 16 deletions.
54 changes: 40 additions & 14 deletions criu/cgroup.c
Original file line number Diff line number Diff line change
Expand Up @@ -1202,17 +1202,12 @@ static int prepare_cgns(CgSetEntry *se)
return 0;
}

static int move_in_cgroup(CgSetEntry *se, bool setup_cgns)
static int move_in_cgroup(CgSetEntry *se)
{
int i;

pr_info("Move into %d\n", se->id);

if (setup_cgns && prepare_cgns(se) < 0) {
pr_err("failed preparing cgns\n");
return -1;
}

for (i = 0; i < se->n_ctls; i++) {
char aux[PATH_MAX];
int fd = -1, err, j, aux_off;
Expand Down Expand Up @@ -1252,7 +1247,44 @@ static int move_in_cgroup(CgSetEntry *se, bool setup_cgns)
return 0;
}

int prepare_task_cgroup(struct pstree_item *me)
int prepare_cgroup_namespace(struct pstree_item *root_task)
{
CgSetEntry *se;

if (opts.manage_cgroups == CG_MODE_IGNORE)
return 0;

if (root_task->parent) {
pr_err("Expecting root_task to restore cgroup namespace\n");
return -1;
}

/*
* If on dump all dumped tasks are in same cgset with criu we don't
* dump cgsets and thus cgroup namespaces and rely that on restore
* criu caller would prepare proper cgset/cgns for us. Also in case
* of --unprivileged we don't even have the root cgset here.
*/
if (!rsti(root_task)->cg_set || rsti(root_task)->cg_set == root_cg_set) {
pr_info("Cgroup namespace inherited from parent\n");
return 0;
}

se = find_rst_set_by_id(rsti(root_task)->cg_set);
if (!se) {
pr_err("No set %d found\n", rsti(root_task)->cg_set);
return -1;
}

if (prepare_cgns(se) < 0) {
pr_err("failed preparing cgns\n");
return -1;
}

return 0;
}

int restore_task_cgroup(struct pstree_item *me)
{
struct pstree_item *parent = me->parent;
CgSetEntry *se;
Expand Down Expand Up @@ -1284,13 +1316,7 @@ int prepare_task_cgroup(struct pstree_item *me)
return -1;
}

/* Since don't support nesting of cgroup namespaces, let's only set up
* the cgns (if it exists) in the init task. In the future, we should
* just check that the cgns prefix string matches for all the entries
* in the cgset, and only unshare if that's true.
*/

return move_in_cgroup(se, !me->parent);
return move_in_cgroup(se);
}

void fini_cgroup(void)
Expand Down
9 changes: 8 additions & 1 deletion criu/cr-restore.c
Original file line number Diff line number Diff line change
Expand Up @@ -1827,6 +1827,13 @@ static int restore_task_with_children(void *_arg)
/* Wait prepare_userns */
if (restore_finish_ns_stage(CR_STATE_ROOT_TASK, CR_STATE_PREPARE_NAMESPACES) < 0)
goto err;

/*
* Since we don't support nesting of cgroup namespaces, let's
* only set up the cgns (if it exists) in the init task.
*/
if (prepare_cgroup_namespace(current) < 0)
goto err;
}

if (needs_prep_creds(current) && (prepare_userns_creds()))
Expand All @@ -1838,7 +1845,7 @@ static int restore_task_with_children(void *_arg)
* we will only move the root one there, others will
* just have it inherited.
*/
if (prepare_task_cgroup(current) < 0)
if (restore_task_cgroup(current) < 0)
goto err;

/* Restore root task */
Expand Down
3 changes: 2 additions & 1 deletion criu/include/cgroup.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ struct parasite_dump_cgroup_args;
extern u32 root_cg_set;
int dump_thread_cgroup(const struct pstree_item *, u32 *, struct parasite_dump_cgroup_args *args, int id);
int dump_cgroups(void);
int prepare_task_cgroup(struct pstree_item *);
int restore_task_cgroup(struct pstree_item *);
int prepare_cgroup_namespace(struct pstree_item *);
int prepare_cgroup(void);
/* Restore things like cpu_limit in known cgroups. */
int prepare_cgroup_properties(void);
Expand Down

0 comments on commit f392ea1

Please sign in to comment.