Release 4.7 tools/lib/api/fs/fs.c
#include <ctype.h>
#include <errno.h>
#include <limits.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/vfs.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mount.h>
#include "fs.h"
#include "debug-internal.h"
#define _STR(x) #x
#define STR(x) _STR(x)
#ifndef SYSFS_MAGIC
#define SYSFS_MAGIC 0x62656572
#endif
#ifndef PROC_SUPER_MAGIC
#define PROC_SUPER_MAGIC 0x9fa0
#endif
#ifndef DEBUGFS_MAGIC
#define DEBUGFS_MAGIC 0x64626720
#endif
#ifndef TRACEFS_MAGIC
#define TRACEFS_MAGIC 0x74726163
#endif
static const char * const sysfs__fs_known_mountpoints[] = {
"/sys",
0,
};
static const char * const procfs__known_mountpoints[] = {
"/proc",
0,
};
#ifndef DEBUGFS_DEFAULT_PATH
#define DEBUGFS_DEFAULT_PATH "/sys/kernel/debug"
#endif
static const char * const debugfs__known_mountpoints[] = {
DEBUGFS_DEFAULT_PATH,
"/debug",
0,
};
#ifndef TRACEFS_DEFAULT_PATH
#define TRACEFS_DEFAULT_PATH "/sys/kernel/tracing"
#endif
static const char * const tracefs__known_mountpoints[] = {
TRACEFS_DEFAULT_PATH,
"/sys/kernel/debug/tracing",
"/tracing",
"/trace",
0,
};
struct fs {
const char *name;
const char * const *mounts;
char path[PATH_MAX];
bool found;
long magic;
};
enum {
FS__SYSFS = 0,
FS__PROCFS = 1,
FS__DEBUGFS = 2,
FS__TRACEFS = 3,
};
#ifndef TRACEFS_MAGIC
#define TRACEFS_MAGIC 0x74726163
#endif
static struct fs fs__entries[] = {
[FS__SYSFS] = {
.name = "sysfs",
.mounts = sysfs__fs_known_mountpoints,
.magic = SYSFS_MAGIC,
},
[FS__PROCFS] = {
.name = "proc",
.mounts = procfs__known_mountpoints,
.magic = PROC_SUPER_MAGIC,
},
[FS__DEBUGFS] = {
.name = "debugfs",
.mounts = debugfs__known_mountpoints,
.magic = DEBUGFS_MAGIC,
},
[FS__TRACEFS] = {
.name = "tracefs",
.mounts = tracefs__known_mountpoints,
.magic = TRACEFS_MAGIC,
},
};
static bool fs__read_mounts(struct fs *fs)
{
bool found = false;
char type[100];
FILE *fp;
fp = fopen("/proc/mounts", "r");
if (fp == NULL)
return NULL;
while (!found &&
fscanf(fp, "%*s %" STR(PATH_MAX) "s %99s %*s %*d %*d\n",
fs->path, type) == 2) {
if (strcmp(type, fs->name) == 0)
found = true;
}
fclose(fp);
return fs->found = found;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
jiri olsa | jiri olsa | 100 | 100.00% | 1 | 100.00% |
| Total | 100 | 100.00% | 1 | 100.00% |
static int fs__valid_mount(const char *fs, long magic)
{
struct statfs st_fs;
if (statfs(fs, &st_fs) < 0)
return -ENOENT;
else if ((long)st_fs.f_type != magic)
return -ENOENT;
return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
jiri olsa | jiri olsa | 50 | 94.34% | 1 | 50.00% |
alexey brodkin | alexey brodkin | 3 | 5.66% | 1 | 50.00% |
| Total | 53 | 100.00% | 2 | 100.00% |
static bool fs__check_mounts(struct fs *fs)
{
const char * const *ptr;
ptr = fs->mounts;
while (*ptr) {
if (fs__valid_mount(*ptr, fs->magic) == 0) {
fs->found = true;
strcpy(fs->path, *ptr);
return true;
}
ptr++;
}
return false;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
jiri olsa | jiri olsa | 72 | 100.00% | 1 | 100.00% |
| Total | 72 | 100.00% | 1 | 100.00% |
static void mem_toupper(char *f, size_t len)
{
while (len) {
*f = toupper(*f);
f++;
len--;
}
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
cody p schafer | cody p schafer | 34 | 100.00% | 1 | 100.00% |
| Total | 34 | 100.00% | 1 | 100.00% |
/*
* Check for "NAME_PATH" environment variable to override fs location (for
* testing). This matches the recommendation in Documentation/sysfs-rules.txt
* for SYSFS_PATH.
*/
static bool fs__env_override(struct fs *fs)
{
char *override_path;
size_t name_len = strlen(fs->name);
/* name + "_PATH" + '\0' */
char upper_name[name_len + 5 + 1];
memcpy(upper_name, fs->name, name_len);
mem_toupper(upper_name, name_len);
strcpy(&upper_name[name_len], "_PATH");
override_path = getenv(upper_name);
if (!override_path)
return false;
fs->found = true;
strncpy(fs->path, override_path, sizeof(fs->path));
return true;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
cody p schafer | cody p schafer | 105 | 100.00% | 1 | 100.00% |
| Total | 105 | 100.00% | 1 | 100.00% |
static const char *fs__get_mountpoint(struct fs *fs)
{
if (fs__env_override(fs))
return fs->path;
if (fs__check_mounts(fs))
return fs->path;
if (fs__read_mounts(fs))
return fs->path;
return NULL;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
jiri olsa | jiri olsa | 34 | 65.38% | 1 | 50.00% |
cody p schafer | cody p schafer | 18 | 34.62% | 1 | 50.00% |
| Total | 52 | 100.00% | 2 | 100.00% |
static const char *fs__mountpoint(int idx)
{
struct fs *fs = &fs__entries[idx];
if (fs->found)
return (const char *)fs->path;
return fs__get_mountpoint(fs);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
jiri olsa | jiri olsa | 43 | 97.73% | 1 | 50.00% |
arnaldo carvalho de melo | arnaldo carvalho de melo | 1 | 2.27% | 1 | 50.00% |
| Total | 44 | 100.00% | 2 | 100.00% |
static const char *mount_overload(struct fs *fs)
{
size_t name_len = strlen(fs->name);
/* "PERF_" + name + "_ENVIRONMENT" + '\0' */
char upper_name[5 + name_len + 12 + 1];
snprintf(upper_name, name_len, "PERF_%s_ENVIRONMENT", fs->name);
mem_toupper(upper_name, name_len);
return getenv(upper_name) ?: *fs->mounts;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
jiri olsa | jiri olsa | 68 | 100.00% | 1 | 100.00% |
| Total | 68 | 100.00% | 1 | 100.00% |
static const char *fs__mount(int idx)
{
struct fs *fs = &fs__entries[idx];
const char *mountpoint;
if (fs__mountpoint(idx))
return (const char *)fs->path;
mountpoint = mount_overload(fs);
if (mount(NULL, mountpoint, fs->name, 0, NULL) < 0)
return NULL;
return fs__check_mounts(fs) ? fs->path : NULL;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
jiri olsa | jiri olsa | 85 | 100.00% | 1 | 100.00% |
| Total | 85 | 100.00% | 1 | 100.00% |
#define FS(name, idx) \
const char *name##__mountpoint(void) \
{ \
return fs__mountpoint(idx); \
} \
\
const char *name##__mount(void) \
{ \
return fs__mount(idx); \
} \
\
bool name##__configured(void) \
{ \
return name##__mountpoint() != NULL; \
}
FS(sysfs, FS__SYSFS);
FS(procfs, FS__PROCFS);
FS(debugfs, FS__DEBUGFS);
FS(tracefs, FS__TRACEFS);
int filename__read_int(const char *filename, int *value)
{
char line[64];
int fd = open(filename, O_RDONLY), err = -1;
if (fd < 0)
return -1;
if (read(fd, line, sizeof(line)) > 0) {
*value = atoi(line);
err = 0;
}
close(fd);
return err;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
arnaldo carvalho de melo | arnaldo carvalho de melo | 83 | 100.00% | 1 | 100.00% |
| Total | 83 | 100.00% | 1 | 100.00% |
int filename__read_ull(const char *filename, unsigned long long *value)
{
char line[64];
int fd = open(filename, O_RDONLY), err = -1;
if (fd < 0)
return -1;
if (read(fd, line, sizeof(line)) > 0) {
*value = strtoull(line, NULL, 10);
if (*value != ULLONG_MAX)
err = 0;
}
close(fd);
return err;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
arnaldo carvalho de melo | arnaldo carvalho de melo | 96 | 100.00% | 1 | 100.00% |
| Total | 96 | 100.00% | 1 | 100.00% |
#define STRERR_BUFSIZE 128
/* For the buffer size of strerror_r */
int filename__read_str(const char *filename, char **buf, size_t *sizep)
{
size_t size = 0, alloc_size = 0;
void *bf = NULL, *nbf;
int fd, n, err = 0;
char sbuf[STRERR_BUFSIZE];
fd = open(filename, O_RDONLY);
if (fd < 0)
return -errno;
do {
if (size == alloc_size) {
alloc_size += BUFSIZ;
nbf = realloc(bf, alloc_size);
if (!nbf) {
err = -ENOMEM;
break;
}
bf = nbf;
}
n = read(fd, bf + size, alloc_size - size);
if (n < 0) {
if (size) {
pr_warning("read failed %d: %s\n", errno,
strerror_r(errno, sbuf, sizeof(sbuf)));
err = 0;
} else
err = -errno;
break;
}
size += n;
} while (n > 0);
if (!err) {
*sizep = size;
*buf = bf;
} else
free(bf);
close(fd);
return err;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
jiri olsa | jiri olsa | 213 | 100.00% | 1 | 100.00% |
| Total | 213 | 100.00% | 1 | 100.00% |
int procfs__read_str(const char *entry, char **buf, size_t *sizep)
{
char path[PATH_MAX];
const char *procfs = procfs__mountpoint();
if (!procfs)
return -1;
snprintf(path, sizeof(path), "%s/%s", procfs, entry);
return filename__read_str(path, buf, sizep);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
arnaldo carvalho de melo | arnaldo carvalho de melo | 68 | 100.00% | 1 | 100.00% |
| Total | 68 | 100.00% | 1 | 100.00% |
int sysfs__read_ull(const char *entry, unsigned long long *value)
{
char path[PATH_MAX];
const char *sysfs = sysfs__mountpoint();
if (!sysfs)
return -1;
snprintf(path, sizeof(path), "%s/%s", sysfs, entry);
return filename__read_ull(path, value);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
arnaldo carvalho de melo | arnaldo carvalho de melo | 63 | 100.00% | 1 | 100.00% |
| Total | 63 | 100.00% | 1 | 100.00% |
int sysfs__read_int(const char *entry, int *value)
{
char path[PATH_MAX];
const char *sysfs = sysfs__mountpoint();
if (!sysfs)
return -1;
snprintf(path, sizeof(path), "%s/%s", sysfs, entry);
return filename__read_int(path, value);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
arnaldo carvalho de melo | arnaldo carvalho de melo | 61 | 100.00% | 1 | 100.00% |
| Total | 61 | 100.00% | 1 | 100.00% |
int sysfs__read_str(const char *entry, char **buf, size_t *sizep)
{
char path[PATH_MAX];
const char *sysfs = sysfs__mountpoint();
if (!sysfs)
return -1;
snprintf(path, sizeof(path), "%s/%s", sysfs, entry);
return filename__read_str(path, buf, sizep);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
jiri olsa | jiri olsa | 68 | 100.00% | 1 | 100.00% |
| Total | 68 | 100.00% | 1 | 100.00% |
int sysctl__read_int(const char *sysctl, int *value)
{
char path[PATH_MAX];
const char *procfs = procfs__mountpoint();
if (!procfs)
return -1;
snprintf(path, sizeof(path), "%s/sys/%s", procfs, sysctl);
return filename__read_int(path, value);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
arnaldo carvalho de melo | arnaldo carvalho de melo | 61 | 100.00% | 1 | 100.00% |
| Total | 61 | 100.00% | 1 | 100.00% |
Overall Contributors
| Person | Tokens | Prop | Commits | CommitProp |
jiri olsa | jiri olsa | 1067 | 62.91% | 10 | 55.56% |
arnaldo carvalho de melo | arnaldo carvalho de melo | 448 | 26.42% | 5 | 27.78% |
cody p schafer | cody p schafer | 164 | 9.67% | 1 | 5.56% |
borislav petkov | borislav petkov | 14 | 0.83% | 1 | 5.56% |
alexey brodkin | alexey brodkin | 3 | 0.18% | 1 | 5.56% |
| Total | 1696 | 100.00% | 18 | 100.00% |
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.