if (cgroupfs_find_mountpoint(mnt, PATH_MAX + 1, subsys)) return -1;
if (statfs(mnt, &stbuf) < 0) return -1;
return (stbuf.f_type == CGROUP2_SUPER_MAGIC);
}
staticstruct cgroup *evlist__find_cgroup(struct evlist *evlist, constchar *str)
{ struct evsel *counter; /* * check if cgrp is already defined, if so we reuse it
*/
evlist__for_each_entry(evlist, counter) { if (!counter->cgrp) continue; if (!strcmp(counter->cgrp->name, str)) return cgroup__get(counter->cgrp);
}
if (!cgrp) return -1; /* * find corresponding event * if add cgroup N, then need to find event N
*/
n = 0;
evlist__for_each_entry(evlist, counter) { if (n == nr_cgroups) goto found;
n++;
}
/* helper function for ftw() in match_cgroups and list_cgroups */ staticint add_cgroup_name(constchar *fpath, conststruct stat *sb __maybe_unused, int typeflag, struct FTW *ftwbuf __maybe_unused)
{ struct cgroup_name *cn;
/* use given name as is when no regex is given */ for (;;) {
p = strchr(str, ',');
e = p ? p : eos;
if (e - str) { int ret;
s = strndup(str, e - str); if (!s) return -1;
ret = check_and_add_cgroup_name(s);
free(s); if (ret < 0) return -1;
} else { if (check_and_add_cgroup_name("/") < 0) return -1;
}
if (!p) break;
str = p+1;
}
/* these groups will be used */
list_for_each_entry(cn, &cgroup_list, list)
cn->used = true;
return 0;
}
/* collect all cgroups first and then match with the pattern */ staticint match_cgroups(constchar *str)
{ char mnt[PATH_MAX]; constchar *p, *e, *eos = str + strlen(str); struct cgroup_name *cn;
regex_t reg; int prefix_len; char *s;
if (cgroupfs_find_mountpoint(mnt, sizeof(mnt), "perf_event")) return -1;
/* cgroup_name will have a full path, skip the root directory */
prefix_len = strlen(mnt);
/* collect all cgroups in the cgroup_list */ if (nftw(mnt, add_cgroup_name, 20, 0) < 0) return -1;
for (;;) {
p = strchr(str, ',');
e = p ? p : eos;
/* allow empty cgroups, i.e., skip */ if (e - str) { /* termination added */
s = strndup(str, e - str); if (!s) return -1; if (regcomp(®, s, REG_NOSUB)) {
free(s); return -1;
}
/* check cgroup name with the pattern */
list_for_each_entry(cn, &cgroup_list, list) { char *name = cn->name + prefix_len;
if (name[0] == '/' && name[1])
name++; if (!regexec(®, name, 0, NULL, 0))
cn->used = true;
}
regfree(®);
free(s);
} else { /* first entry to root cgroup */
cn = list_first_entry(&cgroup_list, struct cgroup_name,
list);
cn->used = true;
}
if (list_empty(&evlist->core.entries)) {
fprintf(stderr, "must define events before cgroups\n"); return -1;
}
for (;;) {
p = strchr(str, ',');
e = p ? p : eos;
/* allow empty cgroups, i.e., skip */ if (e - str) { /* termination added */
s = strndup(str, e - str); if (!s) return -1;
ret = add_cgroup(evlist, s);
free(s); if (ret) return -1;
} /* nr_cgroups is increased een for empty cgroups */
nr_cgroups++; if (!p) break;
str = p+1;
} /* for the case one cgroup combine to multiple events */
i = 0; if (nr_cgroups == 1) {
evlist__for_each_entry(evlist, counter) { if (i == 0)
cgrp = counter->cgrp; else {
counter->cgrp = cgrp;
refcount_inc(&cgrp->refcnt);
}
i++;
}
} return 0;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.