xref: /aosp_15_r20/external/iproute2/lib/fs.c (revision de1e4e894b0c224df933550f0afdecc354b238c4)
1*de1e4e89SAndroid Build Coastguard Worker /*
2*de1e4e89SAndroid Build Coastguard Worker  * fs.c         filesystem APIs
3*de1e4e89SAndroid Build Coastguard Worker  *
4*de1e4e89SAndroid Build Coastguard Worker  *		This program is free software; you can redistribute it and/or
5*de1e4e89SAndroid Build Coastguard Worker  *		modify it under the terms of the GNU General Public License
6*de1e4e89SAndroid Build Coastguard Worker  *		as published by the Free Software Foundation; either version
7*de1e4e89SAndroid Build Coastguard Worker  *		2 of the License, or (at your option) any later version.
8*de1e4e89SAndroid Build Coastguard Worker  *
9*de1e4e89SAndroid Build Coastguard Worker  * Authors:	David Ahern <[email protected]>
10*de1e4e89SAndroid Build Coastguard Worker  *
11*de1e4e89SAndroid Build Coastguard Worker  */
12*de1e4e89SAndroid Build Coastguard Worker 
13*de1e4e89SAndroid Build Coastguard Worker #include <sys/types.h>
14*de1e4e89SAndroid Build Coastguard Worker #include <sys/stat.h>
15*de1e4e89SAndroid Build Coastguard Worker #include <sys/socket.h>
16*de1e4e89SAndroid Build Coastguard Worker #include <sys/mount.h>
17*de1e4e89SAndroid Build Coastguard Worker #include <ctype.h>
18*de1e4e89SAndroid Build Coastguard Worker #include <fcntl.h>
19*de1e4e89SAndroid Build Coastguard Worker #include <stdio.h>
20*de1e4e89SAndroid Build Coastguard Worker #include <stdlib.h>
21*de1e4e89SAndroid Build Coastguard Worker #include <unistd.h>
22*de1e4e89SAndroid Build Coastguard Worker #include <string.h>
23*de1e4e89SAndroid Build Coastguard Worker #include <errno.h>
24*de1e4e89SAndroid Build Coastguard Worker #include <limits.h>
25*de1e4e89SAndroid Build Coastguard Worker 
26*de1e4e89SAndroid Build Coastguard Worker #include "utils.h"
27*de1e4e89SAndroid Build Coastguard Worker 
28*de1e4e89SAndroid Build Coastguard Worker #define CGROUP2_FS_NAME "cgroup2"
29*de1e4e89SAndroid Build Coastguard Worker 
30*de1e4e89SAndroid Build Coastguard Worker /* if not already mounted cgroup2 is mounted here for iproute2's use */
31*de1e4e89SAndroid Build Coastguard Worker #define MNT_CGRP2_PATH  "/var/run/cgroup2"
32*de1e4e89SAndroid Build Coastguard Worker 
33*de1e4e89SAndroid Build Coastguard Worker /* return mount path of first occurrence of given fstype */
find_fs_mount(const char * fs_to_find)34*de1e4e89SAndroid Build Coastguard Worker static char *find_fs_mount(const char *fs_to_find)
35*de1e4e89SAndroid Build Coastguard Worker {
36*de1e4e89SAndroid Build Coastguard Worker 	char path[4096];
37*de1e4e89SAndroid Build Coastguard Worker 	char fstype[128];    /* max length of any filesystem name */
38*de1e4e89SAndroid Build Coastguard Worker 	char *mnt = NULL;
39*de1e4e89SAndroid Build Coastguard Worker 	FILE *fp;
40*de1e4e89SAndroid Build Coastguard Worker 
41*de1e4e89SAndroid Build Coastguard Worker 	fp = fopen("/proc/mounts", "r");
42*de1e4e89SAndroid Build Coastguard Worker 	if (!fp) {
43*de1e4e89SAndroid Build Coastguard Worker 		fprintf(stderr,
44*de1e4e89SAndroid Build Coastguard Worker 			"Failed to open mounts file: %s\n", strerror(errno));
45*de1e4e89SAndroid Build Coastguard Worker 		return NULL;
46*de1e4e89SAndroid Build Coastguard Worker 	}
47*de1e4e89SAndroid Build Coastguard Worker 
48*de1e4e89SAndroid Build Coastguard Worker 	while (fscanf(fp, "%*s %4095s %127s %*s %*d %*d\n",
49*de1e4e89SAndroid Build Coastguard Worker 		      path, fstype) == 2) {
50*de1e4e89SAndroid Build Coastguard Worker 		if (strcmp(fstype, fs_to_find) == 0) {
51*de1e4e89SAndroid Build Coastguard Worker 			mnt = strdup(path);
52*de1e4e89SAndroid Build Coastguard Worker 			break;
53*de1e4e89SAndroid Build Coastguard Worker 		}
54*de1e4e89SAndroid Build Coastguard Worker 	}
55*de1e4e89SAndroid Build Coastguard Worker 
56*de1e4e89SAndroid Build Coastguard Worker 	fclose(fp);
57*de1e4e89SAndroid Build Coastguard Worker 
58*de1e4e89SAndroid Build Coastguard Worker 	return mnt;
59*de1e4e89SAndroid Build Coastguard Worker }
60*de1e4e89SAndroid Build Coastguard Worker 
61*de1e4e89SAndroid Build Coastguard Worker /* caller needs to free string returned */
find_cgroup2_mount(void)62*de1e4e89SAndroid Build Coastguard Worker char *find_cgroup2_mount(void)
63*de1e4e89SAndroid Build Coastguard Worker {
64*de1e4e89SAndroid Build Coastguard Worker 	char *mnt = find_fs_mount(CGROUP2_FS_NAME);
65*de1e4e89SAndroid Build Coastguard Worker 
66*de1e4e89SAndroid Build Coastguard Worker 	if (mnt)
67*de1e4e89SAndroid Build Coastguard Worker 		return mnt;
68*de1e4e89SAndroid Build Coastguard Worker 
69*de1e4e89SAndroid Build Coastguard Worker 	mnt = strdup(MNT_CGRP2_PATH);
70*de1e4e89SAndroid Build Coastguard Worker 	if (!mnt) {
71*de1e4e89SAndroid Build Coastguard Worker 		fprintf(stderr, "Failed to allocate memory for cgroup2 path\n");
72*de1e4e89SAndroid Build Coastguard Worker 		return NULL;
73*de1e4e89SAndroid Build Coastguard Worker 
74*de1e4e89SAndroid Build Coastguard Worker 	}
75*de1e4e89SAndroid Build Coastguard Worker 
76*de1e4e89SAndroid Build Coastguard Worker 	if (make_path(mnt, 0755)) {
77*de1e4e89SAndroid Build Coastguard Worker 		fprintf(stderr, "Failed to setup vrf cgroup2 directory\n");
78*de1e4e89SAndroid Build Coastguard Worker 		free(mnt);
79*de1e4e89SAndroid Build Coastguard Worker 		return NULL;
80*de1e4e89SAndroid Build Coastguard Worker 	}
81*de1e4e89SAndroid Build Coastguard Worker 
82*de1e4e89SAndroid Build Coastguard Worker 	if (mount("none", mnt, CGROUP2_FS_NAME, 0, NULL)) {
83*de1e4e89SAndroid Build Coastguard Worker 		/* EBUSY means already mounted */
84*de1e4e89SAndroid Build Coastguard Worker 		if (errno == EBUSY)
85*de1e4e89SAndroid Build Coastguard Worker 			goto out;
86*de1e4e89SAndroid Build Coastguard Worker 
87*de1e4e89SAndroid Build Coastguard Worker 		if (errno == ENODEV) {
88*de1e4e89SAndroid Build Coastguard Worker 			fprintf(stderr,
89*de1e4e89SAndroid Build Coastguard Worker 				"Failed to mount cgroup2. Are CGROUPS enabled in your kernel?\n");
90*de1e4e89SAndroid Build Coastguard Worker 		} else {
91*de1e4e89SAndroid Build Coastguard Worker 			fprintf(stderr,
92*de1e4e89SAndroid Build Coastguard Worker 				"Failed to mount cgroup2: %s\n",
93*de1e4e89SAndroid Build Coastguard Worker 				strerror(errno));
94*de1e4e89SAndroid Build Coastguard Worker 		}
95*de1e4e89SAndroid Build Coastguard Worker 		free(mnt);
96*de1e4e89SAndroid Build Coastguard Worker 		return NULL;
97*de1e4e89SAndroid Build Coastguard Worker 	}
98*de1e4e89SAndroid Build Coastguard Worker out:
99*de1e4e89SAndroid Build Coastguard Worker 	return mnt;
100*de1e4e89SAndroid Build Coastguard Worker }
101*de1e4e89SAndroid Build Coastguard Worker 
make_path(const char * path,mode_t mode)102*de1e4e89SAndroid Build Coastguard Worker int make_path(const char *path, mode_t mode)
103*de1e4e89SAndroid Build Coastguard Worker {
104*de1e4e89SAndroid Build Coastguard Worker 	char *dir, *delim;
105*de1e4e89SAndroid Build Coastguard Worker 	int rc = -1;
106*de1e4e89SAndroid Build Coastguard Worker 
107*de1e4e89SAndroid Build Coastguard Worker 	delim = dir = strdup(path);
108*de1e4e89SAndroid Build Coastguard Worker 	if (dir == NULL) {
109*de1e4e89SAndroid Build Coastguard Worker 		fprintf(stderr, "strdup failed copying path");
110*de1e4e89SAndroid Build Coastguard Worker 		return -1;
111*de1e4e89SAndroid Build Coastguard Worker 	}
112*de1e4e89SAndroid Build Coastguard Worker 
113*de1e4e89SAndroid Build Coastguard Worker 	/* skip '/' -- it had better exist */
114*de1e4e89SAndroid Build Coastguard Worker 	if (*delim == '/')
115*de1e4e89SAndroid Build Coastguard Worker 		delim++;
116*de1e4e89SAndroid Build Coastguard Worker 
117*de1e4e89SAndroid Build Coastguard Worker 	while (1) {
118*de1e4e89SAndroid Build Coastguard Worker 		delim = strchr(delim, '/');
119*de1e4e89SAndroid Build Coastguard Worker 		if (delim)
120*de1e4e89SAndroid Build Coastguard Worker 			*delim = '\0';
121*de1e4e89SAndroid Build Coastguard Worker 
122*de1e4e89SAndroid Build Coastguard Worker 		rc = mkdir(dir, mode);
123*de1e4e89SAndroid Build Coastguard Worker 		if (mkdir(dir, mode) != 0 && errno != EEXIST) {
124*de1e4e89SAndroid Build Coastguard Worker 			fprintf(stderr, "mkdir failed for %s: %s\n",
125*de1e4e89SAndroid Build Coastguard Worker 				dir, strerror(errno));
126*de1e4e89SAndroid Build Coastguard Worker 			goto out;
127*de1e4e89SAndroid Build Coastguard Worker 		}
128*de1e4e89SAndroid Build Coastguard Worker 
129*de1e4e89SAndroid Build Coastguard Worker 		if (delim == NULL)
130*de1e4e89SAndroid Build Coastguard Worker 			break;
131*de1e4e89SAndroid Build Coastguard Worker 
132*de1e4e89SAndroid Build Coastguard Worker 		*delim = '/';
133*de1e4e89SAndroid Build Coastguard Worker 		delim++;
134*de1e4e89SAndroid Build Coastguard Worker 		if (*delim == '\0')
135*de1e4e89SAndroid Build Coastguard Worker 			break;
136*de1e4e89SAndroid Build Coastguard Worker 	}
137*de1e4e89SAndroid Build Coastguard Worker 	rc = 0;
138*de1e4e89SAndroid Build Coastguard Worker out:
139*de1e4e89SAndroid Build Coastguard Worker 	free(dir);
140*de1e4e89SAndroid Build Coastguard Worker 
141*de1e4e89SAndroid Build Coastguard Worker 	return rc;
142*de1e4e89SAndroid Build Coastguard Worker }
143*de1e4e89SAndroid Build Coastguard Worker 
get_command_name(const char * pid,char * comm,size_t len)144*de1e4e89SAndroid Build Coastguard Worker int get_command_name(const char *pid, char *comm, size_t len)
145*de1e4e89SAndroid Build Coastguard Worker {
146*de1e4e89SAndroid Build Coastguard Worker 	char path[PATH_MAX];
147*de1e4e89SAndroid Build Coastguard Worker 	char line[128];
148*de1e4e89SAndroid Build Coastguard Worker 	FILE *fp;
149*de1e4e89SAndroid Build Coastguard Worker 
150*de1e4e89SAndroid Build Coastguard Worker 	if (snprintf(path, sizeof(path),
151*de1e4e89SAndroid Build Coastguard Worker 		     "/proc/%s/status", pid) >= sizeof(path)) {
152*de1e4e89SAndroid Build Coastguard Worker 		return -1;
153*de1e4e89SAndroid Build Coastguard Worker 	}
154*de1e4e89SAndroid Build Coastguard Worker 
155*de1e4e89SAndroid Build Coastguard Worker 	fp = fopen(path, "r");
156*de1e4e89SAndroid Build Coastguard Worker 	if (!fp)
157*de1e4e89SAndroid Build Coastguard Worker 		return -1;
158*de1e4e89SAndroid Build Coastguard Worker 
159*de1e4e89SAndroid Build Coastguard Worker 	comm[0] = '\0';
160*de1e4e89SAndroid Build Coastguard Worker 	while (fgets(line, sizeof(line), fp)) {
161*de1e4e89SAndroid Build Coastguard Worker 		char *nl, *name;
162*de1e4e89SAndroid Build Coastguard Worker 
163*de1e4e89SAndroid Build Coastguard Worker 		name = strstr(line, "Name:");
164*de1e4e89SAndroid Build Coastguard Worker 		if (!name)
165*de1e4e89SAndroid Build Coastguard Worker 			continue;
166*de1e4e89SAndroid Build Coastguard Worker 
167*de1e4e89SAndroid Build Coastguard Worker 		name += 5;
168*de1e4e89SAndroid Build Coastguard Worker 		while (isspace(*name))
169*de1e4e89SAndroid Build Coastguard Worker 			name++;
170*de1e4e89SAndroid Build Coastguard Worker 
171*de1e4e89SAndroid Build Coastguard Worker 		nl = strchr(name, '\n');
172*de1e4e89SAndroid Build Coastguard Worker 		if (nl)
173*de1e4e89SAndroid Build Coastguard Worker 			*nl = '\0';
174*de1e4e89SAndroid Build Coastguard Worker 
175*de1e4e89SAndroid Build Coastguard Worker 		strlcpy(comm, name, len);
176*de1e4e89SAndroid Build Coastguard Worker 		break;
177*de1e4e89SAndroid Build Coastguard Worker 	}
178*de1e4e89SAndroid Build Coastguard Worker 
179*de1e4e89SAndroid Build Coastguard Worker 	fclose(fp);
180*de1e4e89SAndroid Build Coastguard Worker 
181*de1e4e89SAndroid Build Coastguard Worker 	return 0;
182*de1e4e89SAndroid Build Coastguard Worker }
183