Commit 0f178a1f authored by Tycho Andersen's avatar Tycho Andersen Committed by Pavel Emelyanov

cg: correctly detect co-mounted controller mount point

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: 's avatarTycho Andersen <tycho.andersen@canonical.com>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 3a0ff651
...@@ -168,48 +168,10 @@ int parse_cg_info(void) ...@@ -168,48 +168,10 @@ int parse_cg_info(void)
return 0; 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) /* 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) bool cgroup_contains(char **controllers, unsigned int n_controllers, char *name)
{ {
unsigned int i; unsigned int i;
...@@ -235,6 +197,33 @@ bool cgroup_contains(char **controllers, unsigned int n_controllers, char *name) ...@@ -235,6 +197,33 @@ bool cgroup_contains(char **controllers, unsigned int n_controllers, char *name)
return all_match && n_controllers > 0; 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() /* This is for use in add_cgroup() as additional arguments for the ftw()
* callback */ * callback */
static struct cg_controller *current_controller; static struct cg_controller *current_controller;
...@@ -366,6 +355,8 @@ static int collect_cgroups(struct list_head *ctls) ...@@ -366,6 +355,8 @@ static int collect_cgroups(struct list_head *ctls)
char opts[1024]; char opts[1024];
temp_mount = true; temp_mount = true;
pr_info("Couldn't find mount point for %s mounting..\n", name);
if (mkdtemp(prefix) == NULL) { if (mkdtemp(prefix) == NULL) {
pr_perror("can't make dir for cg mounts\n"); pr_perror("can't make dir for cg mounts\n");
return -1; return -1;
......
...@@ -315,4 +315,5 @@ int mkdirp(const char *path); ...@@ -315,4 +315,5 @@ int mkdirp(const char *path);
*/ */
bool is_path_prefix(const char *path, const char *prefix); bool is_path_prefix(const char *path, const char *prefix);
FILE *fopenat(int dirfd, char *path, char *cflags); FILE *fopenat(int dirfd, char *path, char *cflags);
void split(char *str, char token, char ***out, int *n);
#endif /* __CR_UTIL_H__ */ #endif /* __CR_UTIL_H__ */
...@@ -755,3 +755,50 @@ FILE *fopenat(int dirfd, char *path, char *cflags) ...@@ -755,3 +755,50 @@ FILE *fopenat(int dirfd, char *path, char *cflags)
return fdopen(tmp, 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);
}
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