Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1#define _GNU_SOURCE
2#include <errno.h>
3#include <stdio.h>
4#include <stdlib.h>
5#include <string.h>
6#include <unistd.h>
7#include <stdbool.h>
8#include <sys/vfs.h>
9#include <sys/types.h>
10#include <sys/stat.h>
11#include <sys/mount.h>
12#include <linux/kernel.h>
13
14#include "debugfs.h"
15#include "tracefs.h"
16
17#ifndef DEBUGFS_DEFAULT_PATH
18#define DEBUGFS_DEFAULT_PATH "/sys/kernel/debug"
19#endif
20
21char debugfs_mountpoint[PATH_MAX + 1] = DEBUGFS_DEFAULT_PATH;
22
23static const char * const debugfs_known_mountpoints[] = {
24 DEBUGFS_DEFAULT_PATH,
25 "/debug",
26 0,
27};
28
29static bool debugfs_found;
30
31bool debugfs_configured(void)
32{
33 return debugfs_find_mountpoint() != NULL;
34}
35
36/* find the path to the mounted debugfs */
37const char *debugfs_find_mountpoint(void)
38{
39 const char *ret;
40
41 if (debugfs_found)
42 return (const char *)debugfs_mountpoint;
43
44 ret = find_mountpoint("debugfs", (long) DEBUGFS_MAGIC,
45 debugfs_mountpoint, PATH_MAX + 1,
46 debugfs_known_mountpoints);
47 if (ret)
48 debugfs_found = true;
49
50 return ret;
51}
52
53/* mount the debugfs somewhere if it's not mounted */
54char *debugfs_mount(const char *mountpoint)
55{
56 /* see if it's already mounted */
57 if (debugfs_find_mountpoint())
58 goto out;
59
60 /* if not mounted and no argument */
61 if (mountpoint == NULL) {
62 /* see if environment variable set */
63 mountpoint = getenv(PERF_DEBUGFS_ENVIRONMENT);
64 /* if no environment variable, use default */
65 if (mountpoint == NULL)
66 mountpoint = DEBUGFS_DEFAULT_PATH;
67 }
68
69 if (mount(NULL, mountpoint, "debugfs", 0, NULL) < 0)
70 return NULL;
71
72 /* save the mountpoint */
73 debugfs_found = true;
74 strncpy(debugfs_mountpoint, mountpoint, sizeof(debugfs_mountpoint));
75out:
76 return debugfs_mountpoint;
77}
78
79int debugfs__strerror_open(int err, char *buf, size_t size, const char *filename)
80{
81 char sbuf[128];
82
83 switch (err) {
84 case ENOENT:
85 if (debugfs_found) {
86 snprintf(buf, size,
87 "Error:\tFile %s/%s not found.\n"
88 "Hint:\tPerhaps this kernel misses some CONFIG_ setting to enable this feature?.\n",
89 debugfs_mountpoint, filename);
90 break;
91 }
92 snprintf(buf, size, "%s",
93 "Error:\tUnable to find debugfs\n"
94 "Hint:\tWas your kernel compiled with debugfs support?\n"
95 "Hint:\tIs the debugfs filesystem mounted?\n"
96 "Hint:\tTry 'sudo mount -t debugfs nodev /sys/kernel/debug'");
97 break;
98 case EACCES: {
99 const char *mountpoint = debugfs_mountpoint;
100
101 if (!access(debugfs_mountpoint, R_OK) && strncmp(filename, "tracing/", 8) == 0) {
102 const char *tracefs_mntpoint = tracefs_find_mountpoint();
103
104 if (tracefs_mntpoint)
105 mountpoint = tracefs_mntpoint;
106 }
107
108 snprintf(buf, size,
109 "Error:\tNo permissions to read %s/%s\n"
110 "Hint:\tTry 'sudo mount -o remount,mode=755 %s'\n",
111 debugfs_mountpoint, filename, mountpoint);
112 }
113 break;
114 default:
115 snprintf(buf, size, "%s", strerror_r(err, sbuf, sizeof(sbuf)));
116 break;
117 }
118
119 return 0;
120}
121
122int debugfs__strerror_open_tp(int err, char *buf, size_t size, const char *sys, const char *name)
123{
124 char path[PATH_MAX];
125
126 snprintf(path, PATH_MAX, "tracing/events/%s/%s", sys, name ?: "*");
127
128 return debugfs__strerror_open(err, buf, size, path);
129}