diff options
Diffstat (limited to 'tools/perf/perf.c')
| -rw-r--r-- | tools/perf/perf.c | 82 | 
1 files changed, 77 insertions, 5 deletions
diff --git a/tools/perf/perf.c b/tools/perf/perf.c index 4eb72593370..31982ad064b 100644 --- a/tools/perf/perf.c +++ b/tools/perf/perf.c @@ -12,6 +12,8 @@  #include "util/cache.h"  #include "util/quote.h"  #include "util/run-command.h" +#include "util/parse-events.h" +#include "util/string.h"  const char perf_usage_string[] =  	"perf [--version] [--help] COMMAND [ARGS]"; @@ -25,6 +27,8 @@ struct pager_config {  	int val;  }; +static char debugfs_mntpt[MAXPATHLEN]; +  static int pager_command_config(const char *var, const char *value, void *data)  {  	struct pager_config *c = data; @@ -56,6 +60,15 @@ static void commit_pager_choice(void) {  	}  } +static void set_debugfs_path(void) +{ +	char *path; + +	path = getenv(PERF_DEBUGFS_ENVIRONMENT); +	snprintf(debugfs_path, MAXPATHLEN, "%s/%s", path ?: debugfs_mntpt, +		 "tracing/events"); +} +  static int handle_options(const char*** argv, int* argc, int* envchanged)  {  	int handled = 0; @@ -122,6 +135,22 @@ static int handle_options(const char*** argv, int* argc, int* envchanged)  			setenv(PERF_WORK_TREE_ENVIRONMENT, cmd + 12, 1);  			if (envchanged)  				*envchanged = 1; +		} else if (!strcmp(cmd, "--debugfs-dir")) { +			if (*argc < 2) { +				fprintf(stderr, "No directory given for --debugfs-dir.\n"); +				usage(perf_usage_string); +			} +			strncpy(debugfs_mntpt, (*argv)[1], MAXPATHLEN); +			debugfs_mntpt[MAXPATHLEN - 1] = '\0'; +			if (envchanged) +				*envchanged = 1; +			(*argv)++; +			(*argc)--; +		} else if (!prefixcmp(cmd, "--debugfs-dir=")) { +			strncpy(debugfs_mntpt, cmd + 14, MAXPATHLEN); +			debugfs_mntpt[MAXPATHLEN - 1] = '\0'; +			if (envchanged) +				*envchanged = 1;  		} else {  			fprintf(stderr, "Unknown option: %s\n", cmd);  			usage(perf_usage_string); @@ -228,9 +257,7 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv)  	if (use_pager == -1 && p->option & USE_PAGER)  		use_pager = 1;  	commit_pager_choice(); - -	if (p->option & NEED_WORK_TREE) -		/* setup_work_tree() */; +	set_debugfs_path();  	status = p->fn(argc, argv, prefix);  	if (status) @@ -266,7 +293,7 @@ static void handle_internal_command(int argc, const char **argv)  		{ "annotate", cmd_annotate, 0 },  		{ "version", cmd_version, 0 },  	}; -	int i; +	unsigned int i;  	static const char ext[] = STRIP_EXTENSION;  	if (sizeof(ext) > 1) { @@ -349,6 +376,49 @@ static int run_argv(int *argcp, const char ***argv)  	return done_alias;  } +/* mini /proc/mounts parser: searching for "^blah /mount/point debugfs" */ +static void get_debugfs_mntpt(void) +{ +	FILE *file; +	char fs_type[100]; +	char debugfs[MAXPATHLEN]; + +	/* +	 * try the standard location +	 */ +	if (valid_debugfs_mount("/sys/kernel/debug/") == 0) { +		strcpy(debugfs_mntpt, "/sys/kernel/debug/"); +		return; +	} + +	/* +	 * try the sane location +	 */ +	if (valid_debugfs_mount("/debug/") == 0) { +		strcpy(debugfs_mntpt, "/debug/"); +		return; +	} + +	/* +	 * give up and parse /proc/mounts +	 */ +	file = fopen("/proc/mounts", "r"); +	if (file == NULL) +		return; + +	while (fscanf(file, "%*s %" +		      STR(MAXPATHLEN) +		      "s %99s %*s %*d %*d\n", +		      debugfs, fs_type) == 2) { +		if (strcmp(fs_type, "debugfs") == 0) +			break; +	} +	fclose(file); +	if (strcmp(fs_type, "debugfs") == 0) { +		strncpy(debugfs_mntpt, debugfs, MAXPATHLEN); +		debugfs_mntpt[MAXPATHLEN - 1] = '\0'; +	} +}  int main(int argc, const char **argv)  { @@ -357,7 +427,8 @@ int main(int argc, const char **argv)  	cmd = perf_extract_argv0_path(argv[0]);  	if (!cmd)  		cmd = "perf-help"; - +	/* get debugfs mount point from /proc/mounts */ +	get_debugfs_mntpt();  	/*  	 * "perf-xxxx" is the same as "perf xxxx", but we obviously:  	 * @@ -380,6 +451,7 @@ int main(int argc, const char **argv)  	argc--;  	handle_options(&argv, &argc, NULL);  	commit_pager_choice(); +	set_debugfs_path();  	if (argc > 0) {  		if (!prefixcmp(argv[0], "--"))  			argv[0] += 2;  |