perf list: Use relative path for tracepoint scan
authorNamhyung Kim <namhyung@kernel.org>
Fri, 31 Mar 2023 20:29:41 +0000 (13:29 -0700)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Tue, 4 Apr 2023 16:23:58 +0000 (13:23 -0300)
Committer notes:

Added missing #include <unistd.h> for the close() prototype to fix this
on Alma Linux 8:

   1    21.54 almalinux:8                   : FAIL gcc version 8.5.0 20210514 (Red Hat 8.5.0-16) (GCC)
    util/print-events.c: In function 'print_tracepoint_events':
    util/print-events.c:103:4: error: implicit declaration of function 'close'; did you mean 'clone'? [-Werror=implicit-function-declaration]
        close(evt_fd);
        ^~~~~
        clone

Also use the newly added scandirat feature test to check if that
function is available, providing a HAVE_SCANDIRAT_SUPPORT conditional
warning to the user if it isn't available.

Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Acked-by: Ian Rogers <irogers@google.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Leo Yan <leo.yan@linaro.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: https://lore.kernel.org/r/20230331202949.810326-2-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/util/print-events.c

index 62e9ea7..386b1ab 100644 (file)
@@ -4,7 +4,9 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <fcntl.h>
 #include <sys/param.h>
+#include <unistd.h>
 
 #include <api/fs/tracing_path.h>
 #include <linux/stddef.h>
@@ -56,7 +58,18 @@ static const struct event_symbol event_symbols_tool[PERF_TOOL_MAX] = {
 /*
  * Print the events from <debugfs_mount_point>/tracing/events
  */
-void print_tracepoint_events(const struct print_callbacks *print_cb, void *print_state)
+void print_tracepoint_events(const struct print_callbacks *print_cb __maybe_unused, void *print_state __maybe_unused)
+{
+       char *events_path = get_tracing_file("events");
+       int events_fd = open(events_path, O_PATH);
+
+       put_tracing_file(events_path);
+       if (events_fd < 0) {
+               printf("Error: failed to open tracing events directory\n");
+               return;
+       }
+
+#ifdef HAVE_SCANDIRAT_SUPPORT
 {
        struct dirent **sys_namelist = NULL;
        int sys_items = tracing_events__scandir_alphasort(&sys_namelist);
@@ -64,7 +77,7 @@ void print_tracepoint_events(const struct print_callbacks *print_cb, void *print
        for (int i = 0; i < sys_items; i++) {
                struct dirent *sys_dirent = sys_namelist[i];
                struct dirent **evt_namelist = NULL;
-               char *dir_path;
+               int dir_fd;
                int evt_items;
 
                if (sys_dirent->d_type != DT_DIR ||
@@ -72,22 +85,26 @@ void print_tracepoint_events(const struct print_callbacks *print_cb, void *print
                    !strcmp(sys_dirent->d_name, ".."))
                        continue;
 
-               dir_path = get_events_file(sys_dirent->d_name);
-               if (!dir_path)
+               dir_fd = openat(events_fd, sys_dirent->d_name, O_PATH);
+               if (dir_fd < 0)
                        continue;
 
-               evt_items = scandir(dir_path, &evt_namelist, NULL, alphasort);
+               evt_items = scandirat(events_fd, sys_dirent->d_name, &evt_namelist, NULL, alphasort);
                for (int j = 0; j < evt_items; j++) {
                        struct dirent *evt_dirent = evt_namelist[j];
                        char evt_path[MAXPATHLEN];
+                       int evt_fd;
 
                        if (evt_dirent->d_type != DT_DIR ||
                            !strcmp(evt_dirent->d_name, ".") ||
                            !strcmp(evt_dirent->d_name, ".."))
                                continue;
 
-                       if (tp_event_has_id(dir_path, evt_dirent) != 0)
+                       snprintf(evt_path, sizeof(evt_path), "%s/id", evt_dirent->d_name);
+                       evt_fd = openat(dir_fd, evt_path, O_RDONLY);
+                       if (evt_fd < 0)
                                continue;
+                       close(evt_fd);
 
                        snprintf(evt_path, MAXPATHLEN, "%s:%s",
                                 sys_dirent->d_name, evt_dirent->d_name);
@@ -103,11 +120,18 @@ void print_tracepoint_events(const struct print_callbacks *print_cb, void *print
                                        /*long_desc=*/NULL,
                                        /*encoding_desc=*/NULL);
                }
-               free(dir_path);
+               close(dir_fd);
                free(evt_namelist);
        }
+
        free(sys_namelist);
 }
+#else
+       printf("\nWARNING: Your libc doesn't have the scandir function, please ask its maintainers to implement it.\n"
+              "         As a rough fallback, please do 'ls %s' to see the available tracepoint events.\n", events_path);
+#endif
+       close(events_fd);
+}
 
 void print_sdt_events(const struct print_callbacks *print_cb, void *print_state)
 {