[CRIU] [PATCH] cg: correctly detect co-mounted controller mount point

Tycho Andersen tycho.andersen at canonical.com
Fri Jul 11 09:11:54 PDT 2014


Before we would not detect the mount point for co-mounted controllers. Things
still worked because we'd just re-mount them ourselves and traverse our own
mount point, but this saves an extra mount().

Signed-off-by: Tycho Andersen <tycho.andersen at canonical.com>
---
 cgroup.c       | 71 +++++++++++++++++++++++++---------------------------------
 include/util.h |  1 +
 util.c         | 47 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 79 insertions(+), 40 deletions(-)

diff --git a/cgroup.c b/cgroup.c
index 8be8569..f70653f 100644
--- a/cgroup.c
+++ b/cgroup.c
@@ -168,48 +168,10 @@ int parse_cg_info(void)
 	return 0;
 }
 
-static int get_cgroup_mount_point(const char *controller, char *path)
-{
-	struct mount_info *m;
-	char name[1024];
-
-	for (m = cg_mntinfo; m != NULL; m = m->next) {
-		if (strcmp(m->fstype->name, "cgroup") == 0) {
-			char *start, *end;
-
-			start = strstr(m->options, "name=");
-			if (start) {
-				/* strlen("name=") == 5 */
-				start = start + 5;
-
-				end = strstr(start, ",");
-				if (end) {
-					strncpy(name, start, end - start);
-					name[end - start] = '\0';
-				} else
-					strcpy(name, start);
-			} else {
-				start = strrchr(m->mountpoint, '/');
-				if (!start) {
-					pr_err("bad path %s\n", m->mountpoint);
-					return -1;
-				}
-				strcpy(name, start+1);
-			}
-
-			if (strcmp(name, controller) == 0) {
-				/* skip the leading '.' in mountpoint */
-				strcpy(path, m->mountpoint + 1);
-				return 0;
-			}
-		}
-	}
-
-	return -1;
-}
 
 /* Check that co-mounted controllers from /proc/cgroups (e.g. cpu and cpuacct)
- * are contained in a name from /proc/self/cgroup (e.g. cpu,cpuacct). */
+ * are contained in a comma separated string (e.g. from /proc/self/cgroup or
+ * mount options). */
 bool cgroup_contains(char **controllers, unsigned int n_controllers, char *name)
 {
 	unsigned int i;
@@ -235,6 +197,33 @@ bool cgroup_contains(char **controllers, unsigned int n_controllers, char *name)
 	return all_match && n_controllers > 0;
 }
 
+static int get_cgroup_mount_point(char *controller, char *path)
+{
+	struct mount_info *m;
+	char **names;
+	int n_names, i, ret = -1;
+
+	split(controller, ',', &names, &n_names);
+	if (!names)
+		return -1;
+
+	for (m = cg_mntinfo; m != NULL; m = m->next) {
+		if (strcmp(m->fstype->name, "cgroup") == 0 &&
+				cgroup_contains(names, n_names, m->options)) {
+			/* skip the leading '.' in mountpoint */
+			strcpy(path, m->mountpoint + 1);
+			ret = 0;
+			goto out;
+		}
+	}
+
+out:
+	for (i = 0; i < n_names; i++)
+		xfree(names[i]);
+	xfree(names);
+	return ret;
+}
+
 /* This is for use in add_cgroup() as additional arguments for the ftw()
  * callback */
 static struct cg_controller	*current_controller;
@@ -366,6 +355,8 @@ static int collect_cgroups(struct list_head *ctls)
 			char opts[1024];
 			temp_mount = true;
 
+			pr_info("Couldn't find mount point for %s mounting..\n", name);
+
 			if (mkdtemp(prefix) == NULL) {
 				pr_perror("can't make dir for cg mounts\n");
 				return -1;
diff --git a/include/util.h b/include/util.h
index 522fc33..7d16aa2 100644
--- a/include/util.h
+++ b/include/util.h
@@ -315,4 +315,5 @@ int mkdirp(const char *path);
  */
 bool is_path_prefix(const char *path, const char *prefix);
 FILE *fopenat(int dirfd, char *path, char *cflags);
+void split(char *str, char token, char ***out, int *n);
 #endif /* __CR_UTIL_H__ */
diff --git a/util.c b/util.c
index 2553adc..288f1db 100644
--- a/util.c
+++ b/util.c
@@ -755,3 +755,50 @@ FILE *fopenat(int dirfd, char *path, char *cflags)
 
 	return fdopen(tmp, cflags);
 }
+
+void split(char *str, char token, char ***out, int *n)
+{
+	int i;
+	char *cur;
+
+	*n = 0;
+	for (cur = str; cur != NULL; cur = strchr(cur, token)) {
+		(*n)++;
+		cur++;
+	}
+
+
+	*out = xmalloc((*n) * sizeof(char *));
+	if (!*out) {
+		*n = -1;
+		return;
+
+	}
+
+	cur = str;
+	i = 0;
+	do {
+		char *prev = cur;
+		cur = strchr(cur, token);
+
+		if (cur)
+			*cur = '\0';
+		(*out)[i] = xstrdup(prev);
+		if (cur) {
+			*cur = token;
+			cur++;
+		}
+
+		if (!(*out)[i]) {
+			int j;
+			for (j = 0; j < i; j++)
+				xfree((*out)[j]);
+			xfree(out);
+			*out = NULL;
+			*n = -1;
+			return;
+		}
+
+		i++;
+	} while(cur);
+}
-- 
1.9.1



More information about the CRIU mailing list