cregit-Linux how code gets into the kernel

Release 4.7 tools/lib/api/fs/fs.c

Directory: tools/lib/api/fs
#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

PersonTokensPropCommitsCommitProp
jiri olsajiri olsa100100.00%1100.00%
Total100100.00%1100.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

PersonTokensPropCommitsCommitProp
jiri olsajiri olsa5094.34%150.00%
alexey brodkinalexey brodkin35.66%150.00%
Total53100.00%2100.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

PersonTokensPropCommitsCommitProp
jiri olsajiri olsa72100.00%1100.00%
Total72100.00%1100.00%


static void mem_toupper(char *f, size_t len) { while (len) { *f = toupper(*f); f++; len--; } }

Contributors

PersonTokensPropCommitsCommitProp
cody p schafercody p schafer34100.00%1100.00%
Total34100.00%1100.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

PersonTokensPropCommitsCommitProp
cody p schafercody p schafer105100.00%1100.00%
Total105100.00%1100.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

PersonTokensPropCommitsCommitProp
jiri olsajiri olsa3465.38%150.00%
cody p schafercody p schafer1834.62%150.00%
Total52100.00%2100.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

PersonTokensPropCommitsCommitProp
jiri olsajiri olsa4397.73%150.00%
arnaldo carvalho de meloarnaldo carvalho de melo12.27%150.00%
Total44100.00%2100.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

PersonTokensPropCommitsCommitProp
jiri olsajiri olsa68100.00%1100.00%
Total68100.00%1100.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

PersonTokensPropCommitsCommitProp
jiri olsajiri olsa85100.00%1100.00%
Total85100.00%1100.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

PersonTokensPropCommitsCommitProp
arnaldo carvalho de meloarnaldo carvalho de melo83100.00%1100.00%
Total83100.00%1100.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

PersonTokensPropCommitsCommitProp
arnaldo carvalho de meloarnaldo carvalho de melo96100.00%1100.00%
Total96100.00%1100.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

PersonTokensPropCommitsCommitProp
jiri olsajiri olsa213100.00%1100.00%
Total213100.00%1100.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

PersonTokensPropCommitsCommitProp
arnaldo carvalho de meloarnaldo carvalho de melo68100.00%1100.00%
Total68100.00%1100.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

PersonTokensPropCommitsCommitProp
arnaldo carvalho de meloarnaldo carvalho de melo63100.00%1100.00%
Total63100.00%1100.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

PersonTokensPropCommitsCommitProp
arnaldo carvalho de meloarnaldo carvalho de melo61100.00%1100.00%
Total61100.00%1100.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

PersonTokensPropCommitsCommitProp
jiri olsajiri olsa68100.00%1100.00%
Total68100.00%1100.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

PersonTokensPropCommitsCommitProp
arnaldo carvalho de meloarnaldo carvalho de melo61100.00%1100.00%
Total61100.00%1100.00%


Overall Contributors

PersonTokensPropCommitsCommitProp
jiri olsajiri olsa106762.91%1055.56%
arnaldo carvalho de meloarnaldo carvalho de melo44826.42%527.78%
cody p schafercody p schafer1649.67%15.56%
borislav petkovborislav petkov140.83%15.56%
alexey brodkinalexey brodkin30.18%15.56%
Total1696100.00%18100.00%
Directory: tools/lib/api/fs
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
{% endraw %}