Commit 44a10467 authored by Andrei Vagin's avatar Andrei Vagin

cgroup: allow to specify a new root for each controller separately

A few controllers can be merged and before this patch, criu required to
set a new root by specifying all merged controllers.

This patch allows to specify a new root for each controller separately,
but criu will check that all merged controllers will have the same path.

https://github.com/checkpoint-restore/criu/issues/544Signed-off-by: 's avatarAndrei Vagin <avagin@gmail.com>
parent d01899e1
...@@ -186,7 +186,8 @@ int parse_cg_info(void) ...@@ -186,7 +186,8 @@ int parse_cg_info(void)
/* Check that co-mounted controllers from /proc/cgroups (e.g. cpu and cpuacct) /* Check that co-mounted controllers from /proc/cgroups (e.g. cpu and cpuacct)
* are contained in a comma separated string (e.g. from /proc/self/cgroup or * are contained in a comma separated string (e.g. from /proc/self/cgroup or
* mount options). */ * mount options). */
static bool cgroup_contains(char **controllers, unsigned int n_controllers, char *name) static bool cgroup_contains(char **controllers,
unsigned int n_controllers, char *name, u64 *mask)
{ {
unsigned int i; unsigned int i;
bool all_match = true; bool all_match = true;
...@@ -201,6 +202,8 @@ static bool cgroup_contains(char **controllers, unsigned int n_controllers, char ...@@ -201,6 +202,8 @@ static bool cgroup_contains(char **controllers, unsigned int n_controllers, char
case '\0': case '\0':
case ',': case ',':
found = true; found = true;
if (mask)
*mask &= ~(1ULL << i);
break; break;
} }
} }
...@@ -557,7 +560,7 @@ static int collect_cgroups(struct list_head *ctls) ...@@ -557,7 +560,7 @@ static int collect_cgroups(struct list_head *ctls)
* controller from parse_cgroups(), so find that controller if * controller from parse_cgroups(), so find that controller if
* it exists. */ * it exists. */
list_for_each_entry(cg, &cgroups, l) { list_for_each_entry(cg, &cgroups, l) {
if (cgroup_contains(cg->controllers, cg->n_controllers, cc->name)) { if (cgroup_contains(cg->controllers, cg->n_controllers, cc->name, NULL)) {
current_controller = cg; current_controller = cg;
break; break;
} }
...@@ -1021,7 +1024,7 @@ static int prepare_cgns(CgSetEntry *se) ...@@ -1021,7 +1024,7 @@ static int prepare_cgns(CgSetEntry *se)
for (j = 0; j < n_controllers; j++) { for (j = 0; j < n_controllers; j++) {
CgControllerEntry *cur = controllers[j]; CgControllerEntry *cur = controllers[j];
if (cgroup_contains(cur->cnames, cur->n_cnames, ce->name)) { if (cgroup_contains(cur->cnames, cur->n_cnames, ce->name, NULL)) {
ctrl = cur; ctrl = cur;
break; break;
} }
...@@ -1093,7 +1096,7 @@ static int move_in_cgroup(CgSetEntry *se, bool setup_cgns) ...@@ -1093,7 +1096,7 @@ static int move_in_cgroup(CgSetEntry *se, bool setup_cgns)
for (j = 0; j < n_controllers; j++) { for (j = 0; j < n_controllers; j++) {
CgControllerEntry *cur = controllers[j]; CgControllerEntry *cur = controllers[j];
if (cgroup_contains(cur->cnames, cur->n_cnames, ce->name)) { if (cgroup_contains(cur->cnames, cur->n_cnames, ce->name, NULL)) {
ctrl = cur; ctrl = cur;
break; break;
} }
...@@ -1758,7 +1761,7 @@ static int rewrite_cgsets(CgroupEntry *cge, char **controllers, int n_controller ...@@ -1758,7 +1761,7 @@ static int rewrite_cgsets(CgroupEntry *cge, char **controllers, int n_controller
* and its path with stripping leading * and its path with stripping leading
* "/" is matching to be renamed. * "/" is matching to be renamed.
*/ */
if (!(cgroup_contains(controllers, n_controllers, cg->name) && if (!(cgroup_contains(controllers, n_controllers, cg->name, NULL) &&
strstartswith(cg->path + 1, dir))) strstartswith(cg->path + 1, dir)))
continue; continue;
...@@ -1813,19 +1816,31 @@ static int rewrite_cgroup_roots(CgroupEntry *cge) ...@@ -1813,19 +1816,31 @@ static int rewrite_cgroup_roots(CgroupEntry *cge)
{ {
int i, j; int i, j;
struct cg_root_opt *o; struct cg_root_opt *o;
char *newroot = NULL;
for (i = 0; i < cge->n_controllers; i++) { for (i = 0; i < cge->n_controllers; i++) {
CgControllerEntry *ctrl = cge->controllers[i]; CgControllerEntry *ctrl = cge->controllers[i];
newroot = opts.new_global_cg_root; u64 ctrl_mask = (1ULL << ctrl->n_cnames) - 1;
char *newroot = NULL;
list_for_each_entry(o, &opts.new_cgroup_roots, node) { list_for_each_entry(o, &opts.new_cgroup_roots, node) {
if (cgroup_contains(ctrl->cnames, ctrl->n_cnames, o->controller)) { unsigned old_mask = ctrl_mask;
cgroup_contains(ctrl->cnames, ctrl->n_cnames,
o->controller, &ctrl_mask);
if (old_mask != ctrl_mask) {
if (newroot && strcmp(newroot, o->newroot)) {
pr_err("CG paths mismatch: %s %s\n",
newroot, o->newroot);
return -1;
}
newroot = o->newroot; newroot = o->newroot;
}
if (!ctrl_mask)
break; break;
} }
} if (!newroot)
newroot = opts.new_global_cg_root;
if (newroot) { if (newroot) {
for (j = 0; j < ctrl->n_dirs; j++) { for (j = 0; j < ctrl->n_dirs; j++) {
......
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