2 * probe-file.c : operate ftrace k/uprobe events files
4 * Written by Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
25 #include <api/fs/tracing_path.h>
26 #include "probe-event.h"
27 #include "probe-file.h"
30 #define MAX_CMDLEN 256
32 static void print_open_warning(int err
, bool uprobe
)
34 char sbuf
[STRERR_BUFSIZE
];
40 config
= "CONFIG_UPROBE_EVENTS";
42 config
= "CONFIG_KPROBE_EVENTS";
44 pr_warning("%cprobe_events file does not exist"
45 " - please rebuild kernel with %s.\n",
46 uprobe
? 'u' : 'k', config
);
47 } else if (err
== -ENOTSUP
)
48 pr_warning("Tracefs or debugfs is not mounted.\n");
50 pr_warning("Failed to open %cprobe_events: %s\n",
52 strerror_r(-err
, sbuf
, sizeof(sbuf
)));
55 static void print_both_open_warning(int kerr
, int uerr
)
57 /* Both kprobes and uprobes are disabled, warn it. */
58 if (kerr
== -ENOTSUP
&& uerr
== -ENOTSUP
)
59 pr_warning("Tracefs or debugfs is not mounted.\n");
60 else if (kerr
== -ENOENT
&& uerr
== -ENOENT
)
61 pr_warning("Please rebuild kernel with CONFIG_KPROBE_EVENTS "
62 "or/and CONFIG_UPROBE_EVENTS.\n");
64 char sbuf
[STRERR_BUFSIZE
];
65 pr_warning("Failed to open kprobe events: %s.\n",
66 strerror_r(-kerr
, sbuf
, sizeof(sbuf
)));
67 pr_warning("Failed to open uprobe events: %s.\n",
68 strerror_r(-uerr
, sbuf
, sizeof(sbuf
)));
72 static int open_probe_events(const char *trace_file
, bool readwrite
)
75 const char *tracing_dir
= "";
78 ret
= e_snprintf(buf
, PATH_MAX
, "%s/%s%s",
79 tracing_path
, tracing_dir
, trace_file
);
81 pr_debug("Opening %s write=%d\n", buf
, readwrite
);
82 if (readwrite
&& !probe_event_dry_run
)
83 ret
= open(buf
, O_RDWR
| O_APPEND
, 0);
85 ret
= open(buf
, O_RDONLY
, 0);
93 static int open_kprobe_events(bool readwrite
)
95 return open_probe_events("kprobe_events", readwrite
);
98 static int open_uprobe_events(bool readwrite
)
100 return open_probe_events("uprobe_events", readwrite
);
103 int probe_file__open(int flag
)
107 if (flag
& PF_FL_UPROBE
)
108 fd
= open_uprobe_events(flag
& PF_FL_RW
);
110 fd
= open_kprobe_events(flag
& PF_FL_RW
);
112 print_open_warning(fd
, flag
& PF_FL_UPROBE
);
117 int probe_file__open_both(int *kfd
, int *ufd
, int flag
)
122 *kfd
= open_kprobe_events(flag
& PF_FL_RW
);
123 *ufd
= open_uprobe_events(flag
& PF_FL_RW
);
124 if (*kfd
< 0 && *ufd
< 0) {
125 print_both_open_warning(*kfd
, *ufd
);
132 /* Get raw string list of current kprobe_events or uprobe_events */
133 struct strlist
*probe_file__get_rawlist(int fd
)
137 char buf
[MAX_CMDLEN
];
144 sl
= strlist__new(NULL
, NULL
);
146 fp
= fdopen(dup(fd
), "r");
148 p
= fgets(buf
, MAX_CMDLEN
, fp
);
155 ret
= strlist__add(sl
, buf
);
157 pr_debug("strlist__add failed (%d)\n", ret
);
167 static struct strlist
*__probe_file__get_namelist(int fd
, bool include_group
)
170 struct strlist
*sl
, *rawlist
;
171 struct str_node
*ent
;
172 struct probe_trace_event tev
;
175 memset(&tev
, 0, sizeof(tev
));
176 rawlist
= probe_file__get_rawlist(fd
);
179 sl
= strlist__new(NULL
, NULL
);
180 strlist__for_each(ent
, rawlist
) {
181 ret
= parse_probe_trace_command(ent
->s
, &tev
);
185 ret
= e_snprintf(buf
, 128, "%s:%s", tev
.group
,
188 ret
= strlist__add(sl
, buf
);
190 ret
= strlist__add(sl
, tev
.event
);
191 clear_probe_trace_event(&tev
);
195 strlist__delete(rawlist
);
204 /* Get current perf-probe event names */
205 struct strlist
*probe_file__get_namelist(int fd
)
207 return __probe_file__get_namelist(fd
, false);
210 int probe_file__add_event(int fd
, struct probe_trace_event
*tev
)
213 char *buf
= synthesize_probe_trace_command(tev
);
214 char sbuf
[STRERR_BUFSIZE
];
217 pr_debug("Failed to synthesize probe trace event.\n");
221 pr_debug("Writing event: %s\n", buf
);
222 if (!probe_event_dry_run
) {
223 ret
= write(fd
, buf
, strlen(buf
));
226 pr_warning("Failed to write event: %s\n",
227 strerror_r(errno
, sbuf
, sizeof(sbuf
)));
235 static int __del_trace_probe_event(int fd
, struct str_node
*ent
)
241 /* Convert from perf-probe event to trace-probe event */
242 ret
= e_snprintf(buf
, 128, "-:%s", ent
->s
);
246 p
= strchr(buf
+ 2, ':');
248 pr_debug("Internal error: %s should have ':' but not.\n",
255 pr_debug("Writing event: %s\n", buf
);
256 ret
= write(fd
, buf
, strlen(buf
));
264 pr_warning("Failed to delete event: %s\n",
265 strerror_r(-ret
, buf
, sizeof(buf
)));
269 int probe_file__get_events(int fd
, struct strfilter
*filter
,
270 struct strlist
*plist
)
272 struct strlist
*namelist
;
273 struct str_node
*ent
;
280 namelist
= __probe_file__get_namelist(fd
, true);
284 strlist__for_each(ent
, namelist
) {
285 p
= strchr(ent
->s
, ':');
286 if ((p
&& strfilter__compare(filter
, p
+ 1)) ||
287 strfilter__compare(filter
, ent
->s
)) {
288 strlist__add(plist
, ent
->s
);
292 strlist__delete(namelist
);
297 int probe_file__del_strlist(int fd
, struct strlist
*namelist
)
300 struct str_node
*ent
;
302 strlist__for_each(ent
, namelist
) {
303 ret
= __del_trace_probe_event(fd
, ent
);
310 int probe_file__del_events(int fd
, struct strfilter
*filter
)
312 struct strlist
*namelist
;
315 namelist
= strlist__new(NULL
, NULL
);
319 ret
= probe_file__get_events(fd
, filter
, namelist
);
323 ret
= probe_file__del_strlist(fd
, namelist
);
324 strlist__delete(namelist
);