Something went wrong. Try again.
Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108// SPDX-License-Identifier: GPL-2.0#include <linux/stringify.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include "fs.h"
struct cgroupfs_cache_entry { char subsys[32]; char mountpoint[PATH_MAX];};
/* just cache last used one */static struct cgroupfs_cache_entry *cached;
int cgroupfs_find_mountpoint(char *buf, size_t maxlen, const char *subsys){ FILE *fp; char *line = NULL; size_t len = 0; char *p, *path; char mountpoint[PATH_MAX];
if (cached && !strcmp(cached->subsys, subsys)) { if (strlen(cached->mountpoint) < maxlen) { strcpy(buf, cached->mountpoint); return 0; } return -1; }
fp = fopen("/proc/mounts", "r"); if (!fp) return -1;
/* * in order to handle split hierarchy, we need to scan /proc/mounts * and inspect every cgroupfs mount point to find one that has * the given subsystem. If we found v1, just use it. If not we can * use v2 path as a fallback. */ mountpoint[0] = '\0';
/* * The /proc/mounts has the follow format: * * <devname> <mount point> <fs type> <options> ... * */ while (getline(&line, &len, fp) != -1) { /* skip devname */ p = strchr(line, ' '); if (p == NULL) continue;
/* save the mount point */ path = ++p; p = strchr(p, ' '); if (p == NULL) continue;
*p++ = '\0';
/* check filesystem type */ if (strncmp(p, "cgroup", 6)) continue;
if (p[6] == '2') { /* save cgroup v2 path */ strcpy(mountpoint, path); continue; }
/* now we have cgroup v1, check the options for subsystem */ p += 7;
p = strstr(p, subsys); if (p == NULL) continue;
/* sanity check: it should be separated by a space or a comma */ if (!strchr(" ,", p[-1]) || !strchr(" ,", p[strlen(subsys)])) continue;
strcpy(mountpoint, path); break; } free(line); fclose(fp);
if (!cached) cached = calloc(1, sizeof(*cached));
if (cached) { strncpy(cached->subsys, subsys, sizeof(cached->subsys) - 1); strcpy(cached->mountpoint, mountpoint); }
if (mountpoint[0] && strlen(mountpoint) < maxlen) { strcpy(buf, mountpoint); return 0; } return -1;}