xref: /openbmc/linux/tools/lib/api/fs/tracing_path.c (revision ccb5597f)
1592d5a6bSJiri Olsa #ifndef _GNU_SOURCE
2592d5a6bSJiri Olsa # define _GNU_SOURCE
3592d5a6bSJiri Olsa #endif
4592d5a6bSJiri Olsa 
5592d5a6bSJiri Olsa #include <stdio.h>
6592d5a6bSJiri Olsa #include <stdlib.h>
7592d5a6bSJiri Olsa #include <string.h>
8988bdb31SJiri Olsa #include <errno.h>
9988bdb31SJiri Olsa #include <unistd.h>
104605eab3SJiri Olsa #include "fs.h"
11592d5a6bSJiri Olsa 
12592d5a6bSJiri Olsa #include "tracing_path.h"
13592d5a6bSJiri Olsa 
14592d5a6bSJiri Olsa 
15ccb5597fSJiri Olsa char tracing_mnt[PATH_MAX]         = "/sys/kernel/debug";
16ccb5597fSJiri Olsa char tracing_path[PATH_MAX]        = "/sys/kernel/debug/tracing";
17ccb5597fSJiri Olsa char tracing_events_path[PATH_MAX] = "/sys/kernel/debug/tracing/events";
18592d5a6bSJiri Olsa 
19592d5a6bSJiri Olsa 
20592d5a6bSJiri Olsa static void __tracing_path_set(const char *tracing, const char *mountpoint)
21592d5a6bSJiri Olsa {
22dc240c5dSJiri Olsa 	snprintf(tracing_mnt, sizeof(tracing_mnt), "%s", mountpoint);
23592d5a6bSJiri Olsa 	snprintf(tracing_path, sizeof(tracing_path), "%s/%s",
24592d5a6bSJiri Olsa 		 mountpoint, tracing);
25592d5a6bSJiri Olsa 	snprintf(tracing_events_path, sizeof(tracing_events_path), "%s/%s%s",
26592d5a6bSJiri Olsa 		 mountpoint, tracing, "events");
27592d5a6bSJiri Olsa }
28592d5a6bSJiri Olsa 
29592d5a6bSJiri Olsa static const char *tracing_path_tracefs_mount(void)
30592d5a6bSJiri Olsa {
31592d5a6bSJiri Olsa 	const char *mnt;
32592d5a6bSJiri Olsa 
334605eab3SJiri Olsa 	mnt = tracefs__mount();
34592d5a6bSJiri Olsa 	if (!mnt)
35592d5a6bSJiri Olsa 		return NULL;
36592d5a6bSJiri Olsa 
37592d5a6bSJiri Olsa 	__tracing_path_set("", mnt);
38592d5a6bSJiri Olsa 
39592d5a6bSJiri Olsa 	return mnt;
40592d5a6bSJiri Olsa }
41592d5a6bSJiri Olsa 
42592d5a6bSJiri Olsa static const char *tracing_path_debugfs_mount(void)
43592d5a6bSJiri Olsa {
44592d5a6bSJiri Olsa 	const char *mnt;
45592d5a6bSJiri Olsa 
464605eab3SJiri Olsa 	mnt = debugfs__mount();
47592d5a6bSJiri Olsa 	if (!mnt)
48592d5a6bSJiri Olsa 		return NULL;
49592d5a6bSJiri Olsa 
50592d5a6bSJiri Olsa 	__tracing_path_set("tracing/", mnt);
51592d5a6bSJiri Olsa 
52592d5a6bSJiri Olsa 	return mnt;
53592d5a6bSJiri Olsa }
54592d5a6bSJiri Olsa 
55592d5a6bSJiri Olsa const char *tracing_path_mount(void)
56592d5a6bSJiri Olsa {
57592d5a6bSJiri Olsa 	const char *mnt;
58592d5a6bSJiri Olsa 
59592d5a6bSJiri Olsa 	mnt = tracing_path_tracefs_mount();
60592d5a6bSJiri Olsa 	if (mnt)
61592d5a6bSJiri Olsa 		return mnt;
62592d5a6bSJiri Olsa 
63592d5a6bSJiri Olsa 	mnt = tracing_path_debugfs_mount();
64592d5a6bSJiri Olsa 
65592d5a6bSJiri Olsa 	return mnt;
66592d5a6bSJiri Olsa }
67592d5a6bSJiri Olsa 
68592d5a6bSJiri Olsa void tracing_path_set(const char *mntpt)
69592d5a6bSJiri Olsa {
70592d5a6bSJiri Olsa 	__tracing_path_set("tracing/", mntpt);
71592d5a6bSJiri Olsa }
72592d5a6bSJiri Olsa 
73592d5a6bSJiri Olsa char *get_tracing_file(const char *name)
74592d5a6bSJiri Olsa {
75592d5a6bSJiri Olsa 	char *file;
76592d5a6bSJiri Olsa 
77592d5a6bSJiri Olsa 	if (asprintf(&file, "%s/%s", tracing_path, name) < 0)
78592d5a6bSJiri Olsa 		return NULL;
79592d5a6bSJiri Olsa 
80592d5a6bSJiri Olsa 	return file;
81592d5a6bSJiri Olsa }
82592d5a6bSJiri Olsa 
83592d5a6bSJiri Olsa void put_tracing_file(char *file)
84592d5a6bSJiri Olsa {
85592d5a6bSJiri Olsa 	free(file);
86592d5a6bSJiri Olsa }
87988bdb31SJiri Olsa 
88988bdb31SJiri Olsa static int strerror_open(int err, char *buf, size_t size, const char *filename)
89988bdb31SJiri Olsa {
90988bdb31SJiri Olsa 	char sbuf[128];
91988bdb31SJiri Olsa 
92988bdb31SJiri Olsa 	switch (err) {
93988bdb31SJiri Olsa 	case ENOENT:
944f234f06SJiri Olsa 		/*
954f234f06SJiri Olsa 		 * We will get here if we can't find the tracepoint, but one of
964f234f06SJiri Olsa 		 * debugfs or tracefs is configured, which means you probably
974f234f06SJiri Olsa 		 * want some tracepoint which wasn't compiled in your kernel.
984f234f06SJiri Olsa 		 * - jirka
994f234f06SJiri Olsa 		 */
1004605eab3SJiri Olsa 		if (debugfs__configured() || tracefs__configured()) {
101988bdb31SJiri Olsa 			snprintf(buf, size,
102988bdb31SJiri Olsa 				 "Error:\tFile %s/%s not found.\n"
103988bdb31SJiri Olsa 				 "Hint:\tPerhaps this kernel misses some CONFIG_ setting to enable this feature?.\n",
1044f234f06SJiri Olsa 				 tracing_events_path, filename);
105988bdb31SJiri Olsa 			break;
106988bdb31SJiri Olsa 		}
107988bdb31SJiri Olsa 		snprintf(buf, size, "%s",
1084f234f06SJiri Olsa 			 "Error:\tUnable to find debugfs/tracefs\n"
1094f234f06SJiri Olsa 			 "Hint:\tWas your kernel compiled with debugfs/tracefs support?\n"
1104f234f06SJiri Olsa 			 "Hint:\tIs the debugfs/tracefs filesystem mounted?\n"
111988bdb31SJiri Olsa 			 "Hint:\tTry 'sudo mount -t debugfs nodev /sys/kernel/debug'");
112988bdb31SJiri Olsa 		break;
113988bdb31SJiri Olsa 	case EACCES: {
114988bdb31SJiri Olsa 		snprintf(buf, size,
115988bdb31SJiri Olsa 			 "Error:\tNo permissions to read %s/%s\n"
116988bdb31SJiri Olsa 			 "Hint:\tTry 'sudo mount -o remount,mode=755 %s'\n",
117dc240c5dSJiri Olsa 			 tracing_events_path, filename, tracing_mnt);
118988bdb31SJiri Olsa 	}
119988bdb31SJiri Olsa 		break;
120988bdb31SJiri Olsa 	default:
121988bdb31SJiri Olsa 		snprintf(buf, size, "%s", strerror_r(err, sbuf, sizeof(sbuf)));
122988bdb31SJiri Olsa 		break;
123988bdb31SJiri Olsa 	}
124988bdb31SJiri Olsa 
125988bdb31SJiri Olsa 	return 0;
126988bdb31SJiri Olsa }
127988bdb31SJiri Olsa 
128988bdb31SJiri Olsa int tracing_path__strerror_open_tp(int err, char *buf, size_t size, const char *sys, const char *name)
129988bdb31SJiri Olsa {
130988bdb31SJiri Olsa 	char path[PATH_MAX];
131988bdb31SJiri Olsa 
1324f234f06SJiri Olsa 	snprintf(path, PATH_MAX, "%s/%s", sys, name ?: "*");
133988bdb31SJiri Olsa 
134988bdb31SJiri Olsa 	return strerror_open(err, buf, size, path);
135988bdb31SJiri Olsa }
136