• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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