aboutsummaryrefslogtreecommitdiff
path: root/tracecmd/include/trace-local.h
blob: 77d531d5056a183c3ea938c3d09f8117fa14bb7d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
 *
 */
#ifndef __TRACE_LOCAL_H
#define __TRACE_LOCAL_H

#include <sys/types.h>
#include <dirent.h>	/* for DIR */
#include <ctype.h>	/* for isdigit() */
#include <errno.h>
#include <limits.h>

#include "trace-cmd-private.h"
#include "event-utils.h"

#define TRACE_AGENT_DEFAULT_PORT	823

#define DEFAULT_INPUT_FILE	"trace.dat"
#define GUEST_PIPE_NAME		"trace-pipe-cpu"
#define GUEST_DIR_FMT		"/var/lib/trace-cmd/virt/%s"
#define GUEST_FIFO_FMT		GUEST_DIR_FMT "/" GUEST_PIPE_NAME "%d"
#define VIRTIO_FIFO_FMT		"/dev/virtio-ports/" GUEST_PIPE_NAME "%d"

/* fix stupid glib guint64 typecasts and printf formats */
typedef unsigned long long u64;

struct buffer_instance;

#define __printf(a, b) __attribute__((format(printf,a,b)))

__printf(1,2)
void warning(const char *fmt, ...);

/* for local shared information with trace-cmd executable */

void usage(char **argv);

extern int silence_warnings;
extern int show_status;

int trace_set_verbose(char *level);

enum port_type {
	USE_UDP			= 0,	/* Default setting */
	USE_TCP,
	USE_VSOCK
};

struct pid_record_data {
	int			pid;
	int			brass[2];
	int			cpu;
	int			closed;
	struct tracecmd_input	*stream;
	struct buffer_instance	*instance;
	struct tep_record	*record;
};

void show_file(const char *name);

struct tracecmd_input *read_trace_header(const char *file, int flags);
int read_trace_files(void);

void trace_record(int argc, char **argv);

void trace_stop(int argc, char **argv);

void trace_restart(int argc, char **argv);

void trace_reset(int argc, char **argv);

void trace_start(int argc, char **argv);

void trace_set(int argc, char **argv);

void trace_extract(int argc, char **argv);

void trace_stream(int argc, char **argv);

void trace_profile(int argc, char **argv);

void trace_report(int argc, char **argv);

void trace_split(int argc, char **argv);

void trace_listen(int argc, char **argv);

void trace_agent(int argc, char **argv);

void trace_setup_guest(int argc, char **argv);

void trace_restore(int argc, char **argv);

void trace_clear(int argc, char **argv);

void trace_check_events(int argc, char **argv);

void trace_stack(int argc, char **argv);

void trace_option(int argc, char **argv);

void trace_hist(int argc, char **argv);

void trace_snapshot(int argc, char **argv);

void trace_mem(int argc, char **argv);

void trace_stat(int argc, char **argv);

void trace_show(int argc, char **argv);

void trace_list(int argc, char **argv);

void trace_usage(int argc, char **argv);

void trace_dump(int argc, char **argv);

void trace_convert(int argc, char **argv);

int trace_record_agent(struct tracecmd_msg_handle *msg_handle,
		       int cpus, int *fds,
		       int argc, char **argv, bool use_fifos,
		       unsigned long long trace_id);

struct hook_list;

void trace_init_profile(struct tracecmd_input *handle, struct hook_list *hooks,
			int global);
int do_trace_profile(void);
void trace_profile_set_merge_like_comms(void);

struct tracecmd_input *
trace_stream_init(struct buffer_instance *instance, int cpu, int fd, int cpus,
		  struct hook_list *hooks,
		  tracecmd_handle_init_func handle_init, int global);
int trace_stream_read(struct pid_record_data *pids, int nr_pids, struct timeval *tv);

void trace_show_data(struct tracecmd_input *handle, struct tep_record *record);

/* --- event interation --- */

/*
 * Use this to iterate through the event directories
 */


