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