Linux Audio

Check our new training course

Loading...
v6.8
  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
 11struct cgroupfs_cache_entry {
 12	char	subsys[32];
 13	char	mountpoint[PATH_MAX];
 14};
 15
 16/* just cache last used one */
 17static struct cgroupfs_cache_entry *cached;
 18
 19int 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}
v5.9
 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
 
 
 
 
 
 
 
 
11int cgroupfs_find_mountpoint(char *buf, size_t maxlen, const char *subsys)
12{
13	FILE *fp;
14	char mountpoint[PATH_MAX + 1], tokens[PATH_MAX + 1], type[PATH_MAX + 1];
15	char path_v1[PATH_MAX + 1], path_v2[PATH_MAX + 2], *path;
16	char *token, *saved_ptr = NULL;
 
 
 
 
 
 
 
 
 
17
18	fp = fopen("/proc/mounts", "r");
19	if (!fp)
20		return -1;
21
22	/*
23	 * in order to handle split hierarchy, we need to scan /proc/mounts
24	 * and inspect every cgroupfs mount point to find one that has
25	 * perf_event subsystem
 
26	 */
27	path_v1[0] = '\0';
28	path_v2[0] = '\0';
29
30	while (fscanf(fp, "%*s %"__stringify(PATH_MAX)"s %"__stringify(PATH_MAX)"s %"
31				__stringify(PATH_MAX)"s %*d %*d\n",
32				mountpoint, type, tokens) == 3) {
33
34		if (!path_v1[0] && !strcmp(type, "cgroup")) {
35
36			token = strtok_r(tokens, ",", &saved_ptr);
37
38			while (token != NULL) {
39				if (subsys && !strcmp(token, subsys)) {
40					strcpy(path_v1, mountpoint);
41					break;
42				}
43				token = strtok_r(NULL, ",", &saved_ptr);
44			}
 
 
 
 
 
 
 
 
 
 
 
 
 
45		}
46
47		if (!path_v2[0] && !strcmp(type, "cgroup2"))
48			strcpy(path_v2, mountpoint);
 
 
 
 
 
 
 
 
49
50		if (path_v1[0] && path_v2[0])
51			break;
52	}
 
53	fclose(fp);
54
55	if (path_v1[0])
56		path = path_v1;
57	else if (path_v2[0])
58		path = path_v2;
59	else
60		return -1;
 
61
62	if (strlen(path) < maxlen) {
63		strcpy(buf, path);
64		return 0;
65	}
66	return -1;
67}