enum event_process {
	PROCESSED_NONE,
	PROCESSED_EVENT,
	PROCESSED_SYSTEM
};

enum process_type {
	PROCESS_EVENT,
	PROCESS_SYSTEM
};

struct event_iter {
	DIR *system_dir;
	DIR *event_dir;
	struct dirent *system_dent;
	struct dirent *event_dent;
};

enum event_iter_type {
	EVENT_ITER_NONE,
	EVENT_ITER_SYSTEM,
	EVENT_ITER_EVENT
};

struct event_iter *trace_event_iter_alloc(const char *path);
enum event_iter_type trace_event_iter_next(struct event_iter *iter,
					   const char *path, const char *system);
void trace_event_iter_free(struct event_iter *iter);

char *append_file(const char *dir, const char *name);
char *get_file_content(const char *file);

char *strstrip(char *str);

/* --- instance manipulation --- */

enum buffer_instance_flags {
	BUFFER_FL_KEEP		= 1 << 0,
	BUFFER_FL_PROFILE	= 1 << 1,
	BUFFER_FL_GUEST		= 1 << 2,
	BUFFER_FL_AGENT		= 1 << 3,
	BUFFER_FL_HAS_CLOCK	= 1 << 4,
	BUFFER_FL_TSC2NSEC	= 1 << 5,
	BUFFER_FL_NETWORK	= 1 << 6,
};

struct func_list {
	struct func_list *next;
	const char *func;
	const char *mod;
};

struct pid_addr_maps {
	struct pid_addr_maps		*next;
	struct tracecmd_proc_addr_map	*lib_maps;
	unsigned int			nr_lib_maps;
	char				*proc_name;
	int				pid;
};

struct opt_list {
	struct opt_list *next;
	const char	*option;
};

struct filter_pids {
	struct filter_pids *next;
	int pid;
	int exclude;
};

struct tsc_nsec {
	int mult;
	int shift;
	unsigned long long offset;
};

struct buffer_instance {
	struct buffer_instance	*next;
	char			*name;
	struct tracefs_instance	*tracefs;
	unsigned long long	trace_id;
	char			*cpumask;
	char			*output_file;
	struct event_list	*events;
	struct event_list	**event_next;
	bool			delete;

	struct event_list	*sched_switch_event;
	struct event_list	*sched_wakeup_event;
	struct event_list	*sched_wakeup_new_event;

	const char		*plugin;
	char			*filter_mod;
	struct func_list	*filter_funcs;
	struct func_list	*notrace_funcs;

	struct opt_list		*options;
	struct filter_pids	*filter_pids;
	struct filter_pids	*process_pids;
	char			*common_pid_filter;
	int			nr_filter_pids;
	int			len_filter_pids;
	int			nr_process_pids;
	bool			ptrace_child;

	int			have_set_event_pid;
	int			have_event_fork;
	int			have_func_fork;
	int			get_procmap;

	const char		*clock;
	unsigned int		*client_ports;

	struct trace_seq	*s_save;
	struct trace_seq	*s_print;

	struct tracecmd_input	*handle;

	struct tracecmd_msg_handle *msg_handle;
	struct tracecmd_output *network_handle;

	struct pid_addr_maps	*pid_maps;

	char			*max_graph_depth;

	int			flags;
	int			tracing_on_init_val;
	int			tracing_on_fd;
	int			buffer_size;
	int			cpu_count;

	int			argc;
	char			**argv;

	struct addrinfo		*result;
	unsigned int		cid;
	unsigned int		port;
	int			*fds;
	bool			use_fifos;

	enum port_type		port_type;	/* Default to USE_UDP (zero) */
	int			tsync_loop_interval;
	struct tracecmd_time_sync *tsync;
};

void init_top_instance(void);

extern struct buffer_instance top_instance;
extern struct buffer_instance *buffer_instances;
extern struct buffer_instance *first_instance;

#define for_each_instance(i) for (i = buffer_instances; i; i = (i)->next)
#define for_all_instances(i) for (i = first_instance; i; \
				  i = i == &top_instance ? buffer_instances : (i)->next)

