Merge branch 'for-linus' of git://git.infradead.org/users/eparis/notify
[pandora-kernel.git] / tools / perf / perf.c
index 4eb7259..31982ad 100644 (file)
@@ -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;