drm/bridge: adv7511: Switch to atomic operations
[drm/drm-misc.git] / tools / lib / api / fs / cgroup.c
blob250629a09423368045945bc720e75fa0c4c974c4
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"
11 struct cgroupfs_cache_entry {
12 char subsys[32];
13 char mountpoint[PATH_MAX];
16 /* just cache last used one */
17 static struct cgroupfs_cache_entry *cached;
19 int cgroupfs_find_mountpoint(char *buf, size_t maxlen, const char *subsys)
21 FILE *fp;
22 char *line = NULL;
23 size_t len = 0;
24 char *p, *path;
25 char mountpoint[PATH_MAX];
27 if (cached && !strcmp(cached->subsys, subsys)) {
28 if (strlen(cached->mountpoint) < maxlen) {
29 strcpy(buf, cached->mountpoint);
30 return 0;
32 return -1;
35 fp = fopen("/proc/mounts", "r");
36 if (!fp)
37 return -1;
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.
45 mountpoint[0] = '\0';
48 * The /proc/mounts has the follow format:
50 * <devname> <mount point> <fs type> <options> ...
53 while (getline(&line, &len, fp) != -1) {
54 /* skip devname */
55 p = strchr(line, ' ');
56 if (p == NULL)
57 continue;
59 /* save the mount point */
60 path = ++p;
61 p = strchr(p, ' ');
62 if (p == NULL)
63 continue;
65 *p++ = '\0';
67 /* check filesystem type */
68 if (strncmp(p, "cgroup", 6))
69 continue;
71 if (p[6] == '2') {
72 /* save cgroup v2 path */
73 strcpy(mountpoint, path);
74 continue;
77 /* now we have cgroup v1, check the options for subsystem */
78 p += 7;
80 p = strstr(p, subsys);
81 if (p == NULL)
82 continue;
84 /* sanity check: it should be separated by a space or a comma */
85 if (!strchr(" ,", p[-1]) || !strchr(" ,", p[strlen(subsys)]))
86 continue;
88 strcpy(mountpoint, path);
89 break;
91 free(line);
92 fclose(fp);
94 if (!cached)
95 cached = calloc(1, sizeof(*cached));
97 if (cached) {
98 strncpy(cached->subsys, subsys, sizeof(cached->subsys) - 1);
99 strcpy(cached->mountpoint, mountpoint);
102 if (mountpoint[0] && strlen(mountpoint) < maxlen) {
103 strcpy(buf, mountpoint);
104 return 0;
106 return -1;