mirror of
https://github.com/checkpoint-restore/criu
synced 2025-08-31 06:15:24 +00:00
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: Tycho Andersen <tycho.andersen@canonical.com> Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
This commit is contained in:
committed by
Pavel Emelyanov
parent
3a0ff651db
commit
0f178a1f99
71
cgroup.c
71
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;
|
||||
|
@@ -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__ */
|
||||
|
47
util.c
47
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);
|
||||
}
|
||||
|
Reference in New Issue
Block a user