1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3 * Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
4 *
5 */
6 #ifndef __TRACE_LOCAL_H
7 #define __TRACE_LOCAL_H
8
9 #include <sys/types.h>
10 #include <dirent.h> /* for DIR */
11 #include <ctype.h> /* for isdigit() */
12 #include <errno.h>
13 #include <limits.h>
14 #include <netinet/tcp.h>
15 #include <netinet/in.h>
16
17 #include "trace-cmd-private.h"
18 #include "event-utils.h"
19
20 #define TRACE_AGENT_DEFAULT_PORT 823
21
22 #define DEFAULT_INPUT_FILE "trace.dat"
23 #define GUEST_PIPE_NAME "trace-pipe-cpu"
24 #define GUEST_DIR_FMT "/var/lib/trace-cmd/virt/%s"
25 #define GUEST_FIFO_FMT GUEST_DIR_FMT "/" GUEST_PIPE_NAME "%d"
26 #define VIRTIO_FIFO_FMT "/dev/virtio-ports/" GUEST_PIPE_NAME "%d"
27
28 /* fix stupid glib guint64 typecasts and printf formats */
29 typedef unsigned long long u64;
30
31 struct buffer_instance;
32
33 #define __printf(a, b) __attribute__((format(printf,a,b)))
34
35 __printf(1,2)
36 void warning(const char *fmt, ...);
37
38 /* for local shared information with trace-cmd executable */
39
40 void usage(char **argv);
41
42 extern int silence_warnings;
43 extern int show_status;
44
45 void trace_set_loglevel(int level);
46 int trace_set_verbose(char *level);
47
48 enum port_type {
49 USE_UDP = 0, /* Default setting */
50 USE_TCP,
51 USE_VSOCK
52 };
53
54 struct pid_record_data {
55 int pid;
56 int brass[2];
57 int cpu;
58 int closed;
59 struct tracecmd_input *stream;
60 struct buffer_instance *instance;
61 struct tep_record *record;
62 };
63
64 void show_file(const char *name);
65
66 struct tracecmd_input *read_trace_header(const char *file, int flags);
67 int read_trace_files(void);
68
69 void trace_record(int argc, char **argv);
70
71 void trace_stop(int argc, char **argv);
72
73 void trace_restart(int argc, char **argv);
74
75 void trace_reset(int argc, char **argv);
76
77 void trace_start(int argc, char **argv);
78
79 void trace_set(int argc, char **argv);
80
81 void trace_extract(int argc, char **argv);
82
83 void trace_stream(int argc, char **argv);
84
85 void trace_profile(int argc, char **argv);
86
87 void trace_report(int argc, char **argv);
88
89 void trace_split(int argc, char **argv);
90
91 void trace_listen(int argc, char **argv);
92
93 void trace_agent(int argc, char **argv);
94
95 void trace_setup_guest(int argc, char **argv);
96
97 void trace_restore(int argc, char **argv);
98
99 void trace_clear(int argc, char **argv);
100
101 void trace_check_events(int argc, char **argv);
102
103 void trace_stack(int argc, char **argv);
104
105 void trace_option(int argc, char **argv);
106
107 void trace_hist(int argc, char **argv);
108
109 void trace_snapshot(int argc, char **argv);
110
111 void trace_mem(int argc, char **argv);
112
113 void trace_stat(int argc, char **argv);
114
115 void trace_show(int argc, char **argv);
116
117 void trace_list(int argc, char **argv);
118
119 void trace_usage(int argc, char **argv);
120
121 void trace_dump(int argc, char **argv);
122
123 void trace_attach(int argc, char **argv);
124
125 void trace_convert(int argc, char **argv);
126
127 void trace_sqlhist (int argc, char **argv);
128
129 int trace_record_agent(struct tracecmd_msg_handle *msg_handle,
130 int cpus, int *fds,
131 int argc, char **argv,
132 bool use_fifos, struct tracecmd_time_sync *tsync,
133 unsigned long long trace_id, int rcid, const char *host);
134
135 struct hook_list;
136
137 void trace_init_profile(struct tracecmd_input *handle, struct hook_list *hooks,
138 int global);
139 int do_trace_profile(void);
140 void trace_profile_set_merge_like_comms(void);
141
142 struct tracecmd_input *
143 trace_stream_init(struct buffer_instance *instance, int cpu, int fd, int cpus,
144 struct hook_list *hooks,
145 tracecmd_handle_init_func handle_init, int global);
146 int trace_stream_read(struct pid_record_data *pids, int nr_pids, long sleep_us);
147
148 void trace_show_data(struct tracecmd_input *handle, struct tep_record *record);
149
150 /* --- event interation --- */
151
152 /*
153 * Use this to iterate through the event directories
154 */
155
156
157 enum event_process {
158 PROCESSED_NONE,
159 PROCESSED_EVENT,
160 PROCESSED_SYSTEM
161 };
162
163 enum process_type {
164 PROCESS_EVENT,
165 PROCESS_SYSTEM
166 };
167
168 struct event_iter {
169 DIR *system_dir;
170 DIR *event_dir;
171 struct dirent *system_dent;
172 struct dirent *event_dent;
173 };
174
175 enum event_iter_type {
176 EVENT_ITER_NONE,
177 EVENT_ITER_SYSTEM,
178 EVENT_ITER_EVENT
179 };
180
181 struct event_iter *trace_event_iter_alloc(const char *path);
182 enum event_iter_type trace_event_iter_next(struct event_iter *iter,
183 const char *path, const char *system);
184 void trace_event_iter_free(struct event_iter *iter);
185
186 char *append_file(const char *dir, const char *name);
187 char *get_file_content(const char *file);
188
189 char *strstrip(char *str);
190
191 /* --- instance manipulation --- */
192
193 enum buffer_instance_flags {
194 BUFFER_FL_KEEP = 1 << 0,
195 BUFFER_FL_PROFILE = 1 << 1,
196 BUFFER_FL_GUEST = 1 << 2,
197 BUFFER_FL_AGENT = 1 << 3,
198 BUFFER_FL_HAS_CLOCK = 1 << 4,
199 BUFFER_FL_TSC2NSEC = 1 << 5,
200 BUFFER_FL_NETWORK = 1 << 6,
201 BUFFER_FL_PROXY = 1 << 7,
202 };
203
204 struct func_list {
205 struct func_list *next;
206 const char *func;
207 const char *mod;
208 };
209
210 struct pid_addr_maps {
211 struct pid_addr_maps *next;
212 struct tracecmd_proc_addr_map *lib_maps;
213 unsigned int nr_lib_maps;
214 char *proc_name;
215 int pid;
216 };
217
218 struct opt_list {
219 struct opt_list *next;
220 const char *option;
221 };
222
223 struct filter_pids {
224 struct filter_pids *next;
225 int pid;
226 int exclude;
227 };
228
229 struct tsc_nsec {
230 int mult;
231 int shift;
232 unsigned long long offset;
233 };
234
235 struct buffer_instance {
236 struct buffer_instance *next;
237 char *name;
238 struct tracefs_instance *tracefs;
239 unsigned long long trace_id;
240 char *cpumask;
241 char *output_file;
242 const char *temp_dir;
243 char *temp_file;
244 struct event_list *events;
245 struct event_list **event_next;
246 bool delete;
247
248 struct event_list *sched_switch_event;
249 struct event_list *sched_wakeup_event;
250 struct event_list *sched_wakeup_new_event;
251
252 const char *plugin;
253 char *filter_mod;
254 struct func_list *filter_funcs;
255 struct func_list *notrace_funcs;
256
257 struct opt_list *options;
258 struct filter_pids *filter_pids;
259 struct filter_pids *process_pids;
260 char *common_pid_filter;
261 int nr_filter_pids;
262 int len_filter_pids;
263 int nr_process_pids;
264 bool ptrace_child;
265
266 int have_set_event_pid;
267 int have_event_fork;
268 int have_func_fork;
269 int get_procmap;
270
271 const char *clock;
272 unsigned int *client_ports;
273
274 struct trace_seq *s_save;
275 struct trace_seq *s_print;
276
277 struct tracecmd_input *handle;
278
279 struct tracecmd_msg_handle *msg_handle;
280 struct tracecmd_output *network_handle;
281 const char *host;
282
283 struct pid_addr_maps *pid_maps;
284
285 char *max_graph_depth;
286
287 int flags;
288 int tracing_on_init_val;
289 int tracing_on_fd;
290 int buffer_size;
291 int old_buffer_size;
292 int subbuf_size;
293 int old_subbuf_size;
294 int cpu_count;
295
296 int proxy_fd;
297
298 int argc;
299 char **argv;
300
301 struct addrinfo *result;
302 unsigned int cid;
303 unsigned int port;
304 int *fds;
305 bool use_fifos;
306
307 enum port_type port_type; /* Default to USE_UDP (zero) */
308 int tsync_loop_interval;
309 struct tracecmd_time_sync *tsync;
310 };
311
312 void init_top_instance(void);
313
314 extern struct buffer_instance top_instance;
315 extern struct buffer_instance *buffer_instances;
316 extern struct buffer_instance *first_instance;
317
318 #define for_each_instance(i) for (i = buffer_instances; i; i = (i)->next)
319 #define for_all_instances(i) for (i = first_instance; i; \
320 i = i == &top_instance ? buffer_instances : (i)->next)
321
322 #define is_agent(instance) ((instance)->flags & BUFFER_FL_AGENT)
323 #define is_guest(instance) ((instance)->flags & BUFFER_FL_GUEST)
324 #define is_proxy(instance) ((instance)->flags & BUFFER_FL_PROXY)
325 #define is_network(instance) ((instance)->flags & BUFFER_FL_NETWORK)
326 #define is_proxy_server(instance) \
327 ((instance)->msg_handle && \
328 (instance)->msg_handle->flags & TRACECMD_MSG_FL_PROXY)
329
330 #define START_PORT_SEARCH 1500
331 #define MAX_PORT_SEARCH 6000
332
333 struct sockaddr_storage;
334
335 int trace_net_make(int port, enum port_type type);
336 int trace_net_search(int start_port, int *sfd, enum port_type type);
337 int trace_net_print_connection(int fd);
338 bool trace_net_cmp_connection(struct sockaddr_storage *addr, const char *name);
339 bool trace_net_cmp_connection_fd(int fd, const char *name);
340
341 struct buffer_instance *allocate_instance(const char *name);
342 void add_instance(struct buffer_instance *instance, int cpu_count);
343 void update_first_instance(struct buffer_instance *instance, int topt);
344
345 void show_instance_file(struct buffer_instance *instance, const char *name);
346 void show_options(const char *prefix, struct buffer_instance *buffer);
347
348 struct trace_guest {
349 struct tracefs_instance *instance;
350 char *name;
351 unsigned long long trace_id;
352 int cid;
353 int pid;
354 int cpu_max;
355 int *cpu_pid;
356 int *task_pids;
357 };
358 struct trace_guest *trace_get_guest(unsigned int cid, const char *name);
359 bool trace_have_guests_pid(void);
360 void read_qemu_guests(void);
361 int get_guest_pid(unsigned int guest_cid);
362 int get_guest_vcpu_pid(unsigned int guest_cid, unsigned int guest_vcpu);
363 void trace_add_guest_info(struct tracecmd_output *handle, struct buffer_instance *instance);
364
365 struct tracecmd_time_sync *
366 trace_tsync_as_host(int fd, unsigned long long trace_id,
367 int loop_interval, int guest_id,
368 int guest_cpus, const char *proto_name,
369 const char *clock);
370
371 struct tracecmd_time_sync *
372 trace_tsync_as_guest(int fd, const char *tsync_proto, const char *clock,
373 unsigned int remote_id, unsigned int local_id);
374
375 char *strparse(char *str, char delim, char **save);
376
377 /* moved from trace-cmd.h */
378 void tracecmd_remove_instances(void);
379 int tracecmd_add_event(const char *event_str, int stack);
380 void tracecmd_enable_events(void);
381 void tracecmd_disable_all_tracing(int disable_tracer);
382 void tracecmd_disable_tracing(void);
383 void tracecmd_enable_tracing(void);
384 void tracecmd_stat_cpu(struct trace_seq *s, int cpu);
385
386 int tracecmd_host_tsync(struct buffer_instance *instance,
387 unsigned int tsync_port);
388 void tracecmd_host_tsync_complete(struct buffer_instance *instance);
389 const char *tracecmd_guest_tsync(struct tracecmd_tsync_protos *tsync_protos,
390 char *clock, unsigned int *tsync_port,
391 pthread_t *thr_id);
392
393 int trace_make_vsock(unsigned int port);
394 int trace_get_vsock_port(int sd, unsigned int *port);
395 int trace_open_vsock(unsigned int cid, unsigned int port);
396
397 int get_local_cid(unsigned int *cid);
398
399 char *trace_get_guest_file(const char *file, const char *guest);
400
401 #ifdef VSOCK
402 int trace_vsock_open(unsigned int cid, unsigned int port);
403 int trace_vsock_make(unsigned int port);
404 int trace_vsock_make_any(void);
405 int get_vsocket_params(int fd, unsigned int *lcid, unsigned int *rcid);
406 int trace_vsock_get_port(int sd, unsigned int *port);
407 bool trace_vsock_can_splice_read(void);
408 int trace_vsock_local_cid(void);
409 int trace_vsock_print_connection(int fd);
410 #else
trace_vsock_open(unsigned int cid,unsigned int port)411 static inline int trace_vsock_open(unsigned int cid, unsigned int port)
412 {
413 return -ENOTSUP;
414 }
415
trace_vsock_make(unsigned int port)416 static inline int trace_vsock_make(unsigned int port)
417 {
418 return -ENOTSUP;
419
420 }
421
trace_vsock_make_any(void)422 static inline int trace_vsock_make_any(void)
423 {
424 return -ENOTSUP;
425
426 }
427
get_vsocket_params(int fd,unsigned int * lcid,unsigned int * rcid)428 static inline int get_vsocket_params(int fd, unsigned int *lcid, unsigned int *rcid)
429 {
430 return -ENOTSUP;
431 }
432
trace_vsock_get_port(int sd,unsigned int * port)433 static inline int trace_vsock_get_port(int sd, unsigned int *port)
434 {
435 return -ENOTSUP;
436 }
437
trace_vsock_can_splice_read(void)438 static inline bool trace_vsock_can_splice_read(void)
439 {
440 return false;
441 }
442
trace_vsock_local_cid(void)443 static inline int trace_vsock_local_cid(void)
444 {
445 return -ENOTSUP;
446 }
trace_vsock_print_connection(int fd)447 static inline int trace_vsock_print_connection(int fd)
448 {
449 return -1;
450 }
451 #endif /* VSOCK */
452
453 /* No longer in event-utils.h */
454 __printf(1,2)
455 void __noreturn die(const char *fmt, ...); /* Can be overriden */
456 void *malloc_or_die(unsigned int size); /* Can be overridden */
457 __printf(1,2)
458 void __noreturn __die(const char *fmt, ...);
459 void __noreturn _vdie(const char *fmt, va_list ap);
460
is_digits(const char * s)461 static inline bool is_digits(const char *s)
462 {
463 for (; *s; s++)
464 if (!isdigit(*s))
465 return false;
466 return true;
467 }
468
469 bool trace_tsc2nsec_is_supported(void);
470
471 void make_pid_name(char *buf, const char *pidfile_basename);
472 void remove_pid_file(const char *pidfile_basename);
473 void make_pid_file(const char *pidfile_basename);
474
set_tcp_no_delay(int sockfd,int socktype)475 static inline void set_tcp_no_delay(int sockfd, int socktype)
476 {
477 int flag = 1;
478
479 if (socktype == SOCK_STREAM)
480 setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(flag));
481 }
482
483 #endif /* __TRACE_LOCAL_H */
484