Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/tools/perf/util/debugfs.c
10821 views
1
#include "util.h"
2
#include "debugfs.h"
3
#include "cache.h"
4
5
static int debugfs_premounted;
6
static char debugfs_mountpoint[MAX_PATH+1];
7
8
static const char *debugfs_known_mountpoints[] = {
9
"/sys/kernel/debug/",
10
"/debug/",
11
0,
12
};
13
14
/* use this to force a umount */
15
void debugfs_force_cleanup(void)
16
{
17
debugfs_find_mountpoint();
18
debugfs_premounted = 0;
19
debugfs_umount();
20
}
21
22
/* construct a full path to a debugfs element */
23
int debugfs_make_path(const char *element, char *buffer, int size)
24
{
25
int len;
26
27
if (strlen(debugfs_mountpoint) == 0) {
28
buffer[0] = '\0';
29
return -1;
30
}
31
32
len = strlen(debugfs_mountpoint) + strlen(element) + 1;
33
if (len >= size)
34
return len+1;
35
36
snprintf(buffer, size-1, "%s/%s", debugfs_mountpoint, element);
37
return 0;
38
}
39
40
static int debugfs_found;
41
42
/* find the path to the mounted debugfs */
43
const char *debugfs_find_mountpoint(void)
44
{
45
const char **ptr;
46
char type[100];
47
FILE *fp;
48
49
if (debugfs_found)
50
return (const char *) debugfs_mountpoint;
51
52
ptr = debugfs_known_mountpoints;
53
while (*ptr) {
54
if (debugfs_valid_mountpoint(*ptr) == 0) {
55
debugfs_found = 1;
56
strcpy(debugfs_mountpoint, *ptr);
57
return debugfs_mountpoint;
58
}
59
ptr++;
60
}
61
62
/* give up and parse /proc/mounts */
63
fp = fopen("/proc/mounts", "r");
64
if (fp == NULL)
65
die("Can't open /proc/mounts for read");
66
67
while (fscanf(fp, "%*s %"
68
STR(MAX_PATH)
69
"s %99s %*s %*d %*d\n",
70
debugfs_mountpoint, type) == 2) {
71
if (strcmp(type, "debugfs") == 0)
72
break;
73
}
74
fclose(fp);
75
76
if (strcmp(type, "debugfs") != 0)
77
return NULL;
78
79
debugfs_found = 1;
80
81
return debugfs_mountpoint;
82
}
83
84
/* verify that a mountpoint is actually a debugfs instance */
85
86
int debugfs_valid_mountpoint(const char *debugfs)
87
{
88
struct statfs st_fs;
89
90
if (statfs(debugfs, &st_fs) < 0)
91
return -ENOENT;
92
else if (st_fs.f_type != (long) DEBUGFS_MAGIC)
93
return -ENOENT;
94
95
return 0;
96
}
97
98
99
int debugfs_valid_entry(const char *path)
100
{
101
struct stat st;
102
103
if (stat(path, &st))
104
return -errno;
105
106
return 0;
107
}
108
109
/* mount the debugfs somewhere if it's not mounted */
110
111
char *debugfs_mount(const char *mountpoint)
112
{
113
/* see if it's already mounted */
114
if (debugfs_find_mountpoint()) {
115
debugfs_premounted = 1;
116
return debugfs_mountpoint;
117
}
118
119
/* if not mounted and no argument */
120
if (mountpoint == NULL) {
121
/* see if environment variable set */
122
mountpoint = getenv(PERF_DEBUGFS_ENVIRONMENT);
123
/* if no environment variable, use default */
124
if (mountpoint == NULL)
125
mountpoint = "/sys/kernel/debug";
126
}
127
128
if (mount(NULL, mountpoint, "debugfs", 0, NULL) < 0)
129
return NULL;
130
131
/* save the mountpoint */
132
strncpy(debugfs_mountpoint, mountpoint, sizeof(debugfs_mountpoint));
133
debugfs_found = 1;
134
135
return debugfs_mountpoint;
136
}
137
138
/* umount the debugfs */
139
140
int debugfs_umount(void)
141
{
142
char umountcmd[128];
143
int ret;
144
145
/* if it was already mounted, leave it */
146
if (debugfs_premounted)
147
return 0;
148
149
/* make sure it's a valid mount point */
150
ret = debugfs_valid_mountpoint(debugfs_mountpoint);
151
if (ret)
152
return ret;
153
154
snprintf(umountcmd, sizeof(umountcmd),
155
"/bin/umount %s", debugfs_mountpoint);
156
return system(umountcmd);
157
}
158
159
int debugfs_write(const char *entry, const char *value)
160
{
161
char path[MAX_PATH+1];
162
int ret, count;
163
int fd;
164
165
/* construct the path */
166
snprintf(path, sizeof(path), "%s/%s", debugfs_mountpoint, entry);
167
168
/* verify that it exists */
169
ret = debugfs_valid_entry(path);
170
if (ret)
171
return ret;
172
173
/* get how many chars we're going to write */
174
count = strlen(value);
175
176
/* open the debugfs entry */
177
fd = open(path, O_RDWR);
178
if (fd < 0)
179
return -errno;
180
181
while (count > 0) {
182
/* write it */
183
ret = write(fd, value, count);
184
if (ret <= 0) {
185
if (ret == EAGAIN)
186
continue;
187
close(fd);
188
return -errno;
189
}
190
count -= ret;
191
}
192
193
/* close it */
194
close(fd);
195
196
/* return success */
197
return 0;
198
}
199
200
/*
201
* read a debugfs entry
202
* returns the number of chars read or a negative errno
203
*/
204
int debugfs_read(const char *entry, char *buffer, size_t size)
205
{
206
char path[MAX_PATH+1];
207
int ret;
208
int fd;
209
210
/* construct the path */
211
snprintf(path, sizeof(path), "%s/%s", debugfs_mountpoint, entry);
212
213
/* verify that it exists */
214
ret = debugfs_valid_entry(path);
215
if (ret)
216
return ret;
217
218
/* open the debugfs entry */
219
fd = open(path, O_RDONLY);
220
if (fd < 0)
221
return -errno;
222
223
do {
224
/* read it */
225
ret = read(fd, buffer, size);
226
if (ret == 0) {
227
close(fd);
228
return EOF;
229
}
230
} while (ret < 0 && errno == EAGAIN);
231
232
/* close it */
233
close(fd);
234
235
/* make *sure* there's a null character at the end */
236
buffer[ret] = '\0';
237
238
/* return the number of chars read */
239
return ret;
240
}
241
242