From 13cea8b71517d690e942af2022ceac022cbe4393 Mon Sep 17 00:00:00 2001 From: Gichoel Choi Date: Sun, 6 Aug 2023 22:50:10 +0900 Subject: [PATCH 1/2] utils: Modify logic to check path for tracefs using '/proc/mounts' This logic change is to address issue #1753, which was causing issue on some kernels. The previous logic used '/proc/self/mountinfo', but in some cases the number of fields was different, causing a parse error. This has been fixed by using getmntent() and setmntent() to parse '/proc/mounts' structurally. Signed-off-by: Gichoel Choi --- utils/tracefs.c | 54 +++++++++++++------------------------------------ 1 file changed, 14 insertions(+), 40 deletions(-) diff --git a/utils/tracefs.c b/utils/tracefs.c index 9659496f3..9dc52dab4 100644 --- a/utils/tracefs.c +++ b/utils/tracefs.c @@ -1,67 +1,41 @@ #include +#include #include #include #include "utils/tracefs.h" #include "utils/utils.h" -#define PROC_MOUNTINFO "/proc/self/mountinfo" +#define PROC_MOUNTS_DIR_PATH "/proc/mounts" static char *TRACING_DIR = NULL; static bool find_tracing_dir(void) { FILE *fp; - char *line = NULL, fs_type[NAME_MAX], mount_point[PATH_MAX]; - static char debugfs_suffix[] = "tracing"; - bool debugfs_found = false; - size_t len; + struct mntent *ent; if (TRACING_DIR) - return false; + return true; - fp = fopen(PROC_MOUNTINFO, "r"); + fp = setmntent(PROC_MOUNTS_DIR_PATH, "r"); if (fp == NULL) return false; - while (getline(&line, &len, fp) > 0) { - /* - * /proc//mountinfo format: - * 36 35 98:0 /mnt1 /mnt2 rw,noatime master:1 - ext3 .... .... - * (1)(2)(3) (4) (5) (6) (7) (8) (9) (10) (11) - * mount_point fs_type - * - * (9) is the file system type, (5) is the mount point relative - * to self's root directory. - */ - sscanf(line, "%*i %*i %*u:%*u %*s %s %*s %*s - %s %*s %*s\n", mount_point, fs_type); - - if (!strcmp(fs_type, "tracefs")) { - /* discard previously kept debugfs tracing dir */ - if (TRACING_DIR) - free(TRACING_DIR); - xasprintf(&TRACING_DIR, "%s", mount_point); - pr_dbg2("Found tracefs at %s\n", mount_point); - pr_dbg2("Use %s as TRACING_DIR\n", TRACING_DIR); - return true; - } - - if (!strcmp(fs_type, "debugfs")) { - xasprintf(&TRACING_DIR, "%s/%s", mount_point, debugfs_suffix); - pr_dbg2("Found debugfs at %s\n", mount_point); - pr_dbg2("Keep searching for tracefs...\n"); - debugfs_found = true; + while ((ent = getmntent(fp)) != NULL) { + if (!strcmp(ent->mnt_fsname, "tracefs")) { + xasprintf(&TRACING_DIR, "%s", ent->mnt_dir); + break; } } + endmntent(fp); - /* we couldn't find a tracefs, but found a debugfs... */ - if (debugfs_found) { - pr_dbg2("Use %s as TRACING_DIR\n", TRACING_DIR); - return true; + if (!TRACING_DIR) { + pr_dbg2("No tracefs or debugfs found..!\n"); + return false; } - pr_dbg2("No tracefs or debugfs found..!\n"); - return false; + return true; } char *get_tracing_file(const char *name) From a6892900156033f7c60601ba76a4b68c36af0308 Mon Sep 17 00:00:00 2001 From: Gichoel Choi Date: Mon, 7 Aug 2023 23:13:33 +0900 Subject: [PATCH 2/2] utils: Add logic to check for hardcoded tracefs paths first The logic we added previously was to use '/proc/mounts' to find the tracefs path. However, the logic can be simplified even further by using the canonical ftrace path, as per commit from torvalds/linux@2455f0e. Link: https://git.kernel.org/torvalds/c/2455f0e124d3 Signed-off-by: Gichoel Choi --- utils/tracefs.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/utils/tracefs.c b/utils/tracefs.c index 9dc52dab4..2b96889e7 100644 --- a/utils/tracefs.c +++ b/utils/tracefs.c @@ -1,12 +1,16 @@ #include +#include #include #include #include +#include #include "utils/tracefs.h" #include "utils/utils.h" #define PROC_MOUNTS_DIR_PATH "/proc/mounts" +#define TRACEFS_DIR_PATH "/sys/kernel/tracing" +#define OLD_TRACEFS_DIR_PATH "/sys/kernel/debug/tracing" static char *TRACING_DIR = NULL; @@ -14,10 +18,20 @@ static bool find_tracing_dir(void) { FILE *fp; struct mntent *ent; + struct statfs fs; if (TRACING_DIR) return true; + if (!statfs(TRACEFS_DIR_PATH, &fs) && fs.f_type == TRACEFS_MAGIC) { + xasprintf(&TRACING_DIR, "%s", TRACEFS_DIR_PATH); + return true; + } + else if (!statfs(OLD_TRACEFS_DIR_PATH, &fs) && fs.f_type == TRACEFS_MAGIC) { + xasprintf(&TRACING_DIR, "%s", OLD_TRACEFS_DIR_PATH); + return true; + } + fp = setmntent(PROC_MOUNTS_DIR_PATH, "r"); if (fp == NULL) return false;