[CRIU] [PATCH 06/10] cgroup: fix --cgroup-root and cgns interaction

Tycho Andersen tycho.andersen at canonical.com
Wed Mar 2 11:28:55 PST 2016


Basically, instead of --cgroup-root replacing the actual root, when a cgns
is present, it just replaces the namespace prefix. See patch comments for
details.

Signed-off-by: Tycho Andersen <tycho.andersen at canonical.com>
---
 criu/cgroup.c | 65 ++++++++++++++++++++++++++++++++++++++++++-----------------
 1 file changed, 47 insertions(+), 18 deletions(-)

diff --git a/criu/cgroup.c b/criu/cgroup.c
index cf005d9..0ad70bf 100644
--- a/criu/cgroup.c
+++ b/criu/cgroup.c
@@ -1502,26 +1502,63 @@ err:
 }
 
 static int rewrite_cgsets(CgroupEntry *cge, char **controllers, int n_controllers,
-			  char *from, char *to)
+			  char **from, char *to)
 {
 	int i, j;
+	bool set_from = false;
+
 	for (i = 0; i < cge->n_sets; i++) {
 		CgSetEntry *set = cge->sets[i];
 		for (j = 0; j < set->n_ctls; j++) {
 			CgMemberEntry *cg = set->ctls[j];
-			if (cgroup_contains(controllers, n_controllers, cg->name) &&
-					/* +1 to get rid of leading / */
-					strstartswith(cg->path + 1, from)) {
+			char *tmp = cg->path, *tmp2 = NULL;
 
-				char *tmp = cg->path;
+			if (!(cgroup_contains(controllers, n_controllers, cg->name) &&
+					/* +1 to get rid of leading / */
+					strstartswith(cg->path + 1, *from)))
+				continue;
+
+			/* If this cgset has a cgns prefix, let's use
+			 * that as the start of the root replacement.
+			 */
+			if (cg->has_cgns_prefix && cg->cgns_prefix) {
+				/* Rewrite the group dir to match the
+				 * prefix. We can do this exactly once
+				 * since we know all the tasks are in
+				 * the same cgroup ns (and thus have
+				 * the same per-controller prefix path)
+				 * since we don't support nesting.
+				 */
+				if (!set_from) {
+					set_from = true;
+					/* -2 because cgns_prefix includes leading and trailing /'s */
+					*from = xsprintf("%s%s", to, (*from) + cg->cgns_prefix - 2);
+				}
 
-				/* +1 to get rid of leading /, again */
 				cg->path = xsprintf("%s%s", to, cg->path +
-							strlen(from) + 1);
-				if (!cg->path)
+							cg->cgns_prefix - 1);
+				cg->cgns_prefix = strlen(to);
+			} else {
+				/* otherwise, use the old rewriting strategy */
+				cg->path = xsprintf("%s%s", to, cg->path +
+							strlen(*from) + 1);
+				if (!set_from) {
+					set_from = true;
+					*from = xstrdup(to);
+				}
+			}
+
+			if (tmp2) {
+				if (!*from)
 					return -1;
-				free(tmp);
+
+				xfree(tmp2);
 			}
+
+			if (!cg->path)
+				return -1;
+
+			free(tmp);
 		}
 
 	}
@@ -1549,18 +1586,10 @@ static int rewrite_cgroup_roots(CgroupEntry *cge)
 		if (newroot) {
 			for (j = 0; j < ctrl->n_dirs; j++) {
 				CgroupDirEntry *cgde = ctrl->dirs[j];
-				char *m;
 
 				pr_info("rewriting %s to %s\n", cgde->dir_name, newroot);
-				if (rewrite_cgsets(cge, ctrl->cnames, ctrl->n_cnames, cgde->dir_name, newroot))
-					return -1;
-
-				m = xstrdup(newroot);
-				if (!m)
+				if (rewrite_cgsets(cge, ctrl->cnames, ctrl->n_cnames, &cgde->dir_name, newroot))
 					return -1;
-
-				free(cgde->dir_name);
-				cgde->dir_name = m;
 			}
 		}
 	}
-- 
2.7.0



More information about the CRIU mailing list