diff options
Diffstat (limited to 'tools/lib/api/fs/fs.c')
| -rw-r--r-- | tools/lib/api/fs/fs.c | 165 | 
1 files changed, 153 insertions, 12 deletions
| diff --git a/tools/lib/api/fs/fs.c b/tools/lib/api/fs/fs.c index 128ef6332a6b..459599d1b6c4 100644 --- a/tools/lib/api/fs/fs.c +++ b/tools/lib/api/fs/fs.c @@ -1,7 +1,6 @@ -/* TODO merge/factor in debugfs.c here */ -  #include <ctype.h>  #include <errno.h> +#include <limits.h>  #include <stdbool.h>  #include <stdio.h>  #include <stdlib.h> @@ -11,10 +10,29 @@  #include <sys/stat.h>  #include <fcntl.h>  #include <unistd.h> +#include <sys/mount.h> -#include "debugfs.h"  #include "fs.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, @@ -25,19 +43,48 @@ static const char * const procfs__known_mountpoints[] = {  	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 + 1]; +	char			 path[PATH_MAX];  	bool			 found;  	long			 magic;  };  enum { -	FS__SYSFS  = 0, -	FS__PROCFS = 1, +	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", @@ -49,6 +96,16 @@ static struct fs fs__entries[] = {  		.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) @@ -159,14 +216,54 @@ static const char *fs__mountpoint(int idx)  	return fs__get_mountpoint(fs);  } -#define FS__MOUNTPOINT(name, idx)	\ -const char *name##__mountpoint(void)	\ -{					\ -	return fs__mountpoint(idx);	\ +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; +} + +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; +} + +#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__MOUNTPOINT(sysfs,  FS__SYSFS); -FS__MOUNTPOINT(procfs, FS__PROCFS); +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)  { @@ -185,6 +282,50 @@ int filename__read_int(const char *filename, int *value)  	return err;  } +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; +} + +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); +} + +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); +} +  int sysctl__read_int(const char *sysctl, int *value)  {  	char path[PATH_MAX]; |