#define is_agent(instance)	((instance)->flags & BUFFER_FL_AGENT)
#define is_guest(instance)	((instance)->flags & BUFFER_FL_GUEST)
#define is_network(instance)	((instance)->flags & BUFFER_FL_NETWORK)

#define START_PORT_SEARCH 1500
#define MAX_PORT_SEARCH 6000

int trace_net_make(int port, enum port_type type);
int trace_net_search(int start_port, int *sfd, enum port_type type);

struct buffer_instance *allocate_instance(const char *name);
void add_instance(struct buffer_instance *instance, int cpu_count);
void update_first_instance(struct buffer_instance *instance, int topt);

void show_instance_file(struct buffer_instance *instance, const char *name);
void show_options(const char *prefix, struct buffer_instance *buffer);

struct trace_guest {
	struct tracefs_instance *instance;
	char *name;
	int cid;
	int pid;
	int cpu_max;
	int *cpu_pid;
	int *task_pids;
};
struct trace_guest *trace_get_guest(unsigned int cid, const char *name);
bool trace_have_guests_pid(void);
void read_qemu_guests(void);
int get_guest_pid(unsigned int guest_cid);
int get_guest_vcpu_pid(unsigned int guest_cid, unsigned int guest_vcpu);

/* moved from trace-cmd.h */
void tracecmd_remove_instances(void);
int tracecmd_add_event(const char *event_str, int stack);
void tracecmd_enable_events(void);
void tracecmd_disable_all_tracing(int disable_tracer);
void tracecmd_disable_tracing(void);
void tracecmd_enable_tracing(void);
void tracecmd_stat_cpu(struct trace_seq *s, int cpu);

int tracecmd_host_tsync(struct buffer_instance *instance,
			 unsigned int tsync_port);
void tracecmd_host_tsync_complete(struct buffer_instance *instance);
const char *tracecmd_guest_tsync(struct tracecmd_tsync_protos *tsync_protos,
				 char *clock, unsigned int *tsync_port,
				 pthread_t *thr_id);

int trace_make_vsock(unsigned int port);
int trace_get_vsock_port(int sd, unsigned int *port);
int trace_open_vsock(unsigned int cid, unsigned int port);

int get_local_cid(unsigned int *cid);

char *trace_get_guest_file(const char *file, const char *guest);

#ifdef VSOCK
int trace_vsock_open(unsigned int cid, unsigned int port);
int trace_vsock_make(unsigned int port);
int trace_vsock_make_any(void);
int get_vsocket_params(int fd, unsigned int *lcid, unsigned int *rcid);
int trace_vsock_get_port(int sd, unsigned int *port);
bool trace_vsock_can_splice_read(void);
int trace_vsock_local_cid(void);
#else
static inline int trace_vsock_open(unsigned int cid, unsigned int port)
{
	return -ENOTSUP;
}

static inline int trace_vsock_make(unsigned int port)
{
	return -ENOTSUP;

}

static inline int trace_vsock_make_any(void)
{
	return -ENOTSUP;

}

static inline int get_vsocket_params(int fd, unsigned int *lcid, unsigned int *rcid)
{
	return -ENOTSUP;
}

static inline int trace_vsock_get_port(int sd, unsigned int *port)
{
	return -ENOTSUP;
}

static inline bool trace_vsock_can_splice_read(void)
{
	return false;
}

static inline int trace_vsock_local_cid(void)
{
	return -ENOTSUP;
}
#endif /* VSOCK */

/* No longer in event-utils.h */
__printf(1,2)
void __noreturn die(const char *fmt, ...); /* Can be overriden */
void *malloc_or_die(unsigned int size); /* Can be overridden */
__printf(1,2)
void __noreturn __die(const char *fmt, ...);
void __noreturn _vdie(const char *fmt, va_list ap);

static inline bool is_digits(const char *s)
{
	for (; *s; s++)
		if (!isdigit(*s))
			return false;
	return true;
}

bool trace_tsc2nsec_is_supported(void);

#endif /* __TRACE_LOCAL_H */