1#include <errno.h>
2#include <stdio.h>
3#include <stdlib.h>
4#include <string.h>
5#include <unistd.h>
6#include <stdbool.h>
7#include <sys/vfs.h>
8#include <sys/types.h>
9#include <sys/stat.h>
10#include <sys/mount.h>
11#include <linux/kernel.h>
12
13#include "tracefs.h"
14
15#ifndef TRACEFS_DEFAULT_PATH
16#define TRACEFS_DEFAULT_PATH		"/sys/kernel/tracing"
17#endif
18
19char tracefs_mountpoint[PATH_MAX + 1] = TRACEFS_DEFAULT_PATH;
20
21static const char * const tracefs_known_mountpoints[] = {
22	TRACEFS_DEFAULT_PATH,
23	"/sys/kernel/debug/tracing",
24	"/tracing",
25	"/trace",
26	0,
27};
28
29static bool tracefs_found;
30
31bool tracefs_configured(void)
32{
33	return tracefs_find_mountpoint() != NULL;
34}
35
36/* find the path to the mounted tracefs */
37const char *tracefs_find_mountpoint(void)
38{
39	const char *ret;
40
41	if (tracefs_found)
42		return (const char *)tracefs_mountpoint;
43
44	ret = find_mountpoint("tracefs", (long) TRACEFS_MAGIC,
45			      tracefs_mountpoint, PATH_MAX + 1,
46			      tracefs_known_mountpoints);
47
48	if (ret)
49		tracefs_found = true;
50
51	return ret;
52}
53
54/* mount the tracefs somewhere if it's not mounted */
55char *tracefs_mount(const char *mountpoint)
56{
57	/* see if it's already mounted */
58	if (tracefs_find_mountpoint())
59		goto out;
60
61	/* if not mounted and no argument */
62	if (mountpoint == NULL) {
63		/* see if environment variable set */
64		mountpoint = getenv(PERF_TRACEFS_ENVIRONMENT);
65		/* if no environment variable, use default */
66		if (mountpoint == NULL)
67			mountpoint = TRACEFS_DEFAULT_PATH;
68	}
69
70	if (mount(NULL, mountpoint, "tracefs", 0, NULL) < 0)
71		return NULL;
72
73	/* save the mountpoint */
74	tracefs_found = true;
75	strncpy(tracefs_mountpoint, mountpoint, sizeof(tracefs_mountpoint));
76out:
77	return tracefs_mountpoint;
78}
79