xref: /OK3568_Linux_fs/kernel/tools/lib/api/fs/cgroup.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun #include <linux/stringify.h>
3*4882a593Smuzhiyun #include <sys/types.h>
4*4882a593Smuzhiyun #include <sys/stat.h>
5*4882a593Smuzhiyun #include <fcntl.h>
6*4882a593Smuzhiyun #include <stdio.h>
7*4882a593Smuzhiyun #include <stdlib.h>
8*4882a593Smuzhiyun #include <string.h>
9*4882a593Smuzhiyun #include "fs.h"
10*4882a593Smuzhiyun 
cgroupfs_find_mountpoint(char * buf,size_t maxlen,const char * subsys)11*4882a593Smuzhiyun int cgroupfs_find_mountpoint(char *buf, size_t maxlen, const char *subsys)
12*4882a593Smuzhiyun {
13*4882a593Smuzhiyun 	FILE *fp;
14*4882a593Smuzhiyun 	char mountpoint[PATH_MAX + 1], tokens[PATH_MAX + 1], type[PATH_MAX + 1];
15*4882a593Smuzhiyun 	char path_v1[PATH_MAX + 1], path_v2[PATH_MAX + 2], *path;
16*4882a593Smuzhiyun 	char *token, *saved_ptr = NULL;
17*4882a593Smuzhiyun 
18*4882a593Smuzhiyun 	fp = fopen("/proc/mounts", "r");
19*4882a593Smuzhiyun 	if (!fp)
20*4882a593Smuzhiyun 		return -1;
21*4882a593Smuzhiyun 
22*4882a593Smuzhiyun 	/*
23*4882a593Smuzhiyun 	 * in order to handle split hierarchy, we need to scan /proc/mounts
24*4882a593Smuzhiyun 	 * and inspect every cgroupfs mount point to find one that has
25*4882a593Smuzhiyun 	 * perf_event subsystem
26*4882a593Smuzhiyun 	 */
27*4882a593Smuzhiyun 	path_v1[0] = '\0';
28*4882a593Smuzhiyun 	path_v2[0] = '\0';
29*4882a593Smuzhiyun 
30*4882a593Smuzhiyun 	while (fscanf(fp, "%*s %"__stringify(PATH_MAX)"s %"__stringify(PATH_MAX)"s %"
31*4882a593Smuzhiyun 				__stringify(PATH_MAX)"s %*d %*d\n",
32*4882a593Smuzhiyun 				mountpoint, type, tokens) == 3) {
33*4882a593Smuzhiyun 
34*4882a593Smuzhiyun 		if (!path_v1[0] && !strcmp(type, "cgroup")) {
35*4882a593Smuzhiyun 
36*4882a593Smuzhiyun 			token = strtok_r(tokens, ",", &saved_ptr);
37*4882a593Smuzhiyun 
38*4882a593Smuzhiyun 			while (token != NULL) {
39*4882a593Smuzhiyun 				if (subsys && !strcmp(token, subsys)) {
40*4882a593Smuzhiyun 					strcpy(path_v1, mountpoint);
41*4882a593Smuzhiyun 					break;
42*4882a593Smuzhiyun 				}
43*4882a593Smuzhiyun 				token = strtok_r(NULL, ",", &saved_ptr);
44*4882a593Smuzhiyun 			}
45*4882a593Smuzhiyun 		}
46*4882a593Smuzhiyun 
47*4882a593Smuzhiyun 		if (!path_v2[0] && !strcmp(type, "cgroup2"))
48*4882a593Smuzhiyun 			strcpy(path_v2, mountpoint);
49*4882a593Smuzhiyun 
50*4882a593Smuzhiyun 		if (path_v1[0] && path_v2[0])
51*4882a593Smuzhiyun 			break;
52*4882a593Smuzhiyun 	}
53*4882a593Smuzhiyun 	fclose(fp);
54*4882a593Smuzhiyun 
55*4882a593Smuzhiyun 	if (path_v1[0])
56*4882a593Smuzhiyun 		path = path_v1;
57*4882a593Smuzhiyun 	else if (path_v2[0])
58*4882a593Smuzhiyun 		path = path_v2;
59*4882a593Smuzhiyun 	else
60*4882a593Smuzhiyun 		return -1;
61*4882a593Smuzhiyun 
62*4882a593Smuzhiyun 	if (strlen(path) < maxlen) {
63*4882a593Smuzhiyun 		strcpy(buf, path);
64*4882a593Smuzhiyun 		return 0;
65*4882a593Smuzhiyun 	}
66*4882a593Smuzhiyun 	return -1;
67*4882a593Smuzhiyun }
68