Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/tools/lib/api/fs/cgroup.c
26292 views
1
// SPDX-License-Identifier: GPL-2.0
2
#include <linux/stringify.h>
3
#include <sys/types.h>
4
#include <sys/stat.h>
5
#include <fcntl.h>
6
#include <stdio.h>
7
#include <stdlib.h>
8
#include <string.h>
9
#include "fs.h"
10
11
struct cgroupfs_cache_entry {
12
char subsys[32];
13
char mountpoint[PATH_MAX];
14
};
15
16
/* just cache last used one */
17
static struct cgroupfs_cache_entry *cached;
18
19
int cgroupfs_find_mountpoint(char *buf, size_t maxlen, const char *subsys)
20
{
21
FILE *fp;
22
char *line = NULL;
23
size_t len = 0;
24
char *p, *path;
25
char mountpoint[PATH_MAX];
26
27
if (cached && !strcmp(cached->subsys, subsys)) {
28
if (strlen(cached->mountpoint) < maxlen) {
29
strcpy(buf, cached->mountpoint);
30
return 0;
31
}
32
return -1;
33
}
34
35
fp = fopen("/proc/mounts", "r");
36
if (!fp)
37
return -1;
38
39
/*
40
* in order to handle split hierarchy, we need to scan /proc/mounts
41
* and inspect every cgroupfs mount point to find one that has
42
* the given subsystem. If we found v1, just use it. If not we can
43
* use v2 path as a fallback.
44
*/
45
mountpoint[0] = '\0';
46
47
/*
48
* The /proc/mounts has the follow format:
49
*
50
* <devname> <mount point> <fs type> <options> ...
51
*
52
*/
53
while (getline(&line, &len, fp) != -1) {
54
/* skip devname */
55
p = strchr(line, ' ');
56
if (p == NULL)
57
continue;
58
59
/* save the mount point */
60
path = ++p;
61
p = strchr(p, ' ');
62
if (p == NULL)
63
continue;
64
65
*p++ = '\0';
66
67
/* check filesystem type */
68
if (strncmp(p, "cgroup", 6))
69
continue;
70
71
if (p[6] == '2') {
72
/* save cgroup v2 path */
73
strcpy(mountpoint, path);
74
continue;
75
}
76
77
/* now we have cgroup v1, check the options for subsystem */
78
p += 7;
79
80
p = strstr(p, subsys);
81
if (p == NULL)
82
continue;
83
84
/* sanity check: it should be separated by a space or a comma */
85
if (!strchr(" ,", p[-1]) || !strchr(" ,", p[strlen(subsys)]))
86
continue;
87
88
strcpy(mountpoint, path);
89
break;
90
}
91
free(line);
92
fclose(fp);
93
94
if (!cached)
95
cached = calloc(1, sizeof(*cached));
96
97
if (cached) {
98
strncpy(cached->subsys, subsys, sizeof(cached->subsys) - 1);
99
strcpy(cached->mountpoint, mountpoint);
100
}
101
102
if (mountpoint[0] && strlen(mountpoint) < maxlen) {
103
strcpy(buf, mountpoint);
104
return 0;
105
}
106
return -1;
107
}
108
109