1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0 229f5ffd3SJiri Olsa 397978b3eSJiri Olsa #include <stdio.h> 497978b3eSJiri Olsa #include <unistd.h> 597978b3eSJiri Olsa #include <stdlib.h> 697978b3eSJiri Olsa #include <errno.h> 797978b3eSJiri Olsa #include <sys/types.h> 897978b3eSJiri Olsa #include <sys/stat.h> 997978b3eSJiri Olsa #include <fcntl.h> 1097978b3eSJiri Olsa #include <linux/kernel.h> 118dd2a131SJiri Olsa #include <linux/err.h> 1229f5ffd3SJiri Olsa #include <traceevent/event-parse.h> 13592d5a6bSJiri Olsa #include <api/fs/tracing_path.h> 14607bfbd7SJiri Olsa #include <api/fs/fs.h> 1529f5ffd3SJiri Olsa #include "trace-event.h" 16c3168b0dSArnaldo Carvalho de Melo #include "machine.h" 1797978b3eSJiri Olsa #include "util.h" 1897978b3eSJiri Olsa 1997978b3eSJiri Olsa /* 2097978b3eSJiri Olsa * global trace_event object used by trace_event__tp_format 2197978b3eSJiri Olsa * 2297978b3eSJiri Olsa * TODO There's no cleanup call for this. Add some sort of 2397978b3eSJiri Olsa * __exit function support and call trace_event__cleanup 2497978b3eSJiri Olsa * there. 2597978b3eSJiri Olsa */ 2697978b3eSJiri Olsa static struct trace_event tevent; 27c3168b0dSArnaldo Carvalho de Melo static bool tevent_initialized; 2829f5ffd3SJiri Olsa 2929f5ffd3SJiri Olsa int trace_event__init(struct trace_event *t) 3029f5ffd3SJiri Olsa { 314d5c58b1STzvetomir Stoyanov (VMware) struct tep_handle *pevent = tep_alloc(); 3229f5ffd3SJiri Olsa 3329f5ffd3SJiri Olsa if (pevent) { 34*fc9b6971STzvetomir Stoyanov (VMware) t->plugin_list = tep_load_plugins(pevent); 3529f5ffd3SJiri Olsa t->pevent = pevent; 3629f5ffd3SJiri Olsa } 3729f5ffd3SJiri Olsa 3829f5ffd3SJiri Olsa return pevent ? 0 : -1; 3929f5ffd3SJiri Olsa } 4029f5ffd3SJiri Olsa 41c3168b0dSArnaldo Carvalho de Melo static int trace_event__init2(void) 42c3168b0dSArnaldo Carvalho de Melo { 43*fc9b6971STzvetomir Stoyanov (VMware) int be = tep_host_bigendian(); 44096177a8STzvetomir Stoyanov (VMware) struct tep_handle *pevent; 45c3168b0dSArnaldo Carvalho de Melo 46c3168b0dSArnaldo Carvalho de Melo if (trace_event__init(&tevent)) 47c3168b0dSArnaldo Carvalho de Melo return -1; 48c3168b0dSArnaldo Carvalho de Melo 49c3168b0dSArnaldo Carvalho de Melo pevent = tevent.pevent; 50ece2a4f4STzvetomir Stoyanov (VMware) tep_set_flag(pevent, PEVENT_NSEC_OUTPUT); 51ece2a4f4STzvetomir Stoyanov (VMware) tep_set_file_bigendian(pevent, be); 52ece2a4f4STzvetomir Stoyanov (VMware) tep_set_host_bigendian(pevent, be); 53c3168b0dSArnaldo Carvalho de Melo tevent_initialized = true; 54c3168b0dSArnaldo Carvalho de Melo return 0; 55c3168b0dSArnaldo Carvalho de Melo } 56c3168b0dSArnaldo Carvalho de Melo 57959c2199SArnaldo Carvalho de Melo int trace_event__register_resolver(struct machine *machine, 584d5c58b1STzvetomir Stoyanov (VMware) tep_func_resolver_t *func) 59c3168b0dSArnaldo Carvalho de Melo { 60c3168b0dSArnaldo Carvalho de Melo if (!tevent_initialized && trace_event__init2()) 61c3168b0dSArnaldo Carvalho de Melo return -1; 62c3168b0dSArnaldo Carvalho de Melo 63ece2a4f4STzvetomir Stoyanov (VMware) return tep_set_function_resolver(tevent.pevent, func, machine); 64c3168b0dSArnaldo Carvalho de Melo } 65c3168b0dSArnaldo Carvalho de Melo 6629f5ffd3SJiri Olsa void trace_event__cleanup(struct trace_event *t) 6729f5ffd3SJiri Olsa { 68*fc9b6971STzvetomir Stoyanov (VMware) tep_unload_plugins(t->plugin_list, t->pevent); 694d5c58b1STzvetomir Stoyanov (VMware) tep_free(t->pevent); 7029f5ffd3SJiri Olsa } 7197978b3eSJiri Olsa 728dd2a131SJiri Olsa /* 738dd2a131SJiri Olsa * Returns pointer with encoded error via <linux/err.h> interface. 748dd2a131SJiri Olsa */ 7597978b3eSJiri Olsa static struct event_format* 7697978b3eSJiri Olsa tp_format(const char *sys, const char *name) 7797978b3eSJiri Olsa { 7825a7d914SArnaldo Carvalho de Melo char *tp_dir = get_events_file(sys); 79096177a8STzvetomir Stoyanov (VMware) struct tep_handle *pevent = tevent.pevent; 8097978b3eSJiri Olsa struct event_format *event = NULL; 8197978b3eSJiri Olsa char path[PATH_MAX]; 8297978b3eSJiri Olsa size_t size; 8397978b3eSJiri Olsa char *data; 848dd2a131SJiri Olsa int err; 8597978b3eSJiri Olsa 8625a7d914SArnaldo Carvalho de Melo if (!tp_dir) 8725a7d914SArnaldo Carvalho de Melo return ERR_PTR(-errno); 8825a7d914SArnaldo Carvalho de Melo 8925a7d914SArnaldo Carvalho de Melo scnprintf(path, PATH_MAX, "%s/%s/format", tp_dir, name); 9025a7d914SArnaldo Carvalho de Melo put_events_file(tp_dir); 9197978b3eSJiri Olsa 928dd2a131SJiri Olsa err = filename__read_str(path, &data, &size); 938dd2a131SJiri Olsa if (err) 948dd2a131SJiri Olsa return ERR_PTR(err); 9597978b3eSJiri Olsa 96c60167c1STzvetomir Stoyanov (VMware) tep_parse_format(pevent, &event, data, size, sys); 9797978b3eSJiri Olsa 9897978b3eSJiri Olsa free(data); 9997978b3eSJiri Olsa return event; 10097978b3eSJiri Olsa } 10197978b3eSJiri Olsa 1028dd2a131SJiri Olsa /* 1038dd2a131SJiri Olsa * Returns pointer with encoded error via <linux/err.h> interface. 1048dd2a131SJiri Olsa */ 10597978b3eSJiri Olsa struct event_format* 10697978b3eSJiri Olsa trace_event__tp_format(const char *sys, const char *name) 10797978b3eSJiri Olsa { 108c3168b0dSArnaldo Carvalho de Melo if (!tevent_initialized && trace_event__init2()) 1098dd2a131SJiri Olsa return ERR_PTR(-ENOMEM); 11097978b3eSJiri Olsa 11197978b3eSJiri Olsa return tp_format(sys, name); 11297978b3eSJiri Olsa } 11371fe1052SJiri Olsa 11471fe1052SJiri Olsa struct event_format *trace_event__tp_format_id(int id) 11571fe1052SJiri Olsa { 11671fe1052SJiri Olsa if (!tevent_initialized && trace_event__init2()) 11771fe1052SJiri Olsa return ERR_PTR(-ENOMEM); 11871fe1052SJiri Olsa 119af85cd19STzvetomir Stoyanov (VMware) return tep_find_event(tevent.pevent, id); 12071fe1052SJiri Olsa } 121