brintos

brintos / linux-shallow public Read only

0
0
Text · 2.1 KiB · 250629a Raw
108 lines · c
1// SPDX-License-Identifier: GPL-2.02#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/mounts41	 * and inspect every cgroupfs mount point to find one that has42	 * the given subsystem.  If we found v1, just use it.  If not we can43	 * 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