Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

utils: Fix an issue not finding tracefs on some kernels #1762

Merged
merged 2 commits into from Aug 11, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
68 changes: 28 additions & 40 deletions utils/tracefs.c
@@ -1,67 +1,55 @@
#include <fcntl.h>
#include <linux/magic.h>
#include <mntent.h>
#include <stdio.h>
#include <string.h>
#include <sys/vfs.h>

#include "utils/tracefs.h"
#include "utils/utils.h"

#define PROC_MOUNTINFO "/proc/self/mountinfo"
#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;

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;
struct statfs fs;

if (TRACING_DIR)
return false;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You removed this caching logic..

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll revert the caching logic.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm.. I'm not sure why the original code returns false.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I couldn't figure out why the original code was returning false either.

The original code works fine, but I think it's semantically correct for the caching logic to return true.

return true;

fp = fopen(PROC_MOUNTINFO, "r");
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;

while (getline(&line, &len, fp) > 0) {
/*
* /proc/<pid>/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)
Expand Down