xref: /aosp_15_r20/external/trace-cmd/tracecmd/trace-record.c (revision 58e6ee5f017f6a8912852c892d18457e4bafb554)
1*58e6ee5fSAndroid Build Coastguard Worker // SPDX-License-Identifier: GPL-2.0
2*58e6ee5fSAndroid Build Coastguard Worker /*
3*58e6ee5fSAndroid Build Coastguard Worker  * Copyright (C) 2008, 2009, 2010 Red Hat Inc, Steven Rostedt <[email protected]>
4*58e6ee5fSAndroid Build Coastguard Worker  *
5*58e6ee5fSAndroid Build Coastguard Worker  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
6*58e6ee5fSAndroid Build Coastguard Worker  */
7*58e6ee5fSAndroid Build Coastguard Worker #include <dirent.h>
8*58e6ee5fSAndroid Build Coastguard Worker #include <stdio.h>
9*58e6ee5fSAndroid Build Coastguard Worker #include <stdlib.h>
10*58e6ee5fSAndroid Build Coastguard Worker #include <string.h>
11*58e6ee5fSAndroid Build Coastguard Worker #include <stdarg.h>
12*58e6ee5fSAndroid Build Coastguard Worker #include <getopt.h>
13*58e6ee5fSAndroid Build Coastguard Worker #include <time.h>
14*58e6ee5fSAndroid Build Coastguard Worker #include <sys/types.h>
15*58e6ee5fSAndroid Build Coastguard Worker #include <sys/stat.h>
16*58e6ee5fSAndroid Build Coastguard Worker #include <sys/time.h>
17*58e6ee5fSAndroid Build Coastguard Worker #include <sys/wait.h>
18*58e6ee5fSAndroid Build Coastguard Worker #include <sys/socket.h>
19*58e6ee5fSAndroid Build Coastguard Worker #include <sys/syscall.h>
20*58e6ee5fSAndroid Build Coastguard Worker #include <sys/utsname.h>
21*58e6ee5fSAndroid Build Coastguard Worker #ifndef NO_PTRACE
22*58e6ee5fSAndroid Build Coastguard Worker #include <sys/ptrace.h>
23*58e6ee5fSAndroid Build Coastguard Worker #else
24*58e6ee5fSAndroid Build Coastguard Worker #ifdef WARN_NO_PTRACE
25*58e6ee5fSAndroid Build Coastguard Worker #warning ptrace not supported. -c feature will not work
26*58e6ee5fSAndroid Build Coastguard Worker #endif
27*58e6ee5fSAndroid Build Coastguard Worker #endif
28*58e6ee5fSAndroid Build Coastguard Worker #include <netdb.h>
29*58e6ee5fSAndroid Build Coastguard Worker #include <fcntl.h>
30*58e6ee5fSAndroid Build Coastguard Worker #include <unistd.h>
31*58e6ee5fSAndroid Build Coastguard Worker #include <ctype.h>
32*58e6ee5fSAndroid Build Coastguard Worker #include <sched.h>
33*58e6ee5fSAndroid Build Coastguard Worker #include <glob.h>
34*58e6ee5fSAndroid Build Coastguard Worker #include <errno.h>
35*58e6ee5fSAndroid Build Coastguard Worker #include <limits.h>
36*58e6ee5fSAndroid Build Coastguard Worker #include <libgen.h>
37*58e6ee5fSAndroid Build Coastguard Worker #include <poll.h>
38*58e6ee5fSAndroid Build Coastguard Worker #include <pwd.h>
39*58e6ee5fSAndroid Build Coastguard Worker #include <grp.h>
40*58e6ee5fSAndroid Build Coastguard Worker 
41*58e6ee5fSAndroid Build Coastguard Worker #include "tracefs.h"
42*58e6ee5fSAndroid Build Coastguard Worker #include "version.h"
43*58e6ee5fSAndroid Build Coastguard Worker #include "trace-local.h"
44*58e6ee5fSAndroid Build Coastguard Worker #include "trace-msg.h"
45*58e6ee5fSAndroid Build Coastguard Worker 
46*58e6ee5fSAndroid Build Coastguard Worker #define _STR(x) #x
47*58e6ee5fSAndroid Build Coastguard Worker #define STR(x) _STR(x)
48*58e6ee5fSAndroid Build Coastguard Worker 
49*58e6ee5fSAndroid Build Coastguard Worker #define TRACE_CTRL	"tracing_on"
50*58e6ee5fSAndroid Build Coastguard Worker #define TRACE		"trace"
51*58e6ee5fSAndroid Build Coastguard Worker #define AVAILABLE	"available_tracers"
52*58e6ee5fSAndroid Build Coastguard Worker #define CURRENT		"current_tracer"
53*58e6ee5fSAndroid Build Coastguard Worker #define ITER_CTRL	"trace_options"
54*58e6ee5fSAndroid Build Coastguard Worker #define MAX_LATENCY	"tracing_max_latency"
55*58e6ee5fSAndroid Build Coastguard Worker #define STAMP		"stamp"
56*58e6ee5fSAndroid Build Coastguard Worker #define FUNC_STACK_TRACE "func_stack_trace"
57*58e6ee5fSAndroid Build Coastguard Worker #define TSC_CLOCK	"x86-tsc"
58*58e6ee5fSAndroid Build Coastguard Worker 
59*58e6ee5fSAndroid Build Coastguard Worker #define dprint(fmt, ...)	tracecmd_debug(fmt, ##__VA_ARGS__)
60*58e6ee5fSAndroid Build Coastguard Worker 
61*58e6ee5fSAndroid Build Coastguard Worker enum trace_type {
62*58e6ee5fSAndroid Build Coastguard Worker 	TRACE_TYPE_RECORD	= 1,
63*58e6ee5fSAndroid Build Coastguard Worker 	TRACE_TYPE_START	= (1 << 1),
64*58e6ee5fSAndroid Build Coastguard Worker 	TRACE_TYPE_STREAM	= (1 << 2),
65*58e6ee5fSAndroid Build Coastguard Worker 	TRACE_TYPE_EXTRACT	= (1 << 3),
66*58e6ee5fSAndroid Build Coastguard Worker 	TRACE_TYPE_SET		= (1 << 4),
67*58e6ee5fSAndroid Build Coastguard Worker };
68*58e6ee5fSAndroid Build Coastguard Worker 
69*58e6ee5fSAndroid Build Coastguard Worker static tracecmd_handle_init_func handle_init = NULL;
70*58e6ee5fSAndroid Build Coastguard Worker 
71*58e6ee5fSAndroid Build Coastguard Worker static int rt_prio;
72*58e6ee5fSAndroid Build Coastguard Worker 
73*58e6ee5fSAndroid Build Coastguard Worker static int keep;
74*58e6ee5fSAndroid Build Coastguard Worker 
75*58e6ee5fSAndroid Build Coastguard Worker static int latency;
76*58e6ee5fSAndroid Build Coastguard Worker static int sleep_time = 1000;
77*58e6ee5fSAndroid Build Coastguard Worker static int recorder_threads;
78*58e6ee5fSAndroid Build Coastguard Worker static struct pid_record_data *pids;
79*58e6ee5fSAndroid Build Coastguard Worker static int buffers;
80*58e6ee5fSAndroid Build Coastguard Worker 
81*58e6ee5fSAndroid Build Coastguard Worker /* Clear all function filters */
82*58e6ee5fSAndroid Build Coastguard Worker static int clear_function_filters;
83*58e6ee5fSAndroid Build Coastguard Worker 
84*58e6ee5fSAndroid Build Coastguard Worker static bool no_fifos;
85*58e6ee5fSAndroid Build Coastguard Worker 
86*58e6ee5fSAndroid Build Coastguard Worker static char *host;
87*58e6ee5fSAndroid Build Coastguard Worker 
88*58e6ee5fSAndroid Build Coastguard Worker static const char *gai_err;
89*58e6ee5fSAndroid Build Coastguard Worker 
90*58e6ee5fSAndroid Build Coastguard Worker static bool quiet;
91*58e6ee5fSAndroid Build Coastguard Worker 
92*58e6ee5fSAndroid Build Coastguard Worker static bool fork_process;
93*58e6ee5fSAndroid Build Coastguard Worker 
94*58e6ee5fSAndroid Build Coastguard Worker /* Max size to let a per cpu file get */
95*58e6ee5fSAndroid Build Coastguard Worker static int max_kb;
96*58e6ee5fSAndroid Build Coastguard Worker 
97*58e6ee5fSAndroid Build Coastguard Worker static int do_ptrace;
98*58e6ee5fSAndroid Build Coastguard Worker 
99*58e6ee5fSAndroid Build Coastguard Worker static int filter_task;
100*58e6ee5fSAndroid Build Coastguard Worker static bool no_filter = false;
101*58e6ee5fSAndroid Build Coastguard Worker 
102*58e6ee5fSAndroid Build Coastguard Worker static int local_cpu_count;
103*58e6ee5fSAndroid Build Coastguard Worker 
104*58e6ee5fSAndroid Build Coastguard Worker static int finished;
105*58e6ee5fSAndroid Build Coastguard Worker 
106*58e6ee5fSAndroid Build Coastguard Worker /* setting of /proc/sys/kernel/ftrace_enabled */
107*58e6ee5fSAndroid Build Coastguard Worker static int fset;
108*58e6ee5fSAndroid Build Coastguard Worker 
109*58e6ee5fSAndroid Build Coastguard Worker static unsigned recorder_flags;
110*58e6ee5fSAndroid Build Coastguard Worker 
111*58e6ee5fSAndroid Build Coastguard Worker /* Try a few times to get an accurate date */
112*58e6ee5fSAndroid Build Coastguard Worker static int date2ts_tries = 50;
113*58e6ee5fSAndroid Build Coastguard Worker 
114*58e6ee5fSAndroid Build Coastguard Worker static struct func_list *graph_funcs;
115*58e6ee5fSAndroid Build Coastguard Worker 
116*58e6ee5fSAndroid Build Coastguard Worker static int func_stack;
117*58e6ee5fSAndroid Build Coastguard Worker 
118*58e6ee5fSAndroid Build Coastguard Worker static int save_stdout = -1;
119*58e6ee5fSAndroid Build Coastguard Worker 
120*58e6ee5fSAndroid Build Coastguard Worker static struct hook_list *hooks;
121*58e6ee5fSAndroid Build Coastguard Worker 
122*58e6ee5fSAndroid Build Coastguard Worker struct event_list {
123*58e6ee5fSAndroid Build Coastguard Worker 	struct event_list *next;
124*58e6ee5fSAndroid Build Coastguard Worker 	const char *event;
125*58e6ee5fSAndroid Build Coastguard Worker 	char *trigger;
126*58e6ee5fSAndroid Build Coastguard Worker 	char *filter;
127*58e6ee5fSAndroid Build Coastguard Worker 	char *pid_filter;
128*58e6ee5fSAndroid Build Coastguard Worker 	char *filter_file;
129*58e6ee5fSAndroid Build Coastguard Worker 	char *trigger_file;
130*58e6ee5fSAndroid Build Coastguard Worker 	char *enable_file;
131*58e6ee5fSAndroid Build Coastguard Worker 	int neg;
132*58e6ee5fSAndroid Build Coastguard Worker };
133*58e6ee5fSAndroid Build Coastguard Worker 
134*58e6ee5fSAndroid Build Coastguard Worker struct tracecmd_event_list *listed_events;
135*58e6ee5fSAndroid Build Coastguard Worker 
136*58e6ee5fSAndroid Build Coastguard Worker struct events {
137*58e6ee5fSAndroid Build Coastguard Worker 	struct events *sibling;
138*58e6ee5fSAndroid Build Coastguard Worker 	struct events *children;
139*58e6ee5fSAndroid Build Coastguard Worker 	struct events *next;
140*58e6ee5fSAndroid Build Coastguard Worker 	char *name;
141*58e6ee5fSAndroid Build Coastguard Worker };
142*58e6ee5fSAndroid Build Coastguard Worker 
143*58e6ee5fSAndroid Build Coastguard Worker /* Files to be reset when done recording */
144*58e6ee5fSAndroid Build Coastguard Worker struct reset_file {
145*58e6ee5fSAndroid Build Coastguard Worker 	struct reset_file	*next;
146*58e6ee5fSAndroid Build Coastguard Worker 	char			*path;
147*58e6ee5fSAndroid Build Coastguard Worker 	char			*reset;
148*58e6ee5fSAndroid Build Coastguard Worker 	int			prio;
149*58e6ee5fSAndroid Build Coastguard Worker };
150*58e6ee5fSAndroid Build Coastguard Worker 
151*58e6ee5fSAndroid Build Coastguard Worker static struct reset_file *reset_files;
152*58e6ee5fSAndroid Build Coastguard Worker 
153*58e6ee5fSAndroid Build Coastguard Worker /* Triggers need to be cleared in a special way */
154*58e6ee5fSAndroid Build Coastguard Worker static struct reset_file *reset_triggers;
155*58e6ee5fSAndroid Build Coastguard Worker 
156*58e6ee5fSAndroid Build Coastguard Worker struct buffer_instance top_instance;
157*58e6ee5fSAndroid Build Coastguard Worker struct buffer_instance *buffer_instances;
158*58e6ee5fSAndroid Build Coastguard Worker struct buffer_instance *first_instance;
159*58e6ee5fSAndroid Build Coastguard Worker 
160*58e6ee5fSAndroid Build Coastguard Worker static struct tracecmd_recorder *recorder;
161*58e6ee5fSAndroid Build Coastguard Worker 
162*58e6ee5fSAndroid Build Coastguard Worker static int ignore_event_not_found = 0;
163*58e6ee5fSAndroid Build Coastguard Worker 
is_top_instance(struct buffer_instance * instance)164*58e6ee5fSAndroid Build Coastguard Worker static inline int is_top_instance(struct buffer_instance *instance)
165*58e6ee5fSAndroid Build Coastguard Worker {
166*58e6ee5fSAndroid Build Coastguard Worker 	return instance == &top_instance;
167*58e6ee5fSAndroid Build Coastguard Worker }
168*58e6ee5fSAndroid Build Coastguard Worker 
no_top_instance(void)169*58e6ee5fSAndroid Build Coastguard Worker static inline int no_top_instance(void)
170*58e6ee5fSAndroid Build Coastguard Worker {
171*58e6ee5fSAndroid Build Coastguard Worker 	return first_instance != &top_instance;
172*58e6ee5fSAndroid Build Coastguard Worker }
173*58e6ee5fSAndroid Build Coastguard Worker 
init_instance(struct buffer_instance * instance)174*58e6ee5fSAndroid Build Coastguard Worker static void init_instance(struct buffer_instance *instance)
175*58e6ee5fSAndroid Build Coastguard Worker {
176*58e6ee5fSAndroid Build Coastguard Worker 	instance->event_next = &instance->events;
177*58e6ee5fSAndroid Build Coastguard Worker }
178*58e6ee5fSAndroid Build Coastguard Worker 
179*58e6ee5fSAndroid Build Coastguard Worker enum {
180*58e6ee5fSAndroid Build Coastguard Worker 	RESET_DEFAULT_PRIO	= 0,
181*58e6ee5fSAndroid Build Coastguard Worker 	RESET_HIGH_PRIO		= 100000,
182*58e6ee5fSAndroid Build Coastguard Worker };
183*58e6ee5fSAndroid Build Coastguard Worker 
184*58e6ee5fSAndroid Build Coastguard Worker enum trace_cmd {
185*58e6ee5fSAndroid Build Coastguard Worker 	CMD_extract,
186*58e6ee5fSAndroid Build Coastguard Worker 	CMD_start,
187*58e6ee5fSAndroid Build Coastguard Worker 	CMD_stream,
188*58e6ee5fSAndroid Build Coastguard Worker 	CMD_profile,
189*58e6ee5fSAndroid Build Coastguard Worker 	CMD_record,
190*58e6ee5fSAndroid Build Coastguard Worker 	CMD_record_agent,
191*58e6ee5fSAndroid Build Coastguard Worker 	CMD_set,
192*58e6ee5fSAndroid Build Coastguard Worker };
193*58e6ee5fSAndroid Build Coastguard Worker 
194*58e6ee5fSAndroid Build Coastguard Worker struct common_record_context {
195*58e6ee5fSAndroid Build Coastguard Worker 	enum trace_cmd curr_cmd;
196*58e6ee5fSAndroid Build Coastguard Worker 	struct buffer_instance *instance;
197*58e6ee5fSAndroid Build Coastguard Worker 	const char *output;
198*58e6ee5fSAndroid Build Coastguard Worker 	char *date2ts;
199*58e6ee5fSAndroid Build Coastguard Worker 	char *user;
200*58e6ee5fSAndroid Build Coastguard Worker 	const char *clock;
201*58e6ee5fSAndroid Build Coastguard Worker 	const char *compression;
202*58e6ee5fSAndroid Build Coastguard Worker 	struct tsc_nsec tsc2nsec;
203*58e6ee5fSAndroid Build Coastguard Worker 	int data_flags;
204*58e6ee5fSAndroid Build Coastguard Worker 	int tsync_loop_interval;
205*58e6ee5fSAndroid Build Coastguard Worker 
206*58e6ee5fSAndroid Build Coastguard Worker 	int record_all;
207*58e6ee5fSAndroid Build Coastguard Worker 	int total_disable;
208*58e6ee5fSAndroid Build Coastguard Worker 	int disable;
209*58e6ee5fSAndroid Build Coastguard Worker 	int events;
210*58e6ee5fSAndroid Build Coastguard Worker 	int global;
211*58e6ee5fSAndroid Build Coastguard Worker 	int filtered;
212*58e6ee5fSAndroid Build Coastguard Worker 	int date;
213*58e6ee5fSAndroid Build Coastguard Worker 	int manual;
214*58e6ee5fSAndroid Build Coastguard Worker 	int topt;
215*58e6ee5fSAndroid Build Coastguard Worker 	int run_command;
216*58e6ee5fSAndroid Build Coastguard Worker 	int saved_cmdlines_size;
217*58e6ee5fSAndroid Build Coastguard Worker 	int file_version;
218*58e6ee5fSAndroid Build Coastguard Worker };
219*58e6ee5fSAndroid Build Coastguard Worker 
add_reset_file(const char * file,const char * val,int prio)220*58e6ee5fSAndroid Build Coastguard Worker static void add_reset_file(const char *file, const char *val, int prio)
221*58e6ee5fSAndroid Build Coastguard Worker {
222*58e6ee5fSAndroid Build Coastguard Worker 	struct reset_file *reset;
223*58e6ee5fSAndroid Build Coastguard Worker 	struct reset_file **last = &reset_files;
224*58e6ee5fSAndroid Build Coastguard Worker 
225*58e6ee5fSAndroid Build Coastguard Worker 	/* Only reset if we are not keeping the state */
226*58e6ee5fSAndroid Build Coastguard Worker 	if (keep)
227*58e6ee5fSAndroid Build Coastguard Worker 		return;
228*58e6ee5fSAndroid Build Coastguard Worker 
229*58e6ee5fSAndroid Build Coastguard Worker 	reset = malloc(sizeof(*reset));
230*58e6ee5fSAndroid Build Coastguard Worker 	if (!reset)
231*58e6ee5fSAndroid Build Coastguard Worker 		die("Failed to allocate reset");
232*58e6ee5fSAndroid Build Coastguard Worker 	reset->path = strdup(file);
233*58e6ee5fSAndroid Build Coastguard Worker 	reset->reset = strdup(val);
234*58e6ee5fSAndroid Build Coastguard Worker 	reset->prio = prio;
235*58e6ee5fSAndroid Build Coastguard Worker 	if (!reset->path || !reset->reset)
236*58e6ee5fSAndroid Build Coastguard Worker 		die("Failed to allocate reset path or val");
237*58e6ee5fSAndroid Build Coastguard Worker 
238*58e6ee5fSAndroid Build Coastguard Worker 	while (*last && (*last)->prio > prio)
239*58e6ee5fSAndroid Build Coastguard Worker 		last = &(*last)->next;
240*58e6ee5fSAndroid Build Coastguard Worker 
241*58e6ee5fSAndroid Build Coastguard Worker 	reset->next = *last;
242*58e6ee5fSAndroid Build Coastguard Worker 	*last = reset;
243*58e6ee5fSAndroid Build Coastguard Worker }
244*58e6ee5fSAndroid Build Coastguard Worker 
add_reset_trigger(const char * file)245*58e6ee5fSAndroid Build Coastguard Worker static void add_reset_trigger(const char *file)
246*58e6ee5fSAndroid Build Coastguard Worker {
247*58e6ee5fSAndroid Build Coastguard Worker 	struct reset_file *reset;
248*58e6ee5fSAndroid Build Coastguard Worker 
249*58e6ee5fSAndroid Build Coastguard Worker 	/* Only reset if we are not keeping the state */
250*58e6ee5fSAndroid Build Coastguard Worker 	if (keep)
251*58e6ee5fSAndroid Build Coastguard Worker 		return;
252*58e6ee5fSAndroid Build Coastguard Worker 
253*58e6ee5fSAndroid Build Coastguard Worker 	reset = malloc(sizeof(*reset));
254*58e6ee5fSAndroid Build Coastguard Worker 	if (!reset)
255*58e6ee5fSAndroid Build Coastguard Worker 		die("Failed to allocate reset");
256*58e6ee5fSAndroid Build Coastguard Worker 	reset->path = strdup(file);
257*58e6ee5fSAndroid Build Coastguard Worker 
258*58e6ee5fSAndroid Build Coastguard Worker 	reset->next = reset_triggers;
259*58e6ee5fSAndroid Build Coastguard Worker 	reset_triggers = reset;
260*58e6ee5fSAndroid Build Coastguard Worker }
261*58e6ee5fSAndroid Build Coastguard Worker 
262*58e6ee5fSAndroid Build Coastguard Worker /* To save the contents of the file */
reset_save_file(const char * file,int prio)263*58e6ee5fSAndroid Build Coastguard Worker static void reset_save_file(const char *file, int prio)
264*58e6ee5fSAndroid Build Coastguard Worker {
265*58e6ee5fSAndroid Build Coastguard Worker 	char *content;
266*58e6ee5fSAndroid Build Coastguard Worker 
267*58e6ee5fSAndroid Build Coastguard Worker 	content = get_file_content(file);
268*58e6ee5fSAndroid Build Coastguard Worker 	if (content) {
269*58e6ee5fSAndroid Build Coastguard Worker 		add_reset_file(file, content, prio);
270*58e6ee5fSAndroid Build Coastguard Worker 		free(content);
271*58e6ee5fSAndroid Build Coastguard Worker 	}
272*58e6ee5fSAndroid Build Coastguard Worker }
273*58e6ee5fSAndroid Build Coastguard Worker 
274*58e6ee5fSAndroid Build Coastguard Worker /*
275*58e6ee5fSAndroid Build Coastguard Worker  * @file: the file to check
276*58e6ee5fSAndroid Build Coastguard Worker  * @nop: If the content of the file is this, use the reset value
277*58e6ee5fSAndroid Build Coastguard Worker  * @reset: What to write if the file == @nop
278*58e6ee5fSAndroid Build Coastguard Worker  */
reset_save_file_cond(const char * file,int prio,const char * nop,const char * reset)279*58e6ee5fSAndroid Build Coastguard Worker static void reset_save_file_cond(const char *file, int prio,
280*58e6ee5fSAndroid Build Coastguard Worker 				 const char *nop, const char *reset)
281*58e6ee5fSAndroid Build Coastguard Worker {
282*58e6ee5fSAndroid Build Coastguard Worker 	char *content;
283*58e6ee5fSAndroid Build Coastguard Worker 	char *cond;
284*58e6ee5fSAndroid Build Coastguard Worker 
285*58e6ee5fSAndroid Build Coastguard Worker 	if (keep)
286*58e6ee5fSAndroid Build Coastguard Worker 		return;
287*58e6ee5fSAndroid Build Coastguard Worker 
288*58e6ee5fSAndroid Build Coastguard Worker 	content = get_file_content(file);
289*58e6ee5fSAndroid Build Coastguard Worker 
290*58e6ee5fSAndroid Build Coastguard Worker 	cond = strstrip(content);
291*58e6ee5fSAndroid Build Coastguard Worker 
292*58e6ee5fSAndroid Build Coastguard Worker 	if (strcmp(cond, nop) == 0)
293*58e6ee5fSAndroid Build Coastguard Worker 		add_reset_file(file, reset, prio);
294*58e6ee5fSAndroid Build Coastguard Worker 	else
295*58e6ee5fSAndroid Build Coastguard Worker 		add_reset_file(file, content, prio);
296*58e6ee5fSAndroid Build Coastguard Worker 
297*58e6ee5fSAndroid Build Coastguard Worker 	free(content);
298*58e6ee5fSAndroid Build Coastguard Worker }
299*58e6ee5fSAndroid Build Coastguard Worker 
300*58e6ee5fSAndroid Build Coastguard Worker /**
301*58e6ee5fSAndroid Build Coastguard Worker  * add_instance - add a buffer instance to the internal list
302*58e6ee5fSAndroid Build Coastguard Worker  * @instance: The buffer instance to add
303*58e6ee5fSAndroid Build Coastguard Worker  */
add_instance(struct buffer_instance * instance,int cpu_count)304*58e6ee5fSAndroid Build Coastguard Worker void add_instance(struct buffer_instance *instance, int cpu_count)
305*58e6ee5fSAndroid Build Coastguard Worker {
306*58e6ee5fSAndroid Build Coastguard Worker 	init_instance(instance);
307*58e6ee5fSAndroid Build Coastguard Worker 	instance->next = buffer_instances;
308*58e6ee5fSAndroid Build Coastguard Worker 	if (first_instance == buffer_instances)
309*58e6ee5fSAndroid Build Coastguard Worker 		first_instance = instance;
310*58e6ee5fSAndroid Build Coastguard Worker 	buffer_instances = instance;
311*58e6ee5fSAndroid Build Coastguard Worker 	instance->cpu_count = cpu_count;
312*58e6ee5fSAndroid Build Coastguard Worker 	buffers++;
313*58e6ee5fSAndroid Build Coastguard Worker }
314*58e6ee5fSAndroid Build Coastguard Worker 
instance_reset_file_save(struct buffer_instance * instance,char * file,int prio)315*58e6ee5fSAndroid Build Coastguard Worker static void instance_reset_file_save(struct buffer_instance *instance, char *file, int prio)
316*58e6ee5fSAndroid Build Coastguard Worker {
317*58e6ee5fSAndroid Build Coastguard Worker 	char *path;
318*58e6ee5fSAndroid Build Coastguard Worker 
319*58e6ee5fSAndroid Build Coastguard Worker 	path = tracefs_instance_get_file(instance->tracefs, file);
320*58e6ee5fSAndroid Build Coastguard Worker 	if (path)
321*58e6ee5fSAndroid Build Coastguard Worker 		reset_save_file(path, prio);
322*58e6ee5fSAndroid Build Coastguard Worker 	tracefs_put_tracing_file(path);
323*58e6ee5fSAndroid Build Coastguard Worker }
324*58e6ee5fSAndroid Build Coastguard Worker 
test_set_event_pid(struct buffer_instance * instance)325*58e6ee5fSAndroid Build Coastguard Worker static void test_set_event_pid(struct buffer_instance *instance)
326*58e6ee5fSAndroid Build Coastguard Worker {
327*58e6ee5fSAndroid Build Coastguard Worker 	static int have_set_event_pid;
328*58e6ee5fSAndroid Build Coastguard Worker 	static int have_event_fork;
329*58e6ee5fSAndroid Build Coastguard Worker 	static int have_func_fork;
330*58e6ee5fSAndroid Build Coastguard Worker 
331*58e6ee5fSAndroid Build Coastguard Worker 	if (!have_set_event_pid &&
332*58e6ee5fSAndroid Build Coastguard Worker 	    tracefs_file_exists(top_instance.tracefs, "set_event_pid"))
333*58e6ee5fSAndroid Build Coastguard Worker 		have_set_event_pid = 1;
334*58e6ee5fSAndroid Build Coastguard Worker 	if (!have_event_fork &&
335*58e6ee5fSAndroid Build Coastguard Worker 	    tracefs_file_exists(top_instance.tracefs, "options/event-fork"))
336*58e6ee5fSAndroid Build Coastguard Worker 		have_event_fork = 1;
337*58e6ee5fSAndroid Build Coastguard Worker 	if (!have_func_fork &&
338*58e6ee5fSAndroid Build Coastguard Worker 	    tracefs_file_exists(top_instance.tracefs, "options/function-fork"))
339*58e6ee5fSAndroid Build Coastguard Worker 		have_func_fork = 1;
340*58e6ee5fSAndroid Build Coastguard Worker 
341*58e6ee5fSAndroid Build Coastguard Worker 	if (!instance->have_set_event_pid && have_set_event_pid) {
342*58e6ee5fSAndroid Build Coastguard Worker 		instance->have_set_event_pid = 1;
343*58e6ee5fSAndroid Build Coastguard Worker 		instance_reset_file_save(instance, "set_event_pid",
344*58e6ee5fSAndroid Build Coastguard Worker 					 RESET_DEFAULT_PRIO);
345*58e6ee5fSAndroid Build Coastguard Worker 	}
346*58e6ee5fSAndroid Build Coastguard Worker 	if (!instance->have_event_fork && have_event_fork) {
347*58e6ee5fSAndroid Build Coastguard Worker 		instance->have_event_fork = 1;
348*58e6ee5fSAndroid Build Coastguard Worker 		instance_reset_file_save(instance, "options/event-fork",
349*58e6ee5fSAndroid Build Coastguard Worker 					 RESET_DEFAULT_PRIO);
350*58e6ee5fSAndroid Build Coastguard Worker 	}
351*58e6ee5fSAndroid Build Coastguard Worker 	if (!instance->have_func_fork && have_func_fork) {
352*58e6ee5fSAndroid Build Coastguard Worker 		instance->have_func_fork = 1;
353*58e6ee5fSAndroid Build Coastguard Worker 		instance_reset_file_save(instance, "options/function-fork",
354*58e6ee5fSAndroid Build Coastguard Worker 					 RESET_DEFAULT_PRIO);
355*58e6ee5fSAndroid Build Coastguard Worker 	}
356*58e6ee5fSAndroid Build Coastguard Worker }
357*58e6ee5fSAndroid Build Coastguard Worker 
358*58e6ee5fSAndroid Build Coastguard Worker /**
359*58e6ee5fSAndroid Build Coastguard Worker  * allocate_instance - allocate a new buffer instance,
360*58e6ee5fSAndroid Build Coastguard Worker  *			it must exist in the ftrace system
361*58e6ee5fSAndroid Build Coastguard Worker  * @name: The name of the instance (instance will point to this)
362*58e6ee5fSAndroid Build Coastguard Worker  *
363*58e6ee5fSAndroid Build Coastguard Worker  * Returns a newly allocated instance. In case of an error or if the
364*58e6ee5fSAndroid Build Coastguard Worker  * instance does not exist in the ftrace system, NULL is returned.
365*58e6ee5fSAndroid Build Coastguard Worker  */
allocate_instance(const char * name)366*58e6ee5fSAndroid Build Coastguard Worker struct buffer_instance *allocate_instance(const char *name)
367*58e6ee5fSAndroid Build Coastguard Worker {
368*58e6ee5fSAndroid Build Coastguard Worker 	struct buffer_instance *instance;
369*58e6ee5fSAndroid Build Coastguard Worker 
370*58e6ee5fSAndroid Build Coastguard Worker 	instance = calloc(1, sizeof(*instance));
371*58e6ee5fSAndroid Build Coastguard Worker 	if (!instance)
372*58e6ee5fSAndroid Build Coastguard Worker 		return NULL;
373*58e6ee5fSAndroid Build Coastguard Worker 	if (name)
374*58e6ee5fSAndroid Build Coastguard Worker 		instance->name = strdup(name);
375*58e6ee5fSAndroid Build Coastguard Worker 	if (tracefs_instance_exists(name)) {
376*58e6ee5fSAndroid Build Coastguard Worker 		instance->tracefs = tracefs_instance_create(name);
377*58e6ee5fSAndroid Build Coastguard Worker 		if (!instance->tracefs)
378*58e6ee5fSAndroid Build Coastguard Worker 			goto error;
379*58e6ee5fSAndroid Build Coastguard Worker 	}
380*58e6ee5fSAndroid Build Coastguard Worker 
381*58e6ee5fSAndroid Build Coastguard Worker 	return instance;
382*58e6ee5fSAndroid Build Coastguard Worker 
383*58e6ee5fSAndroid Build Coastguard Worker error:
384*58e6ee5fSAndroid Build Coastguard Worker 	if (instance) {
385*58e6ee5fSAndroid Build Coastguard Worker 		free(instance->name);
386*58e6ee5fSAndroid Build Coastguard Worker 		tracefs_instance_free(instance->tracefs);
387*58e6ee5fSAndroid Build Coastguard Worker 		free(instance);
388*58e6ee5fSAndroid Build Coastguard Worker 	}
389*58e6ee5fSAndroid Build Coastguard Worker 	return NULL;
390*58e6ee5fSAndroid Build Coastguard Worker }
391*58e6ee5fSAndroid Build Coastguard Worker 
__add_all_instances(const char * tracing_dir)392*58e6ee5fSAndroid Build Coastguard Worker static int __add_all_instances(const char *tracing_dir)
393*58e6ee5fSAndroid Build Coastguard Worker {
394*58e6ee5fSAndroid Build Coastguard Worker 	struct dirent *dent;
395*58e6ee5fSAndroid Build Coastguard Worker 	char *instances_dir;
396*58e6ee5fSAndroid Build Coastguard Worker 	struct stat st;
397*58e6ee5fSAndroid Build Coastguard Worker 	DIR *dir;
398*58e6ee5fSAndroid Build Coastguard Worker 	int ret;
399*58e6ee5fSAndroid Build Coastguard Worker 
400*58e6ee5fSAndroid Build Coastguard Worker 	if (!tracing_dir)
401*58e6ee5fSAndroid Build Coastguard Worker 		return -1;
402*58e6ee5fSAndroid Build Coastguard Worker 
403*58e6ee5fSAndroid Build Coastguard Worker 	instances_dir = append_file(tracing_dir, "instances");
404*58e6ee5fSAndroid Build Coastguard Worker 	if (!instances_dir)
405*58e6ee5fSAndroid Build Coastguard Worker 		return -1;
406*58e6ee5fSAndroid Build Coastguard Worker 
407*58e6ee5fSAndroid Build Coastguard Worker 	ret = stat(instances_dir, &st);
408*58e6ee5fSAndroid Build Coastguard Worker 	if (ret < 0 || !S_ISDIR(st.st_mode)) {
409*58e6ee5fSAndroid Build Coastguard Worker 		ret = -1;
410*58e6ee5fSAndroid Build Coastguard Worker 		goto out_free;
411*58e6ee5fSAndroid Build Coastguard Worker 	}
412*58e6ee5fSAndroid Build Coastguard Worker 
413*58e6ee5fSAndroid Build Coastguard Worker 	dir = opendir(instances_dir);
414*58e6ee5fSAndroid Build Coastguard Worker 	if (!dir) {
415*58e6ee5fSAndroid Build Coastguard Worker 		ret = -1;
416*58e6ee5fSAndroid Build Coastguard Worker 		goto out_free;
417*58e6ee5fSAndroid Build Coastguard Worker 	}
418*58e6ee5fSAndroid Build Coastguard Worker 
419*58e6ee5fSAndroid Build Coastguard Worker 	while ((dent = readdir(dir))) {
420*58e6ee5fSAndroid Build Coastguard Worker 		const char *name = strdup(dent->d_name);
421*58e6ee5fSAndroid Build Coastguard Worker 		char *instance_path;
422*58e6ee5fSAndroid Build Coastguard Worker 		struct buffer_instance *instance;
423*58e6ee5fSAndroid Build Coastguard Worker 
424*58e6ee5fSAndroid Build Coastguard Worker 		if (strcmp(name, ".") == 0 ||
425*58e6ee5fSAndroid Build Coastguard Worker 		    strcmp(name, "..") == 0)
426*58e6ee5fSAndroid Build Coastguard Worker 			continue;
427*58e6ee5fSAndroid Build Coastguard Worker 
428*58e6ee5fSAndroid Build Coastguard Worker 		instance_path = append_file(instances_dir, name);
429*58e6ee5fSAndroid Build Coastguard Worker 		ret = stat(instance_path, &st);
430*58e6ee5fSAndroid Build Coastguard Worker 		if (ret < 0 || !S_ISDIR(st.st_mode)) {
431*58e6ee5fSAndroid Build Coastguard Worker 			free(instance_path);
432*58e6ee5fSAndroid Build Coastguard Worker 			continue;
433*58e6ee5fSAndroid Build Coastguard Worker 		}
434*58e6ee5fSAndroid Build Coastguard Worker 		free(instance_path);
435*58e6ee5fSAndroid Build Coastguard Worker 
436*58e6ee5fSAndroid Build Coastguard Worker 		instance = allocate_instance(name);
437*58e6ee5fSAndroid Build Coastguard Worker 		if (!instance)
438*58e6ee5fSAndroid Build Coastguard Worker 			die("Failed to create instance");
439*58e6ee5fSAndroid Build Coastguard Worker 		add_instance(instance, local_cpu_count);
440*58e6ee5fSAndroid Build Coastguard Worker 	}
441*58e6ee5fSAndroid Build Coastguard Worker 
442*58e6ee5fSAndroid Build Coastguard Worker 	closedir(dir);
443*58e6ee5fSAndroid Build Coastguard Worker 	ret = 0;
444*58e6ee5fSAndroid Build Coastguard Worker 
445*58e6ee5fSAndroid Build Coastguard Worker  out_free:
446*58e6ee5fSAndroid Build Coastguard Worker 	free(instances_dir);
447*58e6ee5fSAndroid Build Coastguard Worker 	return ret;
448*58e6ee5fSAndroid Build Coastguard Worker }
449*58e6ee5fSAndroid Build Coastguard Worker 
450*58e6ee5fSAndroid Build Coastguard Worker /**
451*58e6ee5fSAndroid Build Coastguard Worker  * add_all_instances - Add all pre-existing instances to the internal list
452*58e6ee5fSAndroid Build Coastguard Worker  * @tracing_dir: The top-level tracing directory
453*58e6ee5fSAndroid Build Coastguard Worker  *
454*58e6ee5fSAndroid Build Coastguard Worker  * Returns whether the operation succeeded
455*58e6ee5fSAndroid Build Coastguard Worker  */
add_all_instances(void)456*58e6ee5fSAndroid Build Coastguard Worker void add_all_instances(void)
457*58e6ee5fSAndroid Build Coastguard Worker {
458*58e6ee5fSAndroid Build Coastguard Worker 	const char *tracing_dir = tracefs_tracing_dir();
459*58e6ee5fSAndroid Build Coastguard Worker 	if (!tracing_dir)
460*58e6ee5fSAndroid Build Coastguard Worker 		die("can't get the tracing directory");
461*58e6ee5fSAndroid Build Coastguard Worker 
462*58e6ee5fSAndroid Build Coastguard Worker 	__add_all_instances(tracing_dir);
463*58e6ee5fSAndroid Build Coastguard Worker }
464*58e6ee5fSAndroid Build Coastguard Worker 
465*58e6ee5fSAndroid Build Coastguard Worker /**
466*58e6ee5fSAndroid Build Coastguard Worker  * tracecmd_stat_cpu - show the buffer stats of a particular CPU
467*58e6ee5fSAndroid Build Coastguard Worker  * @s: the trace_seq to record the data in.
468*58e6ee5fSAndroid Build Coastguard Worker  * @cpu: the CPU to stat
469*58e6ee5fSAndroid Build Coastguard Worker  *
470*58e6ee5fSAndroid Build Coastguard Worker  */
tracecmd_stat_cpu_instance(struct buffer_instance * instance,struct trace_seq * s,int cpu)471*58e6ee5fSAndroid Build Coastguard Worker void tracecmd_stat_cpu_instance(struct buffer_instance *instance,
472*58e6ee5fSAndroid Build Coastguard Worker 				struct trace_seq *s, int cpu)
473*58e6ee5fSAndroid Build Coastguard Worker {
474*58e6ee5fSAndroid Build Coastguard Worker 	char buf[BUFSIZ];
475*58e6ee5fSAndroid Build Coastguard Worker 	char *path;
476*58e6ee5fSAndroid Build Coastguard Worker 	char *file;
477*58e6ee5fSAndroid Build Coastguard Worker 	int fd;
478*58e6ee5fSAndroid Build Coastguard Worker 	int r;
479*58e6ee5fSAndroid Build Coastguard Worker 
480*58e6ee5fSAndroid Build Coastguard Worker 	file = malloc(40);
481*58e6ee5fSAndroid Build Coastguard Worker 	if (!file)
482*58e6ee5fSAndroid Build Coastguard Worker 		return;
483*58e6ee5fSAndroid Build Coastguard Worker 	snprintf(file, 40, "per_cpu/cpu%d/stats", cpu);
484*58e6ee5fSAndroid Build Coastguard Worker 
485*58e6ee5fSAndroid Build Coastguard Worker 	path = tracefs_instance_get_file(instance->tracefs, file);
486*58e6ee5fSAndroid Build Coastguard Worker 	free(file);
487*58e6ee5fSAndroid Build Coastguard Worker 	fd = open(path, O_RDONLY);
488*58e6ee5fSAndroid Build Coastguard Worker 	tracefs_put_tracing_file(path);
489*58e6ee5fSAndroid Build Coastguard Worker 	if (fd < 0)
490*58e6ee5fSAndroid Build Coastguard Worker 		return;
491*58e6ee5fSAndroid Build Coastguard Worker 
492*58e6ee5fSAndroid Build Coastguard Worker 	while ((r = read(fd, buf, BUFSIZ)) > 0)
493*58e6ee5fSAndroid Build Coastguard Worker 		trace_seq_printf(s, "%.*s", r, buf);
494*58e6ee5fSAndroid Build Coastguard Worker 
495*58e6ee5fSAndroid Build Coastguard Worker 	close(fd);
496*58e6ee5fSAndroid Build Coastguard Worker }
497*58e6ee5fSAndroid Build Coastguard Worker 
498*58e6ee5fSAndroid Build Coastguard Worker /**
499*58e6ee5fSAndroid Build Coastguard Worker  * tracecmd_stat_cpu - show the buffer stats of a particular CPU
500*58e6ee5fSAndroid Build Coastguard Worker  * @s: the trace_seq to record the data in.
501*58e6ee5fSAndroid Build Coastguard Worker  * @cpu: the CPU to stat
502*58e6ee5fSAndroid Build Coastguard Worker  *
503*58e6ee5fSAndroid Build Coastguard Worker  */
tracecmd_stat_cpu(struct trace_seq * s,int cpu)504*58e6ee5fSAndroid Build Coastguard Worker void tracecmd_stat_cpu(struct trace_seq *s, int cpu)
505*58e6ee5fSAndroid Build Coastguard Worker {
506*58e6ee5fSAndroid Build Coastguard Worker 	tracecmd_stat_cpu_instance(&top_instance, s, cpu);
507*58e6ee5fSAndroid Build Coastguard Worker }
508*58e6ee5fSAndroid Build Coastguard Worker 
add_event(struct buffer_instance * instance,struct event_list * event)509*58e6ee5fSAndroid Build Coastguard Worker static void add_event(struct buffer_instance *instance, struct event_list *event)
510*58e6ee5fSAndroid Build Coastguard Worker {
511*58e6ee5fSAndroid Build Coastguard Worker 	*instance->event_next = event;
512*58e6ee5fSAndroid Build Coastguard Worker 	instance->event_next = &event->next;
513*58e6ee5fSAndroid Build Coastguard Worker 	event->next = NULL;
514*58e6ee5fSAndroid Build Coastguard Worker }
515*58e6ee5fSAndroid Build Coastguard Worker 
reset_event_list(struct buffer_instance * instance)516*58e6ee5fSAndroid Build Coastguard Worker static void reset_event_list(struct buffer_instance *instance)
517*58e6ee5fSAndroid Build Coastguard Worker {
518*58e6ee5fSAndroid Build Coastguard Worker 	instance->events = NULL;
519*58e6ee5fSAndroid Build Coastguard Worker 	init_instance(instance);
520*58e6ee5fSAndroid Build Coastguard Worker }
521*58e6ee5fSAndroid Build Coastguard Worker 
get_temp_file(struct buffer_instance * instance,int cpu)522*58e6ee5fSAndroid Build Coastguard Worker static char *get_temp_file(struct buffer_instance *instance, int cpu)
523*58e6ee5fSAndroid Build Coastguard Worker {
524*58e6ee5fSAndroid Build Coastguard Worker 	const char *output_file = instance->output_file;
525*58e6ee5fSAndroid Build Coastguard Worker 	const char *name;
526*58e6ee5fSAndroid Build Coastguard Worker 	char *file = NULL;
527*58e6ee5fSAndroid Build Coastguard Worker 	int size;
528*58e6ee5fSAndroid Build Coastguard Worker 
529*58e6ee5fSAndroid Build Coastguard Worker 	name = tracefs_instance_get_name(instance->tracefs);
530*58e6ee5fSAndroid Build Coastguard Worker 	if (name) {
531*58e6ee5fSAndroid Build Coastguard Worker 		size = snprintf(file, 0, "%s.%s.cpu%d", output_file, name, cpu);
532*58e6ee5fSAndroid Build Coastguard Worker 		file = malloc(size + 1);
533*58e6ee5fSAndroid Build Coastguard Worker 		if (!file)
534*58e6ee5fSAndroid Build Coastguard Worker 			die("Failed to allocate temp file for %s", name);
535*58e6ee5fSAndroid Build Coastguard Worker 		sprintf(file, "%s.%s.cpu%d", output_file, name, cpu);
536*58e6ee5fSAndroid Build Coastguard Worker 	} else {
537*58e6ee5fSAndroid Build Coastguard Worker 		size = snprintf(file, 0, "%s.cpu%d", output_file, cpu);
538*58e6ee5fSAndroid Build Coastguard Worker 		file = malloc(size + 1);
539*58e6ee5fSAndroid Build Coastguard Worker 		if (!file)
540*58e6ee5fSAndroid Build Coastguard Worker 			die("Failed to allocate temp file for %s", name);
541*58e6ee5fSAndroid Build Coastguard Worker 		sprintf(file, "%s.cpu%d", output_file, cpu);
542*58e6ee5fSAndroid Build Coastguard Worker 	}
543*58e6ee5fSAndroid Build Coastguard Worker 
544*58e6ee5fSAndroid Build Coastguard Worker 	return file;
545*58e6ee5fSAndroid Build Coastguard Worker }
546*58e6ee5fSAndroid Build Coastguard Worker 
trace_get_guest_file(const char * file,const char * guest)547*58e6ee5fSAndroid Build Coastguard Worker char *trace_get_guest_file(const char *file, const char *guest)
548*58e6ee5fSAndroid Build Coastguard Worker {
549*58e6ee5fSAndroid Build Coastguard Worker 	const char *p;
550*58e6ee5fSAndroid Build Coastguard Worker 	char *out = NULL;
551*58e6ee5fSAndroid Build Coastguard Worker 	int ret, base_len;
552*58e6ee5fSAndroid Build Coastguard Worker 
553*58e6ee5fSAndroid Build Coastguard Worker 	p = strrchr(file, '.');
554*58e6ee5fSAndroid Build Coastguard Worker 	if (p && p != file)
555*58e6ee5fSAndroid Build Coastguard Worker 		base_len = p - file;
556*58e6ee5fSAndroid Build Coastguard Worker 	else
557*58e6ee5fSAndroid Build Coastguard Worker 		base_len = strlen(file);
558*58e6ee5fSAndroid Build Coastguard Worker 
559*58e6ee5fSAndroid Build Coastguard Worker 	ret = asprintf(&out, "%.*s-%s%s", base_len, file,
560*58e6ee5fSAndroid Build Coastguard Worker 		       guest, file + base_len);
561*58e6ee5fSAndroid Build Coastguard Worker 	if (ret < 0)
562*58e6ee5fSAndroid Build Coastguard Worker 		return NULL;
563*58e6ee5fSAndroid Build Coastguard Worker 	return out;
564*58e6ee5fSAndroid Build Coastguard Worker }
565*58e6ee5fSAndroid Build Coastguard Worker 
put_temp_file(char * file)566*58e6ee5fSAndroid Build Coastguard Worker static void put_temp_file(char *file)
567*58e6ee5fSAndroid Build Coastguard Worker {
568*58e6ee5fSAndroid Build Coastguard Worker 	free(file);
569*58e6ee5fSAndroid Build Coastguard Worker }
570*58e6ee5fSAndroid Build Coastguard Worker 
delete_temp_file(struct buffer_instance * instance,int cpu)571*58e6ee5fSAndroid Build Coastguard Worker static void delete_temp_file(struct buffer_instance *instance, int cpu)
572*58e6ee5fSAndroid Build Coastguard Worker {
573*58e6ee5fSAndroid Build Coastguard Worker 	const char *output_file = instance->output_file;
574*58e6ee5fSAndroid Build Coastguard Worker 	const char *name;
575*58e6ee5fSAndroid Build Coastguard Worker 	char file[PATH_MAX];
576*58e6ee5fSAndroid Build Coastguard Worker 
577*58e6ee5fSAndroid Build Coastguard Worker 	name = tracefs_instance_get_name(instance->tracefs);
578*58e6ee5fSAndroid Build Coastguard Worker 	if (name)
579*58e6ee5fSAndroid Build Coastguard Worker 		snprintf(file, PATH_MAX, "%s.%s.cpu%d", output_file, name, cpu);
580*58e6ee5fSAndroid Build Coastguard Worker 	else
581*58e6ee5fSAndroid Build Coastguard Worker 		snprintf(file, PATH_MAX, "%s.cpu%d", output_file, cpu);
582*58e6ee5fSAndroid Build Coastguard Worker 	unlink(file);
583*58e6ee5fSAndroid Build Coastguard Worker }
584*58e6ee5fSAndroid Build Coastguard Worker 
kill_thread_instance(int start,struct buffer_instance * instance)585*58e6ee5fSAndroid Build Coastguard Worker static int kill_thread_instance(int start, struct buffer_instance *instance)
586*58e6ee5fSAndroid Build Coastguard Worker {
587*58e6ee5fSAndroid Build Coastguard Worker 	int n = start;
588*58e6ee5fSAndroid Build Coastguard Worker 	int i;
589*58e6ee5fSAndroid Build Coastguard Worker 
590*58e6ee5fSAndroid Build Coastguard Worker 	for (i = 0; i < instance->cpu_count; i++) {
591*58e6ee5fSAndroid Build Coastguard Worker 		if (pids[n].pid > 0) {
592*58e6ee5fSAndroid Build Coastguard Worker 			kill(pids[n].pid, SIGKILL);
593*58e6ee5fSAndroid Build Coastguard Worker 			delete_temp_file(instance, i);
594*58e6ee5fSAndroid Build Coastguard Worker 			pids[n].pid = 0;
595*58e6ee5fSAndroid Build Coastguard Worker 			if (pids[n].brass[0] >= 0)
596*58e6ee5fSAndroid Build Coastguard Worker 				close(pids[n].brass[0]);
597*58e6ee5fSAndroid Build Coastguard Worker 		}
598*58e6ee5fSAndroid Build Coastguard Worker 		n++;
599*58e6ee5fSAndroid Build Coastguard Worker 	}
600*58e6ee5fSAndroid Build Coastguard Worker 
601*58e6ee5fSAndroid Build Coastguard Worker 	return n;
602*58e6ee5fSAndroid Build Coastguard Worker }
603*58e6ee5fSAndroid Build Coastguard Worker 
kill_threads(void)604*58e6ee5fSAndroid Build Coastguard Worker static void kill_threads(void)
605*58e6ee5fSAndroid Build Coastguard Worker {
606*58e6ee5fSAndroid Build Coastguard Worker 	struct buffer_instance *instance;
607*58e6ee5fSAndroid Build Coastguard Worker 	int i = 0;
608*58e6ee5fSAndroid Build Coastguard Worker 
609*58e6ee5fSAndroid Build Coastguard Worker 	if (!recorder_threads || !pids)
610*58e6ee5fSAndroid Build Coastguard Worker 		return;
611*58e6ee5fSAndroid Build Coastguard Worker 
612*58e6ee5fSAndroid Build Coastguard Worker 	for_all_instances(instance)
613*58e6ee5fSAndroid Build Coastguard Worker 		i = kill_thread_instance(i, instance);
614*58e6ee5fSAndroid Build Coastguard Worker }
615*58e6ee5fSAndroid Build Coastguard Worker 
die(const char * fmt,...)616*58e6ee5fSAndroid Build Coastguard Worker void die(const char *fmt, ...)
617*58e6ee5fSAndroid Build Coastguard Worker {
618*58e6ee5fSAndroid Build Coastguard Worker 	va_list ap;
619*58e6ee5fSAndroid Build Coastguard Worker 	int ret = errno;
620*58e6ee5fSAndroid Build Coastguard Worker 
621*58e6ee5fSAndroid Build Coastguard Worker 	if (errno)
622*58e6ee5fSAndroid Build Coastguard Worker 		perror("trace-cmd");
623*58e6ee5fSAndroid Build Coastguard Worker 	else
624*58e6ee5fSAndroid Build Coastguard Worker 		ret = -1;
625*58e6ee5fSAndroid Build Coastguard Worker 
626*58e6ee5fSAndroid Build Coastguard Worker 	kill_threads();
627*58e6ee5fSAndroid Build Coastguard Worker 	va_start(ap, fmt);
628*58e6ee5fSAndroid Build Coastguard Worker 	fprintf(stderr, "  ");
629*58e6ee5fSAndroid Build Coastguard Worker 	vfprintf(stderr, fmt, ap);
630*58e6ee5fSAndroid Build Coastguard Worker 	va_end(ap);
631*58e6ee5fSAndroid Build Coastguard Worker 
632*58e6ee5fSAndroid Build Coastguard Worker 	fprintf(stderr, "\n");
633*58e6ee5fSAndroid Build Coastguard Worker 	exit(ret);
634*58e6ee5fSAndroid Build Coastguard Worker }
635*58e6ee5fSAndroid Build Coastguard Worker 
delete_thread_instance(int start,struct buffer_instance * instance)636*58e6ee5fSAndroid Build Coastguard Worker static int delete_thread_instance(int start, struct buffer_instance *instance)
637*58e6ee5fSAndroid Build Coastguard Worker {
638*58e6ee5fSAndroid Build Coastguard Worker 	int n = start;
639*58e6ee5fSAndroid Build Coastguard Worker 	int i;
640*58e6ee5fSAndroid Build Coastguard Worker 
641*58e6ee5fSAndroid Build Coastguard Worker 	for (i = 0; i < instance->cpu_count; i++) {
642*58e6ee5fSAndroid Build Coastguard Worker 		if (pids) {
643*58e6ee5fSAndroid Build Coastguard Worker 			if (pids[n].pid) {
644*58e6ee5fSAndroid Build Coastguard Worker 				delete_temp_file(instance, i);
645*58e6ee5fSAndroid Build Coastguard Worker 				if (pids[n].pid < 0)
646*58e6ee5fSAndroid Build Coastguard Worker 					pids[n].pid = 0;
647*58e6ee5fSAndroid Build Coastguard Worker 			}
648*58e6ee5fSAndroid Build Coastguard Worker 			n++;
649*58e6ee5fSAndroid Build Coastguard Worker 		} else
650*58e6ee5fSAndroid Build Coastguard Worker 			/* Extract does not allocate pids */
651*58e6ee5fSAndroid Build Coastguard Worker 			delete_temp_file(instance, i);
652*58e6ee5fSAndroid Build Coastguard Worker 	}
653*58e6ee5fSAndroid Build Coastguard Worker 	return n;
654*58e6ee5fSAndroid Build Coastguard Worker }
655*58e6ee5fSAndroid Build Coastguard Worker 
delete_thread_data(void)656*58e6ee5fSAndroid Build Coastguard Worker static void delete_thread_data(void)
657*58e6ee5fSAndroid Build Coastguard Worker {
658*58e6ee5fSAndroid Build Coastguard Worker 	struct buffer_instance *instance;
659*58e6ee5fSAndroid Build Coastguard Worker 	int i = 0;
660*58e6ee5fSAndroid Build Coastguard Worker 
661*58e6ee5fSAndroid Build Coastguard Worker 	for_all_instances(instance)
662*58e6ee5fSAndroid Build Coastguard Worker 		i = delete_thread_instance(i, instance);
663*58e6ee5fSAndroid Build Coastguard Worker 	/*
664*58e6ee5fSAndroid Build Coastguard Worker 	 * Top instance temp files are still created even if it
665*58e6ee5fSAndroid Build Coastguard Worker 	 * isn't used.
666*58e6ee5fSAndroid Build Coastguard Worker 	 */
667*58e6ee5fSAndroid Build Coastguard Worker 	if (no_top_instance()) {
668*58e6ee5fSAndroid Build Coastguard Worker 		for (i = 0; i < local_cpu_count; i++)
669*58e6ee5fSAndroid Build Coastguard Worker 			delete_temp_file(&top_instance, i);
670*58e6ee5fSAndroid Build Coastguard Worker 	}
671*58e6ee5fSAndroid Build Coastguard Worker }
672*58e6ee5fSAndroid Build Coastguard Worker 
673*58e6ee5fSAndroid Build Coastguard Worker static void
add_tsc2nsec(struct tracecmd_output * handle,struct tsc_nsec * tsc2nsec)674*58e6ee5fSAndroid Build Coastguard Worker add_tsc2nsec(struct tracecmd_output *handle, struct tsc_nsec *tsc2nsec)
675*58e6ee5fSAndroid Build Coastguard Worker {
676*58e6ee5fSAndroid Build Coastguard Worker 	/* multiplier, shift, offset */
677*58e6ee5fSAndroid Build Coastguard Worker 	struct iovec vector[3];
678*58e6ee5fSAndroid Build Coastguard Worker 
679*58e6ee5fSAndroid Build Coastguard Worker 	vector[0].iov_len = 4;
680*58e6ee5fSAndroid Build Coastguard Worker 	vector[0].iov_base = &tsc2nsec->mult;
681*58e6ee5fSAndroid Build Coastguard Worker 	vector[1].iov_len = 4;
682*58e6ee5fSAndroid Build Coastguard Worker 	vector[1].iov_base = &tsc2nsec->shift;
683*58e6ee5fSAndroid Build Coastguard Worker 	vector[2].iov_len = 8;
684*58e6ee5fSAndroid Build Coastguard Worker 	vector[2].iov_base = &tsc2nsec->offset;
685*58e6ee5fSAndroid Build Coastguard Worker 
686*58e6ee5fSAndroid Build Coastguard Worker 	tracecmd_add_option_v(handle, TRACECMD_OPTION_TSC2NSEC, vector, 3);
687*58e6ee5fSAndroid Build Coastguard Worker }
688*58e6ee5fSAndroid Build Coastguard Worker 
host_tsync_complete(struct common_record_context * ctx,struct buffer_instance * instance)689*58e6ee5fSAndroid Build Coastguard Worker static void host_tsync_complete(struct common_record_context *ctx,
690*58e6ee5fSAndroid Build Coastguard Worker 				struct buffer_instance *instance)
691*58e6ee5fSAndroid Build Coastguard Worker {
692*58e6ee5fSAndroid Build Coastguard Worker 	struct tracecmd_output *handle = NULL;
693*58e6ee5fSAndroid Build Coastguard Worker 	int fd = -1;
694*58e6ee5fSAndroid Build Coastguard Worker 	int ret;
695*58e6ee5fSAndroid Build Coastguard Worker 
696*58e6ee5fSAndroid Build Coastguard Worker 	ret = tracecmd_tsync_with_guest_stop(instance->tsync);
697*58e6ee5fSAndroid Build Coastguard Worker 	if (!ret) {
698*58e6ee5fSAndroid Build Coastguard Worker 		fd = open(instance->output_file, O_RDWR);
699*58e6ee5fSAndroid Build Coastguard Worker 		if (fd < 0)
700*58e6ee5fSAndroid Build Coastguard Worker 			die("error opening %s", instance->output_file);
701*58e6ee5fSAndroid Build Coastguard Worker 		handle = tracecmd_get_output_handle_fd(fd);
702*58e6ee5fSAndroid Build Coastguard Worker 		if (!handle)
703*58e6ee5fSAndroid Build Coastguard Worker 			die("cannot create output handle");
704*58e6ee5fSAndroid Build Coastguard Worker 
705*58e6ee5fSAndroid Build Coastguard Worker 		if (ctx->tsc2nsec.mult)
706*58e6ee5fSAndroid Build Coastguard Worker 			add_tsc2nsec(handle, &ctx->tsc2nsec);
707*58e6ee5fSAndroid Build Coastguard Worker 
708*58e6ee5fSAndroid Build Coastguard Worker 		tracecmd_write_guest_time_shift(handle, instance->tsync);
709*58e6ee5fSAndroid Build Coastguard Worker 		tracecmd_append_options(handle);
710*58e6ee5fSAndroid Build Coastguard Worker 		tracecmd_output_close(handle);
711*58e6ee5fSAndroid Build Coastguard Worker 	}
712*58e6ee5fSAndroid Build Coastguard Worker 
713*58e6ee5fSAndroid Build Coastguard Worker 	tracecmd_tsync_free(instance->tsync);
714*58e6ee5fSAndroid Build Coastguard Worker 	instance->tsync = NULL;
715*58e6ee5fSAndroid Build Coastguard Worker }
716*58e6ee5fSAndroid Build Coastguard Worker 
tell_guests_to_stop(struct common_record_context * ctx)717*58e6ee5fSAndroid Build Coastguard Worker static void tell_guests_to_stop(struct common_record_context *ctx)
718*58e6ee5fSAndroid Build Coastguard Worker {
719*58e6ee5fSAndroid Build Coastguard Worker 	struct buffer_instance *instance;
720*58e6ee5fSAndroid Build Coastguard Worker 
721*58e6ee5fSAndroid Build Coastguard Worker 	/* Send close message to guests */
722*58e6ee5fSAndroid Build Coastguard Worker 	for_all_instances(instance) {
723*58e6ee5fSAndroid Build Coastguard Worker 		if (is_guest(instance))
724*58e6ee5fSAndroid Build Coastguard Worker 			tracecmd_msg_send_close_msg(instance->msg_handle);
725*58e6ee5fSAndroid Build Coastguard Worker 	}
726*58e6ee5fSAndroid Build Coastguard Worker 
727*58e6ee5fSAndroid Build Coastguard Worker 	for_all_instances(instance) {
728*58e6ee5fSAndroid Build Coastguard Worker 		if (is_guest(instance))
729*58e6ee5fSAndroid Build Coastguard Worker 			host_tsync_complete(ctx, instance);
730*58e6ee5fSAndroid Build Coastguard Worker 	}
731*58e6ee5fSAndroid Build Coastguard Worker 
732*58e6ee5fSAndroid Build Coastguard Worker 	/* Wait for guests to acknowledge */
733*58e6ee5fSAndroid Build Coastguard Worker 	for_all_instances(instance) {
734*58e6ee5fSAndroid Build Coastguard Worker 		if (is_guest(instance)) {
735*58e6ee5fSAndroid Build Coastguard Worker 			tracecmd_msg_wait_close_resp(instance->msg_handle);
736*58e6ee5fSAndroid Build Coastguard Worker 			tracecmd_msg_handle_close(instance->msg_handle);
737*58e6ee5fSAndroid Build Coastguard Worker 		}
738*58e6ee5fSAndroid Build Coastguard Worker 	}
739*58e6ee5fSAndroid Build Coastguard Worker }
740*58e6ee5fSAndroid Build Coastguard Worker 
stop_threads(enum trace_type type)741*58e6ee5fSAndroid Build Coastguard Worker static void stop_threads(enum trace_type type)
742*58e6ee5fSAndroid Build Coastguard Worker {
743*58e6ee5fSAndroid Build Coastguard Worker 	int ret;
744*58e6ee5fSAndroid Build Coastguard Worker 	int i;
745*58e6ee5fSAndroid Build Coastguard Worker 
746*58e6ee5fSAndroid Build Coastguard Worker 	if (!recorder_threads)
747*58e6ee5fSAndroid Build Coastguard Worker 		return;
748*58e6ee5fSAndroid Build Coastguard Worker 
749*58e6ee5fSAndroid Build Coastguard Worker 	/* Tell all threads to finish up */
750*58e6ee5fSAndroid Build Coastguard Worker 	for (i = 0; i < recorder_threads; i++) {
751*58e6ee5fSAndroid Build Coastguard Worker 		if (pids[i].pid > 0) {
752*58e6ee5fSAndroid Build Coastguard Worker 			kill(pids[i].pid, SIGUSR1);
753*58e6ee5fSAndroid Build Coastguard Worker 		}
754*58e6ee5fSAndroid Build Coastguard Worker 	}
755*58e6ee5fSAndroid Build Coastguard Worker 
756*58e6ee5fSAndroid Build Coastguard Worker 	/* Flush out the pipes */
757*58e6ee5fSAndroid Build Coastguard Worker 	if (type & TRACE_TYPE_STREAM) {
758*58e6ee5fSAndroid Build Coastguard Worker 		do {
759*58e6ee5fSAndroid Build Coastguard Worker 			ret = trace_stream_read(pids, recorder_threads, NULL);
760*58e6ee5fSAndroid Build Coastguard Worker 		} while (ret > 0);
761*58e6ee5fSAndroid Build Coastguard Worker 	}
762*58e6ee5fSAndroid Build Coastguard Worker }
763*58e6ee5fSAndroid Build Coastguard Worker 
wait_threads()764*58e6ee5fSAndroid Build Coastguard Worker static void wait_threads()
765*58e6ee5fSAndroid Build Coastguard Worker {
766*58e6ee5fSAndroid Build Coastguard Worker 	int i;
767*58e6ee5fSAndroid Build Coastguard Worker 
768*58e6ee5fSAndroid Build Coastguard Worker 	for (i = 0; i < recorder_threads; i++) {
769*58e6ee5fSAndroid Build Coastguard Worker 		if (pids[i].pid > 0) {
770*58e6ee5fSAndroid Build Coastguard Worker 			waitpid(pids[i].pid, NULL, 0);
771*58e6ee5fSAndroid Build Coastguard Worker 			pids[i].pid = -1;
772*58e6ee5fSAndroid Build Coastguard Worker 		}
773*58e6ee5fSAndroid Build Coastguard Worker 	}
774*58e6ee5fSAndroid Build Coastguard Worker }
775*58e6ee5fSAndroid Build Coastguard Worker 
776*58e6ee5fSAndroid Build Coastguard Worker static int create_recorder(struct buffer_instance *instance, int cpu,
777*58e6ee5fSAndroid Build Coastguard Worker 			   enum trace_type type, int *brass);
778*58e6ee5fSAndroid Build Coastguard Worker 
flush_threads(void)779*58e6ee5fSAndroid Build Coastguard Worker static void flush_threads(void)
780*58e6ee5fSAndroid Build Coastguard Worker {
781*58e6ee5fSAndroid Build Coastguard Worker 	struct buffer_instance *instance;
782*58e6ee5fSAndroid Build Coastguard Worker 	long ret;
783*58e6ee5fSAndroid Build Coastguard Worker 	int i;
784*58e6ee5fSAndroid Build Coastguard Worker 
785*58e6ee5fSAndroid Build Coastguard Worker 	for_all_instances(instance) {
786*58e6ee5fSAndroid Build Coastguard Worker 		for (i = 0; i < instance->cpu_count; i++) {
787*58e6ee5fSAndroid Build Coastguard Worker 			/* Extract doesn't support sub buffers yet */
788*58e6ee5fSAndroid Build Coastguard Worker 			ret = create_recorder(instance, i, TRACE_TYPE_EXTRACT, NULL);
789*58e6ee5fSAndroid Build Coastguard Worker 			if (ret < 0)
790*58e6ee5fSAndroid Build Coastguard Worker 				die("error reading ring buffer");
791*58e6ee5fSAndroid Build Coastguard Worker 		}
792*58e6ee5fSAndroid Build Coastguard Worker 	}
793*58e6ee5fSAndroid Build Coastguard Worker }
794*58e6ee5fSAndroid Build Coastguard Worker 
set_ftrace_enable(const char * path,int set)795*58e6ee5fSAndroid Build Coastguard Worker static int set_ftrace_enable(const char *path, int set)
796*58e6ee5fSAndroid Build Coastguard Worker {
797*58e6ee5fSAndroid Build Coastguard Worker 	struct stat st;
798*58e6ee5fSAndroid Build Coastguard Worker 	int fd;
799*58e6ee5fSAndroid Build Coastguard Worker 	char *val = set ? "1" : "0";
800*58e6ee5fSAndroid Build Coastguard Worker 	int ret;
801*58e6ee5fSAndroid Build Coastguard Worker 
802*58e6ee5fSAndroid Build Coastguard Worker 	/* if ftace_enable does not exist, simply ignore it */
803*58e6ee5fSAndroid Build Coastguard Worker 	fd = stat(path, &st);
804*58e6ee5fSAndroid Build Coastguard Worker 	if (fd < 0)
805*58e6ee5fSAndroid Build Coastguard Worker 		return -ENODEV;
806*58e6ee5fSAndroid Build Coastguard Worker 
807*58e6ee5fSAndroid Build Coastguard Worker 	reset_save_file(path, RESET_DEFAULT_PRIO);
808*58e6ee5fSAndroid Build Coastguard Worker 
809*58e6ee5fSAndroid Build Coastguard Worker 	ret = -1;
810*58e6ee5fSAndroid Build Coastguard Worker 	fd = open(path, O_WRONLY);
811*58e6ee5fSAndroid Build Coastguard Worker 	if (fd < 0)
812*58e6ee5fSAndroid Build Coastguard Worker 		goto out;
813*58e6ee5fSAndroid Build Coastguard Worker 
814*58e6ee5fSAndroid Build Coastguard Worker 	/* Now set or clear the function option */
815*58e6ee5fSAndroid Build Coastguard Worker 	ret = write(fd, val, 1);
816*58e6ee5fSAndroid Build Coastguard Worker 	close(fd);
817*58e6ee5fSAndroid Build Coastguard Worker 
818*58e6ee5fSAndroid Build Coastguard Worker  out:
819*58e6ee5fSAndroid Build Coastguard Worker 	return ret < 0 ? ret : 0;
820*58e6ee5fSAndroid Build Coastguard Worker }
821*58e6ee5fSAndroid Build Coastguard Worker 
set_ftrace_proc(int set)822*58e6ee5fSAndroid Build Coastguard Worker static int set_ftrace_proc(int set)
823*58e6ee5fSAndroid Build Coastguard Worker {
824*58e6ee5fSAndroid Build Coastguard Worker 	const char *path = "/proc/sys/kernel/ftrace_enabled";
825*58e6ee5fSAndroid Build Coastguard Worker 	int ret;
826*58e6ee5fSAndroid Build Coastguard Worker 
827*58e6ee5fSAndroid Build Coastguard Worker 	ret = set_ftrace_enable(path, set);
828*58e6ee5fSAndroid Build Coastguard Worker 	if (ret == -1)
829*58e6ee5fSAndroid Build Coastguard Worker 		die ("Can't %s ftrace", set ? "enable" : "disable");
830*58e6ee5fSAndroid Build Coastguard Worker 	return ret;
831*58e6ee5fSAndroid Build Coastguard Worker }
832*58e6ee5fSAndroid Build Coastguard Worker 
set_ftrace(struct buffer_instance * instance,int set,int use_proc)833*58e6ee5fSAndroid Build Coastguard Worker static int set_ftrace(struct buffer_instance *instance, int set, int use_proc)
834*58e6ee5fSAndroid Build Coastguard Worker {
835*58e6ee5fSAndroid Build Coastguard Worker 	char *path;
836*58e6ee5fSAndroid Build Coastguard Worker 	int ret;
837*58e6ee5fSAndroid Build Coastguard Worker 
838*58e6ee5fSAndroid Build Coastguard Worker 	path = tracefs_instance_get_file(instance->tracefs, "options/function-trace");
839*58e6ee5fSAndroid Build Coastguard Worker 	if (!path)
840*58e6ee5fSAndroid Build Coastguard Worker 		return -1;
841*58e6ee5fSAndroid Build Coastguard Worker 	ret = set_ftrace_enable(path, set);
842*58e6ee5fSAndroid Build Coastguard Worker 	tracefs_put_tracing_file(path);
843*58e6ee5fSAndroid Build Coastguard Worker 
844*58e6ee5fSAndroid Build Coastguard Worker 	/* Always enable ftrace_enable proc file when set is true */
845*58e6ee5fSAndroid Build Coastguard Worker 	if (ret < 0 || set || use_proc)
846*58e6ee5fSAndroid Build Coastguard Worker 		ret = set_ftrace_proc(set);
847*58e6ee5fSAndroid Build Coastguard Worker 
848*58e6ee5fSAndroid Build Coastguard Worker 	return ret;
849*58e6ee5fSAndroid Build Coastguard Worker }
850*58e6ee5fSAndroid Build Coastguard Worker 
write_file(const char * file,const char * str)851*58e6ee5fSAndroid Build Coastguard Worker static int write_file(const char *file, const char *str)
852*58e6ee5fSAndroid Build Coastguard Worker {
853*58e6ee5fSAndroid Build Coastguard Worker 	int ret;
854*58e6ee5fSAndroid Build Coastguard Worker 	int fd;
855*58e6ee5fSAndroid Build Coastguard Worker 
856*58e6ee5fSAndroid Build Coastguard Worker 	fd = open(file, O_WRONLY | O_TRUNC);
857*58e6ee5fSAndroid Build Coastguard Worker 	if (fd < 0)
858*58e6ee5fSAndroid Build Coastguard Worker 		die("opening to '%s'", file);
859*58e6ee5fSAndroid Build Coastguard Worker 	ret = write(fd, str, strlen(str));
860*58e6ee5fSAndroid Build Coastguard Worker 	close(fd);
861*58e6ee5fSAndroid Build Coastguard Worker 	return ret;
862*58e6ee5fSAndroid Build Coastguard Worker }
863*58e6ee5fSAndroid Build Coastguard Worker 
__clear_trace(struct buffer_instance * instance)864*58e6ee5fSAndroid Build Coastguard Worker static void __clear_trace(struct buffer_instance *instance)
865*58e6ee5fSAndroid Build Coastguard Worker {
866*58e6ee5fSAndroid Build Coastguard Worker 	FILE *fp;
867*58e6ee5fSAndroid Build Coastguard Worker 	char *path;
868*58e6ee5fSAndroid Build Coastguard Worker 
869*58e6ee5fSAndroid Build Coastguard Worker 	if (is_guest(instance))
870*58e6ee5fSAndroid Build Coastguard Worker 		return;
871*58e6ee5fSAndroid Build Coastguard Worker 
872*58e6ee5fSAndroid Build Coastguard Worker 	/* reset the trace */
873*58e6ee5fSAndroid Build Coastguard Worker 	path = tracefs_instance_get_file(instance->tracefs, "trace");
874*58e6ee5fSAndroid Build Coastguard Worker 	fp = fopen(path, "w");
875*58e6ee5fSAndroid Build Coastguard Worker 	if (!fp)
876*58e6ee5fSAndroid Build Coastguard Worker 		die("writing to '%s'", path);
877*58e6ee5fSAndroid Build Coastguard Worker 	tracefs_put_tracing_file(path);
878*58e6ee5fSAndroid Build Coastguard Worker 	fwrite("0", 1, 1, fp);
879*58e6ee5fSAndroid Build Coastguard Worker 	fclose(fp);
880*58e6ee5fSAndroid Build Coastguard Worker }
881*58e6ee5fSAndroid Build Coastguard Worker 
clear_trace_instances(void)882*58e6ee5fSAndroid Build Coastguard Worker static void clear_trace_instances(void)
883*58e6ee5fSAndroid Build Coastguard Worker {
884*58e6ee5fSAndroid Build Coastguard Worker 	struct buffer_instance *instance;
885*58e6ee5fSAndroid Build Coastguard Worker 
886*58e6ee5fSAndroid Build Coastguard Worker 	for_all_instances(instance)
887*58e6ee5fSAndroid Build Coastguard Worker 		__clear_trace(instance);
888*58e6ee5fSAndroid Build Coastguard Worker }
889*58e6ee5fSAndroid Build Coastguard Worker 
reset_max_latency(struct buffer_instance * instance)890*58e6ee5fSAndroid Build Coastguard Worker static void reset_max_latency(struct buffer_instance *instance)
891*58e6ee5fSAndroid Build Coastguard Worker {
892*58e6ee5fSAndroid Build Coastguard Worker 	tracefs_instance_file_write(instance->tracefs,
893*58e6ee5fSAndroid Build Coastguard Worker 				    "tracing_max_latency", "0");
894*58e6ee5fSAndroid Build Coastguard Worker }
895*58e6ee5fSAndroid Build Coastguard Worker 
add_filter_pid(struct buffer_instance * instance,int pid,int exclude)896*58e6ee5fSAndroid Build Coastguard Worker static int add_filter_pid(struct buffer_instance *instance, int pid, int exclude)
897*58e6ee5fSAndroid Build Coastguard Worker {
898*58e6ee5fSAndroid Build Coastguard Worker 	struct filter_pids *p;
899*58e6ee5fSAndroid Build Coastguard Worker 	char buf[100];
900*58e6ee5fSAndroid Build Coastguard Worker 
901*58e6ee5fSAndroid Build Coastguard Worker 	for (p = instance->filter_pids; p; p = p->next) {
902*58e6ee5fSAndroid Build Coastguard Worker 		if (p->pid == pid) {
903*58e6ee5fSAndroid Build Coastguard Worker 			p->exclude = exclude;
904*58e6ee5fSAndroid Build Coastguard Worker 			return 0;
905*58e6ee5fSAndroid Build Coastguard Worker 		}
906*58e6ee5fSAndroid Build Coastguard Worker 	}
907*58e6ee5fSAndroid Build Coastguard Worker 
908*58e6ee5fSAndroid Build Coastguard Worker 	p = malloc(sizeof(*p));
909*58e6ee5fSAndroid Build Coastguard Worker 	if (!p)
910*58e6ee5fSAndroid Build Coastguard Worker 		die("Failed to allocate pid filter");
911*58e6ee5fSAndroid Build Coastguard Worker 	p->next = instance->filter_pids;
912*58e6ee5fSAndroid Build Coastguard Worker 	p->exclude = exclude;
913*58e6ee5fSAndroid Build Coastguard Worker 	p->pid = pid;
914*58e6ee5fSAndroid Build Coastguard Worker 	instance->filter_pids = p;
915*58e6ee5fSAndroid Build Coastguard Worker 	instance->nr_filter_pids++;
916*58e6ee5fSAndroid Build Coastguard Worker 
917*58e6ee5fSAndroid Build Coastguard Worker 	instance->len_filter_pids += sprintf(buf, "%d", pid);
918*58e6ee5fSAndroid Build Coastguard Worker 
919*58e6ee5fSAndroid Build Coastguard Worker 	return 1;
920*58e6ee5fSAndroid Build Coastguard Worker }
921*58e6ee5fSAndroid Build Coastguard Worker 
add_filter_pid_all(int pid,int exclude)922*58e6ee5fSAndroid Build Coastguard Worker static void add_filter_pid_all(int pid, int exclude)
923*58e6ee5fSAndroid Build Coastguard Worker {
924*58e6ee5fSAndroid Build Coastguard Worker 	struct buffer_instance *instance;
925*58e6ee5fSAndroid Build Coastguard Worker 
926*58e6ee5fSAndroid Build Coastguard Worker 	for_all_instances(instance)
927*58e6ee5fSAndroid Build Coastguard Worker 		add_filter_pid(instance, pid, exclude);
928*58e6ee5fSAndroid Build Coastguard Worker }
929*58e6ee5fSAndroid Build Coastguard Worker 
reset_save_ftrace_pid(struct buffer_instance * instance)930*58e6ee5fSAndroid Build Coastguard Worker static void reset_save_ftrace_pid(struct buffer_instance *instance)
931*58e6ee5fSAndroid Build Coastguard Worker {
932*58e6ee5fSAndroid Build Coastguard Worker 	static char *path;
933*58e6ee5fSAndroid Build Coastguard Worker 
934*58e6ee5fSAndroid Build Coastguard Worker 	if (!tracefs_file_exists(instance->tracefs, "set_ftrace_pid"))
935*58e6ee5fSAndroid Build Coastguard Worker 		return;
936*58e6ee5fSAndroid Build Coastguard Worker 
937*58e6ee5fSAndroid Build Coastguard Worker 	path = tracefs_instance_get_file(instance->tracefs, "set_ftrace_pid");
938*58e6ee5fSAndroid Build Coastguard Worker 	if (!path)
939*58e6ee5fSAndroid Build Coastguard Worker 		return;
940*58e6ee5fSAndroid Build Coastguard Worker 
941*58e6ee5fSAndroid Build Coastguard Worker 	reset_save_file_cond(path, RESET_DEFAULT_PRIO, "no pid", "");
942*58e6ee5fSAndroid Build Coastguard Worker 
943*58e6ee5fSAndroid Build Coastguard Worker 	tracefs_put_tracing_file(path);
944*58e6ee5fSAndroid Build Coastguard Worker }
945*58e6ee5fSAndroid Build Coastguard Worker 
update_ftrace_pid(struct buffer_instance * instance,const char * pid,int reset)946*58e6ee5fSAndroid Build Coastguard Worker static void update_ftrace_pid(struct buffer_instance *instance,
947*58e6ee5fSAndroid Build Coastguard Worker 			      const char *pid, int reset)
948*58e6ee5fSAndroid Build Coastguard Worker {
949*58e6ee5fSAndroid Build Coastguard Worker 	int fd = -1;
950*58e6ee5fSAndroid Build Coastguard Worker 	char *path;
951*58e6ee5fSAndroid Build Coastguard Worker 	int ret;
952*58e6ee5fSAndroid Build Coastguard Worker 
953*58e6ee5fSAndroid Build Coastguard Worker 	if (!tracefs_file_exists(instance->tracefs, "set_ftrace_pid"))
954*58e6ee5fSAndroid Build Coastguard Worker 		return;
955*58e6ee5fSAndroid Build Coastguard Worker 
956*58e6ee5fSAndroid Build Coastguard Worker 	path = tracefs_instance_get_file(instance->tracefs, "set_ftrace_pid");
957*58e6ee5fSAndroid Build Coastguard Worker 	if (!path)
958*58e6ee5fSAndroid Build Coastguard Worker 		return;
959*58e6ee5fSAndroid Build Coastguard Worker 
960*58e6ee5fSAndroid Build Coastguard Worker 	fd = open(path, O_WRONLY | O_CLOEXEC | (reset ? O_TRUNC : 0));
961*58e6ee5fSAndroid Build Coastguard Worker 	tracefs_put_tracing_file(path);
962*58e6ee5fSAndroid Build Coastguard Worker 	if (fd < 0)
963*58e6ee5fSAndroid Build Coastguard Worker 		return;
964*58e6ee5fSAndroid Build Coastguard Worker 
965*58e6ee5fSAndroid Build Coastguard Worker 	ret = write(fd, pid, strlen(pid));
966*58e6ee5fSAndroid Build Coastguard Worker 
967*58e6ee5fSAndroid Build Coastguard Worker 	/*
968*58e6ee5fSAndroid Build Coastguard Worker 	 * Older kernels required "-1" to disable pid
969*58e6ee5fSAndroid Build Coastguard Worker 	 */
970*58e6ee5fSAndroid Build Coastguard Worker 	if (ret < 0 && !strlen(pid))
971*58e6ee5fSAndroid Build Coastguard Worker 		ret = write(fd, "-1", 2);
972*58e6ee5fSAndroid Build Coastguard Worker 
973*58e6ee5fSAndroid Build Coastguard Worker 	if (ret < 0)
974*58e6ee5fSAndroid Build Coastguard Worker 		die("error writing to %s", path);
975*58e6ee5fSAndroid Build Coastguard Worker 	/* add whitespace in case another pid is written */
976*58e6ee5fSAndroid Build Coastguard Worker 	write(fd, " ", 1);
977*58e6ee5fSAndroid Build Coastguard Worker 	close(fd);
978*58e6ee5fSAndroid Build Coastguard Worker }
979*58e6ee5fSAndroid Build Coastguard Worker 
update_ftrace_pids(int reset)980*58e6ee5fSAndroid Build Coastguard Worker static void update_ftrace_pids(int reset)
981*58e6ee5fSAndroid Build Coastguard Worker {
982*58e6ee5fSAndroid Build Coastguard Worker 	struct buffer_instance *instance;
983*58e6ee5fSAndroid Build Coastguard Worker 	struct filter_pids *pid;
984*58e6ee5fSAndroid Build Coastguard Worker 	static int first = 1;
985*58e6ee5fSAndroid Build Coastguard Worker 	char buf[100];
986*58e6ee5fSAndroid Build Coastguard Worker 	int rst;
987*58e6ee5fSAndroid Build Coastguard Worker 
988*58e6ee5fSAndroid Build Coastguard Worker 	for_all_instances(instance) {
989*58e6ee5fSAndroid Build Coastguard Worker 		if (first)
990*58e6ee5fSAndroid Build Coastguard Worker 			reset_save_ftrace_pid(instance);
991*58e6ee5fSAndroid Build Coastguard Worker 		rst = reset;
992*58e6ee5fSAndroid Build Coastguard Worker 		for (pid = instance->filter_pids; pid; pid = pid->next) {
993*58e6ee5fSAndroid Build Coastguard Worker 			if (pid->exclude)
994*58e6ee5fSAndroid Build Coastguard Worker 				continue;
995*58e6ee5fSAndroid Build Coastguard Worker 			snprintf(buf, 100, "%d ", pid->pid);
996*58e6ee5fSAndroid Build Coastguard Worker 			update_ftrace_pid(instance, buf, rst);
997*58e6ee5fSAndroid Build Coastguard Worker 			/* Only reset the first entry */
998*58e6ee5fSAndroid Build Coastguard Worker 			rst = 0;
999*58e6ee5fSAndroid Build Coastguard Worker 		}
1000*58e6ee5fSAndroid Build Coastguard Worker 	}
1001*58e6ee5fSAndroid Build Coastguard Worker 
1002*58e6ee5fSAndroid Build Coastguard Worker 	if (first)
1003*58e6ee5fSAndroid Build Coastguard Worker 		first = 0;
1004*58e6ee5fSAndroid Build Coastguard Worker }
1005*58e6ee5fSAndroid Build Coastguard Worker 
1006*58e6ee5fSAndroid Build Coastguard Worker static void update_event_filters(struct buffer_instance *instance);
1007*58e6ee5fSAndroid Build Coastguard Worker static void update_pid_event_filters(struct buffer_instance *instance);
1008*58e6ee5fSAndroid Build Coastguard Worker 
append_filter_pid_range(char ** filter,int * curr_len,const char * field,int start_pid,int end_pid,bool exclude)1009*58e6ee5fSAndroid Build Coastguard Worker static void append_filter_pid_range(char **filter, int *curr_len,
1010*58e6ee5fSAndroid Build Coastguard Worker 				    const char *field,
1011*58e6ee5fSAndroid Build Coastguard Worker 				    int start_pid, int end_pid, bool exclude)
1012*58e6ee5fSAndroid Build Coastguard Worker {
1013*58e6ee5fSAndroid Build Coastguard Worker 	const char *op = "", *op1, *op2, *op3;
1014*58e6ee5fSAndroid Build Coastguard Worker 	int len;
1015*58e6ee5fSAndroid Build Coastguard Worker 
1016*58e6ee5fSAndroid Build Coastguard Worker 	if (*filter && **filter)
1017*58e6ee5fSAndroid Build Coastguard Worker 		op = exclude ? "&&" : "||";
1018*58e6ee5fSAndroid Build Coastguard Worker 
1019*58e6ee5fSAndroid Build Coastguard Worker 	/* Handle thus case explicitly so that we get `pid==3` instead of
1020*58e6ee5fSAndroid Build Coastguard Worker 	 * `pid>=3&&pid<=3` for singleton ranges
1021*58e6ee5fSAndroid Build Coastguard Worker 	 */
1022*58e6ee5fSAndroid Build Coastguard Worker 	if (start_pid == end_pid) {
1023*58e6ee5fSAndroid Build Coastguard Worker #define FMT	"%s(%s%s%d)"
1024*58e6ee5fSAndroid Build Coastguard Worker 		len = snprintf(NULL, 0, FMT, op,
1025*58e6ee5fSAndroid Build Coastguard Worker 			       field, exclude ? "!=" : "==", start_pid);
1026*58e6ee5fSAndroid Build Coastguard Worker 		*filter = realloc(*filter, *curr_len + len + 1);
1027*58e6ee5fSAndroid Build Coastguard Worker 		if (!*filter)
1028*58e6ee5fSAndroid Build Coastguard Worker 			die("realloc");
1029*58e6ee5fSAndroid Build Coastguard Worker 
1030*58e6ee5fSAndroid Build Coastguard Worker 		len = snprintf(*filter + *curr_len, len + 1, FMT, op,
1031*58e6ee5fSAndroid Build Coastguard Worker 			       field, exclude ? "!=" : "==", start_pid);
1032*58e6ee5fSAndroid Build Coastguard Worker 		*curr_len += len;
1033*58e6ee5fSAndroid Build Coastguard Worker 
1034*58e6ee5fSAndroid Build Coastguard Worker 		return;
1035*58e6ee5fSAndroid Build Coastguard Worker #undef FMT
1036*58e6ee5fSAndroid Build Coastguard Worker 	}
1037*58e6ee5fSAndroid Build Coastguard Worker 
1038*58e6ee5fSAndroid Build Coastguard Worker 	if (exclude) {
1039*58e6ee5fSAndroid Build Coastguard Worker 		op1 = "<";
1040*58e6ee5fSAndroid Build Coastguard Worker 		op2 = "||";
1041*58e6ee5fSAndroid Build Coastguard Worker 		op3 = ">";
1042*58e6ee5fSAndroid Build Coastguard Worker 	} else {
1043*58e6ee5fSAndroid Build Coastguard Worker 		op1 = ">=";
1044*58e6ee5fSAndroid Build Coastguard Worker 		op2 = "&&";
1045*58e6ee5fSAndroid Build Coastguard Worker 		op3 = "<=";
1046*58e6ee5fSAndroid Build Coastguard Worker 	}
1047*58e6ee5fSAndroid Build Coastguard Worker 
1048*58e6ee5fSAndroid Build Coastguard Worker #define FMT	"%s(%s%s%d%s%s%s%d)"
1049*58e6ee5fSAndroid Build Coastguard Worker 	len = snprintf(NULL, 0, FMT, op,
1050*58e6ee5fSAndroid Build Coastguard Worker 		       field, op1, start_pid, op2,
1051*58e6ee5fSAndroid Build Coastguard Worker 		       field, op3, end_pid);
1052*58e6ee5fSAndroid Build Coastguard Worker 	*filter = realloc(*filter, *curr_len + len + 1);
1053*58e6ee5fSAndroid Build Coastguard Worker 	if (!*filter)
1054*58e6ee5fSAndroid Build Coastguard Worker 		die("realloc");
1055*58e6ee5fSAndroid Build Coastguard Worker 
1056*58e6ee5fSAndroid Build Coastguard Worker 	len = snprintf(*filter + *curr_len, len + 1, FMT, op,
1057*58e6ee5fSAndroid Build Coastguard Worker 		       field, op1, start_pid, op2,
1058*58e6ee5fSAndroid Build Coastguard Worker 		       field, op3, end_pid);
1059*58e6ee5fSAndroid Build Coastguard Worker 	*curr_len += len;
1060*58e6ee5fSAndroid Build Coastguard Worker }
1061*58e6ee5fSAndroid Build Coastguard Worker 
1062*58e6ee5fSAndroid Build Coastguard Worker /**
1063*58e6ee5fSAndroid Build Coastguard Worker  * make_pid_filter - create a filter string to all pids against @field
1064*58e6ee5fSAndroid Build Coastguard Worker  * @curr_filter: Append to a previous filter (may realloc). Can be NULL
1065*58e6ee5fSAndroid Build Coastguard Worker  * @field: The field to compare the pids against
1066*58e6ee5fSAndroid Build Coastguard Worker  *
1067*58e6ee5fSAndroid Build Coastguard Worker  * Creates a new string or appends to an existing one if @curr_filter
1068*58e6ee5fSAndroid Build Coastguard Worker  * is not NULL. The new string will contain a filter with all pids
1069*58e6ee5fSAndroid Build Coastguard Worker  * in pid_filter list with the format (@field == pid) || ..
1070*58e6ee5fSAndroid Build Coastguard Worker  * If @curr_filter is not NULL, it will add this string as:
1071*58e6ee5fSAndroid Build Coastguard Worker  *  (@curr_filter) && ((@field == pid) || ...)
1072*58e6ee5fSAndroid Build Coastguard Worker  */
make_pid_filter(struct buffer_instance * instance,char * curr_filter,const char * field)1073*58e6ee5fSAndroid Build Coastguard Worker static char *make_pid_filter(struct buffer_instance *instance,
1074*58e6ee5fSAndroid Build Coastguard Worker 			     char *curr_filter, const char *field)
1075*58e6ee5fSAndroid Build Coastguard Worker {
1076*58e6ee5fSAndroid Build Coastguard Worker 	int start_pid = -1, last_pid = -1;
1077*58e6ee5fSAndroid Build Coastguard Worker 	int last_exclude = -1;
1078*58e6ee5fSAndroid Build Coastguard Worker 	struct filter_pids *p;
1079*58e6ee5fSAndroid Build Coastguard Worker 	char *filter = NULL;
1080*58e6ee5fSAndroid Build Coastguard Worker 	int curr_len = 0;
1081*58e6ee5fSAndroid Build Coastguard Worker 
1082*58e6ee5fSAndroid Build Coastguard Worker 	/* Use the new method if possible */
1083*58e6ee5fSAndroid Build Coastguard Worker 	if (instance->have_set_event_pid)
1084*58e6ee5fSAndroid Build Coastguard Worker 		return NULL;
1085*58e6ee5fSAndroid Build Coastguard Worker 
1086*58e6ee5fSAndroid Build Coastguard Worker 	if (!instance->filter_pids)
1087*58e6ee5fSAndroid Build Coastguard Worker 		return curr_filter;
1088*58e6ee5fSAndroid Build Coastguard Worker 
1089*58e6ee5fSAndroid Build Coastguard Worker 	for (p = instance->filter_pids; p; p = p->next) {
1090*58e6ee5fSAndroid Build Coastguard Worker 		/*
1091*58e6ee5fSAndroid Build Coastguard Worker 		 * PIDs are inserted in `filter_pids` from the front and that's
1092*58e6ee5fSAndroid Build Coastguard Worker 		 * why we expect them in descending order here.
1093*58e6ee5fSAndroid Build Coastguard Worker 		 */
1094*58e6ee5fSAndroid Build Coastguard Worker 		if (p->pid == last_pid - 1 && p->exclude == last_exclude) {
1095*58e6ee5fSAndroid Build Coastguard Worker 			last_pid = p->pid;
1096*58e6ee5fSAndroid Build Coastguard Worker 			continue;
1097*58e6ee5fSAndroid Build Coastguard Worker 		}
1098*58e6ee5fSAndroid Build Coastguard Worker 
1099*58e6ee5fSAndroid Build Coastguard Worker 		if (start_pid != -1)
1100*58e6ee5fSAndroid Build Coastguard Worker 			append_filter_pid_range(&filter, &curr_len, field,
1101*58e6ee5fSAndroid Build Coastguard Worker 						last_pid, start_pid,
1102*58e6ee5fSAndroid Build Coastguard Worker 						last_exclude);
1103*58e6ee5fSAndroid Build Coastguard Worker 
1104*58e6ee5fSAndroid Build Coastguard Worker 		start_pid = last_pid = p->pid;
1105*58e6ee5fSAndroid Build Coastguard Worker 		last_exclude = p->exclude;
1106*58e6ee5fSAndroid Build Coastguard Worker 
1107*58e6ee5fSAndroid Build Coastguard Worker 	}
1108*58e6ee5fSAndroid Build Coastguard Worker 	append_filter_pid_range(&filter, &curr_len, field,
1109*58e6ee5fSAndroid Build Coastguard Worker 				last_pid, start_pid, last_exclude);
1110*58e6ee5fSAndroid Build Coastguard Worker 
1111*58e6ee5fSAndroid Build Coastguard Worker 	if (curr_filter) {
1112*58e6ee5fSAndroid Build Coastguard Worker 		char *save = filter;
1113*58e6ee5fSAndroid Build Coastguard Worker 		asprintf(&filter, "(%s)&&(%s)", curr_filter, filter);
1114*58e6ee5fSAndroid Build Coastguard Worker 		free(save);
1115*58e6ee5fSAndroid Build Coastguard Worker 	}
1116*58e6ee5fSAndroid Build Coastguard Worker 
1117*58e6ee5fSAndroid Build Coastguard Worker 	return filter;
1118*58e6ee5fSAndroid Build Coastguard Worker }
1119*58e6ee5fSAndroid Build Coastguard Worker 
1120*58e6ee5fSAndroid Build Coastguard Worker #define _STRINGIFY(x) #x
1121*58e6ee5fSAndroid Build Coastguard Worker #define STRINGIFY(x) _STRINGIFY(x)
1122*58e6ee5fSAndroid Build Coastguard Worker 
get_pid_addr_maps(struct buffer_instance * instance,int pid)1123*58e6ee5fSAndroid Build Coastguard Worker static int get_pid_addr_maps(struct buffer_instance *instance, int pid)
1124*58e6ee5fSAndroid Build Coastguard Worker {
1125*58e6ee5fSAndroid Build Coastguard Worker 	struct pid_addr_maps *maps = instance->pid_maps;
1126*58e6ee5fSAndroid Build Coastguard Worker 	struct tracecmd_proc_addr_map *map;
1127*58e6ee5fSAndroid Build Coastguard Worker 	unsigned long long begin, end;
1128*58e6ee5fSAndroid Build Coastguard Worker 	struct pid_addr_maps *m;
1129*58e6ee5fSAndroid Build Coastguard Worker 	char mapname[PATH_MAX+1];
1130*58e6ee5fSAndroid Build Coastguard Worker 	char fname[PATH_MAX+1];
1131*58e6ee5fSAndroid Build Coastguard Worker 	char buf[PATH_MAX+100];
1132*58e6ee5fSAndroid Build Coastguard Worker 	FILE *f;
1133*58e6ee5fSAndroid Build Coastguard Worker 	int ret;
1134*58e6ee5fSAndroid Build Coastguard Worker 	int res;
1135*58e6ee5fSAndroid Build Coastguard Worker 	int i;
1136*58e6ee5fSAndroid Build Coastguard Worker 
1137*58e6ee5fSAndroid Build Coastguard Worker 	sprintf(fname, "/proc/%d/exe", pid);
1138*58e6ee5fSAndroid Build Coastguard Worker 	ret = readlink(fname, mapname, PATH_MAX);
1139*58e6ee5fSAndroid Build Coastguard Worker 	if (ret >= PATH_MAX || ret < 0)
1140*58e6ee5fSAndroid Build Coastguard Worker 		return -ENOENT;
1141*58e6ee5fSAndroid Build Coastguard Worker 	mapname[ret] = 0;
1142*58e6ee5fSAndroid Build Coastguard Worker 
1143*58e6ee5fSAndroid Build Coastguard Worker 	sprintf(fname, "/proc/%d/maps", pid);
1144*58e6ee5fSAndroid Build Coastguard Worker 	f = fopen(fname, "r");
1145*58e6ee5fSAndroid Build Coastguard Worker 	if (!f)
1146*58e6ee5fSAndroid Build Coastguard Worker 		return -ENOENT;
1147*58e6ee5fSAndroid Build Coastguard Worker 
1148*58e6ee5fSAndroid Build Coastguard Worker 	while (maps) {
1149*58e6ee5fSAndroid Build Coastguard Worker 		if (pid == maps->pid)
1150*58e6ee5fSAndroid Build Coastguard Worker 			break;
1151*58e6ee5fSAndroid Build Coastguard Worker 		maps = maps->next;
1152*58e6ee5fSAndroid Build Coastguard Worker 	}
1153*58e6ee5fSAndroid Build Coastguard Worker 
1154*58e6ee5fSAndroid Build Coastguard Worker 	ret = -ENOMEM;
1155*58e6ee5fSAndroid Build Coastguard Worker 	if (!maps) {
1156*58e6ee5fSAndroid Build Coastguard Worker 		maps = calloc(1, sizeof(*maps));
1157*58e6ee5fSAndroid Build Coastguard Worker 		if (!maps)
1158*58e6ee5fSAndroid Build Coastguard Worker 			goto out_fail;
1159*58e6ee5fSAndroid Build Coastguard Worker 		maps->pid = pid;
1160*58e6ee5fSAndroid Build Coastguard Worker 		maps->next = instance->pid_maps;
1161*58e6ee5fSAndroid Build Coastguard Worker 		instance->pid_maps = maps;
1162*58e6ee5fSAndroid Build Coastguard Worker 	} else {
1163*58e6ee5fSAndroid Build Coastguard Worker 		for (i = 0; i < maps->nr_lib_maps; i++)
1164*58e6ee5fSAndroid Build Coastguard Worker 			free(maps->lib_maps[i].lib_name);
1165*58e6ee5fSAndroid Build Coastguard Worker 		free(maps->lib_maps);
1166*58e6ee5fSAndroid Build Coastguard Worker 		maps->lib_maps = NULL;
1167*58e6ee5fSAndroid Build Coastguard Worker 		maps->nr_lib_maps = 0;
1168*58e6ee5fSAndroid Build Coastguard Worker 		free(maps->proc_name);
1169*58e6ee5fSAndroid Build Coastguard Worker 	}
1170*58e6ee5fSAndroid Build Coastguard Worker 
1171*58e6ee5fSAndroid Build Coastguard Worker 	maps->proc_name = strdup(mapname);
1172*58e6ee5fSAndroid Build Coastguard Worker 	if (!maps->proc_name)
1173*58e6ee5fSAndroid Build Coastguard Worker 		goto out;
1174*58e6ee5fSAndroid Build Coastguard Worker 
1175*58e6ee5fSAndroid Build Coastguard Worker 	while (fgets(buf, sizeof(buf), f)) {
1176*58e6ee5fSAndroid Build Coastguard Worker 		mapname[0] = '\0';
1177*58e6ee5fSAndroid Build Coastguard Worker 		res = sscanf(buf, "%llx-%llx %*s %*x %*s %*d %"STRINGIFY(PATH_MAX)"s",
1178*58e6ee5fSAndroid Build Coastguard Worker 			     &begin, &end, mapname);
1179*58e6ee5fSAndroid Build Coastguard Worker 		if (res == 3 && mapname[0] != '\0') {
1180*58e6ee5fSAndroid Build Coastguard Worker 			map = realloc(maps->lib_maps,
1181*58e6ee5fSAndroid Build Coastguard Worker 				      (maps->nr_lib_maps + 1) * sizeof(*map));
1182*58e6ee5fSAndroid Build Coastguard Worker 			if (!map)
1183*58e6ee5fSAndroid Build Coastguard Worker 				goto out_fail;
1184*58e6ee5fSAndroid Build Coastguard Worker 			map[maps->nr_lib_maps].end = end;
1185*58e6ee5fSAndroid Build Coastguard Worker 			map[maps->nr_lib_maps].start = begin;
1186*58e6ee5fSAndroid Build Coastguard Worker 			map[maps->nr_lib_maps].lib_name = strdup(mapname);
1187*58e6ee5fSAndroid Build Coastguard Worker 			if (!map[maps->nr_lib_maps].lib_name)
1188*58e6ee5fSAndroid Build Coastguard Worker 				goto out_fail;
1189*58e6ee5fSAndroid Build Coastguard Worker 			maps->lib_maps = map;
1190*58e6ee5fSAndroid Build Coastguard Worker 			maps->nr_lib_maps++;
1191*58e6ee5fSAndroid Build Coastguard Worker 		}
1192*58e6ee5fSAndroid Build Coastguard Worker 	}
1193*58e6ee5fSAndroid Build Coastguard Worker out:
1194*58e6ee5fSAndroid Build Coastguard Worker 	fclose(f);
1195*58e6ee5fSAndroid Build Coastguard Worker 	return 0;
1196*58e6ee5fSAndroid Build Coastguard Worker 
1197*58e6ee5fSAndroid Build Coastguard Worker out_fail:
1198*58e6ee5fSAndroid Build Coastguard Worker 	fclose(f);
1199*58e6ee5fSAndroid Build Coastguard Worker 	if (maps) {
1200*58e6ee5fSAndroid Build Coastguard Worker 		for (i = 0; i < maps->nr_lib_maps; i++)
1201*58e6ee5fSAndroid Build Coastguard Worker 			free(maps->lib_maps[i].lib_name);
1202*58e6ee5fSAndroid Build Coastguard Worker 		if (instance->pid_maps != maps) {
1203*58e6ee5fSAndroid Build Coastguard Worker 			m = instance->pid_maps;
1204*58e6ee5fSAndroid Build Coastguard Worker 			while (m) {
1205*58e6ee5fSAndroid Build Coastguard Worker 				if (m->next == maps) {
1206*58e6ee5fSAndroid Build Coastguard Worker 					m->next = maps->next;
1207*58e6ee5fSAndroid Build Coastguard Worker 					break;
1208*58e6ee5fSAndroid Build Coastguard Worker 				}
1209*58e6ee5fSAndroid Build Coastguard Worker 				m = m->next;
1210*58e6ee5fSAndroid Build Coastguard Worker 			}
1211*58e6ee5fSAndroid Build Coastguard Worker 		} else
1212*58e6ee5fSAndroid Build Coastguard Worker 			instance->pid_maps = maps->next;
1213*58e6ee5fSAndroid Build Coastguard Worker 		free(maps->lib_maps);
1214*58e6ee5fSAndroid Build Coastguard Worker 		maps->lib_maps = NULL;
1215*58e6ee5fSAndroid Build Coastguard Worker 		maps->nr_lib_maps = 0;
1216*58e6ee5fSAndroid Build Coastguard Worker 		free(maps->proc_name);
1217*58e6ee5fSAndroid Build Coastguard Worker 		maps->proc_name = NULL;
1218*58e6ee5fSAndroid Build Coastguard Worker 		free(maps);
1219*58e6ee5fSAndroid Build Coastguard Worker 	}
1220*58e6ee5fSAndroid Build Coastguard Worker 	return ret;
1221*58e6ee5fSAndroid Build Coastguard Worker }
1222*58e6ee5fSAndroid Build Coastguard Worker 
get_filter_pid_maps(void)1223*58e6ee5fSAndroid Build Coastguard Worker static void get_filter_pid_maps(void)
1224*58e6ee5fSAndroid Build Coastguard Worker {
1225*58e6ee5fSAndroid Build Coastguard Worker 	struct buffer_instance *instance;
1226*58e6ee5fSAndroid Build Coastguard Worker 	struct filter_pids *p;
1227*58e6ee5fSAndroid Build Coastguard Worker 
1228*58e6ee5fSAndroid Build Coastguard Worker 	for_all_instances(instance) {
1229*58e6ee5fSAndroid Build Coastguard Worker 		if (!instance->get_procmap)
1230*58e6ee5fSAndroid Build Coastguard Worker 			continue;
1231*58e6ee5fSAndroid Build Coastguard Worker 		for (p = instance->filter_pids; p; p = p->next) {
1232*58e6ee5fSAndroid Build Coastguard Worker 			if (p->exclude)
1233*58e6ee5fSAndroid Build Coastguard Worker 				continue;
1234*58e6ee5fSAndroid Build Coastguard Worker 			get_pid_addr_maps(instance, p->pid);
1235*58e6ee5fSAndroid Build Coastguard Worker 		}
1236*58e6ee5fSAndroid Build Coastguard Worker 	}
1237*58e6ee5fSAndroid Build Coastguard Worker }
1238*58e6ee5fSAndroid Build Coastguard Worker 
update_task_filter(void)1239*58e6ee5fSAndroid Build Coastguard Worker static void update_task_filter(void)
1240*58e6ee5fSAndroid Build Coastguard Worker {
1241*58e6ee5fSAndroid Build Coastguard Worker 	struct buffer_instance *instance;
1242*58e6ee5fSAndroid Build Coastguard Worker 	int pid = getpid();
1243*58e6ee5fSAndroid Build Coastguard Worker 
1244*58e6ee5fSAndroid Build Coastguard Worker 	if (no_filter)
1245*58e6ee5fSAndroid Build Coastguard Worker 		return;
1246*58e6ee5fSAndroid Build Coastguard Worker 
1247*58e6ee5fSAndroid Build Coastguard Worker 	get_filter_pid_maps();
1248*58e6ee5fSAndroid Build Coastguard Worker 
1249*58e6ee5fSAndroid Build Coastguard Worker 	if (filter_task)
1250*58e6ee5fSAndroid Build Coastguard Worker 		add_filter_pid_all(pid, 0);
1251*58e6ee5fSAndroid Build Coastguard Worker 
1252*58e6ee5fSAndroid Build Coastguard Worker 	for_all_instances(instance) {
1253*58e6ee5fSAndroid Build Coastguard Worker 		if (!instance->filter_pids)
1254*58e6ee5fSAndroid Build Coastguard Worker 			continue;
1255*58e6ee5fSAndroid Build Coastguard Worker 		if (instance->common_pid_filter)
1256*58e6ee5fSAndroid Build Coastguard Worker 			free(instance->common_pid_filter);
1257*58e6ee5fSAndroid Build Coastguard Worker 		instance->common_pid_filter = make_pid_filter(instance, NULL,
1258*58e6ee5fSAndroid Build Coastguard Worker 							      "common_pid");
1259*58e6ee5fSAndroid Build Coastguard Worker 	}
1260*58e6ee5fSAndroid Build Coastguard Worker 	update_ftrace_pids(1);
1261*58e6ee5fSAndroid Build Coastguard Worker 	for_all_instances(instance)
1262*58e6ee5fSAndroid Build Coastguard Worker 		update_pid_event_filters(instance);
1263*58e6ee5fSAndroid Build Coastguard Worker }
1264*58e6ee5fSAndroid Build Coastguard Worker 
trace_waitpid(enum trace_type type,pid_t pid,int * status,int options)1265*58e6ee5fSAndroid Build Coastguard Worker static pid_t trace_waitpid(enum trace_type type, pid_t pid, int *status, int options)
1266*58e6ee5fSAndroid Build Coastguard Worker {
1267*58e6ee5fSAndroid Build Coastguard Worker 	struct timeval tv = { 1, 0 };
1268*58e6ee5fSAndroid Build Coastguard Worker 	int ret;
1269*58e6ee5fSAndroid Build Coastguard Worker 
1270*58e6ee5fSAndroid Build Coastguard Worker 	if (type & TRACE_TYPE_STREAM)
1271*58e6ee5fSAndroid Build Coastguard Worker 		options |= WNOHANG;
1272*58e6ee5fSAndroid Build Coastguard Worker 
1273*58e6ee5fSAndroid Build Coastguard Worker 	do {
1274*58e6ee5fSAndroid Build Coastguard Worker 		ret = waitpid(pid, status, options);
1275*58e6ee5fSAndroid Build Coastguard Worker 		if (ret != 0)
1276*58e6ee5fSAndroid Build Coastguard Worker 			return ret;
1277*58e6ee5fSAndroid Build Coastguard Worker 
1278*58e6ee5fSAndroid Build Coastguard Worker 		if (type & TRACE_TYPE_STREAM)
1279*58e6ee5fSAndroid Build Coastguard Worker 			trace_stream_read(pids, recorder_threads, &tv);
1280*58e6ee5fSAndroid Build Coastguard Worker 	} while (1);
1281*58e6ee5fSAndroid Build Coastguard Worker }
1282*58e6ee5fSAndroid Build Coastguard Worker 
1283*58e6ee5fSAndroid Build Coastguard Worker #ifndef __NR_pidfd_open
1284*58e6ee5fSAndroid Build Coastguard Worker #define __NR_pidfd_open 434
1285*58e6ee5fSAndroid Build Coastguard Worker #endif
1286*58e6ee5fSAndroid Build Coastguard Worker 
pidfd_open(pid_t pid,unsigned int flags)1287*58e6ee5fSAndroid Build Coastguard Worker static int pidfd_open(pid_t pid, unsigned int flags) {
1288*58e6ee5fSAndroid Build Coastguard Worker 	return syscall(__NR_pidfd_open, pid, flags);
1289*58e6ee5fSAndroid Build Coastguard Worker }
1290*58e6ee5fSAndroid Build Coastguard Worker 
trace_waitpidfd(id_t pidfd)1291*58e6ee5fSAndroid Build Coastguard Worker static int trace_waitpidfd(id_t pidfd) {
1292*58e6ee5fSAndroid Build Coastguard Worker 	struct pollfd pollfd;
1293*58e6ee5fSAndroid Build Coastguard Worker 
1294*58e6ee5fSAndroid Build Coastguard Worker 	pollfd.fd = pidfd;
1295*58e6ee5fSAndroid Build Coastguard Worker 	pollfd.events = POLLIN;
1296*58e6ee5fSAndroid Build Coastguard Worker 
1297*58e6ee5fSAndroid Build Coastguard Worker 	while (!finished) {
1298*58e6ee5fSAndroid Build Coastguard Worker 		int ret = poll(&pollfd, 1, -1);
1299*58e6ee5fSAndroid Build Coastguard Worker 		/* If waitid was interrupted, keep waiting */
1300*58e6ee5fSAndroid Build Coastguard Worker 		if (ret < 0 && errno == EINTR)
1301*58e6ee5fSAndroid Build Coastguard Worker 			continue;
1302*58e6ee5fSAndroid Build Coastguard Worker 		else if (ret < 0)
1303*58e6ee5fSAndroid Build Coastguard Worker 			return 1;
1304*58e6ee5fSAndroid Build Coastguard Worker 		else
1305*58e6ee5fSAndroid Build Coastguard Worker 			break;
1306*58e6ee5fSAndroid Build Coastguard Worker 	}
1307*58e6ee5fSAndroid Build Coastguard Worker 
1308*58e6ee5fSAndroid Build Coastguard Worker 	return 0;
1309*58e6ee5fSAndroid Build Coastguard Worker }
1310*58e6ee5fSAndroid Build Coastguard Worker 
trace_wait_for_processes(struct buffer_instance * instance)1311*58e6ee5fSAndroid Build Coastguard Worker static int trace_wait_for_processes(struct buffer_instance *instance) {
1312*58e6ee5fSAndroid Build Coastguard Worker 	int ret = 0;
1313*58e6ee5fSAndroid Build Coastguard Worker 	int nr_fds = 0;
1314*58e6ee5fSAndroid Build Coastguard Worker 	int i;
1315*58e6ee5fSAndroid Build Coastguard Worker 	int *pidfds;
1316*58e6ee5fSAndroid Build Coastguard Worker 	struct filter_pids *pid;
1317*58e6ee5fSAndroid Build Coastguard Worker 
1318*58e6ee5fSAndroid Build Coastguard Worker 	pidfds = malloc(sizeof(int) * instance->nr_process_pids);
1319*58e6ee5fSAndroid Build Coastguard Worker 	if (!pidfds)
1320*58e6ee5fSAndroid Build Coastguard Worker 		return 1;
1321*58e6ee5fSAndroid Build Coastguard Worker 
1322*58e6ee5fSAndroid Build Coastguard Worker 	for (pid = instance->process_pids;
1323*58e6ee5fSAndroid Build Coastguard Worker 	     pid && instance->nr_process_pids;
1324*58e6ee5fSAndroid Build Coastguard Worker 	     pid = pid->next) {
1325*58e6ee5fSAndroid Build Coastguard Worker 		if (pid->exclude) {
1326*58e6ee5fSAndroid Build Coastguard Worker 			instance->nr_process_pids--;
1327*58e6ee5fSAndroid Build Coastguard Worker 			continue;
1328*58e6ee5fSAndroid Build Coastguard Worker 		}
1329*58e6ee5fSAndroid Build Coastguard Worker 		pidfds[nr_fds] = pidfd_open(pid->pid, 0);
1330*58e6ee5fSAndroid Build Coastguard Worker 
1331*58e6ee5fSAndroid Build Coastguard Worker 		/* If the pid doesn't exist, the process has probably exited */
1332*58e6ee5fSAndroid Build Coastguard Worker 		if (pidfds[nr_fds] < 0 && errno == ESRCH) {
1333*58e6ee5fSAndroid Build Coastguard Worker 			instance->nr_process_pids--;
1334*58e6ee5fSAndroid Build Coastguard Worker 			continue;
1335*58e6ee5fSAndroid Build Coastguard Worker 		} else if (pidfds[nr_fds] < 0) {
1336*58e6ee5fSAndroid Build Coastguard Worker 			ret = 1;
1337*58e6ee5fSAndroid Build Coastguard Worker 			goto out;
1338*58e6ee5fSAndroid Build Coastguard Worker 		}
1339*58e6ee5fSAndroid Build Coastguard Worker 
1340*58e6ee5fSAndroid Build Coastguard Worker 		nr_fds++;
1341*58e6ee5fSAndroid Build Coastguard Worker 		instance->nr_process_pids--;
1342*58e6ee5fSAndroid Build Coastguard Worker 	}
1343*58e6ee5fSAndroid Build Coastguard Worker 
1344*58e6ee5fSAndroid Build Coastguard Worker 	for (i = 0; i < nr_fds; i++) {
1345*58e6ee5fSAndroid Build Coastguard Worker 		if (trace_waitpidfd(pidfds[i])) {
1346*58e6ee5fSAndroid Build Coastguard Worker 			ret = 1;
1347*58e6ee5fSAndroid Build Coastguard Worker 			goto out;
1348*58e6ee5fSAndroid Build Coastguard Worker 		}
1349*58e6ee5fSAndroid Build Coastguard Worker 	}
1350*58e6ee5fSAndroid Build Coastguard Worker 
1351*58e6ee5fSAndroid Build Coastguard Worker out:
1352*58e6ee5fSAndroid Build Coastguard Worker 	for (i = 0; i < nr_fds; i++)
1353*58e6ee5fSAndroid Build Coastguard Worker 		close(pidfds[i]);
1354*58e6ee5fSAndroid Build Coastguard Worker 	free(pidfds);
1355*58e6ee5fSAndroid Build Coastguard Worker 	return ret;
1356*58e6ee5fSAndroid Build Coastguard Worker }
1357*58e6ee5fSAndroid Build Coastguard Worker 
add_event_pid(struct buffer_instance * instance,const char * buf)1358*58e6ee5fSAndroid Build Coastguard Worker static void add_event_pid(struct buffer_instance *instance, const char *buf)
1359*58e6ee5fSAndroid Build Coastguard Worker {
1360*58e6ee5fSAndroid Build Coastguard Worker 	tracefs_instance_file_write(instance->tracefs, "set_event_pid", buf);
1361*58e6ee5fSAndroid Build Coastguard Worker }
1362*58e6ee5fSAndroid Build Coastguard Worker 
1363*58e6ee5fSAndroid Build Coastguard Worker #ifndef NO_PTRACE
1364*58e6ee5fSAndroid Build Coastguard Worker /**
1365*58e6ee5fSAndroid Build Coastguard Worker  * append_pid_filter - add a new pid to an existing filter
1366*58e6ee5fSAndroid Build Coastguard Worker  * @curr_filter: the filter to append to. If NULL, then allocate one
1367*58e6ee5fSAndroid Build Coastguard Worker  * @field: The fild to compare the pid to
1368*58e6ee5fSAndroid Build Coastguard Worker  * @pid: The pid to add to.
1369*58e6ee5fSAndroid Build Coastguard Worker  */
append_pid_filter(char * curr_filter,const char * field,int pid)1370*58e6ee5fSAndroid Build Coastguard Worker static char *append_pid_filter(char *curr_filter, const char *field, int pid)
1371*58e6ee5fSAndroid Build Coastguard Worker {
1372*58e6ee5fSAndroid Build Coastguard Worker 	char *filter;
1373*58e6ee5fSAndroid Build Coastguard Worker 	int len;
1374*58e6ee5fSAndroid Build Coastguard Worker 
1375*58e6ee5fSAndroid Build Coastguard Worker 	len = snprintf(NULL, 0, "(%s==%d)||", field, pid);
1376*58e6ee5fSAndroid Build Coastguard Worker 
1377*58e6ee5fSAndroid Build Coastguard Worker 	if (!curr_filter) {
1378*58e6ee5fSAndroid Build Coastguard Worker 		/* No need for +1 as we don't use the "||" */
1379*58e6ee5fSAndroid Build Coastguard Worker 		filter = malloc(len);
1380*58e6ee5fSAndroid Build Coastguard Worker 		if (!filter)
1381*58e6ee5fSAndroid Build Coastguard Worker 			die("Failed to allocate pid filter");
1382*58e6ee5fSAndroid Build Coastguard Worker 		sprintf(filter, "(%s==%d)", field, pid);
1383*58e6ee5fSAndroid Build Coastguard Worker 	} else {
1384*58e6ee5fSAndroid Build Coastguard Worker 		int indx = strlen(curr_filter);
1385*58e6ee5fSAndroid Build Coastguard Worker 
1386*58e6ee5fSAndroid Build Coastguard Worker 		len += indx;
1387*58e6ee5fSAndroid Build Coastguard Worker 		filter = realloc(curr_filter, len + indx + 1);
1388*58e6ee5fSAndroid Build Coastguard Worker 		if (!filter)
1389*58e6ee5fSAndroid Build Coastguard Worker 			die("realloc");
1390*58e6ee5fSAndroid Build Coastguard Worker 		sprintf(filter + indx, "||(%s==%d)", field, pid);
1391*58e6ee5fSAndroid Build Coastguard Worker 	}
1392*58e6ee5fSAndroid Build Coastguard Worker 
1393*58e6ee5fSAndroid Build Coastguard Worker 	return filter;
1394*58e6ee5fSAndroid Build Coastguard Worker }
1395*58e6ee5fSAndroid Build Coastguard Worker 
append_sched_event(struct event_list * event,const char * field,int pid)1396*58e6ee5fSAndroid Build Coastguard Worker static void append_sched_event(struct event_list *event, const char *field, int pid)
1397*58e6ee5fSAndroid Build Coastguard Worker {
1398*58e6ee5fSAndroid Build Coastguard Worker 	if (!event || !event->pid_filter)
1399*58e6ee5fSAndroid Build Coastguard Worker 		return;
1400*58e6ee5fSAndroid Build Coastguard Worker 
1401*58e6ee5fSAndroid Build Coastguard Worker 	event->pid_filter = append_pid_filter(event->pid_filter, field, pid);
1402*58e6ee5fSAndroid Build Coastguard Worker }
1403*58e6ee5fSAndroid Build Coastguard Worker 
update_sched_events(struct buffer_instance * instance,int pid)1404*58e6ee5fSAndroid Build Coastguard Worker static void update_sched_events(struct buffer_instance *instance, int pid)
1405*58e6ee5fSAndroid Build Coastguard Worker {
1406*58e6ee5fSAndroid Build Coastguard Worker 	/*
1407*58e6ee5fSAndroid Build Coastguard Worker 	 * Also make sure that the sched_switch to this pid
1408*58e6ee5fSAndroid Build Coastguard Worker 	 * and wakeups of this pid are also traced.
1409*58e6ee5fSAndroid Build Coastguard Worker 	 * Only need to do this if the events are active.
1410*58e6ee5fSAndroid Build Coastguard Worker 	 */
1411*58e6ee5fSAndroid Build Coastguard Worker 	append_sched_event(instance->sched_switch_event, "next_pid", pid);
1412*58e6ee5fSAndroid Build Coastguard Worker 	append_sched_event(instance->sched_wakeup_event, "pid", pid);
1413*58e6ee5fSAndroid Build Coastguard Worker 	append_sched_event(instance->sched_wakeup_new_event, "pid", pid);
1414*58e6ee5fSAndroid Build Coastguard Worker }
1415*58e6ee5fSAndroid Build Coastguard Worker 
1416*58e6ee5fSAndroid Build Coastguard Worker static int open_instance_fd(struct buffer_instance *instance,
1417*58e6ee5fSAndroid Build Coastguard Worker 			    const char *file, int flags);
1418*58e6ee5fSAndroid Build Coastguard Worker 
add_new_filter_child_pid(int pid,int child)1419*58e6ee5fSAndroid Build Coastguard Worker static void add_new_filter_child_pid(int pid, int child)
1420*58e6ee5fSAndroid Build Coastguard Worker {
1421*58e6ee5fSAndroid Build Coastguard Worker 	struct buffer_instance *instance;
1422*58e6ee5fSAndroid Build Coastguard Worker 	struct filter_pids *fpid;
1423*58e6ee5fSAndroid Build Coastguard Worker 	char buf[100];
1424*58e6ee5fSAndroid Build Coastguard Worker 
1425*58e6ee5fSAndroid Build Coastguard Worker 	for_all_instances(instance) {
1426*58e6ee5fSAndroid Build Coastguard Worker 		if (!instance->ptrace_child || !instance->filter_pids)
1427*58e6ee5fSAndroid Build Coastguard Worker 			continue;
1428*58e6ee5fSAndroid Build Coastguard Worker 		for (fpid = instance->filter_pids; fpid; fpid = fpid->next) {
1429*58e6ee5fSAndroid Build Coastguard Worker 			if (fpid->pid == pid)
1430*58e6ee5fSAndroid Build Coastguard Worker 				break;
1431*58e6ee5fSAndroid Build Coastguard Worker 		}
1432*58e6ee5fSAndroid Build Coastguard Worker 		if (!fpid)
1433*58e6ee5fSAndroid Build Coastguard Worker 			continue;
1434*58e6ee5fSAndroid Build Coastguard Worker 
1435*58e6ee5fSAndroid Build Coastguard Worker 		add_filter_pid(instance, child, 0);
1436*58e6ee5fSAndroid Build Coastguard Worker 		sprintf(buf, "%d", child);
1437*58e6ee5fSAndroid Build Coastguard Worker 		update_ftrace_pid(instance, buf, 0);
1438*58e6ee5fSAndroid Build Coastguard Worker 
1439*58e6ee5fSAndroid Build Coastguard Worker 		instance->common_pid_filter = append_pid_filter(instance->common_pid_filter,
1440*58e6ee5fSAndroid Build Coastguard Worker 								"common_pid", pid);
1441*58e6ee5fSAndroid Build Coastguard Worker 		if (instance->have_set_event_pid) {
1442*58e6ee5fSAndroid Build Coastguard Worker 			add_event_pid(instance, buf);
1443*58e6ee5fSAndroid Build Coastguard Worker 		} else {
1444*58e6ee5fSAndroid Build Coastguard Worker 			update_sched_events(instance, pid);
1445*58e6ee5fSAndroid Build Coastguard Worker 			update_event_filters(instance);
1446*58e6ee5fSAndroid Build Coastguard Worker 		}
1447*58e6ee5fSAndroid Build Coastguard Worker 	}
1448*58e6ee5fSAndroid Build Coastguard Worker 
1449*58e6ee5fSAndroid Build Coastguard Worker }
1450*58e6ee5fSAndroid Build Coastguard Worker 
ptrace_attach(struct buffer_instance * instance,int pid)1451*58e6ee5fSAndroid Build Coastguard Worker static void ptrace_attach(struct buffer_instance *instance, int pid)
1452*58e6ee5fSAndroid Build Coastguard Worker {
1453*58e6ee5fSAndroid Build Coastguard Worker 	int ret;
1454*58e6ee5fSAndroid Build Coastguard Worker 
1455*58e6ee5fSAndroid Build Coastguard Worker 	ret = ptrace(PTRACE_ATTACH, pid, NULL, 0);
1456*58e6ee5fSAndroid Build Coastguard Worker 	if (ret < 0) {
1457*58e6ee5fSAndroid Build Coastguard Worker 		warning("Unable to trace process %d children", pid);
1458*58e6ee5fSAndroid Build Coastguard Worker 		do_ptrace = 0;
1459*58e6ee5fSAndroid Build Coastguard Worker 		return;
1460*58e6ee5fSAndroid Build Coastguard Worker 	}
1461*58e6ee5fSAndroid Build Coastguard Worker 	if (instance)
1462*58e6ee5fSAndroid Build Coastguard Worker 		add_filter_pid(instance, pid, 0);
1463*58e6ee5fSAndroid Build Coastguard Worker 	else
1464*58e6ee5fSAndroid Build Coastguard Worker 		add_filter_pid_all(pid, 0);
1465*58e6ee5fSAndroid Build Coastguard Worker }
1466*58e6ee5fSAndroid Build Coastguard Worker 
enable_ptrace(void)1467*58e6ee5fSAndroid Build Coastguard Worker static void enable_ptrace(void)
1468*58e6ee5fSAndroid Build Coastguard Worker {
1469*58e6ee5fSAndroid Build Coastguard Worker 	if (!do_ptrace || !filter_task)
1470*58e6ee5fSAndroid Build Coastguard Worker 		return;
1471*58e6ee5fSAndroid Build Coastguard Worker 
1472*58e6ee5fSAndroid Build Coastguard Worker 	ptrace(PTRACE_TRACEME, 0, NULL, 0);
1473*58e6ee5fSAndroid Build Coastguard Worker }
1474*58e6ee5fSAndroid Build Coastguard Worker 
get_intance_fpid(int pid)1475*58e6ee5fSAndroid Build Coastguard Worker static struct buffer_instance *get_intance_fpid(int pid)
1476*58e6ee5fSAndroid Build Coastguard Worker {
1477*58e6ee5fSAndroid Build Coastguard Worker 	struct buffer_instance *instance;
1478*58e6ee5fSAndroid Build Coastguard Worker 	struct filter_pids *fpid;
1479*58e6ee5fSAndroid Build Coastguard Worker 
1480*58e6ee5fSAndroid Build Coastguard Worker 	for_all_instances(instance) {
1481*58e6ee5fSAndroid Build Coastguard Worker 		for (fpid = instance->filter_pids; fpid; fpid = fpid->next) {
1482*58e6ee5fSAndroid Build Coastguard Worker 			if (fpid->exclude)
1483*58e6ee5fSAndroid Build Coastguard Worker 				continue;
1484*58e6ee5fSAndroid Build Coastguard Worker 			if (fpid->pid == pid)
1485*58e6ee5fSAndroid Build Coastguard Worker 				break;
1486*58e6ee5fSAndroid Build Coastguard Worker 		}
1487*58e6ee5fSAndroid Build Coastguard Worker 		if (fpid)
1488*58e6ee5fSAndroid Build Coastguard Worker 			return instance;
1489*58e6ee5fSAndroid Build Coastguard Worker 	}
1490*58e6ee5fSAndroid Build Coastguard Worker 
1491*58e6ee5fSAndroid Build Coastguard Worker 	return NULL;
1492*58e6ee5fSAndroid Build Coastguard Worker }
1493*58e6ee5fSAndroid Build Coastguard Worker 
ptrace_wait(enum trace_type type)1494*58e6ee5fSAndroid Build Coastguard Worker static void ptrace_wait(enum trace_type type)
1495*58e6ee5fSAndroid Build Coastguard Worker {
1496*58e6ee5fSAndroid Build Coastguard Worker 	struct buffer_instance *instance;
1497*58e6ee5fSAndroid Build Coastguard Worker 	struct filter_pids *fpid;
1498*58e6ee5fSAndroid Build Coastguard Worker 	unsigned long send_sig;
1499*58e6ee5fSAndroid Build Coastguard Worker 	unsigned long child;
1500*58e6ee5fSAndroid Build Coastguard Worker 	int nr_pids = 0;
1501*58e6ee5fSAndroid Build Coastguard Worker 	siginfo_t sig;
1502*58e6ee5fSAndroid Build Coastguard Worker 	int main_pids;
1503*58e6ee5fSAndroid Build Coastguard Worker 	int cstatus;
1504*58e6ee5fSAndroid Build Coastguard Worker 	int status;
1505*58e6ee5fSAndroid Build Coastguard Worker 	int i = 0;
1506*58e6ee5fSAndroid Build Coastguard Worker 	int *pids;
1507*58e6ee5fSAndroid Build Coastguard Worker 	int event;
1508*58e6ee5fSAndroid Build Coastguard Worker 	int pid;
1509*58e6ee5fSAndroid Build Coastguard Worker 	int ret;
1510*58e6ee5fSAndroid Build Coastguard Worker 
1511*58e6ee5fSAndroid Build Coastguard Worker 
1512*58e6ee5fSAndroid Build Coastguard Worker 	for_all_instances(instance)
1513*58e6ee5fSAndroid Build Coastguard Worker 		nr_pids += instance->nr_filter_pids;
1514*58e6ee5fSAndroid Build Coastguard Worker 
1515*58e6ee5fSAndroid Build Coastguard Worker 	pids = calloc(nr_pids, sizeof(int));
1516*58e6ee5fSAndroid Build Coastguard Worker 	if (!pids) {
1517*58e6ee5fSAndroid Build Coastguard Worker 		warning("Unable to allocate array for %d PIDs", nr_pids);
1518*58e6ee5fSAndroid Build Coastguard Worker 		return;
1519*58e6ee5fSAndroid Build Coastguard Worker 	}
1520*58e6ee5fSAndroid Build Coastguard Worker 	for_all_instances(instance) {
1521*58e6ee5fSAndroid Build Coastguard Worker 		if (!instance->ptrace_child && !instance->get_procmap)
1522*58e6ee5fSAndroid Build Coastguard Worker 			continue;
1523*58e6ee5fSAndroid Build Coastguard Worker 
1524*58e6ee5fSAndroid Build Coastguard Worker 		for (fpid = instance->filter_pids; fpid && i < nr_pids; fpid = fpid->next) {
1525*58e6ee5fSAndroid Build Coastguard Worker 			if (fpid->exclude)
1526*58e6ee5fSAndroid Build Coastguard Worker 				continue;
1527*58e6ee5fSAndroid Build Coastguard Worker 			pids[i++] = fpid->pid;
1528*58e6ee5fSAndroid Build Coastguard Worker 		}
1529*58e6ee5fSAndroid Build Coastguard Worker 	}
1530*58e6ee5fSAndroid Build Coastguard Worker 	main_pids = i;
1531*58e6ee5fSAndroid Build Coastguard Worker 
1532*58e6ee5fSAndroid Build Coastguard Worker 	do {
1533*58e6ee5fSAndroid Build Coastguard Worker 		ret = trace_waitpid(type, -1, &status, WSTOPPED | __WALL);
1534*58e6ee5fSAndroid Build Coastguard Worker 		if (ret < 0)
1535*58e6ee5fSAndroid Build Coastguard Worker 			continue;
1536*58e6ee5fSAndroid Build Coastguard Worker 
1537*58e6ee5fSAndroid Build Coastguard Worker 		pid = ret;
1538*58e6ee5fSAndroid Build Coastguard Worker 
1539*58e6ee5fSAndroid Build Coastguard Worker 		if (WIFSTOPPED(status)) {
1540*58e6ee5fSAndroid Build Coastguard Worker 			event = (status >> 16) & 0xff;
1541*58e6ee5fSAndroid Build Coastguard Worker 			ptrace(PTRACE_GETSIGINFO, pid, NULL, &sig);
1542*58e6ee5fSAndroid Build Coastguard Worker 			send_sig = sig.si_signo;
1543*58e6ee5fSAndroid Build Coastguard Worker 			/* Don't send ptrace sigs to child */
1544*58e6ee5fSAndroid Build Coastguard Worker 			if (send_sig == SIGTRAP || send_sig == SIGSTOP)
1545*58e6ee5fSAndroid Build Coastguard Worker 				send_sig = 0;
1546*58e6ee5fSAndroid Build Coastguard Worker 			switch (event) {
1547*58e6ee5fSAndroid Build Coastguard Worker 			case PTRACE_EVENT_FORK:
1548*58e6ee5fSAndroid Build Coastguard Worker 			case PTRACE_EVENT_VFORK:
1549*58e6ee5fSAndroid Build Coastguard Worker 			case PTRACE_EVENT_CLONE:
1550*58e6ee5fSAndroid Build Coastguard Worker 				/* forked a child */
1551*58e6ee5fSAndroid Build Coastguard Worker 				ptrace(PTRACE_GETEVENTMSG, pid, NULL, &child);
1552*58e6ee5fSAndroid Build Coastguard Worker 				ptrace(PTRACE_SETOPTIONS, child, NULL,
1553*58e6ee5fSAndroid Build Coastguard Worker 				       PTRACE_O_TRACEFORK |
1554*58e6ee5fSAndroid Build Coastguard Worker 				       PTRACE_O_TRACEVFORK |
1555*58e6ee5fSAndroid Build Coastguard Worker 				       PTRACE_O_TRACECLONE |
1556*58e6ee5fSAndroid Build Coastguard Worker 				       PTRACE_O_TRACEEXIT);
1557*58e6ee5fSAndroid Build Coastguard Worker 				add_new_filter_child_pid(pid, child);
1558*58e6ee5fSAndroid Build Coastguard Worker 				ptrace(PTRACE_CONT, child, NULL, 0);
1559*58e6ee5fSAndroid Build Coastguard Worker 				break;
1560*58e6ee5fSAndroid Build Coastguard Worker 
1561*58e6ee5fSAndroid Build Coastguard Worker 			case PTRACE_EVENT_EXIT:
1562*58e6ee5fSAndroid Build Coastguard Worker 				instance = get_intance_fpid(pid);
1563*58e6ee5fSAndroid Build Coastguard Worker 				if (instance && instance->get_procmap)
1564*58e6ee5fSAndroid Build Coastguard Worker 					get_pid_addr_maps(instance, pid);
1565*58e6ee5fSAndroid Build Coastguard Worker 				ptrace(PTRACE_GETEVENTMSG, pid, NULL, &cstatus);
1566*58e6ee5fSAndroid Build Coastguard Worker 				ptrace(PTRACE_DETACH, pid, NULL, NULL);
1567*58e6ee5fSAndroid Build Coastguard Worker 				break;
1568*58e6ee5fSAndroid Build Coastguard Worker 			}
1569*58e6ee5fSAndroid Build Coastguard Worker 			ptrace(PTRACE_SETOPTIONS, pid, NULL,
1570*58e6ee5fSAndroid Build Coastguard Worker 			       PTRACE_O_TRACEFORK |
1571*58e6ee5fSAndroid Build Coastguard Worker 			       PTRACE_O_TRACEVFORK |
1572*58e6ee5fSAndroid Build Coastguard Worker 			       PTRACE_O_TRACECLONE |
1573*58e6ee5fSAndroid Build Coastguard Worker 			       PTRACE_O_TRACEEXIT);
1574*58e6ee5fSAndroid Build Coastguard Worker 			ptrace(PTRACE_CONT, pid, NULL, send_sig);
1575*58e6ee5fSAndroid Build Coastguard Worker 		}
1576*58e6ee5fSAndroid Build Coastguard Worker 		if (WIFEXITED(status) ||
1577*58e6ee5fSAndroid Build Coastguard Worker 		   (WIFSTOPPED(status) && event == PTRACE_EVENT_EXIT)) {
1578*58e6ee5fSAndroid Build Coastguard Worker 			for (i = 0; i < nr_pids; i++) {
1579*58e6ee5fSAndroid Build Coastguard Worker 				if (pid == pids[i]) {
1580*58e6ee5fSAndroid Build Coastguard Worker 					pids[i] = 0;
1581*58e6ee5fSAndroid Build Coastguard Worker 					main_pids--;
1582*58e6ee5fSAndroid Build Coastguard Worker 					if (!main_pids)
1583*58e6ee5fSAndroid Build Coastguard Worker 						finished = 1;
1584*58e6ee5fSAndroid Build Coastguard Worker 				}
1585*58e6ee5fSAndroid Build Coastguard Worker 			}
1586*58e6ee5fSAndroid Build Coastguard Worker 		}
1587*58e6ee5fSAndroid Build Coastguard Worker 	} while (!finished && ret > 0);
1588*58e6ee5fSAndroid Build Coastguard Worker 
1589*58e6ee5fSAndroid Build Coastguard Worker 	free(pids);
1590*58e6ee5fSAndroid Build Coastguard Worker }
1591*58e6ee5fSAndroid Build Coastguard Worker #else
ptrace_wait(enum trace_type type)1592*58e6ee5fSAndroid Build Coastguard Worker static inline void ptrace_wait(enum trace_type type) { }
enable_ptrace(void)1593*58e6ee5fSAndroid Build Coastguard Worker static inline void enable_ptrace(void) { }
ptrace_attach(struct buffer_instance * instance,int pid)1594*58e6ee5fSAndroid Build Coastguard Worker static inline void ptrace_attach(struct buffer_instance *instance, int pid) { }
1595*58e6ee5fSAndroid Build Coastguard Worker 
1596*58e6ee5fSAndroid Build Coastguard Worker #endif /* NO_PTRACE */
1597*58e6ee5fSAndroid Build Coastguard Worker 
trace_or_sleep(enum trace_type type,bool pwait)1598*58e6ee5fSAndroid Build Coastguard Worker static void trace_or_sleep(enum trace_type type, bool pwait)
1599*58e6ee5fSAndroid Build Coastguard Worker {
1600*58e6ee5fSAndroid Build Coastguard Worker 	struct timeval tv = { 1 , 0 };
1601*58e6ee5fSAndroid Build Coastguard Worker 
1602*58e6ee5fSAndroid Build Coastguard Worker 	if (pwait)
1603*58e6ee5fSAndroid Build Coastguard Worker 		ptrace_wait(type);
1604*58e6ee5fSAndroid Build Coastguard Worker 	else if (type & TRACE_TYPE_STREAM)
1605*58e6ee5fSAndroid Build Coastguard Worker 		trace_stream_read(pids, recorder_threads, &tv);
1606*58e6ee5fSAndroid Build Coastguard Worker 	else
1607*58e6ee5fSAndroid Build Coastguard Worker 		sleep(10);
1608*58e6ee5fSAndroid Build Coastguard Worker }
1609*58e6ee5fSAndroid Build Coastguard Worker 
change_user(const char * user)1610*58e6ee5fSAndroid Build Coastguard Worker static int change_user(const char *user)
1611*58e6ee5fSAndroid Build Coastguard Worker {
1612*58e6ee5fSAndroid Build Coastguard Worker 	struct passwd *pwd;
1613*58e6ee5fSAndroid Build Coastguard Worker 
1614*58e6ee5fSAndroid Build Coastguard Worker 	if (!user)
1615*58e6ee5fSAndroid Build Coastguard Worker 		return 0;
1616*58e6ee5fSAndroid Build Coastguard Worker 
1617*58e6ee5fSAndroid Build Coastguard Worker 	pwd = getpwnam(user);
1618*58e6ee5fSAndroid Build Coastguard Worker 	if (!pwd)
1619*58e6ee5fSAndroid Build Coastguard Worker 		return -1;
1620*58e6ee5fSAndroid Build Coastguard Worker 	if (initgroups(user, pwd->pw_gid) < 0)
1621*58e6ee5fSAndroid Build Coastguard Worker 		return -1;
1622*58e6ee5fSAndroid Build Coastguard Worker 	if (setgid(pwd->pw_gid) < 0)
1623*58e6ee5fSAndroid Build Coastguard Worker 		return -1;
1624*58e6ee5fSAndroid Build Coastguard Worker 	if (setuid(pwd->pw_uid) < 0)
1625*58e6ee5fSAndroid Build Coastguard Worker 		return -1;
1626*58e6ee5fSAndroid Build Coastguard Worker 
1627*58e6ee5fSAndroid Build Coastguard Worker 	if (setenv("HOME", pwd->pw_dir, 1) < 0)
1628*58e6ee5fSAndroid Build Coastguard Worker 		return -1;
1629*58e6ee5fSAndroid Build Coastguard Worker 	if (setenv("USER", pwd->pw_name, 1) < 0)
1630*58e6ee5fSAndroid Build Coastguard Worker 		return -1;
1631*58e6ee5fSAndroid Build Coastguard Worker 	if (setenv("LOGNAME", pwd->pw_name, 1) < 0)
1632*58e6ee5fSAndroid Build Coastguard Worker 		return -1;
1633*58e6ee5fSAndroid Build Coastguard Worker 
1634*58e6ee5fSAndroid Build Coastguard Worker 	return 0;
1635*58e6ee5fSAndroid Build Coastguard Worker }
1636*58e6ee5fSAndroid Build Coastguard Worker 
run_cmd(enum trace_type type,const char * user,int argc,char ** argv)1637*58e6ee5fSAndroid Build Coastguard Worker static void run_cmd(enum trace_type type, const char *user, int argc, char **argv)
1638*58e6ee5fSAndroid Build Coastguard Worker {
1639*58e6ee5fSAndroid Build Coastguard Worker 	int status;
1640*58e6ee5fSAndroid Build Coastguard Worker 	int pid;
1641*58e6ee5fSAndroid Build Coastguard Worker 
1642*58e6ee5fSAndroid Build Coastguard Worker 	if ((pid = fork()) < 0)
1643*58e6ee5fSAndroid Build Coastguard Worker 		die("failed to fork");
1644*58e6ee5fSAndroid Build Coastguard Worker 	if (!pid) {
1645*58e6ee5fSAndroid Build Coastguard Worker 		/* child */
1646*58e6ee5fSAndroid Build Coastguard Worker 		update_task_filter();
1647*58e6ee5fSAndroid Build Coastguard Worker 		tracecmd_enable_tracing();
1648*58e6ee5fSAndroid Build Coastguard Worker 		if (!fork_process)
1649*58e6ee5fSAndroid Build Coastguard Worker 			enable_ptrace();
1650*58e6ee5fSAndroid Build Coastguard Worker 		/*
1651*58e6ee5fSAndroid Build Coastguard Worker 		 * If we are using stderr for stdout, switch
1652*58e6ee5fSAndroid Build Coastguard Worker 		 * it back to the saved stdout for the code we run.
1653*58e6ee5fSAndroid Build Coastguard Worker 		 */
1654*58e6ee5fSAndroid Build Coastguard Worker 		if (save_stdout >= 0) {
1655*58e6ee5fSAndroid Build Coastguard Worker 			close(1);
1656*58e6ee5fSAndroid Build Coastguard Worker 			dup2(save_stdout, 1);
1657*58e6ee5fSAndroid Build Coastguard Worker 			close(save_stdout);
1658*58e6ee5fSAndroid Build Coastguard Worker 		}
1659*58e6ee5fSAndroid Build Coastguard Worker 
1660*58e6ee5fSAndroid Build Coastguard Worker 		if (change_user(user) < 0)
1661*58e6ee5fSAndroid Build Coastguard Worker 			die("Failed to change user to %s", user);
1662*58e6ee5fSAndroid Build Coastguard Worker 
1663*58e6ee5fSAndroid Build Coastguard Worker 		if (execvp(argv[0], argv)) {
1664*58e6ee5fSAndroid Build Coastguard Worker 			fprintf(stderr, "\n********************\n");
1665*58e6ee5fSAndroid Build Coastguard Worker 			fprintf(stderr, " Unable to exec %s\n", argv[0]);
1666*58e6ee5fSAndroid Build Coastguard Worker 			fprintf(stderr, "********************\n");
1667*58e6ee5fSAndroid Build Coastguard Worker 			die("Failed to exec %s", argv[0]);
1668*58e6ee5fSAndroid Build Coastguard Worker 		}
1669*58e6ee5fSAndroid Build Coastguard Worker 	}
1670*58e6ee5fSAndroid Build Coastguard Worker 	if (fork_process)
1671*58e6ee5fSAndroid Build Coastguard Worker 		exit(0);
1672*58e6ee5fSAndroid Build Coastguard Worker 	if (do_ptrace) {
1673*58e6ee5fSAndroid Build Coastguard Worker 		ptrace_attach(NULL, pid);
1674*58e6ee5fSAndroid Build Coastguard Worker 		ptrace_wait(type);
1675*58e6ee5fSAndroid Build Coastguard Worker 	} else
1676*58e6ee5fSAndroid Build Coastguard Worker 		trace_waitpid(type, pid, &status, 0);
1677*58e6ee5fSAndroid Build Coastguard Worker 	if (type & (TRACE_TYPE_START | TRACE_TYPE_SET))
1678*58e6ee5fSAndroid Build Coastguard Worker 		exit(0);
1679*58e6ee5fSAndroid Build Coastguard Worker }
1680*58e6ee5fSAndroid Build Coastguard Worker 
1681*58e6ee5fSAndroid Build Coastguard Worker static void
set_plugin_instance(struct buffer_instance * instance,const char * name)1682*58e6ee5fSAndroid Build Coastguard Worker set_plugin_instance(struct buffer_instance *instance, const char *name)
1683*58e6ee5fSAndroid Build Coastguard Worker {
1684*58e6ee5fSAndroid Build Coastguard Worker 	char *path;
1685*58e6ee5fSAndroid Build Coastguard Worker 	char zero = '0';
1686*58e6ee5fSAndroid Build Coastguard Worker 	int ret;
1687*58e6ee5fSAndroid Build Coastguard Worker 	int fd;
1688*58e6ee5fSAndroid Build Coastguard Worker 
1689*58e6ee5fSAndroid Build Coastguard Worker 	if (is_guest(instance))
1690*58e6ee5fSAndroid Build Coastguard Worker 		return;
1691*58e6ee5fSAndroid Build Coastguard Worker 
1692*58e6ee5fSAndroid Build Coastguard Worker 	path = tracefs_instance_get_file(instance->tracefs, "current_tracer");
1693*58e6ee5fSAndroid Build Coastguard Worker 	fd = open(path, O_WRONLY);
1694*58e6ee5fSAndroid Build Coastguard Worker 	if (fd < 0) {
1695*58e6ee5fSAndroid Build Coastguard Worker 		/*
1696*58e6ee5fSAndroid Build Coastguard Worker 		 * Legacy kernels do not have current_tracer file, and they
1697*58e6ee5fSAndroid Build Coastguard Worker 		 * always use nop. So, it doesn't need to try to change the
1698*58e6ee5fSAndroid Build Coastguard Worker 		 * plugin for those if name is "nop".
1699*58e6ee5fSAndroid Build Coastguard Worker 		 */
1700*58e6ee5fSAndroid Build Coastguard Worker 		if (!strncmp(name, "nop", 3)) {
1701*58e6ee5fSAndroid Build Coastguard Worker 			tracefs_put_tracing_file(path);
1702*58e6ee5fSAndroid Build Coastguard Worker 			return;
1703*58e6ee5fSAndroid Build Coastguard Worker 		}
1704*58e6ee5fSAndroid Build Coastguard Worker 		die("Opening '%s'", path);
1705*58e6ee5fSAndroid Build Coastguard Worker 	}
1706*58e6ee5fSAndroid Build Coastguard Worker 	ret = write(fd, name, strlen(name));
1707*58e6ee5fSAndroid Build Coastguard Worker 	close(fd);
1708*58e6ee5fSAndroid Build Coastguard Worker 
1709*58e6ee5fSAndroid Build Coastguard Worker 	if (ret < 0)
1710*58e6ee5fSAndroid Build Coastguard Worker 		die("writing to '%s'", path);
1711*58e6ee5fSAndroid Build Coastguard Worker 
1712*58e6ee5fSAndroid Build Coastguard Worker 	tracefs_put_tracing_file(path);
1713*58e6ee5fSAndroid Build Coastguard Worker 
1714*58e6ee5fSAndroid Build Coastguard Worker 	if (strncmp(name, "function", 8) != 0)
1715*58e6ee5fSAndroid Build Coastguard Worker 		return;
1716*58e6ee5fSAndroid Build Coastguard Worker 
1717*58e6ee5fSAndroid Build Coastguard Worker 	/* Make sure func_stack_trace option is disabled */
1718*58e6ee5fSAndroid Build Coastguard Worker 	/* First try instance file, then top level */
1719*58e6ee5fSAndroid Build Coastguard Worker 	path = tracefs_instance_get_file(instance->tracefs, "options/func_stack_trace");
1720*58e6ee5fSAndroid Build Coastguard Worker 	fd = open(path, O_WRONLY);
1721*58e6ee5fSAndroid Build Coastguard Worker 	if (fd < 0) {
1722*58e6ee5fSAndroid Build Coastguard Worker 		tracefs_put_tracing_file(path);
1723*58e6ee5fSAndroid Build Coastguard Worker 		path = tracefs_get_tracing_file("options/func_stack_trace");
1724*58e6ee5fSAndroid Build Coastguard Worker 		fd = open(path, O_WRONLY);
1725*58e6ee5fSAndroid Build Coastguard Worker 		if (fd < 0) {
1726*58e6ee5fSAndroid Build Coastguard Worker 			tracefs_put_tracing_file(path);
1727*58e6ee5fSAndroid Build Coastguard Worker 			return;
1728*58e6ee5fSAndroid Build Coastguard Worker 		}
1729*58e6ee5fSAndroid Build Coastguard Worker 	}
1730*58e6ee5fSAndroid Build Coastguard Worker 	/*
1731*58e6ee5fSAndroid Build Coastguard Worker 	 * Always reset func_stack_trace to zero. Don't bother saving
1732*58e6ee5fSAndroid Build Coastguard Worker 	 * the original content.
1733*58e6ee5fSAndroid Build Coastguard Worker 	 */
1734*58e6ee5fSAndroid Build Coastguard Worker 	add_reset_file(path, "0", RESET_HIGH_PRIO);
1735*58e6ee5fSAndroid Build Coastguard Worker 	tracefs_put_tracing_file(path);
1736*58e6ee5fSAndroid Build Coastguard Worker 	write(fd, &zero, 1);
1737*58e6ee5fSAndroid Build Coastguard Worker 	close(fd);
1738*58e6ee5fSAndroid Build Coastguard Worker }
1739*58e6ee5fSAndroid Build Coastguard Worker 
set_plugin(const char * name)1740*58e6ee5fSAndroid Build Coastguard Worker static void set_plugin(const char *name)
1741*58e6ee5fSAndroid Build Coastguard Worker {
1742*58e6ee5fSAndroid Build Coastguard Worker 	struct buffer_instance *instance;
1743*58e6ee5fSAndroid Build Coastguard Worker 
1744*58e6ee5fSAndroid Build Coastguard Worker 	for_all_instances(instance)
1745*58e6ee5fSAndroid Build Coastguard Worker 		set_plugin_instance(instance, name);
1746*58e6ee5fSAndroid Build Coastguard Worker }
1747*58e6ee5fSAndroid Build Coastguard Worker 
save_option(struct buffer_instance * instance,const char * option)1748*58e6ee5fSAndroid Build Coastguard Worker static void save_option(struct buffer_instance *instance, const char *option)
1749*58e6ee5fSAndroid Build Coastguard Worker {
1750*58e6ee5fSAndroid Build Coastguard Worker 	struct opt_list *opt;
1751*58e6ee5fSAndroid Build Coastguard Worker 
1752*58e6ee5fSAndroid Build Coastguard Worker 	opt = malloc(sizeof(*opt));
1753*58e6ee5fSAndroid Build Coastguard Worker 	if (!opt)
1754*58e6ee5fSAndroid Build Coastguard Worker 		die("Failed to allocate option");
1755*58e6ee5fSAndroid Build Coastguard Worker 	opt->next = instance->options;
1756*58e6ee5fSAndroid Build Coastguard Worker 	instance->options = opt;
1757*58e6ee5fSAndroid Build Coastguard Worker 	opt->option = option;
1758*58e6ee5fSAndroid Build Coastguard Worker }
1759*58e6ee5fSAndroid Build Coastguard Worker 
set_option(struct buffer_instance * instance,const char * option)1760*58e6ee5fSAndroid Build Coastguard Worker static int set_option(struct buffer_instance *instance, const char *option)
1761*58e6ee5fSAndroid Build Coastguard Worker {
1762*58e6ee5fSAndroid Build Coastguard Worker 	FILE *fp;
1763*58e6ee5fSAndroid Build Coastguard Worker 	char *path;
1764*58e6ee5fSAndroid Build Coastguard Worker 
1765*58e6ee5fSAndroid Build Coastguard Worker 	path = tracefs_instance_get_file(instance->tracefs, "trace_options");
1766*58e6ee5fSAndroid Build Coastguard Worker 	fp = fopen(path, "w");
1767*58e6ee5fSAndroid Build Coastguard Worker 	if (!fp)
1768*58e6ee5fSAndroid Build Coastguard Worker 		warning("writing to '%s'", path);
1769*58e6ee5fSAndroid Build Coastguard Worker 	tracefs_put_tracing_file(path);
1770*58e6ee5fSAndroid Build Coastguard Worker 
1771*58e6ee5fSAndroid Build Coastguard Worker 	if (!fp)
1772*58e6ee5fSAndroid Build Coastguard Worker 		return -1;
1773*58e6ee5fSAndroid Build Coastguard Worker 
1774*58e6ee5fSAndroid Build Coastguard Worker 	fwrite(option, 1, strlen(option), fp);
1775*58e6ee5fSAndroid Build Coastguard Worker 	fclose(fp);
1776*58e6ee5fSAndroid Build Coastguard Worker 
1777*58e6ee5fSAndroid Build Coastguard Worker 	return 0;
1778*58e6ee5fSAndroid Build Coastguard Worker }
1779*58e6ee5fSAndroid Build Coastguard Worker 
disable_func_stack_trace_instance(struct buffer_instance * instance)1780*58e6ee5fSAndroid Build Coastguard Worker static void disable_func_stack_trace_instance(struct buffer_instance *instance)
1781*58e6ee5fSAndroid Build Coastguard Worker {
1782*58e6ee5fSAndroid Build Coastguard Worker 	struct stat st;
1783*58e6ee5fSAndroid Build Coastguard Worker 	char *content;
1784*58e6ee5fSAndroid Build Coastguard Worker 	char *path;
1785*58e6ee5fSAndroid Build Coastguard Worker 	char *cond;
1786*58e6ee5fSAndroid Build Coastguard Worker 	int size;
1787*58e6ee5fSAndroid Build Coastguard Worker 	int ret;
1788*58e6ee5fSAndroid Build Coastguard Worker 
1789*58e6ee5fSAndroid Build Coastguard Worker 	if (is_guest(instance))
1790*58e6ee5fSAndroid Build Coastguard Worker 		return;
1791*58e6ee5fSAndroid Build Coastguard Worker 
1792*58e6ee5fSAndroid Build Coastguard Worker 	path = tracefs_instance_get_file(instance->tracefs, "current_tracer");
1793*58e6ee5fSAndroid Build Coastguard Worker 	ret = stat(path, &st);
1794*58e6ee5fSAndroid Build Coastguard Worker 	tracefs_put_tracing_file(path);
1795*58e6ee5fSAndroid Build Coastguard Worker 	if (ret < 0)
1796*58e6ee5fSAndroid Build Coastguard Worker 		return;
1797*58e6ee5fSAndroid Build Coastguard Worker 
1798*58e6ee5fSAndroid Build Coastguard Worker 	content = tracefs_instance_file_read(instance->tracefs,
1799*58e6ee5fSAndroid Build Coastguard Worker 					     "current_tracer", &size);
1800*58e6ee5fSAndroid Build Coastguard Worker 	cond = strstrip(content);
1801*58e6ee5fSAndroid Build Coastguard Worker 	if (memcmp(cond, "function", size - (cond - content)) !=0)
1802*58e6ee5fSAndroid Build Coastguard Worker 		goto out;
1803*58e6ee5fSAndroid Build Coastguard Worker 
1804*58e6ee5fSAndroid Build Coastguard Worker 	set_option(instance, "nofunc_stack_trace");
1805*58e6ee5fSAndroid Build Coastguard Worker  out:
1806*58e6ee5fSAndroid Build Coastguard Worker 	free(content);
1807*58e6ee5fSAndroid Build Coastguard Worker }
1808*58e6ee5fSAndroid Build Coastguard Worker 
disable_func_stack_trace(void)1809*58e6ee5fSAndroid Build Coastguard Worker static void disable_func_stack_trace(void)
1810*58e6ee5fSAndroid Build Coastguard Worker {
1811*58e6ee5fSAndroid Build Coastguard Worker 	struct buffer_instance *instance;
1812*58e6ee5fSAndroid Build Coastguard Worker 
1813*58e6ee5fSAndroid Build Coastguard Worker 	for_all_instances(instance)
1814*58e6ee5fSAndroid Build Coastguard Worker 		disable_func_stack_trace_instance(instance);
1815*58e6ee5fSAndroid Build Coastguard Worker }
1816*58e6ee5fSAndroid Build Coastguard Worker 
add_reset_options(struct buffer_instance * instance)1817*58e6ee5fSAndroid Build Coastguard Worker static void add_reset_options(struct buffer_instance *instance)
1818*58e6ee5fSAndroid Build Coastguard Worker {
1819*58e6ee5fSAndroid Build Coastguard Worker 	struct opt_list *opt;
1820*58e6ee5fSAndroid Build Coastguard Worker 	const char *option;
1821*58e6ee5fSAndroid Build Coastguard Worker 	char *content;
1822*58e6ee5fSAndroid Build Coastguard Worker 	char *path;
1823*58e6ee5fSAndroid Build Coastguard Worker 	char *ptr;
1824*58e6ee5fSAndroid Build Coastguard Worker 	int len;
1825*58e6ee5fSAndroid Build Coastguard Worker 
1826*58e6ee5fSAndroid Build Coastguard Worker 	if (keep)
1827*58e6ee5fSAndroid Build Coastguard Worker 		return;
1828*58e6ee5fSAndroid Build Coastguard Worker 
1829*58e6ee5fSAndroid Build Coastguard Worker 	path = tracefs_instance_get_file(instance->tracefs, "trace_options");
1830*58e6ee5fSAndroid Build Coastguard Worker 	content = get_file_content(path);
1831*58e6ee5fSAndroid Build Coastguard Worker 
1832*58e6ee5fSAndroid Build Coastguard Worker 	for (opt = instance->options; opt; opt = opt->next) {
1833*58e6ee5fSAndroid Build Coastguard Worker 		option = opt->option;
1834*58e6ee5fSAndroid Build Coastguard Worker 		len = strlen(option);
1835*58e6ee5fSAndroid Build Coastguard Worker 		ptr = content;
1836*58e6ee5fSAndroid Build Coastguard Worker  again:
1837*58e6ee5fSAndroid Build Coastguard Worker 		ptr = strstr(ptr, option);
1838*58e6ee5fSAndroid Build Coastguard Worker 		if (ptr) {
1839*58e6ee5fSAndroid Build Coastguard Worker 			/* First make sure its the option we want */
1840*58e6ee5fSAndroid Build Coastguard Worker 			if (ptr[len] != '\n') {
1841*58e6ee5fSAndroid Build Coastguard Worker 				ptr += len;
1842*58e6ee5fSAndroid Build Coastguard Worker 				goto again;
1843*58e6ee5fSAndroid Build Coastguard Worker 			}
1844*58e6ee5fSAndroid Build Coastguard Worker 			if (ptr - content >= 2 && strncmp(ptr - 2, "no", 2) == 0) {
1845*58e6ee5fSAndroid Build Coastguard Worker 				/* Make sure this isn't ohno-option */
1846*58e6ee5fSAndroid Build Coastguard Worker 				if (ptr > content + 2 && *(ptr - 3) != '\n') {
1847*58e6ee5fSAndroid Build Coastguard Worker 					ptr += len;
1848*58e6ee5fSAndroid Build Coastguard Worker 					goto again;
1849*58e6ee5fSAndroid Build Coastguard Worker 				}
1850*58e6ee5fSAndroid Build Coastguard Worker 				/* we enabled it */
1851*58e6ee5fSAndroid Build Coastguard Worker 				ptr[len] = 0;
1852*58e6ee5fSAndroid Build Coastguard Worker 				add_reset_file(path, ptr-2, RESET_DEFAULT_PRIO);
1853*58e6ee5fSAndroid Build Coastguard Worker 				ptr[len] = '\n';
1854*58e6ee5fSAndroid Build Coastguard Worker 				continue;
1855*58e6ee5fSAndroid Build Coastguard Worker 			}
1856*58e6ee5fSAndroid Build Coastguard Worker 			/* make sure this is our option */
1857*58e6ee5fSAndroid Build Coastguard Worker 			if (ptr > content && *(ptr - 1) != '\n') {
1858*58e6ee5fSAndroid Build Coastguard Worker 				ptr += len;
1859*58e6ee5fSAndroid Build Coastguard Worker 				goto again;
1860*58e6ee5fSAndroid Build Coastguard Worker 			}
1861*58e6ee5fSAndroid Build Coastguard Worker 			/* this option hasn't changed, ignore it */
1862*58e6ee5fSAndroid Build Coastguard Worker 			continue;
1863*58e6ee5fSAndroid Build Coastguard Worker 		}
1864*58e6ee5fSAndroid Build Coastguard Worker 
1865*58e6ee5fSAndroid Build Coastguard Worker 		/* ptr is NULL, not found, maybe option is a no */
1866*58e6ee5fSAndroid Build Coastguard Worker 		if (strncmp(option, "no", 2) != 0)
1867*58e6ee5fSAndroid Build Coastguard Worker 			/* option is really not found? */
1868*58e6ee5fSAndroid Build Coastguard Worker 			continue;
1869*58e6ee5fSAndroid Build Coastguard Worker 
1870*58e6ee5fSAndroid Build Coastguard Worker 		option += 2;
1871*58e6ee5fSAndroid Build Coastguard Worker 		len = strlen(option);
1872*58e6ee5fSAndroid Build Coastguard Worker 		ptr = content;
1873*58e6ee5fSAndroid Build Coastguard Worker  loop:
1874*58e6ee5fSAndroid Build Coastguard Worker 		ptr = strstr(content, option);
1875*58e6ee5fSAndroid Build Coastguard Worker 		if (!ptr)
1876*58e6ee5fSAndroid Build Coastguard Worker 			/* Really not found? */
1877*58e6ee5fSAndroid Build Coastguard Worker 			continue;
1878*58e6ee5fSAndroid Build Coastguard Worker 
1879*58e6ee5fSAndroid Build Coastguard Worker 		/* make sure this is our option */
1880*58e6ee5fSAndroid Build Coastguard Worker 		if (ptr[len] != '\n') {
1881*58e6ee5fSAndroid Build Coastguard Worker 			ptr += len;
1882*58e6ee5fSAndroid Build Coastguard Worker 			goto loop;
1883*58e6ee5fSAndroid Build Coastguard Worker 		}
1884*58e6ee5fSAndroid Build Coastguard Worker 
1885*58e6ee5fSAndroid Build Coastguard Worker 		if (ptr > content && *(ptr - 1) != '\n') {
1886*58e6ee5fSAndroid Build Coastguard Worker 			ptr += len;
1887*58e6ee5fSAndroid Build Coastguard Worker 			goto loop;
1888*58e6ee5fSAndroid Build Coastguard Worker 		}
1889*58e6ee5fSAndroid Build Coastguard Worker 
1890*58e6ee5fSAndroid Build Coastguard Worker 		add_reset_file(path, option, RESET_DEFAULT_PRIO);
1891*58e6ee5fSAndroid Build Coastguard Worker 	}
1892*58e6ee5fSAndroid Build Coastguard Worker 	tracefs_put_tracing_file(path);
1893*58e6ee5fSAndroid Build Coastguard Worker 	free(content);
1894*58e6ee5fSAndroid Build Coastguard Worker }
1895*58e6ee5fSAndroid Build Coastguard Worker 
set_options(void)1896*58e6ee5fSAndroid Build Coastguard Worker static void set_options(void)
1897*58e6ee5fSAndroid Build Coastguard Worker {
1898*58e6ee5fSAndroid Build Coastguard Worker 	struct buffer_instance *instance;
1899*58e6ee5fSAndroid Build Coastguard Worker 	struct opt_list *opt;
1900*58e6ee5fSAndroid Build Coastguard Worker 	int ret;
1901*58e6ee5fSAndroid Build Coastguard Worker 
1902*58e6ee5fSAndroid Build Coastguard Worker 	for_all_instances(instance) {
1903*58e6ee5fSAndroid Build Coastguard Worker 		add_reset_options(instance);
1904*58e6ee5fSAndroid Build Coastguard Worker 		while (instance->options) {
1905*58e6ee5fSAndroid Build Coastguard Worker 			opt = instance->options;
1906*58e6ee5fSAndroid Build Coastguard Worker 			instance->options = opt->next;
1907*58e6ee5fSAndroid Build Coastguard Worker 			ret = set_option(instance, opt->option);
1908*58e6ee5fSAndroid Build Coastguard Worker 			if (ret < 0)
1909*58e6ee5fSAndroid Build Coastguard Worker 				die("Failed to  set ftrace option %s",
1910*58e6ee5fSAndroid Build Coastguard Worker 				    opt->option);
1911*58e6ee5fSAndroid Build Coastguard Worker 			free(opt);
1912*58e6ee5fSAndroid Build Coastguard Worker 		}
1913*58e6ee5fSAndroid Build Coastguard Worker 	}
1914*58e6ee5fSAndroid Build Coastguard Worker }
1915*58e6ee5fSAndroid Build Coastguard Worker 
set_saved_cmdlines_size(struct common_record_context * ctx)1916*58e6ee5fSAndroid Build Coastguard Worker static void set_saved_cmdlines_size(struct common_record_context *ctx)
1917*58e6ee5fSAndroid Build Coastguard Worker {
1918*58e6ee5fSAndroid Build Coastguard Worker 	int fd, len, ret = -1;
1919*58e6ee5fSAndroid Build Coastguard Worker 	char *path, *str;
1920*58e6ee5fSAndroid Build Coastguard Worker 
1921*58e6ee5fSAndroid Build Coastguard Worker 	if (!ctx->saved_cmdlines_size)
1922*58e6ee5fSAndroid Build Coastguard Worker 		return;
1923*58e6ee5fSAndroid Build Coastguard Worker 
1924*58e6ee5fSAndroid Build Coastguard Worker 	path = tracefs_get_tracing_file("saved_cmdlines_size");
1925*58e6ee5fSAndroid Build Coastguard Worker 	if (!path)
1926*58e6ee5fSAndroid Build Coastguard Worker 		goto err;
1927*58e6ee5fSAndroid Build Coastguard Worker 
1928*58e6ee5fSAndroid Build Coastguard Worker 	reset_save_file(path, RESET_DEFAULT_PRIO);
1929*58e6ee5fSAndroid Build Coastguard Worker 
1930*58e6ee5fSAndroid Build Coastguard Worker 	fd = open(path, O_WRONLY);
1931*58e6ee5fSAndroid Build Coastguard Worker 	tracefs_put_tracing_file(path);
1932*58e6ee5fSAndroid Build Coastguard Worker 	if (fd < 0)
1933*58e6ee5fSAndroid Build Coastguard Worker 		goto err;
1934*58e6ee5fSAndroid Build Coastguard Worker 
1935*58e6ee5fSAndroid Build Coastguard Worker 	len = asprintf(&str, "%d", ctx->saved_cmdlines_size);
1936*58e6ee5fSAndroid Build Coastguard Worker 	if (len < 0)
1937*58e6ee5fSAndroid Build Coastguard Worker 		die("%s couldn't allocate memory", __func__);
1938*58e6ee5fSAndroid Build Coastguard Worker 
1939*58e6ee5fSAndroid Build Coastguard Worker 	if (write(fd, str, len) > 0)
1940*58e6ee5fSAndroid Build Coastguard Worker 		ret = 0;
1941*58e6ee5fSAndroid Build Coastguard Worker 
1942*58e6ee5fSAndroid Build Coastguard Worker 	close(fd);
1943*58e6ee5fSAndroid Build Coastguard Worker 	free(str);
1944*58e6ee5fSAndroid Build Coastguard Worker err:
1945*58e6ee5fSAndroid Build Coastguard Worker 	if (ret)
1946*58e6ee5fSAndroid Build Coastguard Worker 		warning("Couldn't set saved_cmdlines_size");
1947*58e6ee5fSAndroid Build Coastguard Worker }
1948*58e6ee5fSAndroid Build Coastguard Worker 
trace_check_file_exists(struct buffer_instance * instance,char * file)1949*58e6ee5fSAndroid Build Coastguard Worker static int trace_check_file_exists(struct buffer_instance *instance, char *file)
1950*58e6ee5fSAndroid Build Coastguard Worker {
1951*58e6ee5fSAndroid Build Coastguard Worker 	struct stat st;
1952*58e6ee5fSAndroid Build Coastguard Worker 	char *path;
1953*58e6ee5fSAndroid Build Coastguard Worker 	int ret;
1954*58e6ee5fSAndroid Build Coastguard Worker 
1955*58e6ee5fSAndroid Build Coastguard Worker 	path = tracefs_instance_get_file(instance->tracefs, file);
1956*58e6ee5fSAndroid Build Coastguard Worker 	ret = stat(path, &st);
1957*58e6ee5fSAndroid Build Coastguard Worker 	tracefs_put_tracing_file(path);
1958*58e6ee5fSAndroid Build Coastguard Worker 
1959*58e6ee5fSAndroid Build Coastguard Worker 	return ret < 0 ? 0 : 1;
1960*58e6ee5fSAndroid Build Coastguard Worker }
1961*58e6ee5fSAndroid Build Coastguard Worker 
use_old_event_method(void)1962*58e6ee5fSAndroid Build Coastguard Worker static int use_old_event_method(void)
1963*58e6ee5fSAndroid Build Coastguard Worker {
1964*58e6ee5fSAndroid Build Coastguard Worker 	static int old_event_method;
1965*58e6ee5fSAndroid Build Coastguard Worker 	static int processed;
1966*58e6ee5fSAndroid Build Coastguard Worker 
1967*58e6ee5fSAndroid Build Coastguard Worker 	if (processed)
1968*58e6ee5fSAndroid Build Coastguard Worker 		return old_event_method;
1969*58e6ee5fSAndroid Build Coastguard Worker 
1970*58e6ee5fSAndroid Build Coastguard Worker 	/* Check if the kernel has the events/enable file */
1971*58e6ee5fSAndroid Build Coastguard Worker 	if (!trace_check_file_exists(&top_instance, "events/enable"))
1972*58e6ee5fSAndroid Build Coastguard Worker 		old_event_method = 1;
1973*58e6ee5fSAndroid Build Coastguard Worker 
1974*58e6ee5fSAndroid Build Coastguard Worker 	processed = 1;
1975*58e6ee5fSAndroid Build Coastguard Worker 
1976*58e6ee5fSAndroid Build Coastguard Worker 	return old_event_method;
1977*58e6ee5fSAndroid Build Coastguard Worker }
1978*58e6ee5fSAndroid Build Coastguard Worker 
old_update_events(const char * name,char update)1979*58e6ee5fSAndroid Build Coastguard Worker static void old_update_events(const char *name, char update)
1980*58e6ee5fSAndroid Build Coastguard Worker {
1981*58e6ee5fSAndroid Build Coastguard Worker 	char *path;
1982*58e6ee5fSAndroid Build Coastguard Worker 	FILE *fp;
1983*58e6ee5fSAndroid Build Coastguard Worker 	int ret;
1984*58e6ee5fSAndroid Build Coastguard Worker 
1985*58e6ee5fSAndroid Build Coastguard Worker 	if (strcmp(name, "all") == 0)
1986*58e6ee5fSAndroid Build Coastguard Worker 		name = "*:*";
1987*58e6ee5fSAndroid Build Coastguard Worker 
1988*58e6ee5fSAndroid Build Coastguard Worker 	/* need to use old way */
1989*58e6ee5fSAndroid Build Coastguard Worker 	path = tracefs_get_tracing_file("set_event");
1990*58e6ee5fSAndroid Build Coastguard Worker 	fp = fopen(path, "w");
1991*58e6ee5fSAndroid Build Coastguard Worker 	if (!fp)
1992*58e6ee5fSAndroid Build Coastguard Worker 		die("opening '%s'", path);
1993*58e6ee5fSAndroid Build Coastguard Worker 	tracefs_put_tracing_file(path);
1994*58e6ee5fSAndroid Build Coastguard Worker 
1995*58e6ee5fSAndroid Build Coastguard Worker 	/* Disable the event with "!" */
1996*58e6ee5fSAndroid Build Coastguard Worker 	if (update == '0')
1997*58e6ee5fSAndroid Build Coastguard Worker 		fwrite("!", 1, 1, fp);
1998*58e6ee5fSAndroid Build Coastguard Worker 
1999*58e6ee5fSAndroid Build Coastguard Worker 	ret = fwrite(name, 1, strlen(name), fp);
2000*58e6ee5fSAndroid Build Coastguard Worker 	if (ret < 0)
2001*58e6ee5fSAndroid Build Coastguard Worker 		die("bad event '%s'", name);
2002*58e6ee5fSAndroid Build Coastguard Worker 
2003*58e6ee5fSAndroid Build Coastguard Worker 	ret = fwrite("\n", 1, 1, fp);
2004*58e6ee5fSAndroid Build Coastguard Worker 	if (ret < 0)
2005*58e6ee5fSAndroid Build Coastguard Worker 		die("bad event '%s'", name);
2006*58e6ee5fSAndroid Build Coastguard Worker 
2007*58e6ee5fSAndroid Build Coastguard Worker 	fclose(fp);
2008*58e6ee5fSAndroid Build Coastguard Worker 
2009*58e6ee5fSAndroid Build Coastguard Worker 	return;
2010*58e6ee5fSAndroid Build Coastguard Worker }
2011*58e6ee5fSAndroid Build Coastguard Worker 
2012*58e6ee5fSAndroid Build Coastguard Worker static void
reset_events_instance(struct buffer_instance * instance)2013*58e6ee5fSAndroid Build Coastguard Worker reset_events_instance(struct buffer_instance *instance)
2014*58e6ee5fSAndroid Build Coastguard Worker {
2015*58e6ee5fSAndroid Build Coastguard Worker 	glob_t globbuf;
2016*58e6ee5fSAndroid Build Coastguard Worker 	char *path;
2017*58e6ee5fSAndroid Build Coastguard Worker 	char c;
2018*58e6ee5fSAndroid Build Coastguard Worker 	int fd;
2019*58e6ee5fSAndroid Build Coastguard Worker 	int i;
2020*58e6ee5fSAndroid Build Coastguard Worker 	int ret;
2021*58e6ee5fSAndroid Build Coastguard Worker 
2022*58e6ee5fSAndroid Build Coastguard Worker 	if (is_guest(instance))
2023*58e6ee5fSAndroid Build Coastguard Worker 		return;
2024*58e6ee5fSAndroid Build Coastguard Worker 
2025*58e6ee5fSAndroid Build Coastguard Worker 	if (use_old_event_method()) {
2026*58e6ee5fSAndroid Build Coastguard Worker 		/* old way only had top instance */
2027*58e6ee5fSAndroid Build Coastguard Worker 		if (!is_top_instance(instance))
2028*58e6ee5fSAndroid Build Coastguard Worker 			return;
2029*58e6ee5fSAndroid Build Coastguard Worker 		old_update_events("all", '0');
2030*58e6ee5fSAndroid Build Coastguard Worker 		return;
2031*58e6ee5fSAndroid Build Coastguard Worker 	}
2032*58e6ee5fSAndroid Build Coastguard Worker 
2033*58e6ee5fSAndroid Build Coastguard Worker 	c = '0';
2034*58e6ee5fSAndroid Build Coastguard Worker 	path = tracefs_instance_get_file(instance->tracefs, "events/enable");
2035*58e6ee5fSAndroid Build Coastguard Worker 	fd = open(path, O_WRONLY);
2036*58e6ee5fSAndroid Build Coastguard Worker 	if (fd < 0)
2037*58e6ee5fSAndroid Build Coastguard Worker 		die("opening to '%s'", path);
2038*58e6ee5fSAndroid Build Coastguard Worker 	ret = write(fd, &c, 1);
2039*58e6ee5fSAndroid Build Coastguard Worker 	close(fd);
2040*58e6ee5fSAndroid Build Coastguard Worker 	tracefs_put_tracing_file(path);
2041*58e6ee5fSAndroid Build Coastguard Worker 
2042*58e6ee5fSAndroid Build Coastguard Worker 	path = tracefs_instance_get_file(instance->tracefs, "events/*/filter");
2043*58e6ee5fSAndroid Build Coastguard Worker 	globbuf.gl_offs = 0;
2044*58e6ee5fSAndroid Build Coastguard Worker 	ret = glob(path, 0, NULL, &globbuf);
2045*58e6ee5fSAndroid Build Coastguard Worker 	tracefs_put_tracing_file(path);
2046*58e6ee5fSAndroid Build Coastguard Worker 	if (ret < 0)
2047*58e6ee5fSAndroid Build Coastguard Worker 		return;
2048*58e6ee5fSAndroid Build Coastguard Worker 
2049*58e6ee5fSAndroid Build Coastguard Worker 	for (i = 0; i < globbuf.gl_pathc; i++) {
2050*58e6ee5fSAndroid Build Coastguard Worker 		path = globbuf.gl_pathv[i];
2051*58e6ee5fSAndroid Build Coastguard Worker 		fd = open(path, O_WRONLY);
2052*58e6ee5fSAndroid Build Coastguard Worker 		if (fd < 0)
2053*58e6ee5fSAndroid Build Coastguard Worker 			die("opening to '%s'", path);
2054*58e6ee5fSAndroid Build Coastguard Worker 		ret = write(fd, &c, 1);
2055*58e6ee5fSAndroid Build Coastguard Worker 		close(fd);
2056*58e6ee5fSAndroid Build Coastguard Worker 	}
2057*58e6ee5fSAndroid Build Coastguard Worker 	globfree(&globbuf);
2058*58e6ee5fSAndroid Build Coastguard Worker }
2059*58e6ee5fSAndroid Build Coastguard Worker 
reset_events(void)2060*58e6ee5fSAndroid Build Coastguard Worker static void reset_events(void)
2061*58e6ee5fSAndroid Build Coastguard Worker {
2062*58e6ee5fSAndroid Build Coastguard Worker 	struct buffer_instance *instance;
2063*58e6ee5fSAndroid Build Coastguard Worker 
2064*58e6ee5fSAndroid Build Coastguard Worker 	for_all_instances(instance)
2065*58e6ee5fSAndroid Build Coastguard Worker 		reset_events_instance(instance);
2066*58e6ee5fSAndroid Build Coastguard Worker }
2067*58e6ee5fSAndroid Build Coastguard Worker 
2068*58e6ee5fSAndroid Build Coastguard Worker enum {
2069*58e6ee5fSAndroid Build Coastguard Worker 	STATE_NEWLINE,
2070*58e6ee5fSAndroid Build Coastguard Worker 	STATE_SKIP,
2071*58e6ee5fSAndroid Build Coastguard Worker 	STATE_COPY,
2072*58e6ee5fSAndroid Build Coastguard Worker };
2073*58e6ee5fSAndroid Build Coastguard Worker 
read_file(const char * file)2074*58e6ee5fSAndroid Build Coastguard Worker static char *read_file(const char *file)
2075*58e6ee5fSAndroid Build Coastguard Worker {
2076*58e6ee5fSAndroid Build Coastguard Worker 	char stbuf[BUFSIZ];
2077*58e6ee5fSAndroid Build Coastguard Worker 	char *buf = NULL;
2078*58e6ee5fSAndroid Build Coastguard Worker 	int size = 0;
2079*58e6ee5fSAndroid Build Coastguard Worker 	char *nbuf;
2080*58e6ee5fSAndroid Build Coastguard Worker 	int fd;
2081*58e6ee5fSAndroid Build Coastguard Worker 	int r;
2082*58e6ee5fSAndroid Build Coastguard Worker 
2083*58e6ee5fSAndroid Build Coastguard Worker 	fd = open(file, O_RDONLY);
2084*58e6ee5fSAndroid Build Coastguard Worker 	if (fd < 0)
2085*58e6ee5fSAndroid Build Coastguard Worker 		return NULL;
2086*58e6ee5fSAndroid Build Coastguard Worker 
2087*58e6ee5fSAndroid Build Coastguard Worker 	do {
2088*58e6ee5fSAndroid Build Coastguard Worker 		r = read(fd, stbuf, BUFSIZ);
2089*58e6ee5fSAndroid Build Coastguard Worker 		if (r <= 0)
2090*58e6ee5fSAndroid Build Coastguard Worker 			continue;
2091*58e6ee5fSAndroid Build Coastguard Worker 		nbuf = realloc(buf, size+r+1);
2092*58e6ee5fSAndroid Build Coastguard Worker 		if (!nbuf) {
2093*58e6ee5fSAndroid Build Coastguard Worker 			free(buf);
2094*58e6ee5fSAndroid Build Coastguard Worker 			buf = NULL;
2095*58e6ee5fSAndroid Build Coastguard Worker 			break;
2096*58e6ee5fSAndroid Build Coastguard Worker 		}
2097*58e6ee5fSAndroid Build Coastguard Worker 		buf = nbuf;
2098*58e6ee5fSAndroid Build Coastguard Worker 		memcpy(buf+size, stbuf, r);
2099*58e6ee5fSAndroid Build Coastguard Worker 		size += r;
2100*58e6ee5fSAndroid Build Coastguard Worker 	} while (r > 0);
2101*58e6ee5fSAndroid Build Coastguard Worker 
2102*58e6ee5fSAndroid Build Coastguard Worker 	close(fd);
2103*58e6ee5fSAndroid Build Coastguard Worker 	if (r == 0 && size > 0)
2104*58e6ee5fSAndroid Build Coastguard Worker 		buf[size] = '\0';
2105*58e6ee5fSAndroid Build Coastguard Worker 
2106*58e6ee5fSAndroid Build Coastguard Worker 	return buf;
2107*58e6ee5fSAndroid Build Coastguard Worker }
2108*58e6ee5fSAndroid Build Coastguard Worker 
read_error_log(const char * log)2109*58e6ee5fSAndroid Build Coastguard Worker static void read_error_log(const char *log)
2110*58e6ee5fSAndroid Build Coastguard Worker {
2111*58e6ee5fSAndroid Build Coastguard Worker 	char *buf, *line;
2112*58e6ee5fSAndroid Build Coastguard Worker 	char *start = NULL;
2113*58e6ee5fSAndroid Build Coastguard Worker 	char *p;
2114*58e6ee5fSAndroid Build Coastguard Worker 
2115*58e6ee5fSAndroid Build Coastguard Worker 	buf = read_file(log);
2116*58e6ee5fSAndroid Build Coastguard Worker 	if (!buf)
2117*58e6ee5fSAndroid Build Coastguard Worker 		return;
2118*58e6ee5fSAndroid Build Coastguard Worker 
2119*58e6ee5fSAndroid Build Coastguard Worker 	line = buf;
2120*58e6ee5fSAndroid Build Coastguard Worker 
2121*58e6ee5fSAndroid Build Coastguard Worker 	/* Only the last lines have meaning */
2122*58e6ee5fSAndroid Build Coastguard Worker 	while ((p = strstr(line, "\n")) && p[1]) {
2123*58e6ee5fSAndroid Build Coastguard Worker 		if (line[0] != ' ')
2124*58e6ee5fSAndroid Build Coastguard Worker 			start = line;
2125*58e6ee5fSAndroid Build Coastguard Worker 		line = p + 1;
2126*58e6ee5fSAndroid Build Coastguard Worker 	}
2127*58e6ee5fSAndroid Build Coastguard Worker 
2128*58e6ee5fSAndroid Build Coastguard Worker 	if (start)
2129*58e6ee5fSAndroid Build Coastguard Worker 		printf("%s", start);
2130*58e6ee5fSAndroid Build Coastguard Worker 
2131*58e6ee5fSAndroid Build Coastguard Worker 	free(buf);
2132*58e6ee5fSAndroid Build Coastguard Worker }
2133*58e6ee5fSAndroid Build Coastguard Worker 
show_error(const char * file,const char * type)2134*58e6ee5fSAndroid Build Coastguard Worker static void show_error(const char *file, const char *type)
2135*58e6ee5fSAndroid Build Coastguard Worker {
2136*58e6ee5fSAndroid Build Coastguard Worker 	struct stat st;
2137*58e6ee5fSAndroid Build Coastguard Worker 	char *path = strdup(file);
2138*58e6ee5fSAndroid Build Coastguard Worker 	char *p;
2139*58e6ee5fSAndroid Build Coastguard Worker 	int ret;
2140*58e6ee5fSAndroid Build Coastguard Worker 
2141*58e6ee5fSAndroid Build Coastguard Worker 	if (!path)
2142*58e6ee5fSAndroid Build Coastguard Worker 		die("Could not allocate memory");
2143*58e6ee5fSAndroid Build Coastguard Worker 
2144*58e6ee5fSAndroid Build Coastguard Worker 	p = strstr(path, "tracing");
2145*58e6ee5fSAndroid Build Coastguard Worker 	if (p) {
2146*58e6ee5fSAndroid Build Coastguard Worker 		if (strncmp(p + sizeof("tracing"), "instances", sizeof("instances") - 1) == 0) {
2147*58e6ee5fSAndroid Build Coastguard Worker 			p = strstr(p + sizeof("tracing") + sizeof("instances"), "/");
2148*58e6ee5fSAndroid Build Coastguard Worker 			if (!p)
2149*58e6ee5fSAndroid Build Coastguard Worker 				goto read_file;
2150*58e6ee5fSAndroid Build Coastguard Worker 		} else {
2151*58e6ee5fSAndroid Build Coastguard Worker 			p += sizeof("tracing") - 1;
2152*58e6ee5fSAndroid Build Coastguard Worker 		}
2153*58e6ee5fSAndroid Build Coastguard Worker 		ret = asprintf(&p, "%.*s/error_log", (int)(p - path), path);
2154*58e6ee5fSAndroid Build Coastguard Worker 		if (ret < 0)
2155*58e6ee5fSAndroid Build Coastguard Worker 			die("Could not allocate memory");
2156*58e6ee5fSAndroid Build Coastguard Worker 		ret = stat(p, &st);
2157*58e6ee5fSAndroid Build Coastguard Worker 		if (ret < 0) {
2158*58e6ee5fSAndroid Build Coastguard Worker 			free(p);
2159*58e6ee5fSAndroid Build Coastguard Worker 			goto read_file;
2160*58e6ee5fSAndroid Build Coastguard Worker 		}
2161*58e6ee5fSAndroid Build Coastguard Worker 		read_error_log(p);
2162*58e6ee5fSAndroid Build Coastguard Worker 		goto out;
2163*58e6ee5fSAndroid Build Coastguard Worker 	}
2164*58e6ee5fSAndroid Build Coastguard Worker 
2165*58e6ee5fSAndroid Build Coastguard Worker  read_file:
2166*58e6ee5fSAndroid Build Coastguard Worker 	p = read_file(path);
2167*58e6ee5fSAndroid Build Coastguard Worker 	if (p)
2168*58e6ee5fSAndroid Build Coastguard Worker 		printf("%s", p);
2169*58e6ee5fSAndroid Build Coastguard Worker 
2170*58e6ee5fSAndroid Build Coastguard Worker  out:
2171*58e6ee5fSAndroid Build Coastguard Worker 	printf("Failed %s of %s\n", type, file);
2172*58e6ee5fSAndroid Build Coastguard Worker 	free(path);
2173*58e6ee5fSAndroid Build Coastguard Worker 	return;
2174*58e6ee5fSAndroid Build Coastguard Worker }
2175*58e6ee5fSAndroid Build Coastguard Worker 
write_filter(const char * file,const char * filter)2176*58e6ee5fSAndroid Build Coastguard Worker static void write_filter(const char *file, const char *filter)
2177*58e6ee5fSAndroid Build Coastguard Worker {
2178*58e6ee5fSAndroid Build Coastguard Worker 	if (write_file(file, filter) < 0)
2179*58e6ee5fSAndroid Build Coastguard Worker 		show_error(file, "filter");
2180*58e6ee5fSAndroid Build Coastguard Worker }
2181*58e6ee5fSAndroid Build Coastguard Worker 
clear_filter(const char * file)2182*58e6ee5fSAndroid Build Coastguard Worker static void clear_filter(const char *file)
2183*58e6ee5fSAndroid Build Coastguard Worker {
2184*58e6ee5fSAndroid Build Coastguard Worker 	write_filter(file, "0");
2185*58e6ee5fSAndroid Build Coastguard Worker }
2186*58e6ee5fSAndroid Build Coastguard Worker 
write_trigger(const char * file,const char * trigger)2187*58e6ee5fSAndroid Build Coastguard Worker static void write_trigger(const char *file, const char *trigger)
2188*58e6ee5fSAndroid Build Coastguard Worker {
2189*58e6ee5fSAndroid Build Coastguard Worker 	if (write_file(file, trigger) < 0)
2190*58e6ee5fSAndroid Build Coastguard Worker 		show_error(file, "trigger");
2191*58e6ee5fSAndroid Build Coastguard Worker }
2192*58e6ee5fSAndroid Build Coastguard Worker 
clear_trigger(const char * file)2193*58e6ee5fSAndroid Build Coastguard Worker static int clear_trigger(const char *file)
2194*58e6ee5fSAndroid Build Coastguard Worker {
2195*58e6ee5fSAndroid Build Coastguard Worker 	char trigger[BUFSIZ];
2196*58e6ee5fSAndroid Build Coastguard Worker 	char *save = NULL;
2197*58e6ee5fSAndroid Build Coastguard Worker 	char *line;
2198*58e6ee5fSAndroid Build Coastguard Worker 	char *buf;
2199*58e6ee5fSAndroid Build Coastguard Worker 	int len;
2200*58e6ee5fSAndroid Build Coastguard Worker 	int ret;
2201*58e6ee5fSAndroid Build Coastguard Worker 
2202*58e6ee5fSAndroid Build Coastguard Worker 	buf = read_file(file);
2203*58e6ee5fSAndroid Build Coastguard Worker 	if (!buf) {
2204*58e6ee5fSAndroid Build Coastguard Worker 		perror(file);
2205*58e6ee5fSAndroid Build Coastguard Worker 		return 0;
2206*58e6ee5fSAndroid Build Coastguard Worker 	}
2207*58e6ee5fSAndroid Build Coastguard Worker 
2208*58e6ee5fSAndroid Build Coastguard Worker 	trigger[0] = '!';
2209*58e6ee5fSAndroid Build Coastguard Worker 
2210*58e6ee5fSAndroid Build Coastguard Worker 	for (line = strtok_r(buf, "\n", &save); line; line = strtok_r(NULL, "\n", &save)) {
2211*58e6ee5fSAndroid Build Coastguard Worker 		if (line[0] == '#')
2212*58e6ee5fSAndroid Build Coastguard Worker 			continue;
2213*58e6ee5fSAndroid Build Coastguard Worker 		len = strlen(line);
2214*58e6ee5fSAndroid Build Coastguard Worker 		if (len > BUFSIZ - 2)
2215*58e6ee5fSAndroid Build Coastguard Worker 			len = BUFSIZ - 2;
2216*58e6ee5fSAndroid Build Coastguard Worker 		strncpy(trigger + 1, line, len);
2217*58e6ee5fSAndroid Build Coastguard Worker 		trigger[len + 1] = '\0';
2218*58e6ee5fSAndroid Build Coastguard Worker 		/* We don't want any filters or extra on the line */
2219*58e6ee5fSAndroid Build Coastguard Worker 		strtok(trigger, " ");
2220*58e6ee5fSAndroid Build Coastguard Worker 		write_file(file, trigger);
2221*58e6ee5fSAndroid Build Coastguard Worker 	}
2222*58e6ee5fSAndroid Build Coastguard Worker 
2223*58e6ee5fSAndroid Build Coastguard Worker 	free(buf);
2224*58e6ee5fSAndroid Build Coastguard Worker 
2225*58e6ee5fSAndroid Build Coastguard Worker 	/*
2226*58e6ee5fSAndroid Build Coastguard Worker 	 * Some triggers have an order in removing them.
2227*58e6ee5fSAndroid Build Coastguard Worker 	 * They will not be removed if done in the wrong order.
2228*58e6ee5fSAndroid Build Coastguard Worker 	 */
2229*58e6ee5fSAndroid Build Coastguard Worker 	buf = read_file(file);
2230*58e6ee5fSAndroid Build Coastguard Worker 	if (!buf)
2231*58e6ee5fSAndroid Build Coastguard Worker 		return 0;
2232*58e6ee5fSAndroid Build Coastguard Worker 
2233*58e6ee5fSAndroid Build Coastguard Worker 	ret = 0;
2234*58e6ee5fSAndroid Build Coastguard Worker 	for (line = strtok(buf, "\n"); line; line = strtok(NULL, "\n")) {
2235*58e6ee5fSAndroid Build Coastguard Worker 		if (line[0] == '#')
2236*58e6ee5fSAndroid Build Coastguard Worker 			continue;
2237*58e6ee5fSAndroid Build Coastguard Worker 		ret = 1;
2238*58e6ee5fSAndroid Build Coastguard Worker 		break;
2239*58e6ee5fSAndroid Build Coastguard Worker 	}
2240*58e6ee5fSAndroid Build Coastguard Worker 	free(buf);
2241*58e6ee5fSAndroid Build Coastguard Worker 	return ret;
2242*58e6ee5fSAndroid Build Coastguard Worker }
2243*58e6ee5fSAndroid Build Coastguard Worker 
clear_func_filter(const char * file)2244*58e6ee5fSAndroid Build Coastguard Worker static void clear_func_filter(const char *file)
2245*58e6ee5fSAndroid Build Coastguard Worker {
2246*58e6ee5fSAndroid Build Coastguard Worker 	char filter[BUFSIZ];
2247*58e6ee5fSAndroid Build Coastguard Worker 	struct stat st;
2248*58e6ee5fSAndroid Build Coastguard Worker 	char *line;
2249*58e6ee5fSAndroid Build Coastguard Worker 	char *buf;
2250*58e6ee5fSAndroid Build Coastguard Worker 	char *p;
2251*58e6ee5fSAndroid Build Coastguard Worker 	int len;
2252*58e6ee5fSAndroid Build Coastguard Worker 	int ret;
2253*58e6ee5fSAndroid Build Coastguard Worker 	int fd;
2254*58e6ee5fSAndroid Build Coastguard Worker 
2255*58e6ee5fSAndroid Build Coastguard Worker 	/* Function filters may not exist */
2256*58e6ee5fSAndroid Build Coastguard Worker 	ret = stat(file, &st);
2257*58e6ee5fSAndroid Build Coastguard Worker 	if (ret < 0)
2258*58e6ee5fSAndroid Build Coastguard Worker 		return;
2259*58e6ee5fSAndroid Build Coastguard Worker 
2260*58e6ee5fSAndroid Build Coastguard Worker 	/*  First zero out normal filters */
2261*58e6ee5fSAndroid Build Coastguard Worker 	fd = open(file, O_WRONLY | O_TRUNC);
2262*58e6ee5fSAndroid Build Coastguard Worker 	if (fd < 0)
2263*58e6ee5fSAndroid Build Coastguard Worker 		die("opening to '%s'", file);
2264*58e6ee5fSAndroid Build Coastguard Worker 	close(fd);
2265*58e6ee5fSAndroid Build Coastguard Worker 
2266*58e6ee5fSAndroid Build Coastguard Worker 	buf = read_file(file);
2267*58e6ee5fSAndroid Build Coastguard Worker 	if (!buf) {
2268*58e6ee5fSAndroid Build Coastguard Worker 		perror(file);
2269*58e6ee5fSAndroid Build Coastguard Worker 		return;
2270*58e6ee5fSAndroid Build Coastguard Worker 	}
2271*58e6ee5fSAndroid Build Coastguard Worker 
2272*58e6ee5fSAndroid Build Coastguard Worker 	/* Now remove filters */
2273*58e6ee5fSAndroid Build Coastguard Worker 	filter[0] = '!';
2274*58e6ee5fSAndroid Build Coastguard Worker 
2275*58e6ee5fSAndroid Build Coastguard Worker 	/*
2276*58e6ee5fSAndroid Build Coastguard Worker 	 * To delete a filter, we need to write a '!filter'
2277*58e6ee5fSAndroid Build Coastguard Worker 	 * to the file for each filter.
2278*58e6ee5fSAndroid Build Coastguard Worker 	 */
2279*58e6ee5fSAndroid Build Coastguard Worker 	for (line = strtok(buf, "\n"); line; line = strtok(NULL, "\n")) {
2280*58e6ee5fSAndroid Build Coastguard Worker 		if (line[0] == '#')
2281*58e6ee5fSAndroid Build Coastguard Worker 			continue;
2282*58e6ee5fSAndroid Build Coastguard Worker 		len = strlen(line);
2283*58e6ee5fSAndroid Build Coastguard Worker 		if (len > BUFSIZ - 2)
2284*58e6ee5fSAndroid Build Coastguard Worker 			len = BUFSIZ - 2;
2285*58e6ee5fSAndroid Build Coastguard Worker 
2286*58e6ee5fSAndroid Build Coastguard Worker 		strncpy(filter + 1, line, len);
2287*58e6ee5fSAndroid Build Coastguard Worker 		filter[len + 1] = '\0';
2288*58e6ee5fSAndroid Build Coastguard Worker 		/*
2289*58e6ee5fSAndroid Build Coastguard Worker 		 * To remove "unlimited" filters, we must remove
2290*58e6ee5fSAndroid Build Coastguard Worker 		 * the ":unlimited" from what we write.
2291*58e6ee5fSAndroid Build Coastguard Worker 		 */
2292*58e6ee5fSAndroid Build Coastguard Worker 		if ((p = strstr(filter, ":unlimited"))) {
2293*58e6ee5fSAndroid Build Coastguard Worker 			*p = '\0';
2294*58e6ee5fSAndroid Build Coastguard Worker 			len = p - filter;
2295*58e6ee5fSAndroid Build Coastguard Worker 		}
2296*58e6ee5fSAndroid Build Coastguard Worker 		/*
2297*58e6ee5fSAndroid Build Coastguard Worker 		 * The write to this file expects white space
2298*58e6ee5fSAndroid Build Coastguard Worker 		 * at the end :-p
2299*58e6ee5fSAndroid Build Coastguard Worker 		 */
2300*58e6ee5fSAndroid Build Coastguard Worker 		filter[len] = '\n';
2301*58e6ee5fSAndroid Build Coastguard Worker 		filter[len+1] = '\0';
2302*58e6ee5fSAndroid Build Coastguard Worker 		write_file(file, filter);
2303*58e6ee5fSAndroid Build Coastguard Worker 	}
2304*58e6ee5fSAndroid Build Coastguard Worker }
2305*58e6ee5fSAndroid Build Coastguard Worker 
update_reset_triggers(void)2306*58e6ee5fSAndroid Build Coastguard Worker static void update_reset_triggers(void)
2307*58e6ee5fSAndroid Build Coastguard Worker {
2308*58e6ee5fSAndroid Build Coastguard Worker 	struct reset_file *reset;
2309*58e6ee5fSAndroid Build Coastguard Worker 
2310*58e6ee5fSAndroid Build Coastguard Worker 	while (reset_triggers) {
2311*58e6ee5fSAndroid Build Coastguard Worker 		reset = reset_triggers;
2312*58e6ee5fSAndroid Build Coastguard Worker 		reset_triggers = reset->next;
2313*58e6ee5fSAndroid Build Coastguard Worker 
2314*58e6ee5fSAndroid Build Coastguard Worker 		clear_trigger(reset->path);
2315*58e6ee5fSAndroid Build Coastguard Worker 		free(reset->path);
2316*58e6ee5fSAndroid Build Coastguard Worker 		free(reset);
2317*58e6ee5fSAndroid Build Coastguard Worker 	}
2318*58e6ee5fSAndroid Build Coastguard Worker }
2319*58e6ee5fSAndroid Build Coastguard Worker 
update_reset_files(void)2320*58e6ee5fSAndroid Build Coastguard Worker static void update_reset_files(void)
2321*58e6ee5fSAndroid Build Coastguard Worker {
2322*58e6ee5fSAndroid Build Coastguard Worker 	struct reset_file *reset;
2323*58e6ee5fSAndroid Build Coastguard Worker 
2324*58e6ee5fSAndroid Build Coastguard Worker 	while (reset_files) {
2325*58e6ee5fSAndroid Build Coastguard Worker 		reset = reset_files;
2326*58e6ee5fSAndroid Build Coastguard Worker 		reset_files = reset->next;
2327*58e6ee5fSAndroid Build Coastguard Worker 
2328*58e6ee5fSAndroid Build Coastguard Worker 		if (!keep)
2329*58e6ee5fSAndroid Build Coastguard Worker 			write_file(reset->path, reset->reset);
2330*58e6ee5fSAndroid Build Coastguard Worker 		free(reset->path);
2331*58e6ee5fSAndroid Build Coastguard Worker 		free(reset->reset);
2332*58e6ee5fSAndroid Build Coastguard Worker 		free(reset);
2333*58e6ee5fSAndroid Build Coastguard Worker 	}
2334*58e6ee5fSAndroid Build Coastguard Worker }
2335*58e6ee5fSAndroid Build Coastguard Worker 
2336*58e6ee5fSAndroid Build Coastguard Worker static void
update_event(struct event_list * event,const char * filter,int filter_only,char update)2337*58e6ee5fSAndroid Build Coastguard Worker update_event(struct event_list *event, const char *filter,
2338*58e6ee5fSAndroid Build Coastguard Worker 	     int filter_only, char update)
2339*58e6ee5fSAndroid Build Coastguard Worker {
2340*58e6ee5fSAndroid Build Coastguard Worker 	const char *name = event->event;
2341*58e6ee5fSAndroid Build Coastguard Worker 	FILE *fp;
2342*58e6ee5fSAndroid Build Coastguard Worker 	char *path;
2343*58e6ee5fSAndroid Build Coastguard Worker 	int ret;
2344*58e6ee5fSAndroid Build Coastguard Worker 
2345*58e6ee5fSAndroid Build Coastguard Worker 	if (use_old_event_method()) {
2346*58e6ee5fSAndroid Build Coastguard Worker 		if (filter_only)
2347*58e6ee5fSAndroid Build Coastguard Worker 			return;
2348*58e6ee5fSAndroid Build Coastguard Worker 		old_update_events(name, update);
2349*58e6ee5fSAndroid Build Coastguard Worker 		return;
2350*58e6ee5fSAndroid Build Coastguard Worker 	}
2351*58e6ee5fSAndroid Build Coastguard Worker 
2352*58e6ee5fSAndroid Build Coastguard Worker 	if (filter && event->filter_file) {
2353*58e6ee5fSAndroid Build Coastguard Worker 		add_reset_file(event->filter_file, "0", RESET_DEFAULT_PRIO);
2354*58e6ee5fSAndroid Build Coastguard Worker 		write_filter(event->filter_file, filter);
2355*58e6ee5fSAndroid Build Coastguard Worker 	}
2356*58e6ee5fSAndroid Build Coastguard Worker 
2357*58e6ee5fSAndroid Build Coastguard Worker 	if (event->trigger_file) {
2358*58e6ee5fSAndroid Build Coastguard Worker 		add_reset_trigger(event->trigger_file);
2359*58e6ee5fSAndroid Build Coastguard Worker 		clear_trigger(event->trigger_file);
2360*58e6ee5fSAndroid Build Coastguard Worker 		write_trigger(event->trigger_file, event->trigger);
2361*58e6ee5fSAndroid Build Coastguard Worker 		/* Make sure we don't write this again */
2362*58e6ee5fSAndroid Build Coastguard Worker 		free(event->trigger_file);
2363*58e6ee5fSAndroid Build Coastguard Worker 		free(event->trigger);
2364*58e6ee5fSAndroid Build Coastguard Worker 		event->trigger_file = NULL;
2365*58e6ee5fSAndroid Build Coastguard Worker 		event->trigger = NULL;
2366*58e6ee5fSAndroid Build Coastguard Worker 	}
2367*58e6ee5fSAndroid Build Coastguard Worker 
2368*58e6ee5fSAndroid Build Coastguard Worker 	if (filter_only || !event->enable_file)
2369*58e6ee5fSAndroid Build Coastguard Worker 		return;
2370*58e6ee5fSAndroid Build Coastguard Worker 
2371*58e6ee5fSAndroid Build Coastguard Worker 	path = event->enable_file;
2372*58e6ee5fSAndroid Build Coastguard Worker 
2373*58e6ee5fSAndroid Build Coastguard Worker 	fp = fopen(path, "w");
2374*58e6ee5fSAndroid Build Coastguard Worker 	if (!fp)
2375*58e6ee5fSAndroid Build Coastguard Worker 		die("writing to '%s'", path);
2376*58e6ee5fSAndroid Build Coastguard Worker 	ret = fwrite(&update, 1, 1, fp);
2377*58e6ee5fSAndroid Build Coastguard Worker 	fclose(fp);
2378*58e6ee5fSAndroid Build Coastguard Worker 	if (ret < 0)
2379*58e6ee5fSAndroid Build Coastguard Worker 		die("writing to '%s'", path);
2380*58e6ee5fSAndroid Build Coastguard Worker }
2381*58e6ee5fSAndroid Build Coastguard Worker 
2382*58e6ee5fSAndroid Build Coastguard Worker /*
2383*58e6ee5fSAndroid Build Coastguard Worker  * The debugfs file tracing_enabled needs to be deprecated.
2384*58e6ee5fSAndroid Build Coastguard Worker  * But just in case anyone fiddled with it. If it exists,
2385*58e6ee5fSAndroid Build Coastguard Worker  * make sure it is one.
2386*58e6ee5fSAndroid Build Coastguard Worker  * No error checking needed here.
2387*58e6ee5fSAndroid Build Coastguard Worker  */
check_tracing_enabled(void)2388*58e6ee5fSAndroid Build Coastguard Worker static void check_tracing_enabled(void)
2389*58e6ee5fSAndroid Build Coastguard Worker {
2390*58e6ee5fSAndroid Build Coastguard Worker 	static int fd = -1;
2391*58e6ee5fSAndroid Build Coastguard Worker 	char *path;
2392*58e6ee5fSAndroid Build Coastguard Worker 
2393*58e6ee5fSAndroid Build Coastguard Worker 	if (fd < 0) {
2394*58e6ee5fSAndroid Build Coastguard Worker 		path = tracefs_get_tracing_file("tracing_enabled");
2395*58e6ee5fSAndroid Build Coastguard Worker 		fd = open(path, O_WRONLY | O_CLOEXEC);
2396*58e6ee5fSAndroid Build Coastguard Worker 		tracefs_put_tracing_file(path);
2397*58e6ee5fSAndroid Build Coastguard Worker 
2398*58e6ee5fSAndroid Build Coastguard Worker 		if (fd < 0)
2399*58e6ee5fSAndroid Build Coastguard Worker 			return;
2400*58e6ee5fSAndroid Build Coastguard Worker 	}
2401*58e6ee5fSAndroid Build Coastguard Worker 	write(fd, "1", 1);
2402*58e6ee5fSAndroid Build Coastguard Worker }
2403*58e6ee5fSAndroid Build Coastguard Worker 
open_instance_fd(struct buffer_instance * instance,const char * file,int flags)2404*58e6ee5fSAndroid Build Coastguard Worker static int open_instance_fd(struct buffer_instance *instance,
2405*58e6ee5fSAndroid Build Coastguard Worker 			    const char *file, int flags)
2406*58e6ee5fSAndroid Build Coastguard Worker {
2407*58e6ee5fSAndroid Build Coastguard Worker 	int fd;
2408*58e6ee5fSAndroid Build Coastguard Worker 	char *path;
2409*58e6ee5fSAndroid Build Coastguard Worker 
2410*58e6ee5fSAndroid Build Coastguard Worker 	path = tracefs_instance_get_file(instance->tracefs, file);
2411*58e6ee5fSAndroid Build Coastguard Worker 	fd = open(path, flags);
2412*58e6ee5fSAndroid Build Coastguard Worker 	if (fd < 0) {
2413*58e6ee5fSAndroid Build Coastguard Worker 		/* instances may not be created yet */
2414*58e6ee5fSAndroid Build Coastguard Worker 		if (is_top_instance(instance))
2415*58e6ee5fSAndroid Build Coastguard Worker 			die("opening '%s'", path);
2416*58e6ee5fSAndroid Build Coastguard Worker 	}
2417*58e6ee5fSAndroid Build Coastguard Worker 	tracefs_put_tracing_file(path);
2418*58e6ee5fSAndroid Build Coastguard Worker 
2419*58e6ee5fSAndroid Build Coastguard Worker 	return fd;
2420*58e6ee5fSAndroid Build Coastguard Worker }
2421*58e6ee5fSAndroid Build Coastguard Worker 
open_tracing_on(struct buffer_instance * instance)2422*58e6ee5fSAndroid Build Coastguard Worker static int open_tracing_on(struct buffer_instance *instance)
2423*58e6ee5fSAndroid Build Coastguard Worker {
2424*58e6ee5fSAndroid Build Coastguard Worker 	int fd = instance->tracing_on_fd;
2425*58e6ee5fSAndroid Build Coastguard Worker 
2426*58e6ee5fSAndroid Build Coastguard Worker 	/* OK, we keep zero for stdin */
2427*58e6ee5fSAndroid Build Coastguard Worker 	if (fd > 0)
2428*58e6ee5fSAndroid Build Coastguard Worker 		return fd;
2429*58e6ee5fSAndroid Build Coastguard Worker 
2430*58e6ee5fSAndroid Build Coastguard Worker 	fd = open_instance_fd(instance, "tracing_on", O_RDWR | O_CLOEXEC);
2431*58e6ee5fSAndroid Build Coastguard Worker 	if (fd < 0) {
2432*58e6ee5fSAndroid Build Coastguard Worker 		return fd;
2433*58e6ee5fSAndroid Build Coastguard Worker 	}
2434*58e6ee5fSAndroid Build Coastguard Worker 	instance->tracing_on_fd = fd;
2435*58e6ee5fSAndroid Build Coastguard Worker 
2436*58e6ee5fSAndroid Build Coastguard Worker 	return fd;
2437*58e6ee5fSAndroid Build Coastguard Worker }
2438*58e6ee5fSAndroid Build Coastguard Worker 
write_tracing_on(struct buffer_instance * instance,int on)2439*58e6ee5fSAndroid Build Coastguard Worker static void write_tracing_on(struct buffer_instance *instance, int on)
2440*58e6ee5fSAndroid Build Coastguard Worker {
2441*58e6ee5fSAndroid Build Coastguard Worker 	int ret;
2442*58e6ee5fSAndroid Build Coastguard Worker 	int fd;
2443*58e6ee5fSAndroid Build Coastguard Worker 
2444*58e6ee5fSAndroid Build Coastguard Worker 	if (is_guest(instance))
2445*58e6ee5fSAndroid Build Coastguard Worker 		return;
2446*58e6ee5fSAndroid Build Coastguard Worker 
2447*58e6ee5fSAndroid Build Coastguard Worker 	fd = open_tracing_on(instance);
2448*58e6ee5fSAndroid Build Coastguard Worker 	if (fd < 0)
2449*58e6ee5fSAndroid Build Coastguard Worker 		return;
2450*58e6ee5fSAndroid Build Coastguard Worker 
2451*58e6ee5fSAndroid Build Coastguard Worker 	if (on)
2452*58e6ee5fSAndroid Build Coastguard Worker 		ret = write(fd, "1", 1);
2453*58e6ee5fSAndroid Build Coastguard Worker 	else
2454*58e6ee5fSAndroid Build Coastguard Worker 		ret = write(fd, "0", 1);
2455*58e6ee5fSAndroid Build Coastguard Worker 
2456*58e6ee5fSAndroid Build Coastguard Worker 	if (ret < 0)
2457*58e6ee5fSAndroid Build Coastguard Worker 		die("writing 'tracing_on'");
2458*58e6ee5fSAndroid Build Coastguard Worker }
2459*58e6ee5fSAndroid Build Coastguard Worker 
read_tracing_on(struct buffer_instance * instance)2460*58e6ee5fSAndroid Build Coastguard Worker static int read_tracing_on(struct buffer_instance *instance)
2461*58e6ee5fSAndroid Build Coastguard Worker {
2462*58e6ee5fSAndroid Build Coastguard Worker 	int fd;
2463*58e6ee5fSAndroid Build Coastguard Worker 	char buf[10];
2464*58e6ee5fSAndroid Build Coastguard Worker 	int ret;
2465*58e6ee5fSAndroid Build Coastguard Worker 
2466*58e6ee5fSAndroid Build Coastguard Worker 	if (is_guest(instance))
2467*58e6ee5fSAndroid Build Coastguard Worker 		return -1;
2468*58e6ee5fSAndroid Build Coastguard Worker 
2469*58e6ee5fSAndroid Build Coastguard Worker 	fd = open_tracing_on(instance);
2470*58e6ee5fSAndroid Build Coastguard Worker 	if (fd < 0)
2471*58e6ee5fSAndroid Build Coastguard Worker 		return fd;
2472*58e6ee5fSAndroid Build Coastguard Worker 
2473*58e6ee5fSAndroid Build Coastguard Worker 	ret = read(fd, buf, 10);
2474*58e6ee5fSAndroid Build Coastguard Worker 	if (ret <= 0)
2475*58e6ee5fSAndroid Build Coastguard Worker 		die("Reading 'tracing_on'");
2476*58e6ee5fSAndroid Build Coastguard Worker 	buf[9] = 0;
2477*58e6ee5fSAndroid Build Coastguard Worker 	ret = atoi(buf);
2478*58e6ee5fSAndroid Build Coastguard Worker 
2479*58e6ee5fSAndroid Build Coastguard Worker 	return ret;
2480*58e6ee5fSAndroid Build Coastguard Worker }
2481*58e6ee5fSAndroid Build Coastguard Worker 
reset_max_latency_instance(void)2482*58e6ee5fSAndroid Build Coastguard Worker static void reset_max_latency_instance(void)
2483*58e6ee5fSAndroid Build Coastguard Worker {
2484*58e6ee5fSAndroid Build Coastguard Worker 	struct buffer_instance *instance;
2485*58e6ee5fSAndroid Build Coastguard Worker 
2486*58e6ee5fSAndroid Build Coastguard Worker 	for_all_instances(instance)
2487*58e6ee5fSAndroid Build Coastguard Worker 		reset_max_latency(instance);
2488*58e6ee5fSAndroid Build Coastguard Worker }
2489*58e6ee5fSAndroid Build Coastguard Worker 
tracecmd_enable_tracing(void)2490*58e6ee5fSAndroid Build Coastguard Worker void tracecmd_enable_tracing(void)
2491*58e6ee5fSAndroid Build Coastguard Worker {
2492*58e6ee5fSAndroid Build Coastguard Worker 	struct buffer_instance *instance;
2493*58e6ee5fSAndroid Build Coastguard Worker 
2494*58e6ee5fSAndroid Build Coastguard Worker 	check_tracing_enabled();
2495*58e6ee5fSAndroid Build Coastguard Worker 
2496*58e6ee5fSAndroid Build Coastguard Worker 	for_all_instances(instance)
2497*58e6ee5fSAndroid Build Coastguard Worker 		write_tracing_on(instance, 1);
2498*58e6ee5fSAndroid Build Coastguard Worker 
2499*58e6ee5fSAndroid Build Coastguard Worker 	if (latency)
2500*58e6ee5fSAndroid Build Coastguard Worker 		reset_max_latency_instance();
2501*58e6ee5fSAndroid Build Coastguard Worker }
2502*58e6ee5fSAndroid Build Coastguard Worker 
tracecmd_disable_tracing(void)2503*58e6ee5fSAndroid Build Coastguard Worker void tracecmd_disable_tracing(void)
2504*58e6ee5fSAndroid Build Coastguard Worker {
2505*58e6ee5fSAndroid Build Coastguard Worker 	struct buffer_instance *instance;
2506*58e6ee5fSAndroid Build Coastguard Worker 
2507*58e6ee5fSAndroid Build Coastguard Worker 	for_all_instances(instance)
2508*58e6ee5fSAndroid Build Coastguard Worker 		write_tracing_on(instance, 0);
2509*58e6ee5fSAndroid Build Coastguard Worker }
2510*58e6ee5fSAndroid Build Coastguard Worker 
tracecmd_disable_all_tracing(int disable_tracer)2511*58e6ee5fSAndroid Build Coastguard Worker void tracecmd_disable_all_tracing(int disable_tracer)
2512*58e6ee5fSAndroid Build Coastguard Worker {
2513*58e6ee5fSAndroid Build Coastguard Worker 	struct buffer_instance *instance;
2514*58e6ee5fSAndroid Build Coastguard Worker 
2515*58e6ee5fSAndroid Build Coastguard Worker 	tracecmd_disable_tracing();
2516*58e6ee5fSAndroid Build Coastguard Worker 
2517*58e6ee5fSAndroid Build Coastguard Worker 	if (disable_tracer) {
2518*58e6ee5fSAndroid Build Coastguard Worker 		disable_func_stack_trace();
2519*58e6ee5fSAndroid Build Coastguard Worker 		set_plugin("nop");
2520*58e6ee5fSAndroid Build Coastguard Worker 	}
2521*58e6ee5fSAndroid Build Coastguard Worker 
2522*58e6ee5fSAndroid Build Coastguard Worker 	reset_events();
2523*58e6ee5fSAndroid Build Coastguard Worker 
2524*58e6ee5fSAndroid Build Coastguard Worker 	/* Force close and reset of ftrace pid file */
2525*58e6ee5fSAndroid Build Coastguard Worker 	for_all_instances(instance)
2526*58e6ee5fSAndroid Build Coastguard Worker 		update_ftrace_pid(instance, "", 1);
2527*58e6ee5fSAndroid Build Coastguard Worker 
2528*58e6ee5fSAndroid Build Coastguard Worker 	clear_trace_instances();
2529*58e6ee5fSAndroid Build Coastguard Worker }
2530*58e6ee5fSAndroid Build Coastguard Worker 
2531*58e6ee5fSAndroid Build Coastguard Worker static void
update_sched_event(struct buffer_instance * instance,struct event_list * event,const char * field)2532*58e6ee5fSAndroid Build Coastguard Worker update_sched_event(struct buffer_instance *instance,
2533*58e6ee5fSAndroid Build Coastguard Worker 		   struct event_list *event, const char *field)
2534*58e6ee5fSAndroid Build Coastguard Worker {
2535*58e6ee5fSAndroid Build Coastguard Worker 	if (!event)
2536*58e6ee5fSAndroid Build Coastguard Worker 		return;
2537*58e6ee5fSAndroid Build Coastguard Worker 
2538*58e6ee5fSAndroid Build Coastguard Worker 	event->pid_filter = make_pid_filter(instance, event->pid_filter, field);
2539*58e6ee5fSAndroid Build Coastguard Worker }
2540*58e6ee5fSAndroid Build Coastguard Worker 
update_event_filters(struct buffer_instance * instance)2541*58e6ee5fSAndroid Build Coastguard Worker static void update_event_filters(struct buffer_instance *instance)
2542*58e6ee5fSAndroid Build Coastguard Worker {
2543*58e6ee5fSAndroid Build Coastguard Worker 	struct event_list *event;
2544*58e6ee5fSAndroid Build Coastguard Worker 	char *event_filter;
2545*58e6ee5fSAndroid Build Coastguard Worker 	int free_it;
2546*58e6ee5fSAndroid Build Coastguard Worker 	int len;
2547*58e6ee5fSAndroid Build Coastguard Worker 	int common_len = 0;
2548*58e6ee5fSAndroid Build Coastguard Worker 
2549*58e6ee5fSAndroid Build Coastguard Worker 	if (instance->common_pid_filter)
2550*58e6ee5fSAndroid Build Coastguard Worker 		common_len = strlen(instance->common_pid_filter);
2551*58e6ee5fSAndroid Build Coastguard Worker 
2552*58e6ee5fSAndroid Build Coastguard Worker 	for (event = instance->events; event; event = event->next) {
2553*58e6ee5fSAndroid Build Coastguard Worker 		if (!event->neg) {
2554*58e6ee5fSAndroid Build Coastguard Worker 
2555*58e6ee5fSAndroid Build Coastguard Worker 			free_it = 0;
2556*58e6ee5fSAndroid Build Coastguard Worker 			if (event->filter) {
2557*58e6ee5fSAndroid Build Coastguard Worker 				if (!instance->common_pid_filter)
2558*58e6ee5fSAndroid Build Coastguard Worker 					/*
2559*58e6ee5fSAndroid Build Coastguard Worker 					 * event->pid_filter is only created if
2560*58e6ee5fSAndroid Build Coastguard Worker 					 * common_pid_filter is. No need to check that.
2561*58e6ee5fSAndroid Build Coastguard Worker 					 * Just use the current event->filter.
2562*58e6ee5fSAndroid Build Coastguard Worker 					 */
2563*58e6ee5fSAndroid Build Coastguard Worker 					event_filter = event->filter;
2564*58e6ee5fSAndroid Build Coastguard Worker 				else if (event->pid_filter) {
2565*58e6ee5fSAndroid Build Coastguard Worker 					free_it = 1;
2566*58e6ee5fSAndroid Build Coastguard Worker 					len = common_len + strlen(event->pid_filter) +
2567*58e6ee5fSAndroid Build Coastguard Worker 						strlen(event->filter) + strlen("()&&(||)") + 1;
2568*58e6ee5fSAndroid Build Coastguard Worker 					event_filter = malloc(len);
2569*58e6ee5fSAndroid Build Coastguard Worker 					if (!event_filter)
2570*58e6ee5fSAndroid Build Coastguard Worker 						die("Failed to allocate event_filter");
2571*58e6ee5fSAndroid Build Coastguard Worker 					sprintf(event_filter, "(%s)&&(%s||%s)",
2572*58e6ee5fSAndroid Build Coastguard Worker 						event->filter, instance->common_pid_filter,
2573*58e6ee5fSAndroid Build Coastguard Worker 						event->pid_filter);
2574*58e6ee5fSAndroid Build Coastguard Worker 				} else {
2575*58e6ee5fSAndroid Build Coastguard Worker 					free_it = 1;
2576*58e6ee5fSAndroid Build Coastguard Worker 					len = common_len + strlen(event->filter) +
2577*58e6ee5fSAndroid Build Coastguard Worker 						strlen("()&&()") + 1;
2578*58e6ee5fSAndroid Build Coastguard Worker 					event_filter = malloc(len);
2579*58e6ee5fSAndroid Build Coastguard Worker 					if (!event_filter)
2580*58e6ee5fSAndroid Build Coastguard Worker 						die("Failed to allocate event_filter");
2581*58e6ee5fSAndroid Build Coastguard Worker 					sprintf(event_filter, "(%s)&&(%s)",
2582*58e6ee5fSAndroid Build Coastguard Worker 						event->filter, instance->common_pid_filter);
2583*58e6ee5fSAndroid Build Coastguard Worker 				}
2584*58e6ee5fSAndroid Build Coastguard Worker 			} else {
2585*58e6ee5fSAndroid Build Coastguard Worker 				/* event->pid_filter only exists when common_pid_filter does */
2586*58e6ee5fSAndroid Build Coastguard Worker 				if (!instance->common_pid_filter)
2587*58e6ee5fSAndroid Build Coastguard Worker 					continue;
2588*58e6ee5fSAndroid Build Coastguard Worker 
2589*58e6ee5fSAndroid Build Coastguard Worker 				if (event->pid_filter) {
2590*58e6ee5fSAndroid Build Coastguard Worker 					free_it = 1;
2591*58e6ee5fSAndroid Build Coastguard Worker 					len = common_len + strlen(event->pid_filter) +
2592*58e6ee5fSAndroid Build Coastguard Worker 						strlen("||") + 1;
2593*58e6ee5fSAndroid Build Coastguard Worker 					event_filter = malloc(len);
2594*58e6ee5fSAndroid Build Coastguard Worker 					if (!event_filter)
2595*58e6ee5fSAndroid Build Coastguard Worker 						die("Failed to allocate event_filter");
2596*58e6ee5fSAndroid Build Coastguard Worker 					sprintf(event_filter, "%s||%s",
2597*58e6ee5fSAndroid Build Coastguard Worker 							instance->common_pid_filter, event->pid_filter);
2598*58e6ee5fSAndroid Build Coastguard Worker 				} else
2599*58e6ee5fSAndroid Build Coastguard Worker 					event_filter = instance->common_pid_filter;
2600*58e6ee5fSAndroid Build Coastguard Worker 			}
2601*58e6ee5fSAndroid Build Coastguard Worker 
2602*58e6ee5fSAndroid Build Coastguard Worker 			update_event(event, event_filter, 1, '1');
2603*58e6ee5fSAndroid Build Coastguard Worker 			if (free_it)
2604*58e6ee5fSAndroid Build Coastguard Worker 				free(event_filter);
2605*58e6ee5fSAndroid Build Coastguard Worker 		}
2606*58e6ee5fSAndroid Build Coastguard Worker 	}
2607*58e6ee5fSAndroid Build Coastguard Worker }
2608*58e6ee5fSAndroid Build Coastguard Worker 
update_pid_filters(struct buffer_instance * instance)2609*58e6ee5fSAndroid Build Coastguard Worker static void update_pid_filters(struct buffer_instance *instance)
2610*58e6ee5fSAndroid Build Coastguard Worker {
2611*58e6ee5fSAndroid Build Coastguard Worker 	struct filter_pids *p;
2612*58e6ee5fSAndroid Build Coastguard Worker 	char *filter;
2613*58e6ee5fSAndroid Build Coastguard Worker 	char *str;
2614*58e6ee5fSAndroid Build Coastguard Worker 	int len;
2615*58e6ee5fSAndroid Build Coastguard Worker 	int ret;
2616*58e6ee5fSAndroid Build Coastguard Worker 	int fd;
2617*58e6ee5fSAndroid Build Coastguard Worker 
2618*58e6ee5fSAndroid Build Coastguard Worker 	if (is_guest(instance))
2619*58e6ee5fSAndroid Build Coastguard Worker 		return;
2620*58e6ee5fSAndroid Build Coastguard Worker 
2621*58e6ee5fSAndroid Build Coastguard Worker 	fd = open_instance_fd(instance, "set_event_pid",
2622*58e6ee5fSAndroid Build Coastguard Worker 			      O_WRONLY | O_CLOEXEC | O_TRUNC);
2623*58e6ee5fSAndroid Build Coastguard Worker 	if (fd < 0)
2624*58e6ee5fSAndroid Build Coastguard Worker 		die("Failed to access set_event_pid");
2625*58e6ee5fSAndroid Build Coastguard Worker 
2626*58e6ee5fSAndroid Build Coastguard Worker 	len = instance->len_filter_pids + instance->nr_filter_pids;
2627*58e6ee5fSAndroid Build Coastguard Worker 	filter = malloc(len);
2628*58e6ee5fSAndroid Build Coastguard Worker 	if (!filter)
2629*58e6ee5fSAndroid Build Coastguard Worker 		die("Failed to allocate pid filter");
2630*58e6ee5fSAndroid Build Coastguard Worker 
2631*58e6ee5fSAndroid Build Coastguard Worker 	str = filter;
2632*58e6ee5fSAndroid Build Coastguard Worker 
2633*58e6ee5fSAndroid Build Coastguard Worker 	for (p = instance->filter_pids; p; p = p->next) {
2634*58e6ee5fSAndroid Build Coastguard Worker 		if (p->exclude)
2635*58e6ee5fSAndroid Build Coastguard Worker 			continue;
2636*58e6ee5fSAndroid Build Coastguard Worker 		len = sprintf(str, "%d ", p->pid);
2637*58e6ee5fSAndroid Build Coastguard Worker 		str += len;
2638*58e6ee5fSAndroid Build Coastguard Worker 	}
2639*58e6ee5fSAndroid Build Coastguard Worker 
2640*58e6ee5fSAndroid Build Coastguard Worker 	if (filter == str)
2641*58e6ee5fSAndroid Build Coastguard Worker 		goto out;
2642*58e6ee5fSAndroid Build Coastguard Worker 
2643*58e6ee5fSAndroid Build Coastguard Worker 	len = str - filter;
2644*58e6ee5fSAndroid Build Coastguard Worker 	str = filter;
2645*58e6ee5fSAndroid Build Coastguard Worker 	do {
2646*58e6ee5fSAndroid Build Coastguard Worker 		ret = write(fd, str, len);
2647*58e6ee5fSAndroid Build Coastguard Worker 		if (ret < 0)
2648*58e6ee5fSAndroid Build Coastguard Worker 			die("Failed to write to set_event_pid");
2649*58e6ee5fSAndroid Build Coastguard Worker 		str += ret;
2650*58e6ee5fSAndroid Build Coastguard Worker 		len -= ret;
2651*58e6ee5fSAndroid Build Coastguard Worker 	} while (ret >= 0 && len);
2652*58e6ee5fSAndroid Build Coastguard Worker 
2653*58e6ee5fSAndroid Build Coastguard Worker  out:
2654*58e6ee5fSAndroid Build Coastguard Worker 	close(fd);
2655*58e6ee5fSAndroid Build Coastguard Worker }
2656*58e6ee5fSAndroid Build Coastguard Worker 
update_pid_event_filters(struct buffer_instance * instance)2657*58e6ee5fSAndroid Build Coastguard Worker static void update_pid_event_filters(struct buffer_instance *instance)
2658*58e6ee5fSAndroid Build Coastguard Worker {
2659*58e6ee5fSAndroid Build Coastguard Worker 	if (instance->have_set_event_pid)
2660*58e6ee5fSAndroid Build Coastguard Worker 		return update_pid_filters(instance);
2661*58e6ee5fSAndroid Build Coastguard Worker 	/*
2662*58e6ee5fSAndroid Build Coastguard Worker 	 * Also make sure that the sched_switch to this pid
2663*58e6ee5fSAndroid Build Coastguard Worker 	 * and wakeups of this pid are also traced.
2664*58e6ee5fSAndroid Build Coastguard Worker 	 * Only need to do this if the events are active.
2665*58e6ee5fSAndroid Build Coastguard Worker 	 */
2666*58e6ee5fSAndroid Build Coastguard Worker 	update_sched_event(instance, instance->sched_switch_event, "next_pid");
2667*58e6ee5fSAndroid Build Coastguard Worker 	update_sched_event(instance, instance->sched_wakeup_event, "pid");
2668*58e6ee5fSAndroid Build Coastguard Worker 	update_sched_event(instance, instance->sched_wakeup_new_event, "pid");
2669*58e6ee5fSAndroid Build Coastguard Worker 
2670*58e6ee5fSAndroid Build Coastguard Worker 	update_event_filters(instance);
2671*58e6ee5fSAndroid Build Coastguard Worker }
2672*58e6ee5fSAndroid Build Coastguard Worker 
2673*58e6ee5fSAndroid Build Coastguard Worker #define MASK_STR_MAX 4096 /* Don't expect more than 32768 CPUS */
2674*58e6ee5fSAndroid Build Coastguard Worker 
alloc_mask_from_hex(struct buffer_instance * instance,const char * str)2675*58e6ee5fSAndroid Build Coastguard Worker static char *alloc_mask_from_hex(struct buffer_instance *instance, const char *str)
2676*58e6ee5fSAndroid Build Coastguard Worker {
2677*58e6ee5fSAndroid Build Coastguard Worker 	char *cpumask;
2678*58e6ee5fSAndroid Build Coastguard Worker 
2679*58e6ee5fSAndroid Build Coastguard Worker 	if (strcmp(str, "-1") == 0) {
2680*58e6ee5fSAndroid Build Coastguard Worker 		/* set all CPUs */
2681*58e6ee5fSAndroid Build Coastguard Worker 		int bytes = (instance->cpu_count + 7) / 8;
2682*58e6ee5fSAndroid Build Coastguard Worker 		int last = instance->cpu_count % 8;
2683*58e6ee5fSAndroid Build Coastguard Worker 		int i;
2684*58e6ee5fSAndroid Build Coastguard Worker 
2685*58e6ee5fSAndroid Build Coastguard Worker 		cpumask = malloc(MASK_STR_MAX);
2686*58e6ee5fSAndroid Build Coastguard Worker 		if (!cpumask)
2687*58e6ee5fSAndroid Build Coastguard Worker 			die("can't allocate cpumask");
2688*58e6ee5fSAndroid Build Coastguard Worker 
2689*58e6ee5fSAndroid Build Coastguard Worker 		if (bytes > (MASK_STR_MAX-1)) {
2690*58e6ee5fSAndroid Build Coastguard Worker 			warning("cpumask can't handle more than 32768 CPUS!");
2691*58e6ee5fSAndroid Build Coastguard Worker 			bytes = MASK_STR_MAX-1;
2692*58e6ee5fSAndroid Build Coastguard Worker 		}
2693*58e6ee5fSAndroid Build Coastguard Worker 
2694*58e6ee5fSAndroid Build Coastguard Worker 		sprintf(cpumask, "%x", (1 << last) - 1);
2695*58e6ee5fSAndroid Build Coastguard Worker 
2696*58e6ee5fSAndroid Build Coastguard Worker 		for (i = 1; i < bytes; i++)
2697*58e6ee5fSAndroid Build Coastguard Worker 			cpumask[i] = 'f';
2698*58e6ee5fSAndroid Build Coastguard Worker 
2699*58e6ee5fSAndroid Build Coastguard Worker 		cpumask[i+1] = 0;
2700*58e6ee5fSAndroid Build Coastguard Worker 	} else {
2701*58e6ee5fSAndroid Build Coastguard Worker 		cpumask = strdup(str);
2702*58e6ee5fSAndroid Build Coastguard Worker 		if (!cpumask)
2703*58e6ee5fSAndroid Build Coastguard Worker 			die("can't allocate cpumask");
2704*58e6ee5fSAndroid Build Coastguard Worker 	}
2705*58e6ee5fSAndroid Build Coastguard Worker 
2706*58e6ee5fSAndroid Build Coastguard Worker 	return cpumask;
2707*58e6ee5fSAndroid Build Coastguard Worker }
2708*58e6ee5fSAndroid Build Coastguard Worker 
set_mask(struct buffer_instance * instance)2709*58e6ee5fSAndroid Build Coastguard Worker static void set_mask(struct buffer_instance *instance)
2710*58e6ee5fSAndroid Build Coastguard Worker {
2711*58e6ee5fSAndroid Build Coastguard Worker 	struct stat st;
2712*58e6ee5fSAndroid Build Coastguard Worker 	char *path;
2713*58e6ee5fSAndroid Build Coastguard Worker 	int fd;
2714*58e6ee5fSAndroid Build Coastguard Worker 	int ret;
2715*58e6ee5fSAndroid Build Coastguard Worker 
2716*58e6ee5fSAndroid Build Coastguard Worker 	if (is_guest(instance))
2717*58e6ee5fSAndroid Build Coastguard Worker 		return;
2718*58e6ee5fSAndroid Build Coastguard Worker 
2719*58e6ee5fSAndroid Build Coastguard Worker 	if (!instance->cpumask)
2720*58e6ee5fSAndroid Build Coastguard Worker 		return;
2721*58e6ee5fSAndroid Build Coastguard Worker 
2722*58e6ee5fSAndroid Build Coastguard Worker 	path = tracefs_instance_get_file(instance->tracefs, "tracing_cpumask");
2723*58e6ee5fSAndroid Build Coastguard Worker 	if (!path)
2724*58e6ee5fSAndroid Build Coastguard Worker 		die("could not allocate path");
2725*58e6ee5fSAndroid Build Coastguard Worker 	reset_save_file(path, RESET_DEFAULT_PRIO);
2726*58e6ee5fSAndroid Build Coastguard Worker 
2727*58e6ee5fSAndroid Build Coastguard Worker 	ret = stat(path, &st);
2728*58e6ee5fSAndroid Build Coastguard Worker 	if (ret < 0) {
2729*58e6ee5fSAndroid Build Coastguard Worker 		warning("%s not found", path);
2730*58e6ee5fSAndroid Build Coastguard Worker 		goto out;
2731*58e6ee5fSAndroid Build Coastguard Worker 	}
2732*58e6ee5fSAndroid Build Coastguard Worker 
2733*58e6ee5fSAndroid Build Coastguard Worker 	fd = open(path, O_WRONLY | O_TRUNC);
2734*58e6ee5fSAndroid Build Coastguard Worker 	if (fd < 0)
2735*58e6ee5fSAndroid Build Coastguard Worker 		die("could not open %s\n", path);
2736*58e6ee5fSAndroid Build Coastguard Worker 
2737*58e6ee5fSAndroid Build Coastguard Worker 	write(fd, instance->cpumask, strlen(instance->cpumask));
2738*58e6ee5fSAndroid Build Coastguard Worker 
2739*58e6ee5fSAndroid Build Coastguard Worker 	close(fd);
2740*58e6ee5fSAndroid Build Coastguard Worker  out:
2741*58e6ee5fSAndroid Build Coastguard Worker 	tracefs_put_tracing_file(path);
2742*58e6ee5fSAndroid Build Coastguard Worker 	free(instance->cpumask);
2743*58e6ee5fSAndroid Build Coastguard Worker 	instance->cpumask = NULL;
2744*58e6ee5fSAndroid Build Coastguard Worker }
2745*58e6ee5fSAndroid Build Coastguard Worker 
enable_events(struct buffer_instance * instance)2746*58e6ee5fSAndroid Build Coastguard Worker static void enable_events(struct buffer_instance *instance)
2747*58e6ee5fSAndroid Build Coastguard Worker {
2748*58e6ee5fSAndroid Build Coastguard Worker 	struct event_list *event;
2749*58e6ee5fSAndroid Build Coastguard Worker 
2750*58e6ee5fSAndroid Build Coastguard Worker 	if (is_guest(instance))
2751*58e6ee5fSAndroid Build Coastguard Worker 		return;
2752*58e6ee5fSAndroid Build Coastguard Worker 
2753*58e6ee5fSAndroid Build Coastguard Worker 	for (event = instance->events; event; event = event->next) {
2754*58e6ee5fSAndroid Build Coastguard Worker 		if (!event->neg)
2755*58e6ee5fSAndroid Build Coastguard Worker 			update_event(event, event->filter, 0, '1');
2756*58e6ee5fSAndroid Build Coastguard Worker 	}
2757*58e6ee5fSAndroid Build Coastguard Worker 
2758*58e6ee5fSAndroid Build Coastguard Worker 	/* Now disable any events */
2759*58e6ee5fSAndroid Build Coastguard Worker 	for (event = instance->events; event; event = event->next) {
2760*58e6ee5fSAndroid Build Coastguard Worker 		if (event->neg)
2761*58e6ee5fSAndroid Build Coastguard Worker 			update_event(event, NULL, 0, '0');
2762*58e6ee5fSAndroid Build Coastguard Worker 	}
2763*58e6ee5fSAndroid Build Coastguard Worker }
2764*58e6ee5fSAndroid Build Coastguard Worker 
tracecmd_enable_events(void)2765*58e6ee5fSAndroid Build Coastguard Worker void tracecmd_enable_events(void)
2766*58e6ee5fSAndroid Build Coastguard Worker {
2767*58e6ee5fSAndroid Build Coastguard Worker 	enable_events(first_instance);
2768*58e6ee5fSAndroid Build Coastguard Worker }
2769*58e6ee5fSAndroid Build Coastguard Worker 
set_clock(struct common_record_context * ctx,struct buffer_instance * instance)2770*58e6ee5fSAndroid Build Coastguard Worker static void set_clock(struct common_record_context *ctx, struct buffer_instance *instance)
2771*58e6ee5fSAndroid Build Coastguard Worker {
2772*58e6ee5fSAndroid Build Coastguard Worker 	const char *clock;
2773*58e6ee5fSAndroid Build Coastguard Worker 	char *path;
2774*58e6ee5fSAndroid Build Coastguard Worker 	char *content;
2775*58e6ee5fSAndroid Build Coastguard Worker 	char *str;
2776*58e6ee5fSAndroid Build Coastguard Worker 
2777*58e6ee5fSAndroid Build Coastguard Worker 	if (is_guest(instance))
2778*58e6ee5fSAndroid Build Coastguard Worker 		return;
2779*58e6ee5fSAndroid Build Coastguard Worker 
2780*58e6ee5fSAndroid Build Coastguard Worker 	if (instance->clock)
2781*58e6ee5fSAndroid Build Coastguard Worker 		clock = instance->clock;
2782*58e6ee5fSAndroid Build Coastguard Worker 	else
2783*58e6ee5fSAndroid Build Coastguard Worker 		clock = ctx->clock;
2784*58e6ee5fSAndroid Build Coastguard Worker 
2785*58e6ee5fSAndroid Build Coastguard Worker 	if (!clock)
2786*58e6ee5fSAndroid Build Coastguard Worker 		return;
2787*58e6ee5fSAndroid Build Coastguard Worker 
2788*58e6ee5fSAndroid Build Coastguard Worker 	/* The current clock is in brackets, reset it when we are done */
2789*58e6ee5fSAndroid Build Coastguard Worker 	content = tracefs_instance_file_read(instance->tracefs,
2790*58e6ee5fSAndroid Build Coastguard Worker 					     "trace_clock", NULL);
2791*58e6ee5fSAndroid Build Coastguard Worker 
2792*58e6ee5fSAndroid Build Coastguard Worker 	/* check if first clock is set */
2793*58e6ee5fSAndroid Build Coastguard Worker 	if (*content == '[')
2794*58e6ee5fSAndroid Build Coastguard Worker 		str = strtok(content+1, "]");
2795*58e6ee5fSAndroid Build Coastguard Worker 	else {
2796*58e6ee5fSAndroid Build Coastguard Worker 		str = strtok(content, "[");
2797*58e6ee5fSAndroid Build Coastguard Worker 		if (!str)
2798*58e6ee5fSAndroid Build Coastguard Worker 			die("Can not find clock in trace_clock");
2799*58e6ee5fSAndroid Build Coastguard Worker 		str = strtok(NULL, "]");
2800*58e6ee5fSAndroid Build Coastguard Worker 	}
2801*58e6ee5fSAndroid Build Coastguard Worker 	path = tracefs_instance_get_file(instance->tracefs, "trace_clock");
2802*58e6ee5fSAndroid Build Coastguard Worker 	add_reset_file(path, str, RESET_DEFAULT_PRIO);
2803*58e6ee5fSAndroid Build Coastguard Worker 
2804*58e6ee5fSAndroid Build Coastguard Worker 	free(content);
2805*58e6ee5fSAndroid Build Coastguard Worker 	tracefs_put_tracing_file(path);
2806*58e6ee5fSAndroid Build Coastguard Worker 
2807*58e6ee5fSAndroid Build Coastguard Worker 	tracefs_instance_file_write(instance->tracefs,
2808*58e6ee5fSAndroid Build Coastguard Worker 				    "trace_clock", clock);
2809*58e6ee5fSAndroid Build Coastguard Worker }
2810*58e6ee5fSAndroid Build Coastguard Worker 
set_max_graph_depth(struct buffer_instance * instance,char * max_graph_depth)2811*58e6ee5fSAndroid Build Coastguard Worker static void set_max_graph_depth(struct buffer_instance *instance, char *max_graph_depth)
2812*58e6ee5fSAndroid Build Coastguard Worker {
2813*58e6ee5fSAndroid Build Coastguard Worker 	char *path;
2814*58e6ee5fSAndroid Build Coastguard Worker 	int ret;
2815*58e6ee5fSAndroid Build Coastguard Worker 
2816*58e6ee5fSAndroid Build Coastguard Worker 	if (is_guest(instance))
2817*58e6ee5fSAndroid Build Coastguard Worker 		return;
2818*58e6ee5fSAndroid Build Coastguard Worker 
2819*58e6ee5fSAndroid Build Coastguard Worker 	path = tracefs_instance_get_file(instance->tracefs, "max_graph_depth");
2820*58e6ee5fSAndroid Build Coastguard Worker 	reset_save_file(path, RESET_DEFAULT_PRIO);
2821*58e6ee5fSAndroid Build Coastguard Worker 	tracefs_put_tracing_file(path);
2822*58e6ee5fSAndroid Build Coastguard Worker 	ret = tracefs_instance_file_write(instance->tracefs, "max_graph_depth",
2823*58e6ee5fSAndroid Build Coastguard Worker 					  max_graph_depth);
2824*58e6ee5fSAndroid Build Coastguard Worker 	if (ret < 0)
2825*58e6ee5fSAndroid Build Coastguard Worker 		die("could not write to max_graph_depth");
2826*58e6ee5fSAndroid Build Coastguard Worker }
2827*58e6ee5fSAndroid Build Coastguard Worker 
check_file_in_dir(char * dir,char * file)2828*58e6ee5fSAndroid Build Coastguard Worker static bool check_file_in_dir(char *dir, char *file)
2829*58e6ee5fSAndroid Build Coastguard Worker {
2830*58e6ee5fSAndroid Build Coastguard Worker 	struct stat st;
2831*58e6ee5fSAndroid Build Coastguard Worker 	char *path;
2832*58e6ee5fSAndroid Build Coastguard Worker 	int ret;
2833*58e6ee5fSAndroid Build Coastguard Worker 
2834*58e6ee5fSAndroid Build Coastguard Worker 	ret = asprintf(&path, "%s/%s", dir, file);
2835*58e6ee5fSAndroid Build Coastguard Worker 	if (ret < 0)
2836*58e6ee5fSAndroid Build Coastguard Worker 		die("Failed to allocate id file path for %s/%s", dir, file);
2837*58e6ee5fSAndroid Build Coastguard Worker 	ret = stat(path, &st);
2838*58e6ee5fSAndroid Build Coastguard Worker 	free(path);
2839*58e6ee5fSAndroid Build Coastguard Worker 	if (ret < 0 || S_ISDIR(st.st_mode))
2840*58e6ee5fSAndroid Build Coastguard Worker 		return false;
2841*58e6ee5fSAndroid Build Coastguard Worker 	return true;
2842*58e6ee5fSAndroid Build Coastguard Worker }
2843*58e6ee5fSAndroid Build Coastguard Worker 
2844*58e6ee5fSAndroid Build Coastguard Worker /**
2845*58e6ee5fSAndroid Build Coastguard Worker  * create_event - create and event descriptor
2846*58e6ee5fSAndroid Build Coastguard Worker  * @instance: instance to use
2847*58e6ee5fSAndroid Build Coastguard Worker  * @path: path to event attribute
2848*58e6ee5fSAndroid Build Coastguard Worker  * @old_event: event descriptor to use as base
2849*58e6ee5fSAndroid Build Coastguard Worker  *
2850*58e6ee5fSAndroid Build Coastguard Worker  * NOTE: the function purpose is to create a data structure to describe
2851*58e6ee5fSAndroid Build Coastguard Worker  * an ftrace event. During the process it becomes handy to change the
2852*58e6ee5fSAndroid Build Coastguard Worker  * string `path`. So, do not rely on the content of `path` after you
2853*58e6ee5fSAndroid Build Coastguard Worker  * invoke this function.
2854*58e6ee5fSAndroid Build Coastguard Worker  */
2855*58e6ee5fSAndroid Build Coastguard Worker static struct event_list *
create_event(struct buffer_instance * instance,char * path,struct event_list * old_event)2856*58e6ee5fSAndroid Build Coastguard Worker create_event(struct buffer_instance *instance, char *path, struct event_list *old_event)
2857*58e6ee5fSAndroid Build Coastguard Worker {
2858*58e6ee5fSAndroid Build Coastguard Worker 	struct event_list *event;
2859*58e6ee5fSAndroid Build Coastguard Worker 	struct stat st;
2860*58e6ee5fSAndroid Build Coastguard Worker 	char *path_dirname;
2861*58e6ee5fSAndroid Build Coastguard Worker 	char *p;
2862*58e6ee5fSAndroid Build Coastguard Worker 	int ret;
2863*58e6ee5fSAndroid Build Coastguard Worker 
2864*58e6ee5fSAndroid Build Coastguard Worker 	event = malloc(sizeof(*event));
2865*58e6ee5fSAndroid Build Coastguard Worker 	if (!event)
2866*58e6ee5fSAndroid Build Coastguard Worker 		die("Failed to allocate event");
2867*58e6ee5fSAndroid Build Coastguard Worker 	*event = *old_event;
2868*58e6ee5fSAndroid Build Coastguard Worker 	add_event(instance, event);
2869*58e6ee5fSAndroid Build Coastguard Worker 
2870*58e6ee5fSAndroid Build Coastguard Worker 	if (event->filter || filter_task || instance->filter_pids) {
2871*58e6ee5fSAndroid Build Coastguard Worker 		event->filter_file = strdup(path);
2872*58e6ee5fSAndroid Build Coastguard Worker 		if (!event->filter_file)
2873*58e6ee5fSAndroid Build Coastguard Worker 			die("malloc filter file");
2874*58e6ee5fSAndroid Build Coastguard Worker 	}
2875*58e6ee5fSAndroid Build Coastguard Worker 
2876*58e6ee5fSAndroid Build Coastguard Worker 	path_dirname = dirname(path);
2877*58e6ee5fSAndroid Build Coastguard Worker 
2878*58e6ee5fSAndroid Build Coastguard Worker 	ret = asprintf(&p, "%s/enable", path_dirname);
2879*58e6ee5fSAndroid Build Coastguard Worker 	if (ret < 0)
2880*58e6ee5fSAndroid Build Coastguard Worker 		die("Failed to allocate enable path for %s", path);
2881*58e6ee5fSAndroid Build Coastguard Worker 	ret = stat(p, &st);
2882*58e6ee5fSAndroid Build Coastguard Worker 	if (ret >= 0)
2883*58e6ee5fSAndroid Build Coastguard Worker 		event->enable_file = p;
2884*58e6ee5fSAndroid Build Coastguard Worker 	else
2885*58e6ee5fSAndroid Build Coastguard Worker 		free(p);
2886*58e6ee5fSAndroid Build Coastguard Worker 
2887*58e6ee5fSAndroid Build Coastguard Worker 	if (old_event->trigger) {
2888*58e6ee5fSAndroid Build Coastguard Worker 		if (check_file_in_dir(path_dirname, "trigger")) {
2889*58e6ee5fSAndroid Build Coastguard Worker 			event->trigger = strdup(old_event->trigger);
2890*58e6ee5fSAndroid Build Coastguard Worker 			ret = asprintf(&p, "%s/trigger", path_dirname);
2891*58e6ee5fSAndroid Build Coastguard Worker 			if (ret < 0)
2892*58e6ee5fSAndroid Build Coastguard Worker 				die("Failed to allocate trigger path for %s", path);
2893*58e6ee5fSAndroid Build Coastguard Worker 			event->trigger_file = p;
2894*58e6ee5fSAndroid Build Coastguard Worker 		} else {
2895*58e6ee5fSAndroid Build Coastguard Worker 			/* Check if this is event or system.
2896*58e6ee5fSAndroid Build Coastguard Worker 			 * Systems do not have trigger files by design
2897*58e6ee5fSAndroid Build Coastguard Worker 			 */
2898*58e6ee5fSAndroid Build Coastguard Worker 			if (check_file_in_dir(path_dirname, "id"))
2899*58e6ee5fSAndroid Build Coastguard Worker 				die("trigger specified but not supported by this kernel");
2900*58e6ee5fSAndroid Build Coastguard Worker 		}
2901*58e6ee5fSAndroid Build Coastguard Worker 	}
2902*58e6ee5fSAndroid Build Coastguard Worker 
2903*58e6ee5fSAndroid Build Coastguard Worker 	return event;
2904*58e6ee5fSAndroid Build Coastguard Worker }
2905*58e6ee5fSAndroid Build Coastguard Worker 
make_sched_event(struct buffer_instance * instance,struct event_list ** event,struct event_list * sched,const char * sched_path)2906*58e6ee5fSAndroid Build Coastguard Worker static void make_sched_event(struct buffer_instance *instance,
2907*58e6ee5fSAndroid Build Coastguard Worker 			     struct event_list **event, struct event_list *sched,
2908*58e6ee5fSAndroid Build Coastguard Worker 			     const char *sched_path)
2909*58e6ee5fSAndroid Build Coastguard Worker {
2910*58e6ee5fSAndroid Build Coastguard Worker 	char *path_dirname;
2911*58e6ee5fSAndroid Build Coastguard Worker 	char *tmp_file;
2912*58e6ee5fSAndroid Build Coastguard Worker 	char *path;
2913*58e6ee5fSAndroid Build Coastguard Worker 	int ret;
2914*58e6ee5fSAndroid Build Coastguard Worker 
2915*58e6ee5fSAndroid Build Coastguard Worker 	/* Do nothing if the event already exists */
2916*58e6ee5fSAndroid Build Coastguard Worker 	if (*event)
2917*58e6ee5fSAndroid Build Coastguard Worker 		return;
2918*58e6ee5fSAndroid Build Coastguard Worker 
2919*58e6ee5fSAndroid Build Coastguard Worker 	/* we do not want to corrupt sched->filter_file when using dirname() */
2920*58e6ee5fSAndroid Build Coastguard Worker 	tmp_file = strdup(sched->filter_file);
2921*58e6ee5fSAndroid Build Coastguard Worker 	if (!tmp_file)
2922*58e6ee5fSAndroid Build Coastguard Worker 		die("Failed to allocate path for %s", sched_path);
2923*58e6ee5fSAndroid Build Coastguard Worker 	path_dirname = dirname(tmp_file);
2924*58e6ee5fSAndroid Build Coastguard Worker 
2925*58e6ee5fSAndroid Build Coastguard Worker 	ret = asprintf(&path, "%s/%s/filter", path_dirname, sched_path);
2926*58e6ee5fSAndroid Build Coastguard Worker 	free(tmp_file);
2927*58e6ee5fSAndroid Build Coastguard Worker 	if (ret < 0)
2928*58e6ee5fSAndroid Build Coastguard Worker 		die("Failed to allocate path for %s", sched_path);
2929*58e6ee5fSAndroid Build Coastguard Worker 
2930*58e6ee5fSAndroid Build Coastguard Worker 	*event = create_event(instance, path, sched);
2931*58e6ee5fSAndroid Build Coastguard Worker 	free(path);
2932*58e6ee5fSAndroid Build Coastguard Worker }
2933*58e6ee5fSAndroid Build Coastguard Worker 
test_event(struct event_list * event,const char * path,const char * name,struct event_list ** save,int len)2934*58e6ee5fSAndroid Build Coastguard Worker static void test_event(struct event_list *event, const char *path,
2935*58e6ee5fSAndroid Build Coastguard Worker 		       const char *name, struct event_list **save, int len)
2936*58e6ee5fSAndroid Build Coastguard Worker {
2937*58e6ee5fSAndroid Build Coastguard Worker 	path += len - strlen(name);
2938*58e6ee5fSAndroid Build Coastguard Worker 
2939*58e6ee5fSAndroid Build Coastguard Worker 	if (strcmp(path, name) != 0)
2940*58e6ee5fSAndroid Build Coastguard Worker 		return;
2941*58e6ee5fSAndroid Build Coastguard Worker 
2942*58e6ee5fSAndroid Build Coastguard Worker 	*save = event;
2943*58e6ee5fSAndroid Build Coastguard Worker }
2944*58e6ee5fSAndroid Build Coastguard Worker 
print_event(const char * fmt,...)2945*58e6ee5fSAndroid Build Coastguard Worker static void print_event(const char *fmt, ...)
2946*58e6ee5fSAndroid Build Coastguard Worker {
2947*58e6ee5fSAndroid Build Coastguard Worker 	va_list ap;
2948*58e6ee5fSAndroid Build Coastguard Worker 
2949*58e6ee5fSAndroid Build Coastguard Worker 	if (!show_status)
2950*58e6ee5fSAndroid Build Coastguard Worker 		return;
2951*58e6ee5fSAndroid Build Coastguard Worker 
2952*58e6ee5fSAndroid Build Coastguard Worker 	va_start(ap, fmt);
2953*58e6ee5fSAndroid Build Coastguard Worker 	vprintf(fmt, ap);
2954*58e6ee5fSAndroid Build Coastguard Worker 	va_end(ap);
2955*58e6ee5fSAndroid Build Coastguard Worker 
2956*58e6ee5fSAndroid Build Coastguard Worker 	printf("\n");
2957*58e6ee5fSAndroid Build Coastguard Worker }
2958*58e6ee5fSAndroid Build Coastguard Worker 
2959*58e6ee5fSAndroid Build Coastguard Worker 
expand_event_files(struct buffer_instance * instance,const char * file,struct event_list * old_event)2960*58e6ee5fSAndroid Build Coastguard Worker static int expand_event_files(struct buffer_instance *instance,
2961*58e6ee5fSAndroid Build Coastguard Worker 			      const char *file, struct event_list *old_event)
2962*58e6ee5fSAndroid Build Coastguard Worker {
2963*58e6ee5fSAndroid Build Coastguard Worker 	struct event_list **save_event_tail = instance->event_next;
2964*58e6ee5fSAndroid Build Coastguard Worker 	struct event_list *sched_event = NULL;
2965*58e6ee5fSAndroid Build Coastguard Worker 	struct event_list *event;
2966*58e6ee5fSAndroid Build Coastguard Worker 	glob_t globbuf;
2967*58e6ee5fSAndroid Build Coastguard Worker 	char *path;
2968*58e6ee5fSAndroid Build Coastguard Worker 	char *p;
2969*58e6ee5fSAndroid Build Coastguard Worker 	int ret;
2970*58e6ee5fSAndroid Build Coastguard Worker 	int i;
2971*58e6ee5fSAndroid Build Coastguard Worker 
2972*58e6ee5fSAndroid Build Coastguard Worker 	ret = asprintf(&p, "events/%s/filter", file);
2973*58e6ee5fSAndroid Build Coastguard Worker 	if (ret < 0)
2974*58e6ee5fSAndroid Build Coastguard Worker 		die("Failed to allocate event filter path for %s", file);
2975*58e6ee5fSAndroid Build Coastguard Worker 
2976*58e6ee5fSAndroid Build Coastguard Worker 	path = tracefs_instance_get_file(instance->tracefs, p);
2977*58e6ee5fSAndroid Build Coastguard Worker 
2978*58e6ee5fSAndroid Build Coastguard Worker 	globbuf.gl_offs = 0;
2979*58e6ee5fSAndroid Build Coastguard Worker 	ret = glob(path, 0, NULL, &globbuf);
2980*58e6ee5fSAndroid Build Coastguard Worker 	tracefs_put_tracing_file(path);
2981*58e6ee5fSAndroid Build Coastguard Worker 	free(p);
2982*58e6ee5fSAndroid Build Coastguard Worker 
2983*58e6ee5fSAndroid Build Coastguard Worker 	if (ret < 0)
2984*58e6ee5fSAndroid Build Coastguard Worker 		die("No filters found");
2985*58e6ee5fSAndroid Build Coastguard Worker 
2986*58e6ee5fSAndroid Build Coastguard Worker 	for (i = 0; i < globbuf.gl_pathc; i++) {
2987*58e6ee5fSAndroid Build Coastguard Worker 		int len;
2988*58e6ee5fSAndroid Build Coastguard Worker 
2989*58e6ee5fSAndroid Build Coastguard Worker 		path = globbuf.gl_pathv[i];
2990*58e6ee5fSAndroid Build Coastguard Worker 
2991*58e6ee5fSAndroid Build Coastguard Worker 		event = create_event(instance, path, old_event);
2992*58e6ee5fSAndroid Build Coastguard Worker 		print_event("%s\n", path);
2993*58e6ee5fSAndroid Build Coastguard Worker 
2994*58e6ee5fSAndroid Build Coastguard Worker 		len = strlen(path);
2995*58e6ee5fSAndroid Build Coastguard Worker 
2996*58e6ee5fSAndroid Build Coastguard Worker 		test_event(event, path, "sched", &sched_event, len);
2997*58e6ee5fSAndroid Build Coastguard Worker 		test_event(event, path, "sched/sched_switch", &instance->sched_switch_event, len);
2998*58e6ee5fSAndroid Build Coastguard Worker 		test_event(event, path, "sched/sched_wakeup_new", &instance->sched_wakeup_new_event, len);
2999*58e6ee5fSAndroid Build Coastguard Worker 		test_event(event, path, "sched/sched_wakeup", &instance->sched_wakeup_event, len);
3000*58e6ee5fSAndroid Build Coastguard Worker 	}
3001*58e6ee5fSAndroid Build Coastguard Worker 
3002*58e6ee5fSAndroid Build Coastguard Worker 	if (sched_event && sched_event->filter_file) {
3003*58e6ee5fSAndroid Build Coastguard Worker 		/* make sure all sched events exist */
3004*58e6ee5fSAndroid Build Coastguard Worker 		make_sched_event(instance, &instance->sched_switch_event,
3005*58e6ee5fSAndroid Build Coastguard Worker 				 sched_event, "sched_switch");
3006*58e6ee5fSAndroid Build Coastguard Worker 		make_sched_event(instance, &instance->sched_wakeup_event,
3007*58e6ee5fSAndroid Build Coastguard Worker 				 sched_event, "sched_wakeup");
3008*58e6ee5fSAndroid Build Coastguard Worker 		make_sched_event(instance, &instance->sched_wakeup_new_event,
3009*58e6ee5fSAndroid Build Coastguard Worker 				 sched_event, "sched_wakeup_new");
3010*58e6ee5fSAndroid Build Coastguard Worker 
3011*58e6ee5fSAndroid Build Coastguard Worker 	}
3012*58e6ee5fSAndroid Build Coastguard Worker 
3013*58e6ee5fSAndroid Build Coastguard Worker 
3014*58e6ee5fSAndroid Build Coastguard Worker 	globfree(&globbuf);
3015*58e6ee5fSAndroid Build Coastguard Worker 
3016*58e6ee5fSAndroid Build Coastguard Worker 	/* If the event list tail changed, that means events were added */
3017*58e6ee5fSAndroid Build Coastguard Worker 	return save_event_tail == instance->event_next;
3018*58e6ee5fSAndroid Build Coastguard Worker }
3019*58e6ee5fSAndroid Build Coastguard Worker 
expand_events_all(struct buffer_instance * instance,char * system_name,char * event_name,struct event_list * event)3020*58e6ee5fSAndroid Build Coastguard Worker static int expand_events_all(struct buffer_instance *instance,
3021*58e6ee5fSAndroid Build Coastguard Worker 			     char *system_name, char *event_name,
3022*58e6ee5fSAndroid Build Coastguard Worker 			     struct event_list *event)
3023*58e6ee5fSAndroid Build Coastguard Worker {
3024*58e6ee5fSAndroid Build Coastguard Worker 	char *name;
3025*58e6ee5fSAndroid Build Coastguard Worker 	int ret;
3026*58e6ee5fSAndroid Build Coastguard Worker 
3027*58e6ee5fSAndroid Build Coastguard Worker 	ret = asprintf(&name, "%s/%s", system_name, event_name);
3028*58e6ee5fSAndroid Build Coastguard Worker 	if (ret < 0)
3029*58e6ee5fSAndroid Build Coastguard Worker 		die("Failed to allocate system/event for %s/%s",
3030*58e6ee5fSAndroid Build Coastguard Worker 		     system_name, event_name);
3031*58e6ee5fSAndroid Build Coastguard Worker 	ret = expand_event_files(instance, name, event);
3032*58e6ee5fSAndroid Build Coastguard Worker 	free(name);
3033*58e6ee5fSAndroid Build Coastguard Worker 
3034*58e6ee5fSAndroid Build Coastguard Worker 	return ret;
3035*58e6ee5fSAndroid Build Coastguard Worker }
3036*58e6ee5fSAndroid Build Coastguard Worker 
expand_event(struct buffer_instance * instance,struct event_list * event)3037*58e6ee5fSAndroid Build Coastguard Worker static void expand_event(struct buffer_instance *instance, struct event_list *event)
3038*58e6ee5fSAndroid Build Coastguard Worker {
3039*58e6ee5fSAndroid Build Coastguard Worker 	const char *name = event->event;
3040*58e6ee5fSAndroid Build Coastguard Worker 	char *str;
3041*58e6ee5fSAndroid Build Coastguard Worker 	char *ptr;
3042*58e6ee5fSAndroid Build Coastguard Worker 	int ret;
3043*58e6ee5fSAndroid Build Coastguard Worker 
3044*58e6ee5fSAndroid Build Coastguard Worker 	/*
3045*58e6ee5fSAndroid Build Coastguard Worker 	 * We allow the user to use "all" to enable all events.
3046*58e6ee5fSAndroid Build Coastguard Worker 	 * Expand event_selection to all systems.
3047*58e6ee5fSAndroid Build Coastguard Worker 	 */
3048*58e6ee5fSAndroid Build Coastguard Worker 	if (strcmp(name, "all") == 0) {
3049*58e6ee5fSAndroid Build Coastguard Worker 		expand_event_files(instance, "*", event);
3050*58e6ee5fSAndroid Build Coastguard Worker 		return;
3051*58e6ee5fSAndroid Build Coastguard Worker 	}
3052*58e6ee5fSAndroid Build Coastguard Worker 
3053*58e6ee5fSAndroid Build Coastguard Worker 	str = strdup(name);
3054*58e6ee5fSAndroid Build Coastguard Worker 	if (!str)
3055*58e6ee5fSAndroid Build Coastguard Worker 		die("Failed to allocate %s string", name);
3056*58e6ee5fSAndroid Build Coastguard Worker 
3057*58e6ee5fSAndroid Build Coastguard Worker 	ptr = strchr(str, ':');
3058*58e6ee5fSAndroid Build Coastguard Worker 	if (ptr) {
3059*58e6ee5fSAndroid Build Coastguard Worker 		*ptr = '\0';
3060*58e6ee5fSAndroid Build Coastguard Worker 		ptr++;
3061*58e6ee5fSAndroid Build Coastguard Worker 
3062*58e6ee5fSAndroid Build Coastguard Worker 		if (strlen(ptr))
3063*58e6ee5fSAndroid Build Coastguard Worker 			ret = expand_events_all(instance, str, ptr, event);
3064*58e6ee5fSAndroid Build Coastguard Worker 		else
3065*58e6ee5fSAndroid Build Coastguard Worker 			ret = expand_events_all(instance, str, "*", event);
3066*58e6ee5fSAndroid Build Coastguard Worker 
3067*58e6ee5fSAndroid Build Coastguard Worker 		if (!ignore_event_not_found && ret)
3068*58e6ee5fSAndroid Build Coastguard Worker 			die("No events enabled with %s", name);
3069*58e6ee5fSAndroid Build Coastguard Worker 
3070*58e6ee5fSAndroid Build Coastguard Worker 		goto out;
3071*58e6ee5fSAndroid Build Coastguard Worker 	}
3072*58e6ee5fSAndroid Build Coastguard Worker 
3073*58e6ee5fSAndroid Build Coastguard Worker 	/* No ':' so enable all matching systems and events */
3074*58e6ee5fSAndroid Build Coastguard Worker 	ret = expand_event_files(instance, str, event);
3075*58e6ee5fSAndroid Build Coastguard Worker 	ret &= expand_events_all(instance, "*", str, event);
3076*58e6ee5fSAndroid Build Coastguard Worker 	if (event->trigger)
3077*58e6ee5fSAndroid Build Coastguard Worker 		ret &= expand_events_all(instance, str, "*", event);
3078*58e6ee5fSAndroid Build Coastguard Worker 
3079*58e6ee5fSAndroid Build Coastguard Worker 	if (!ignore_event_not_found && ret)
3080*58e6ee5fSAndroid Build Coastguard Worker 		die("No events enabled with %s", name);
3081*58e6ee5fSAndroid Build Coastguard Worker 
3082*58e6ee5fSAndroid Build Coastguard Worker out:
3083*58e6ee5fSAndroid Build Coastguard Worker 	free(str);
3084*58e6ee5fSAndroid Build Coastguard Worker }
3085*58e6ee5fSAndroid Build Coastguard Worker 
expand_event_instance(struct buffer_instance * instance)3086*58e6ee5fSAndroid Build Coastguard Worker static void expand_event_instance(struct buffer_instance *instance)
3087*58e6ee5fSAndroid Build Coastguard Worker {
3088*58e6ee5fSAndroid Build Coastguard Worker 	struct event_list *compressed_list = instance->events;
3089*58e6ee5fSAndroid Build Coastguard Worker 	struct event_list *event;
3090*58e6ee5fSAndroid Build Coastguard Worker 
3091*58e6ee5fSAndroid Build Coastguard Worker 	if (is_guest(instance))
3092*58e6ee5fSAndroid Build Coastguard Worker 		return;
3093*58e6ee5fSAndroid Build Coastguard Worker 
3094*58e6ee5fSAndroid Build Coastguard Worker 	reset_event_list(instance);
3095*58e6ee5fSAndroid Build Coastguard Worker 
3096*58e6ee5fSAndroid Build Coastguard Worker 	while (compressed_list) {
3097*58e6ee5fSAndroid Build Coastguard Worker 		event = compressed_list;
3098*58e6ee5fSAndroid Build Coastguard Worker 		compressed_list = event->next;
3099*58e6ee5fSAndroid Build Coastguard Worker 		expand_event(instance, event);
3100*58e6ee5fSAndroid Build Coastguard Worker 		free(event->trigger);
3101*58e6ee5fSAndroid Build Coastguard Worker 		free(event);
3102*58e6ee5fSAndroid Build Coastguard Worker 	}
3103*58e6ee5fSAndroid Build Coastguard Worker }
3104*58e6ee5fSAndroid Build Coastguard Worker 
expand_event_list(void)3105*58e6ee5fSAndroid Build Coastguard Worker static void expand_event_list(void)
3106*58e6ee5fSAndroid Build Coastguard Worker {
3107*58e6ee5fSAndroid Build Coastguard Worker 	struct buffer_instance *instance;
3108*58e6ee5fSAndroid Build Coastguard Worker 
3109*58e6ee5fSAndroid Build Coastguard Worker 	if (use_old_event_method())
3110*58e6ee5fSAndroid Build Coastguard Worker 		return;
3111*58e6ee5fSAndroid Build Coastguard Worker 
3112*58e6ee5fSAndroid Build Coastguard Worker 	for_all_instances(instance)
3113*58e6ee5fSAndroid Build Coastguard Worker 		expand_event_instance(instance);
3114*58e6ee5fSAndroid Build Coastguard Worker }
3115*58e6ee5fSAndroid Build Coastguard Worker 
finish(int sig)3116*58e6ee5fSAndroid Build Coastguard Worker static void finish(int sig)
3117*58e6ee5fSAndroid Build Coastguard Worker {
3118*58e6ee5fSAndroid Build Coastguard Worker 	/* all done */
3119*58e6ee5fSAndroid Build Coastguard Worker 	if (recorder)
3120*58e6ee5fSAndroid Build Coastguard Worker 		tracecmd_stop_recording(recorder);
3121*58e6ee5fSAndroid Build Coastguard Worker 	finished = 1;
3122*58e6ee5fSAndroid Build Coastguard Worker }
3123*58e6ee5fSAndroid Build Coastguard Worker 
do_getaddrinfo(const char * host,unsigned int port,enum port_type type)3124*58e6ee5fSAndroid Build Coastguard Worker static struct addrinfo *do_getaddrinfo(const char *host, unsigned int port,
3125*58e6ee5fSAndroid Build Coastguard Worker 				       enum port_type type)
3126*58e6ee5fSAndroid Build Coastguard Worker {
3127*58e6ee5fSAndroid Build Coastguard Worker 	struct addrinfo *results;
3128*58e6ee5fSAndroid Build Coastguard Worker 	struct addrinfo hints;
3129*58e6ee5fSAndroid Build Coastguard Worker 	char buf[BUFSIZ];
3130*58e6ee5fSAndroid Build Coastguard Worker 	int s;
3131*58e6ee5fSAndroid Build Coastguard Worker 
3132*58e6ee5fSAndroid Build Coastguard Worker 	snprintf(buf, BUFSIZ, "%u", port);
3133*58e6ee5fSAndroid Build Coastguard Worker 
3134*58e6ee5fSAndroid Build Coastguard Worker 	memset(&hints, 0, sizeof(hints));
3135*58e6ee5fSAndroid Build Coastguard Worker 	hints.ai_family = AF_UNSPEC;
3136*58e6ee5fSAndroid Build Coastguard Worker 	hints.ai_socktype = type == USE_TCP ? SOCK_STREAM : SOCK_DGRAM;
3137*58e6ee5fSAndroid Build Coastguard Worker 
3138*58e6ee5fSAndroid Build Coastguard Worker 	s = getaddrinfo(host, buf, &hints, &results);
3139*58e6ee5fSAndroid Build Coastguard Worker 	if (s != 0) {
3140*58e6ee5fSAndroid Build Coastguard Worker 		gai_err = gai_strerror(s);
3141*58e6ee5fSAndroid Build Coastguard Worker 		return NULL;
3142*58e6ee5fSAndroid Build Coastguard Worker 	}
3143*58e6ee5fSAndroid Build Coastguard Worker 
3144*58e6ee5fSAndroid Build Coastguard Worker 	dprint("Attached port %s: %d to results: %p\n",
3145*58e6ee5fSAndroid Build Coastguard Worker 	       type == USE_TCP ? "TCP" : "UDP", port, results);
3146*58e6ee5fSAndroid Build Coastguard Worker 
3147*58e6ee5fSAndroid Build Coastguard Worker 	return results;
3148*58e6ee5fSAndroid Build Coastguard Worker }
3149*58e6ee5fSAndroid Build Coastguard Worker 
connect_addr(struct addrinfo * results)3150*58e6ee5fSAndroid Build Coastguard Worker static int connect_addr(struct addrinfo *results)
3151*58e6ee5fSAndroid Build Coastguard Worker {
3152*58e6ee5fSAndroid Build Coastguard Worker 	struct addrinfo *rp;
3153*58e6ee5fSAndroid Build Coastguard Worker 	int sfd = -1;
3154*58e6ee5fSAndroid Build Coastguard Worker 
3155*58e6ee5fSAndroid Build Coastguard Worker 	for (rp = results; rp != NULL; rp = rp->ai_next) {
3156*58e6ee5fSAndroid Build Coastguard Worker 		sfd = socket(rp->ai_family, rp->ai_socktype,
3157*58e6ee5fSAndroid Build Coastguard Worker 			     rp->ai_protocol);
3158*58e6ee5fSAndroid Build Coastguard Worker 		if (sfd == -1)
3159*58e6ee5fSAndroid Build Coastguard Worker 			continue;
3160*58e6ee5fSAndroid Build Coastguard Worker 		if (connect(sfd, rp->ai_addr, rp->ai_addrlen) != -1)
3161*58e6ee5fSAndroid Build Coastguard Worker 			break;
3162*58e6ee5fSAndroid Build Coastguard Worker 		close(sfd);
3163*58e6ee5fSAndroid Build Coastguard Worker 	}
3164*58e6ee5fSAndroid Build Coastguard Worker 
3165*58e6ee5fSAndroid Build Coastguard Worker 	if (rp == NULL)
3166*58e6ee5fSAndroid Build Coastguard Worker 		return -1;
3167*58e6ee5fSAndroid Build Coastguard Worker 
3168*58e6ee5fSAndroid Build Coastguard Worker 	dprint("connect results: %p with fd: %d\n", results, sfd);
3169*58e6ee5fSAndroid Build Coastguard Worker 
3170*58e6ee5fSAndroid Build Coastguard Worker 	return sfd;
3171*58e6ee5fSAndroid Build Coastguard Worker }
3172*58e6ee5fSAndroid Build Coastguard Worker 
connect_port(const char * host,unsigned int port,enum port_type type)3173*58e6ee5fSAndroid Build Coastguard Worker static int connect_port(const char *host, unsigned int port, enum port_type type)
3174*58e6ee5fSAndroid Build Coastguard Worker {
3175*58e6ee5fSAndroid Build Coastguard Worker 	struct addrinfo *results;
3176*58e6ee5fSAndroid Build Coastguard Worker 	int sfd;
3177*58e6ee5fSAndroid Build Coastguard Worker 
3178*58e6ee5fSAndroid Build Coastguard Worker 	if (type == USE_VSOCK)
3179*58e6ee5fSAndroid Build Coastguard Worker 		return trace_vsock_open(atoi(host), port);
3180*58e6ee5fSAndroid Build Coastguard Worker 
3181*58e6ee5fSAndroid Build Coastguard Worker 	results = do_getaddrinfo(host, port, type);
3182*58e6ee5fSAndroid Build Coastguard Worker 
3183*58e6ee5fSAndroid Build Coastguard Worker 	if (!results)
3184*58e6ee5fSAndroid Build Coastguard Worker 		die("connecting to %s server %s:%u",
3185*58e6ee5fSAndroid Build Coastguard Worker 		    type == USE_TCP ? "TCP" : "UDP", host, port);
3186*58e6ee5fSAndroid Build Coastguard Worker 
3187*58e6ee5fSAndroid Build Coastguard Worker 	sfd = connect_addr(results);
3188*58e6ee5fSAndroid Build Coastguard Worker 
3189*58e6ee5fSAndroid Build Coastguard Worker 	freeaddrinfo(results);
3190*58e6ee5fSAndroid Build Coastguard Worker 
3191*58e6ee5fSAndroid Build Coastguard Worker 	if (sfd < 0)
3192*58e6ee5fSAndroid Build Coastguard Worker 		die("Can not connect to %s server %s:%u",
3193*58e6ee5fSAndroid Build Coastguard Worker 		    type == USE_TCP ? "TCP" : "UDP", host, port);
3194*58e6ee5fSAndroid Build Coastguard Worker 
3195*58e6ee5fSAndroid Build Coastguard Worker 	return sfd;
3196*58e6ee5fSAndroid Build Coastguard Worker }
3197*58e6ee5fSAndroid Build Coastguard Worker 
do_accept(int sd)3198*58e6ee5fSAndroid Build Coastguard Worker static int do_accept(int sd)
3199*58e6ee5fSAndroid Build Coastguard Worker {
3200*58e6ee5fSAndroid Build Coastguard Worker 	int cd;
3201*58e6ee5fSAndroid Build Coastguard Worker 
3202*58e6ee5fSAndroid Build Coastguard Worker 	for (;;) {
3203*58e6ee5fSAndroid Build Coastguard Worker 		dprint("Wait on accept: %d\n", sd);
3204*58e6ee5fSAndroid Build Coastguard Worker 		cd = accept(sd, NULL, NULL);
3205*58e6ee5fSAndroid Build Coastguard Worker 		dprint("accepted: %d\n", cd);
3206*58e6ee5fSAndroid Build Coastguard Worker 		if (cd < 0) {
3207*58e6ee5fSAndroid Build Coastguard Worker 			if (errno == EINTR)
3208*58e6ee5fSAndroid Build Coastguard Worker 				continue;
3209*58e6ee5fSAndroid Build Coastguard Worker 			die("accept");
3210*58e6ee5fSAndroid Build Coastguard Worker 		}
3211*58e6ee5fSAndroid Build Coastguard Worker 
3212*58e6ee5fSAndroid Build Coastguard Worker 		return cd;
3213*58e6ee5fSAndroid Build Coastguard Worker 	}
3214*58e6ee5fSAndroid Build Coastguard Worker 
3215*58e6ee5fSAndroid Build Coastguard Worker 	return -1;
3216*58e6ee5fSAndroid Build Coastguard Worker }
3217*58e6ee5fSAndroid Build Coastguard Worker 
3218*58e6ee5fSAndroid Build Coastguard Worker /* Find all the tasks associated with the guest pid */
find_tasks(struct trace_guest * guest)3219*58e6ee5fSAndroid Build Coastguard Worker static void find_tasks(struct trace_guest *guest)
3220*58e6ee5fSAndroid Build Coastguard Worker {
3221*58e6ee5fSAndroid Build Coastguard Worker 	struct dirent *dent;
3222*58e6ee5fSAndroid Build Coastguard Worker 	char *path;
3223*58e6ee5fSAndroid Build Coastguard Worker 	DIR *dir;
3224*58e6ee5fSAndroid Build Coastguard Worker 	int ret;
3225*58e6ee5fSAndroid Build Coastguard Worker 	int tasks = 0;
3226*58e6ee5fSAndroid Build Coastguard Worker 
3227*58e6ee5fSAndroid Build Coastguard Worker 	ret = asprintf(&path, "/proc/%d/task", guest->pid);
3228*58e6ee5fSAndroid Build Coastguard Worker 	if (ret < 0)
3229*58e6ee5fSAndroid Build Coastguard Worker 		return;
3230*58e6ee5fSAndroid Build Coastguard Worker 
3231*58e6ee5fSAndroid Build Coastguard Worker 	dir = opendir(path);
3232*58e6ee5fSAndroid Build Coastguard Worker 	free(path);
3233*58e6ee5fSAndroid Build Coastguard Worker 	if (!dir)
3234*58e6ee5fSAndroid Build Coastguard Worker 		return;
3235*58e6ee5fSAndroid Build Coastguard Worker 
3236*58e6ee5fSAndroid Build Coastguard Worker 	while ((dent = readdir(dir))) {
3237*58e6ee5fSAndroid Build Coastguard Worker 		int *pids;
3238*58e6ee5fSAndroid Build Coastguard Worker 		if (!(dent->d_type == DT_DIR && is_digits(dent->d_name)))
3239*58e6ee5fSAndroid Build Coastguard Worker 			continue;
3240*58e6ee5fSAndroid Build Coastguard Worker 		pids = realloc(guest->task_pids, sizeof(int) * (tasks + 2));
3241*58e6ee5fSAndroid Build Coastguard Worker 		if (!pids)
3242*58e6ee5fSAndroid Build Coastguard Worker 			break;
3243*58e6ee5fSAndroid Build Coastguard Worker 		pids[tasks++] = strtol(dent->d_name, NULL, 0);
3244*58e6ee5fSAndroid Build Coastguard Worker 		pids[tasks] = -1;
3245*58e6ee5fSAndroid Build Coastguard Worker 		guest->task_pids = pids;
3246*58e6ee5fSAndroid Build Coastguard Worker 	}
3247*58e6ee5fSAndroid Build Coastguard Worker 	closedir(dir);
3248*58e6ee5fSAndroid Build Coastguard Worker }
3249*58e6ee5fSAndroid Build Coastguard Worker 
parse_guest_name(char * gname,int * cid,int * port,struct addrinfo ** res)3250*58e6ee5fSAndroid Build Coastguard Worker static char *parse_guest_name(char *gname, int *cid, int *port,
3251*58e6ee5fSAndroid Build Coastguard Worker 			      struct addrinfo **res)
3252*58e6ee5fSAndroid Build Coastguard Worker {
3253*58e6ee5fSAndroid Build Coastguard Worker 	struct trace_guest *guest = NULL;
3254*58e6ee5fSAndroid Build Coastguard Worker 	struct addrinfo *result;
3255*58e6ee5fSAndroid Build Coastguard Worker 	char *ip = NULL;
3256*58e6ee5fSAndroid Build Coastguard Worker 	char *p;
3257*58e6ee5fSAndroid Build Coastguard Worker 
3258*58e6ee5fSAndroid Build Coastguard Worker 	*res = NULL;
3259*58e6ee5fSAndroid Build Coastguard Worker 
3260*58e6ee5fSAndroid Build Coastguard Worker 	*port = -1;
3261*58e6ee5fSAndroid Build Coastguard Worker 	for (p = gname + strlen(gname); p > gname; p--) {
3262*58e6ee5fSAndroid Build Coastguard Worker 		if (*p == ':')
3263*58e6ee5fSAndroid Build Coastguard Worker 			break;
3264*58e6ee5fSAndroid Build Coastguard Worker 	}
3265*58e6ee5fSAndroid Build Coastguard Worker 	if (p > gname) {
3266*58e6ee5fSAndroid Build Coastguard Worker 		*p = '\0';
3267*58e6ee5fSAndroid Build Coastguard Worker 		*port = atoi(p + 1);
3268*58e6ee5fSAndroid Build Coastguard Worker 	}
3269*58e6ee5fSAndroid Build Coastguard Worker 
3270*58e6ee5fSAndroid Build Coastguard Worker 	*cid = -1;
3271*58e6ee5fSAndroid Build Coastguard Worker 	p = strrchr(gname, '@');
3272*58e6ee5fSAndroid Build Coastguard Worker 	if (p) {
3273*58e6ee5fSAndroid Build Coastguard Worker 		*p = '\0';
3274*58e6ee5fSAndroid Build Coastguard Worker 		*cid = atoi(p + 1);
3275*58e6ee5fSAndroid Build Coastguard Worker 	} else if (is_digits(gname)) {
3276*58e6ee5fSAndroid Build Coastguard Worker 		*cid = atoi(gname);
3277*58e6ee5fSAndroid Build Coastguard Worker 	} else {
3278*58e6ee5fSAndroid Build Coastguard Worker 		/* Check if this is an IP address */
3279*58e6ee5fSAndroid Build Coastguard Worker 		if (strstr(gname, ":") || strstr(gname, "."))
3280*58e6ee5fSAndroid Build Coastguard Worker 			ip = gname;
3281*58e6ee5fSAndroid Build Coastguard Worker 	}
3282*58e6ee5fSAndroid Build Coastguard Worker 
3283*58e6ee5fSAndroid Build Coastguard Worker 	if (!ip && *cid < 0)
3284*58e6ee5fSAndroid Build Coastguard Worker 		read_qemu_guests();
3285*58e6ee5fSAndroid Build Coastguard Worker 
3286*58e6ee5fSAndroid Build Coastguard Worker 	if (!ip)
3287*58e6ee5fSAndroid Build Coastguard Worker 		guest = trace_get_guest(*cid, gname);
3288*58e6ee5fSAndroid Build Coastguard Worker 	if (guest) {
3289*58e6ee5fSAndroid Build Coastguard Worker 		*cid = guest->cid;
3290*58e6ee5fSAndroid Build Coastguard Worker 		/* Mapping not found, search for them */
3291*58e6ee5fSAndroid Build Coastguard Worker 		if (!guest->cpu_pid)
3292*58e6ee5fSAndroid Build Coastguard Worker 			find_tasks(guest);
3293*58e6ee5fSAndroid Build Coastguard Worker 		return guest->name;
3294*58e6ee5fSAndroid Build Coastguard Worker 	}
3295*58e6ee5fSAndroid Build Coastguard Worker 
3296*58e6ee5fSAndroid Build Coastguard Worker 	/* Test to see if this is an internet address */
3297*58e6ee5fSAndroid Build Coastguard Worker 	result = do_getaddrinfo(gname, *port, USE_TCP);
3298*58e6ee5fSAndroid Build Coastguard Worker 	if (!result)
3299*58e6ee5fSAndroid Build Coastguard Worker 		return NULL;
3300*58e6ee5fSAndroid Build Coastguard Worker 
3301*58e6ee5fSAndroid Build Coastguard Worker 	*res = result;
3302*58e6ee5fSAndroid Build Coastguard Worker 
3303*58e6ee5fSAndroid Build Coastguard Worker 	return gname;
3304*58e6ee5fSAndroid Build Coastguard Worker }
3305*58e6ee5fSAndroid Build Coastguard Worker 
set_prio(int prio)3306*58e6ee5fSAndroid Build Coastguard Worker static void set_prio(int prio)
3307*58e6ee5fSAndroid Build Coastguard Worker {
3308*58e6ee5fSAndroid Build Coastguard Worker 	struct sched_param sp;
3309*58e6ee5fSAndroid Build Coastguard Worker 
3310*58e6ee5fSAndroid Build Coastguard Worker 	memset(&sp, 0, sizeof(sp));
3311*58e6ee5fSAndroid Build Coastguard Worker 	sp.sched_priority = prio;
3312*58e6ee5fSAndroid Build Coastguard Worker 	if (sched_setscheduler(0, SCHED_FIFO, &sp) < 0)
3313*58e6ee5fSAndroid Build Coastguard Worker 		warning("failed to set priority");
3314*58e6ee5fSAndroid Build Coastguard Worker }
3315*58e6ee5fSAndroid Build Coastguard Worker 
3316*58e6ee5fSAndroid Build Coastguard Worker static struct tracecmd_recorder *
create_recorder_instance_pipe(struct buffer_instance * instance,int cpu,int * brass)3317*58e6ee5fSAndroid Build Coastguard Worker create_recorder_instance_pipe(struct buffer_instance *instance,
3318*58e6ee5fSAndroid Build Coastguard Worker 			      int cpu, int *brass)
3319*58e6ee5fSAndroid Build Coastguard Worker {
3320*58e6ee5fSAndroid Build Coastguard Worker 	struct tracecmd_recorder *recorder;
3321*58e6ee5fSAndroid Build Coastguard Worker 	unsigned flags = recorder_flags | TRACECMD_RECORD_BLOCK_SPLICE;
3322*58e6ee5fSAndroid Build Coastguard Worker 	char *path;
3323*58e6ee5fSAndroid Build Coastguard Worker 
3324*58e6ee5fSAndroid Build Coastguard Worker 	path = tracefs_instance_get_dir(instance->tracefs);
3325*58e6ee5fSAndroid Build Coastguard Worker 
3326*58e6ee5fSAndroid Build Coastguard Worker 	if (!path)
3327*58e6ee5fSAndroid Build Coastguard Worker 		die("malloc");
3328*58e6ee5fSAndroid Build Coastguard Worker 
3329*58e6ee5fSAndroid Build Coastguard Worker 	/* This is already the child */
3330*58e6ee5fSAndroid Build Coastguard Worker 	close(brass[0]);
3331*58e6ee5fSAndroid Build Coastguard Worker 
3332*58e6ee5fSAndroid Build Coastguard Worker 	recorder = tracecmd_create_buffer_recorder_fd(brass[1], cpu, flags, path);
3333*58e6ee5fSAndroid Build Coastguard Worker 
3334*58e6ee5fSAndroid Build Coastguard Worker 	tracefs_put_tracing_file(path);
3335*58e6ee5fSAndroid Build Coastguard Worker 
3336*58e6ee5fSAndroid Build Coastguard Worker 	return recorder;
3337*58e6ee5fSAndroid Build Coastguard Worker }
3338*58e6ee5fSAndroid Build Coastguard Worker 
3339*58e6ee5fSAndroid Build Coastguard Worker static struct tracecmd_recorder *
create_recorder_instance(struct buffer_instance * instance,const char * file,int cpu,int * brass)3340*58e6ee5fSAndroid Build Coastguard Worker create_recorder_instance(struct buffer_instance *instance, const char *file, int cpu,
3341*58e6ee5fSAndroid Build Coastguard Worker 			 int *brass)
3342*58e6ee5fSAndroid Build Coastguard Worker {
3343*58e6ee5fSAndroid Build Coastguard Worker 	struct tracecmd_recorder *record;
3344*58e6ee5fSAndroid Build Coastguard Worker 	struct addrinfo *result;
3345*58e6ee5fSAndroid Build Coastguard Worker 	char *path;
3346*58e6ee5fSAndroid Build Coastguard Worker 
3347*58e6ee5fSAndroid Build Coastguard Worker 	if (is_guest(instance)) {
3348*58e6ee5fSAndroid Build Coastguard Worker 		int fd;
3349*58e6ee5fSAndroid Build Coastguard Worker 		unsigned int flags;
3350*58e6ee5fSAndroid Build Coastguard Worker 
3351*58e6ee5fSAndroid Build Coastguard Worker 		if (instance->use_fifos)
3352*58e6ee5fSAndroid Build Coastguard Worker 			fd = instance->fds[cpu];
3353*58e6ee5fSAndroid Build Coastguard Worker 		else if (is_network(instance)) {
3354*58e6ee5fSAndroid Build Coastguard Worker 			result = do_getaddrinfo(instance->name,
3355*58e6ee5fSAndroid Build Coastguard Worker 						instance->client_ports[cpu],
3356*58e6ee5fSAndroid Build Coastguard Worker 						instance->port_type);
3357*58e6ee5fSAndroid Build Coastguard Worker 			if (!result)
3358*58e6ee5fSAndroid Build Coastguard Worker 				die("Failed to connect to %s port %d\n",
3359*58e6ee5fSAndroid Build Coastguard Worker 				    instance->name,
3360*58e6ee5fSAndroid Build Coastguard Worker 				    instance->client_ports[cpu]);
3361*58e6ee5fSAndroid Build Coastguard Worker 			fd = connect_addr(result);
3362*58e6ee5fSAndroid Build Coastguard Worker 			freeaddrinfo(result);
3363*58e6ee5fSAndroid Build Coastguard Worker 		} else
3364*58e6ee5fSAndroid Build Coastguard Worker 			fd = trace_vsock_open(instance->cid, instance->client_ports[cpu]);
3365*58e6ee5fSAndroid Build Coastguard Worker 		if (fd < 0)
3366*58e6ee5fSAndroid Build Coastguard Worker 			die("Failed to connect to agent");
3367*58e6ee5fSAndroid Build Coastguard Worker 
3368*58e6ee5fSAndroid Build Coastguard Worker 		flags = recorder_flags;
3369*58e6ee5fSAndroid Build Coastguard Worker 		if (instance->use_fifos)
3370*58e6ee5fSAndroid Build Coastguard Worker 			flags |= TRACECMD_RECORD_NOBRASS;
3371*58e6ee5fSAndroid Build Coastguard Worker 		else if (!trace_vsock_can_splice_read())
3372*58e6ee5fSAndroid Build Coastguard Worker 			flags |= TRACECMD_RECORD_NOSPLICE;
3373*58e6ee5fSAndroid Build Coastguard Worker 		return tracecmd_create_recorder_virt(file, cpu, flags, fd);
3374*58e6ee5fSAndroid Build Coastguard Worker 	}
3375*58e6ee5fSAndroid Build Coastguard Worker 
3376*58e6ee5fSAndroid Build Coastguard Worker 	if (brass)
3377*58e6ee5fSAndroid Build Coastguard Worker 		return create_recorder_instance_pipe(instance, cpu, brass);
3378*58e6ee5fSAndroid Build Coastguard Worker 
3379*58e6ee5fSAndroid Build Coastguard Worker 	if (!tracefs_instance_get_name(instance->tracefs))
3380*58e6ee5fSAndroid Build Coastguard Worker 		return tracecmd_create_recorder_maxkb(file, cpu, recorder_flags, max_kb);
3381*58e6ee5fSAndroid Build Coastguard Worker 
3382*58e6ee5fSAndroid Build Coastguard Worker 	path = tracefs_instance_get_dir(instance->tracefs);
3383*58e6ee5fSAndroid Build Coastguard Worker 
3384*58e6ee5fSAndroid Build Coastguard Worker 	record = tracecmd_create_buffer_recorder_maxkb(file, cpu, recorder_flags,
3385*58e6ee5fSAndroid Build Coastguard Worker 						       path, max_kb);
3386*58e6ee5fSAndroid Build Coastguard Worker 	tracefs_put_tracing_file(path);
3387*58e6ee5fSAndroid Build Coastguard Worker 
3388*58e6ee5fSAndroid Build Coastguard Worker 	return record;
3389*58e6ee5fSAndroid Build Coastguard Worker }
3390*58e6ee5fSAndroid Build Coastguard Worker 
3391*58e6ee5fSAndroid Build Coastguard Worker /*
3392*58e6ee5fSAndroid Build Coastguard Worker  * If extract is set, then this is going to set up the recorder,
3393*58e6ee5fSAndroid Build Coastguard Worker  * connections and exit as the tracing is serialized by a single thread.
3394*58e6ee5fSAndroid Build Coastguard Worker  */
create_recorder(struct buffer_instance * instance,int cpu,enum trace_type type,int * brass)3395*58e6ee5fSAndroid Build Coastguard Worker static int create_recorder(struct buffer_instance *instance, int cpu,
3396*58e6ee5fSAndroid Build Coastguard Worker 			   enum trace_type type, int *brass)
3397*58e6ee5fSAndroid Build Coastguard Worker {
3398*58e6ee5fSAndroid Build Coastguard Worker 	long ret;
3399*58e6ee5fSAndroid Build Coastguard Worker 	char *file;
3400*58e6ee5fSAndroid Build Coastguard Worker 	pid_t pid;
3401*58e6ee5fSAndroid Build Coastguard Worker 
3402*58e6ee5fSAndroid Build Coastguard Worker 	if (type != TRACE_TYPE_EXTRACT) {
3403*58e6ee5fSAndroid Build Coastguard Worker 
3404*58e6ee5fSAndroid Build Coastguard Worker 		pid = fork();
3405*58e6ee5fSAndroid Build Coastguard Worker 		if (pid < 0)
3406*58e6ee5fSAndroid Build Coastguard Worker 			die("fork");
3407*58e6ee5fSAndroid Build Coastguard Worker 
3408*58e6ee5fSAndroid Build Coastguard Worker 		if (pid)
3409*58e6ee5fSAndroid Build Coastguard Worker 			return pid;
3410*58e6ee5fSAndroid Build Coastguard Worker 
3411*58e6ee5fSAndroid Build Coastguard Worker 		signal(SIGINT, SIG_IGN);
3412*58e6ee5fSAndroid Build Coastguard Worker 		signal(SIGUSR1, finish);
3413*58e6ee5fSAndroid Build Coastguard Worker 
3414*58e6ee5fSAndroid Build Coastguard Worker 		if (rt_prio)
3415*58e6ee5fSAndroid Build Coastguard Worker 			set_prio(rt_prio);
3416*58e6ee5fSAndroid Build Coastguard Worker 
3417*58e6ee5fSAndroid Build Coastguard Worker 		/* do not kill tasks on error */
3418*58e6ee5fSAndroid Build Coastguard Worker 		instance->cpu_count = 0;
3419*58e6ee5fSAndroid Build Coastguard Worker 	}
3420*58e6ee5fSAndroid Build Coastguard Worker 
3421*58e6ee5fSAndroid Build Coastguard Worker 	if ((instance->client_ports && !is_guest(instance)) || is_agent(instance)) {
3422*58e6ee5fSAndroid Build Coastguard Worker 		unsigned int flags = recorder_flags;
3423*58e6ee5fSAndroid Build Coastguard Worker 		char *path = NULL;
3424*58e6ee5fSAndroid Build Coastguard Worker 		int fd;
3425*58e6ee5fSAndroid Build Coastguard Worker 
3426*58e6ee5fSAndroid Build Coastguard Worker 		if (is_agent(instance)) {
3427*58e6ee5fSAndroid Build Coastguard Worker 			if (instance->use_fifos)
3428*58e6ee5fSAndroid Build Coastguard Worker 				fd = instance->fds[cpu];
3429*58e6ee5fSAndroid Build Coastguard Worker 			else {
3430*58e6ee5fSAndroid Build Coastguard Worker  again:
3431*58e6ee5fSAndroid Build Coastguard Worker 				fd = do_accept(instance->fds[cpu]);
3432*58e6ee5fSAndroid Build Coastguard Worker 				if (instance->host &&
3433*58e6ee5fSAndroid Build Coastguard Worker 				    !trace_net_cmp_connection_fd(fd, instance->host)) {
3434*58e6ee5fSAndroid Build Coastguard Worker 					dprint("Client does not match '%s' for cpu:%d\n",
3435*58e6ee5fSAndroid Build Coastguard Worker 					       instance->host, cpu);
3436*58e6ee5fSAndroid Build Coastguard Worker 					goto again;
3437*58e6ee5fSAndroid Build Coastguard Worker 				}
3438*58e6ee5fSAndroid Build Coastguard Worker 			}
3439*58e6ee5fSAndroid Build Coastguard Worker 		} else {
3440*58e6ee5fSAndroid Build Coastguard Worker 			fd = connect_port(host, instance->client_ports[cpu],
3441*58e6ee5fSAndroid Build Coastguard Worker 					  instance->port_type);
3442*58e6ee5fSAndroid Build Coastguard Worker 		}
3443*58e6ee5fSAndroid Build Coastguard Worker 		if (fd < 0)
3444*58e6ee5fSAndroid Build Coastguard Worker 			die("Failed connecting to client");
3445*58e6ee5fSAndroid Build Coastguard Worker 		if (tracefs_instance_get_name(instance->tracefs) && !is_agent(instance)) {
3446*58e6ee5fSAndroid Build Coastguard Worker 			path = tracefs_instance_get_dir(instance->tracefs);
3447*58e6ee5fSAndroid Build Coastguard Worker 		} else {
3448*58e6ee5fSAndroid Build Coastguard Worker 			const char *dir = tracefs_tracing_dir();
3449*58e6ee5fSAndroid Build Coastguard Worker 
3450*58e6ee5fSAndroid Build Coastguard Worker 			if (dir)
3451*58e6ee5fSAndroid Build Coastguard Worker 				path = strdup(dir);
3452*58e6ee5fSAndroid Build Coastguard Worker 		}
3453*58e6ee5fSAndroid Build Coastguard Worker 		if (!path)
3454*58e6ee5fSAndroid Build Coastguard Worker 			die("can't get the tracing directory");
3455*58e6ee5fSAndroid Build Coastguard Worker 
3456*58e6ee5fSAndroid Build Coastguard Worker 		recorder = tracecmd_create_buffer_recorder_fd(fd, cpu, flags, path);
3457*58e6ee5fSAndroid Build Coastguard Worker 		tracefs_put_tracing_file(path);
3458*58e6ee5fSAndroid Build Coastguard Worker 	} else {
3459*58e6ee5fSAndroid Build Coastguard Worker 		file = get_temp_file(instance, cpu);
3460*58e6ee5fSAndroid Build Coastguard Worker 		recorder = create_recorder_instance(instance, file, cpu, brass);
3461*58e6ee5fSAndroid Build Coastguard Worker 		put_temp_file(file);
3462*58e6ee5fSAndroid Build Coastguard Worker 	}
3463*58e6ee5fSAndroid Build Coastguard Worker 
3464*58e6ee5fSAndroid Build Coastguard Worker 	if (!recorder)
3465*58e6ee5fSAndroid Build Coastguard Worker 		die ("can't create recorder");
3466*58e6ee5fSAndroid Build Coastguard Worker 
3467*58e6ee5fSAndroid Build Coastguard Worker 	if (type == TRACE_TYPE_EXTRACT) {
3468*58e6ee5fSAndroid Build Coastguard Worker 		ret = tracecmd_flush_recording(recorder);
3469*58e6ee5fSAndroid Build Coastguard Worker 		tracecmd_free_recorder(recorder);
3470*58e6ee5fSAndroid Build Coastguard Worker 		recorder = NULL;
3471*58e6ee5fSAndroid Build Coastguard Worker 		return ret;
3472*58e6ee5fSAndroid Build Coastguard Worker 	}
3473*58e6ee5fSAndroid Build Coastguard Worker 
3474*58e6ee5fSAndroid Build Coastguard Worker 	while (!finished) {
3475*58e6ee5fSAndroid Build Coastguard Worker 		if (tracecmd_start_recording(recorder, sleep_time) < 0)
3476*58e6ee5fSAndroid Build Coastguard Worker 			break;
3477*58e6ee5fSAndroid Build Coastguard Worker 	}
3478*58e6ee5fSAndroid Build Coastguard Worker 	tracecmd_free_recorder(recorder);
3479*58e6ee5fSAndroid Build Coastguard Worker 	recorder = NULL;
3480*58e6ee5fSAndroid Build Coastguard Worker 
3481*58e6ee5fSAndroid Build Coastguard Worker 	exit(0);
3482*58e6ee5fSAndroid Build Coastguard Worker }
3483*58e6ee5fSAndroid Build Coastguard Worker 
check_first_msg_from_server(struct tracecmd_msg_handle * msg_handle)3484*58e6ee5fSAndroid Build Coastguard Worker static void check_first_msg_from_server(struct tracecmd_msg_handle *msg_handle)
3485*58e6ee5fSAndroid Build Coastguard Worker {
3486*58e6ee5fSAndroid Build Coastguard Worker 	char buf[BUFSIZ];
3487*58e6ee5fSAndroid Build Coastguard Worker 
3488*58e6ee5fSAndroid Build Coastguard Worker 	read(msg_handle->fd, buf, 8);
3489*58e6ee5fSAndroid Build Coastguard Worker 
3490*58e6ee5fSAndroid Build Coastguard Worker 	/* Make sure the server is the tracecmd server */
3491*58e6ee5fSAndroid Build Coastguard Worker 	if (memcmp(buf, "tracecmd", 8) != 0)
3492*58e6ee5fSAndroid Build Coastguard Worker 		die("server not tracecmd server");
3493*58e6ee5fSAndroid Build Coastguard Worker }
3494*58e6ee5fSAndroid Build Coastguard Worker 
communicate_with_listener_v1(struct tracecmd_msg_handle * msg_handle,struct buffer_instance * instance)3495*58e6ee5fSAndroid Build Coastguard Worker static void communicate_with_listener_v1(struct tracecmd_msg_handle *msg_handle,
3496*58e6ee5fSAndroid Build Coastguard Worker 					 struct buffer_instance *instance)
3497*58e6ee5fSAndroid Build Coastguard Worker {
3498*58e6ee5fSAndroid Build Coastguard Worker 	unsigned int *client_ports;
3499*58e6ee5fSAndroid Build Coastguard Worker 	char buf[BUFSIZ];
3500*58e6ee5fSAndroid Build Coastguard Worker 	ssize_t n;
3501*58e6ee5fSAndroid Build Coastguard Worker 	int cpu, i;
3502*58e6ee5fSAndroid Build Coastguard Worker 
3503*58e6ee5fSAndroid Build Coastguard Worker 	check_first_msg_from_server(msg_handle);
3504*58e6ee5fSAndroid Build Coastguard Worker 
3505*58e6ee5fSAndroid Build Coastguard Worker 	/* write the number of CPUs we have (in ASCII) */
3506*58e6ee5fSAndroid Build Coastguard Worker 	sprintf(buf, "%d", local_cpu_count);
3507*58e6ee5fSAndroid Build Coastguard Worker 
3508*58e6ee5fSAndroid Build Coastguard Worker 	/* include \0 */
3509*58e6ee5fSAndroid Build Coastguard Worker 	write(msg_handle->fd, buf, strlen(buf)+1);
3510*58e6ee5fSAndroid Build Coastguard Worker 
3511*58e6ee5fSAndroid Build Coastguard Worker 	/* write the pagesize (in ASCII) */
3512*58e6ee5fSAndroid Build Coastguard Worker 	sprintf(buf, "%d", page_size);
3513*58e6ee5fSAndroid Build Coastguard Worker 
3514*58e6ee5fSAndroid Build Coastguard Worker 	/* include \0 */
3515*58e6ee5fSAndroid Build Coastguard Worker 	write(msg_handle->fd, buf, strlen(buf)+1);
3516*58e6ee5fSAndroid Build Coastguard Worker 
3517*58e6ee5fSAndroid Build Coastguard Worker 	/*
3518*58e6ee5fSAndroid Build Coastguard Worker 	 * If we are using IPV4 and our page size is greater than
3519*58e6ee5fSAndroid Build Coastguard Worker 	 * or equal to 64K, we need to punt and use TCP. :-(
3520*58e6ee5fSAndroid Build Coastguard Worker 	 */
3521*58e6ee5fSAndroid Build Coastguard Worker 
3522*58e6ee5fSAndroid Build Coastguard Worker 	/* TODO, test for ipv4 */
3523*58e6ee5fSAndroid Build Coastguard Worker 	if (page_size >= UDP_MAX_PACKET) {
3524*58e6ee5fSAndroid Build Coastguard Worker 		warning("page size too big for UDP using TCP in live read");
3525*58e6ee5fSAndroid Build Coastguard Worker 		instance->port_type = USE_TCP;
3526*58e6ee5fSAndroid Build Coastguard Worker 		msg_handle->flags |= TRACECMD_MSG_FL_USE_TCP;
3527*58e6ee5fSAndroid Build Coastguard Worker 	}
3528*58e6ee5fSAndroid Build Coastguard Worker 
3529*58e6ee5fSAndroid Build Coastguard Worker 	if (instance->port_type == USE_TCP) {
3530*58e6ee5fSAndroid Build Coastguard Worker 		/* Send one option */
3531*58e6ee5fSAndroid Build Coastguard Worker 		write(msg_handle->fd, "1", 2);
3532*58e6ee5fSAndroid Build Coastguard Worker 		/* Size 4 */
3533*58e6ee5fSAndroid Build Coastguard Worker 		write(msg_handle->fd, "4", 2);
3534*58e6ee5fSAndroid Build Coastguard Worker 		/* use TCP */
3535*58e6ee5fSAndroid Build Coastguard Worker 		write(msg_handle->fd, "TCP", 4);
3536*58e6ee5fSAndroid Build Coastguard Worker 	} else
3537*58e6ee5fSAndroid Build Coastguard Worker 		/* No options */
3538*58e6ee5fSAndroid Build Coastguard Worker 		write(msg_handle->fd, "0", 2);
3539*58e6ee5fSAndroid Build Coastguard Worker 
3540*58e6ee5fSAndroid Build Coastguard Worker 	client_ports = malloc(local_cpu_count * sizeof(*client_ports));
3541*58e6ee5fSAndroid Build Coastguard Worker 	if (!client_ports)
3542*58e6ee5fSAndroid Build Coastguard Worker 		die("Failed to allocate client ports for %d cpus", local_cpu_count);
3543*58e6ee5fSAndroid Build Coastguard Worker 
3544*58e6ee5fSAndroid Build Coastguard Worker 	/*
3545*58e6ee5fSAndroid Build Coastguard Worker 	 * Now we will receive back a comma deliminated list
3546*58e6ee5fSAndroid Build Coastguard Worker 	 * of client ports to connect to.
3547*58e6ee5fSAndroid Build Coastguard Worker 	 */
3548*58e6ee5fSAndroid Build Coastguard Worker 	for (cpu = 0; cpu < local_cpu_count; cpu++) {
3549*58e6ee5fSAndroid Build Coastguard Worker 		for (i = 0; i < BUFSIZ; i++) {
3550*58e6ee5fSAndroid Build Coastguard Worker 			n = read(msg_handle->fd, buf+i, 1);
3551*58e6ee5fSAndroid Build Coastguard Worker 			if (n != 1)
3552*58e6ee5fSAndroid Build Coastguard Worker 				die("Error, reading server ports");
3553*58e6ee5fSAndroid Build Coastguard Worker 			if (!buf[i] || buf[i] == ',')
3554*58e6ee5fSAndroid Build Coastguard Worker 				break;
3555*58e6ee5fSAndroid Build Coastguard Worker 		}
3556*58e6ee5fSAndroid Build Coastguard Worker 		if (i == BUFSIZ)
3557*58e6ee5fSAndroid Build Coastguard Worker 			die("read bad port number");
3558*58e6ee5fSAndroid Build Coastguard Worker 		buf[i] = 0;
3559*58e6ee5fSAndroid Build Coastguard Worker 		client_ports[cpu] = atoi(buf);
3560*58e6ee5fSAndroid Build Coastguard Worker 	}
3561*58e6ee5fSAndroid Build Coastguard Worker 
3562*58e6ee5fSAndroid Build Coastguard Worker 	instance->client_ports = client_ports;
3563*58e6ee5fSAndroid Build Coastguard Worker }
3564*58e6ee5fSAndroid Build Coastguard Worker 
communicate_with_listener_v3(struct tracecmd_msg_handle * msg_handle,unsigned int ** client_ports)3565*58e6ee5fSAndroid Build Coastguard Worker static void communicate_with_listener_v3(struct tracecmd_msg_handle *msg_handle,
3566*58e6ee5fSAndroid Build Coastguard Worker 					 unsigned int **client_ports)
3567*58e6ee5fSAndroid Build Coastguard Worker {
3568*58e6ee5fSAndroid Build Coastguard Worker 	if (tracecmd_msg_send_init_data(msg_handle, client_ports) < 0)
3569*58e6ee5fSAndroid Build Coastguard Worker 		die("Cannot communicate with server");
3570*58e6ee5fSAndroid Build Coastguard Worker }
3571*58e6ee5fSAndroid Build Coastguard Worker 
check_protocol_version(struct tracecmd_msg_handle * msg_handle)3572*58e6ee5fSAndroid Build Coastguard Worker static void check_protocol_version(struct tracecmd_msg_handle *msg_handle)
3573*58e6ee5fSAndroid Build Coastguard Worker {
3574*58e6ee5fSAndroid Build Coastguard Worker 	char buf[BUFSIZ];
3575*58e6ee5fSAndroid Build Coastguard Worker 	int fd = msg_handle->fd;
3576*58e6ee5fSAndroid Build Coastguard Worker 	int n;
3577*58e6ee5fSAndroid Build Coastguard Worker 
3578*58e6ee5fSAndroid Build Coastguard Worker 	check_first_msg_from_server(msg_handle);
3579*58e6ee5fSAndroid Build Coastguard Worker 
3580*58e6ee5fSAndroid Build Coastguard Worker 	/*
3581*58e6ee5fSAndroid Build Coastguard Worker 	 * Write the protocol version, the magic number, and the dummy
3582*58e6ee5fSAndroid Build Coastguard Worker 	 * option(0) (in ASCII). The client understands whether the client
3583*58e6ee5fSAndroid Build Coastguard Worker 	 * uses the v3 protocol or not by checking a reply message from the
3584*58e6ee5fSAndroid Build Coastguard Worker 	 * server. If the message is "V3", the server uses v3 protocol. On the
3585*58e6ee5fSAndroid Build Coastguard Worker 	 * other hands, if the message is just number strings, the server
3586*58e6ee5fSAndroid Build Coastguard Worker 	 * returned port numbers. So, in that time, the client understands the
3587*58e6ee5fSAndroid Build Coastguard Worker 	 * server uses the v1 protocol. However, the old server tells the
3588*58e6ee5fSAndroid Build Coastguard Worker 	 * client port numbers after reading cpu_count, page_size, and option.
3589*58e6ee5fSAndroid Build Coastguard Worker 	 * So, we add the dummy number (the magic number and 0 option) to the
3590*58e6ee5fSAndroid Build Coastguard Worker 	 * first client message.
3591*58e6ee5fSAndroid Build Coastguard Worker 	 */
3592*58e6ee5fSAndroid Build Coastguard Worker 	write(fd, V3_CPU, sizeof(V3_CPU));
3593*58e6ee5fSAndroid Build Coastguard Worker 
3594*58e6ee5fSAndroid Build Coastguard Worker 	buf[0] = 0;
3595*58e6ee5fSAndroid Build Coastguard Worker 
3596*58e6ee5fSAndroid Build Coastguard Worker 	/* read a reply message */
3597*58e6ee5fSAndroid Build Coastguard Worker 	n = read(fd, buf, BUFSIZ);
3598*58e6ee5fSAndroid Build Coastguard Worker 
3599*58e6ee5fSAndroid Build Coastguard Worker 	if (n < 0 || !buf[0]) {
3600*58e6ee5fSAndroid Build Coastguard Worker 		/* the server uses the v1 protocol, so we'll use it */
3601*58e6ee5fSAndroid Build Coastguard Worker 		msg_handle->version = V1_PROTOCOL;
3602*58e6ee5fSAndroid Build Coastguard Worker 		tracecmd_plog("Use the v1 protocol\n");
3603*58e6ee5fSAndroid Build Coastguard Worker 	} else {
3604*58e6ee5fSAndroid Build Coastguard Worker 		if (memcmp(buf, "V3", n) != 0)
3605*58e6ee5fSAndroid Build Coastguard Worker 			die("Cannot handle the protocol %s", buf);
3606*58e6ee5fSAndroid Build Coastguard Worker 		/* OK, let's use v3 protocol */
3607*58e6ee5fSAndroid Build Coastguard Worker 		write(fd, V3_MAGIC, sizeof(V3_MAGIC));
3608*58e6ee5fSAndroid Build Coastguard Worker 
3609*58e6ee5fSAndroid Build Coastguard Worker 		n = read(fd, buf, BUFSIZ - 1);
3610*58e6ee5fSAndroid Build Coastguard Worker 		if (n != 2 || memcmp(buf, "OK", 2) != 0) {
3611*58e6ee5fSAndroid Build Coastguard Worker 			if (n < 0)
3612*58e6ee5fSAndroid Build Coastguard Worker 				n  = 0;
3613*58e6ee5fSAndroid Build Coastguard Worker 			buf[n] = 0;
3614*58e6ee5fSAndroid Build Coastguard Worker 			die("Cannot handle the protocol %s", buf);
3615*58e6ee5fSAndroid Build Coastguard Worker 		}
3616*58e6ee5fSAndroid Build Coastguard Worker 	}
3617*58e6ee5fSAndroid Build Coastguard Worker }
3618*58e6ee5fSAndroid Build Coastguard Worker 
connect_vsock(char * vhost)3619*58e6ee5fSAndroid Build Coastguard Worker static int connect_vsock(char *vhost)
3620*58e6ee5fSAndroid Build Coastguard Worker {
3621*58e6ee5fSAndroid Build Coastguard Worker 	char *cid;
3622*58e6ee5fSAndroid Build Coastguard Worker 	char *port;
3623*58e6ee5fSAndroid Build Coastguard Worker 	char *p;
3624*58e6ee5fSAndroid Build Coastguard Worker 	int sd;
3625*58e6ee5fSAndroid Build Coastguard Worker 
3626*58e6ee5fSAndroid Build Coastguard Worker 	host = strdup(vhost);
3627*58e6ee5fSAndroid Build Coastguard Worker 	if (!host)
3628*58e6ee5fSAndroid Build Coastguard Worker 		die("alloctating server");
3629*58e6ee5fSAndroid Build Coastguard Worker 
3630*58e6ee5fSAndroid Build Coastguard Worker 	cid = strtok_r(host, ":", &p);
3631*58e6ee5fSAndroid Build Coastguard Worker 	port = strtok_r(NULL, "", &p);
3632*58e6ee5fSAndroid Build Coastguard Worker 
3633*58e6ee5fSAndroid Build Coastguard Worker 	if (!port)
3634*58e6ee5fSAndroid Build Coastguard Worker 		die("vsocket must have format of 'CID:PORT'");
3635*58e6ee5fSAndroid Build Coastguard Worker 
3636*58e6ee5fSAndroid Build Coastguard Worker 	sd = trace_vsock_open(atoi(cid), atoi(port));
3637*58e6ee5fSAndroid Build Coastguard Worker 
3638*58e6ee5fSAndroid Build Coastguard Worker 	return sd;
3639*58e6ee5fSAndroid Build Coastguard Worker }
3640*58e6ee5fSAndroid Build Coastguard Worker 
connect_ip(char * thost)3641*58e6ee5fSAndroid Build Coastguard Worker static int connect_ip(char *thost)
3642*58e6ee5fSAndroid Build Coastguard Worker {
3643*58e6ee5fSAndroid Build Coastguard Worker 	struct addrinfo *result;
3644*58e6ee5fSAndroid Build Coastguard Worker 	int sfd;
3645*58e6ee5fSAndroid Build Coastguard Worker 	char *server;
3646*58e6ee5fSAndroid Build Coastguard Worker 	char *port;
3647*58e6ee5fSAndroid Build Coastguard Worker 	char *p;
3648*58e6ee5fSAndroid Build Coastguard Worker 
3649*58e6ee5fSAndroid Build Coastguard Worker 	if (!strchr(host, ':')) {
3650*58e6ee5fSAndroid Build Coastguard Worker 		server = strdup("localhost");
3651*58e6ee5fSAndroid Build Coastguard Worker 		if (!server)
3652*58e6ee5fSAndroid Build Coastguard Worker 			die("alloctating server");
3653*58e6ee5fSAndroid Build Coastguard Worker 		port = thost;
3654*58e6ee5fSAndroid Build Coastguard Worker 		host = server;
3655*58e6ee5fSAndroid Build Coastguard Worker 	} else {
3656*58e6ee5fSAndroid Build Coastguard Worker 		host = strdup(thost);
3657*58e6ee5fSAndroid Build Coastguard Worker 		if (!host)
3658*58e6ee5fSAndroid Build Coastguard Worker 			die("alloctating server");
3659*58e6ee5fSAndroid Build Coastguard Worker 		server = strtok_r(host, ":", &p);
3660*58e6ee5fSAndroid Build Coastguard Worker 		port = strtok_r(NULL, ":", &p);
3661*58e6ee5fSAndroid Build Coastguard Worker 	}
3662*58e6ee5fSAndroid Build Coastguard Worker 
3663*58e6ee5fSAndroid Build Coastguard Worker 	result = do_getaddrinfo(server, atoi(port), USE_TCP);
3664*58e6ee5fSAndroid Build Coastguard Worker 	if (!result)
3665*58e6ee5fSAndroid Build Coastguard Worker 		die("getaddrinfo: %s", gai_err);
3666*58e6ee5fSAndroid Build Coastguard Worker 
3667*58e6ee5fSAndroid Build Coastguard Worker 	sfd = connect_addr(result);
3668*58e6ee5fSAndroid Build Coastguard Worker 
3669*58e6ee5fSAndroid Build Coastguard Worker 	freeaddrinfo(result);
3670*58e6ee5fSAndroid Build Coastguard Worker 
3671*58e6ee5fSAndroid Build Coastguard Worker 	if (sfd < 0)
3672*58e6ee5fSAndroid Build Coastguard Worker 		die("Can not connect to %s:%s", server, port);
3673*58e6ee5fSAndroid Build Coastguard Worker 
3674*58e6ee5fSAndroid Build Coastguard Worker 	return sfd;
3675*58e6ee5fSAndroid Build Coastguard Worker }
3676*58e6ee5fSAndroid Build Coastguard Worker 
setup_network(struct buffer_instance * instance)3677*58e6ee5fSAndroid Build Coastguard Worker static struct tracecmd_msg_handle *setup_network(struct buffer_instance *instance)
3678*58e6ee5fSAndroid Build Coastguard Worker {
3679*58e6ee5fSAndroid Build Coastguard Worker 	struct tracecmd_msg_handle *msg_handle = NULL;
3680*58e6ee5fSAndroid Build Coastguard Worker 	enum port_type type = instance->port_type;
3681*58e6ee5fSAndroid Build Coastguard Worker 	int sfd;
3682*58e6ee5fSAndroid Build Coastguard Worker 
3683*58e6ee5fSAndroid Build Coastguard Worker again:
3684*58e6ee5fSAndroid Build Coastguard Worker 	switch (type) {
3685*58e6ee5fSAndroid Build Coastguard Worker 	case USE_VSOCK:
3686*58e6ee5fSAndroid Build Coastguard Worker 		sfd = connect_vsock(host);
3687*58e6ee5fSAndroid Build Coastguard Worker 		break;
3688*58e6ee5fSAndroid Build Coastguard Worker 	default:
3689*58e6ee5fSAndroid Build Coastguard Worker 		sfd = connect_ip(host);
3690*58e6ee5fSAndroid Build Coastguard Worker 	}
3691*58e6ee5fSAndroid Build Coastguard Worker 
3692*58e6ee5fSAndroid Build Coastguard Worker 	if (sfd < 0)
3693*58e6ee5fSAndroid Build Coastguard Worker 		return NULL;
3694*58e6ee5fSAndroid Build Coastguard Worker 
3695*58e6ee5fSAndroid Build Coastguard Worker 	if (msg_handle) {
3696*58e6ee5fSAndroid Build Coastguard Worker 		msg_handle->fd = sfd;
3697*58e6ee5fSAndroid Build Coastguard Worker 	} else {
3698*58e6ee5fSAndroid Build Coastguard Worker 		msg_handle = tracecmd_msg_handle_alloc(sfd, 0);
3699*58e6ee5fSAndroid Build Coastguard Worker 		if (!msg_handle)
3700*58e6ee5fSAndroid Build Coastguard Worker 			die("Failed to allocate message handle");
3701*58e6ee5fSAndroid Build Coastguard Worker 
3702*58e6ee5fSAndroid Build Coastguard Worker 		msg_handle->cpu_count = local_cpu_count;
3703*58e6ee5fSAndroid Build Coastguard Worker 		msg_handle->version = V3_PROTOCOL;
3704*58e6ee5fSAndroid Build Coastguard Worker 	}
3705*58e6ee5fSAndroid Build Coastguard Worker 
3706*58e6ee5fSAndroid Build Coastguard Worker 	switch (type) {
3707*58e6ee5fSAndroid Build Coastguard Worker 	case USE_TCP:
3708*58e6ee5fSAndroid Build Coastguard Worker 		msg_handle->flags |= TRACECMD_MSG_FL_USE_TCP;
3709*58e6ee5fSAndroid Build Coastguard Worker 		break;
3710*58e6ee5fSAndroid Build Coastguard Worker 	case USE_VSOCK:
3711*58e6ee5fSAndroid Build Coastguard Worker 		msg_handle->flags |= TRACECMD_MSG_FL_USE_VSOCK;
3712*58e6ee5fSAndroid Build Coastguard Worker 		break;
3713*58e6ee5fSAndroid Build Coastguard Worker 	default:
3714*58e6ee5fSAndroid Build Coastguard Worker 		break;
3715*58e6ee5fSAndroid Build Coastguard Worker 	}
3716*58e6ee5fSAndroid Build Coastguard Worker 
3717*58e6ee5fSAndroid Build Coastguard Worker 	if (msg_handle->version == V3_PROTOCOL) {
3718*58e6ee5fSAndroid Build Coastguard Worker 		check_protocol_version(msg_handle);
3719*58e6ee5fSAndroid Build Coastguard Worker 		if (msg_handle->version == V1_PROTOCOL) {
3720*58e6ee5fSAndroid Build Coastguard Worker 			/* reconnect to the server for using the v1 protocol */
3721*58e6ee5fSAndroid Build Coastguard Worker 			close(sfd);
3722*58e6ee5fSAndroid Build Coastguard Worker 			free(host);
3723*58e6ee5fSAndroid Build Coastguard Worker 			goto again;
3724*58e6ee5fSAndroid Build Coastguard Worker 		}
3725*58e6ee5fSAndroid Build Coastguard Worker 		communicate_with_listener_v3(msg_handle, &instance->client_ports);
3726*58e6ee5fSAndroid Build Coastguard Worker 	}
3727*58e6ee5fSAndroid Build Coastguard Worker 
3728*58e6ee5fSAndroid Build Coastguard Worker 	if (msg_handle->version == V1_PROTOCOL)
3729*58e6ee5fSAndroid Build Coastguard Worker 		communicate_with_listener_v1(msg_handle, instance);
3730*58e6ee5fSAndroid Build Coastguard Worker 
3731*58e6ee5fSAndroid Build Coastguard Worker 	return msg_handle;
3732*58e6ee5fSAndroid Build Coastguard Worker }
3733*58e6ee5fSAndroid Build Coastguard Worker 
3734*58e6ee5fSAndroid Build Coastguard Worker static void add_options(struct tracecmd_output *handle, struct common_record_context *ctx);
3735*58e6ee5fSAndroid Build Coastguard Worker 
create_net_output(struct common_record_context * ctx,struct tracecmd_msg_handle * msg_handle)3736*58e6ee5fSAndroid Build Coastguard Worker static struct tracecmd_output *create_net_output(struct common_record_context *ctx,
3737*58e6ee5fSAndroid Build Coastguard Worker 						 struct tracecmd_msg_handle *msg_handle)
3738*58e6ee5fSAndroid Build Coastguard Worker {
3739*58e6ee5fSAndroid Build Coastguard Worker 	struct tracecmd_output *out;
3740*58e6ee5fSAndroid Build Coastguard Worker 
3741*58e6ee5fSAndroid Build Coastguard Worker 	out = tracecmd_output_create(NULL);
3742*58e6ee5fSAndroid Build Coastguard Worker 	if (!out)
3743*58e6ee5fSAndroid Build Coastguard Worker 		return NULL;
3744*58e6ee5fSAndroid Build Coastguard Worker 	if (ctx->file_version && tracecmd_output_set_version(out, ctx->file_version))
3745*58e6ee5fSAndroid Build Coastguard Worker 		goto error;
3746*58e6ee5fSAndroid Build Coastguard Worker 	if (tracecmd_output_set_msg(out, msg_handle))
3747*58e6ee5fSAndroid Build Coastguard Worker 		goto error;
3748*58e6ee5fSAndroid Build Coastguard Worker 
3749*58e6ee5fSAndroid Build Coastguard Worker 	if (ctx->compression) {
3750*58e6ee5fSAndroid Build Coastguard Worker 		if (tracecmd_output_set_compression(out, ctx->compression))
3751*58e6ee5fSAndroid Build Coastguard Worker 			goto error;
3752*58e6ee5fSAndroid Build Coastguard Worker 	} else if (ctx->file_version >= FILE_VERSION_COMPRESSION) {
3753*58e6ee5fSAndroid Build Coastguard Worker 		tracecmd_output_set_compression(out, "any");
3754*58e6ee5fSAndroid Build Coastguard Worker 	}
3755*58e6ee5fSAndroid Build Coastguard Worker 
3756*58e6ee5fSAndroid Build Coastguard Worker 	if (tracecmd_output_write_headers(out, listed_events))
3757*58e6ee5fSAndroid Build Coastguard Worker 		goto error;
3758*58e6ee5fSAndroid Build Coastguard Worker 
3759*58e6ee5fSAndroid Build Coastguard Worker 	return out;
3760*58e6ee5fSAndroid Build Coastguard Worker error:
3761*58e6ee5fSAndroid Build Coastguard Worker 	tracecmd_output_close(out);
3762*58e6ee5fSAndroid Build Coastguard Worker 	return NULL;
3763*58e6ee5fSAndroid Build Coastguard Worker }
3764*58e6ee5fSAndroid Build Coastguard Worker 
3765*58e6ee5fSAndroid Build Coastguard Worker static struct tracecmd_msg_handle *
setup_connection(struct buffer_instance * instance,struct common_record_context * ctx)3766*58e6ee5fSAndroid Build Coastguard Worker setup_connection(struct buffer_instance *instance, struct common_record_context *ctx)
3767*58e6ee5fSAndroid Build Coastguard Worker {
3768*58e6ee5fSAndroid Build Coastguard Worker 	struct tracecmd_msg_handle *msg_handle = NULL;
3769*58e6ee5fSAndroid Build Coastguard Worker 	struct tracecmd_output *network_handle = NULL;
3770*58e6ee5fSAndroid Build Coastguard Worker 	int ret;
3771*58e6ee5fSAndroid Build Coastguard Worker 
3772*58e6ee5fSAndroid Build Coastguard Worker 	msg_handle = setup_network(instance);
3773*58e6ee5fSAndroid Build Coastguard Worker 	if (!msg_handle)
3774*58e6ee5fSAndroid Build Coastguard Worker 		die("Failed to make connection");
3775*58e6ee5fSAndroid Build Coastguard Worker 
3776*58e6ee5fSAndroid Build Coastguard Worker 	/* Now create the handle through this socket */
3777*58e6ee5fSAndroid Build Coastguard Worker 	if (msg_handle->version == V3_PROTOCOL) {
3778*58e6ee5fSAndroid Build Coastguard Worker 		network_handle = create_net_output(ctx, msg_handle);
3779*58e6ee5fSAndroid Build Coastguard Worker 		if (!network_handle)
3780*58e6ee5fSAndroid Build Coastguard Worker 			goto error;
3781*58e6ee5fSAndroid Build Coastguard Worker 		tracecmd_set_quiet(network_handle, quiet);
3782*58e6ee5fSAndroid Build Coastguard Worker 		add_options(network_handle, ctx);
3783*58e6ee5fSAndroid Build Coastguard Worker 		ret = tracecmd_write_cmdlines(network_handle);
3784*58e6ee5fSAndroid Build Coastguard Worker 		if (ret)
3785*58e6ee5fSAndroid Build Coastguard Worker 			goto error;
3786*58e6ee5fSAndroid Build Coastguard Worker 		ret = tracecmd_write_cpus(network_handle, instance->cpu_count);
3787*58e6ee5fSAndroid Build Coastguard Worker 		if (ret)
3788*58e6ee5fSAndroid Build Coastguard Worker 			goto error;
3789*58e6ee5fSAndroid Build Coastguard Worker 		ret = tracecmd_write_buffer_info(network_handle);
3790*58e6ee5fSAndroid Build Coastguard Worker 		if (ret)
3791*58e6ee5fSAndroid Build Coastguard Worker 			goto error;
3792*58e6ee5fSAndroid Build Coastguard Worker 		ret = tracecmd_write_options(network_handle);
3793*58e6ee5fSAndroid Build Coastguard Worker 		if (ret)
3794*58e6ee5fSAndroid Build Coastguard Worker 			goto error;
3795*58e6ee5fSAndroid Build Coastguard Worker 		ret = tracecmd_msg_finish_sending_data(msg_handle);
3796*58e6ee5fSAndroid Build Coastguard Worker 		if (ret)
3797*58e6ee5fSAndroid Build Coastguard Worker 			goto error;
3798*58e6ee5fSAndroid Build Coastguard Worker 	} else {
3799*58e6ee5fSAndroid Build Coastguard Worker 		network_handle = tracecmd_output_create_fd(msg_handle->fd);
3800*58e6ee5fSAndroid Build Coastguard Worker 		if (!network_handle)
3801*58e6ee5fSAndroid Build Coastguard Worker 			goto error;
3802*58e6ee5fSAndroid Build Coastguard Worker 		if (tracecmd_output_set_version(network_handle, ctx->file_version))
3803*58e6ee5fSAndroid Build Coastguard Worker 			goto error;
3804*58e6ee5fSAndroid Build Coastguard Worker 
3805*58e6ee5fSAndroid Build Coastguard Worker 		if (ctx->compression) {
3806*58e6ee5fSAndroid Build Coastguard Worker 			if (tracecmd_output_set_compression(network_handle, ctx->compression))
3807*58e6ee5fSAndroid Build Coastguard Worker 				goto error;
3808*58e6ee5fSAndroid Build Coastguard Worker 		} else if (ctx->file_version >= FILE_VERSION_COMPRESSION) {
3809*58e6ee5fSAndroid Build Coastguard Worker 			tracecmd_output_set_compression(network_handle, "any");
3810*58e6ee5fSAndroid Build Coastguard Worker 		}
3811*58e6ee5fSAndroid Build Coastguard Worker 
3812*58e6ee5fSAndroid Build Coastguard Worker 		if (tracecmd_output_write_headers(network_handle, listed_events))
3813*58e6ee5fSAndroid Build Coastguard Worker 			goto error;
3814*58e6ee5fSAndroid Build Coastguard Worker 		tracecmd_set_quiet(network_handle, quiet);
3815*58e6ee5fSAndroid Build Coastguard Worker 	}
3816*58e6ee5fSAndroid Build Coastguard Worker 
3817*58e6ee5fSAndroid Build Coastguard Worker 	instance->network_handle = network_handle;
3818*58e6ee5fSAndroid Build Coastguard Worker 
3819*58e6ee5fSAndroid Build Coastguard Worker 	/* OK, we are all set, let'r rip! */
3820*58e6ee5fSAndroid Build Coastguard Worker 	return msg_handle;
3821*58e6ee5fSAndroid Build Coastguard Worker 
3822*58e6ee5fSAndroid Build Coastguard Worker error:
3823*58e6ee5fSAndroid Build Coastguard Worker 	if (msg_handle)
3824*58e6ee5fSAndroid Build Coastguard Worker 		tracecmd_msg_handle_close(msg_handle);
3825*58e6ee5fSAndroid Build Coastguard Worker 	if (network_handle)
3826*58e6ee5fSAndroid Build Coastguard Worker 		tracecmd_output_close(network_handle);
3827*58e6ee5fSAndroid Build Coastguard Worker 	return NULL;
3828*58e6ee5fSAndroid Build Coastguard Worker }
3829*58e6ee5fSAndroid Build Coastguard Worker 
finish_network(struct tracecmd_msg_handle * msg_handle)3830*58e6ee5fSAndroid Build Coastguard Worker static void finish_network(struct tracecmd_msg_handle *msg_handle)
3831*58e6ee5fSAndroid Build Coastguard Worker {
3832*58e6ee5fSAndroid Build Coastguard Worker 	if (msg_handle->version == V3_PROTOCOL)
3833*58e6ee5fSAndroid Build Coastguard Worker 		tracecmd_msg_send_close_msg(msg_handle);
3834*58e6ee5fSAndroid Build Coastguard Worker 	tracecmd_msg_handle_close(msg_handle);
3835*58e6ee5fSAndroid Build Coastguard Worker 	free(host);
3836*58e6ee5fSAndroid Build Coastguard Worker }
3837*58e6ee5fSAndroid Build Coastguard Worker 
open_guest_fifos(const char * guest,int ** fds)3838*58e6ee5fSAndroid Build Coastguard Worker static int open_guest_fifos(const char *guest, int **fds)
3839*58e6ee5fSAndroid Build Coastguard Worker {
3840*58e6ee5fSAndroid Build Coastguard Worker 	char path[PATH_MAX];
3841*58e6ee5fSAndroid Build Coastguard Worker 	int i, fd, flags;
3842*58e6ee5fSAndroid Build Coastguard Worker 
3843*58e6ee5fSAndroid Build Coastguard Worker 	for (i = 0; ; i++) {
3844*58e6ee5fSAndroid Build Coastguard Worker 		snprintf(path, sizeof(path), GUEST_FIFO_FMT ".out", guest, i);
3845*58e6ee5fSAndroid Build Coastguard Worker 
3846*58e6ee5fSAndroid Build Coastguard Worker 		/* O_NONBLOCK so we don't wait for writers */
3847*58e6ee5fSAndroid Build Coastguard Worker 		fd = open(path, O_RDONLY | O_NONBLOCK);
3848*58e6ee5fSAndroid Build Coastguard Worker 		if (fd < 0)
3849*58e6ee5fSAndroid Build Coastguard Worker 			break;
3850*58e6ee5fSAndroid Build Coastguard Worker 
3851*58e6ee5fSAndroid Build Coastguard Worker 		/* Success, now clear O_NONBLOCK */
3852*58e6ee5fSAndroid Build Coastguard Worker 		flags = fcntl(fd, F_GETFL);
3853*58e6ee5fSAndroid Build Coastguard Worker 		fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
3854*58e6ee5fSAndroid Build Coastguard Worker 
3855*58e6ee5fSAndroid Build Coastguard Worker 		*fds = realloc(*fds, i + 1);
3856*58e6ee5fSAndroid Build Coastguard Worker 		(*fds)[i] = fd;
3857*58e6ee5fSAndroid Build Coastguard Worker 	}
3858*58e6ee5fSAndroid Build Coastguard Worker 
3859*58e6ee5fSAndroid Build Coastguard Worker 	return i;
3860*58e6ee5fSAndroid Build Coastguard Worker }
3861*58e6ee5fSAndroid Build Coastguard Worker 
3862*58e6ee5fSAndroid Build Coastguard Worker struct trace_mapping {
3863*58e6ee5fSAndroid Build Coastguard Worker 	struct tep_event		*kvm_entry;
3864*58e6ee5fSAndroid Build Coastguard Worker 	struct tep_format_field		*vcpu_id;
3865*58e6ee5fSAndroid Build Coastguard Worker 	struct tep_format_field		*common_pid;
3866*58e6ee5fSAndroid Build Coastguard Worker 	int				*pids;
3867*58e6ee5fSAndroid Build Coastguard Worker 	int				*map;
3868*58e6ee5fSAndroid Build Coastguard Worker 	int				max_cpus;
3869*58e6ee5fSAndroid Build Coastguard Worker };
3870*58e6ee5fSAndroid Build Coastguard Worker 
start_mapping_vcpus(struct trace_guest * guest)3871*58e6ee5fSAndroid Build Coastguard Worker static void start_mapping_vcpus(struct trace_guest *guest)
3872*58e6ee5fSAndroid Build Coastguard Worker {
3873*58e6ee5fSAndroid Build Coastguard Worker 	char *pids = NULL;
3874*58e6ee5fSAndroid Build Coastguard Worker 	char *t;
3875*58e6ee5fSAndroid Build Coastguard Worker 	int len = 0;
3876*58e6ee5fSAndroid Build Coastguard Worker 	int s;
3877*58e6ee5fSAndroid Build Coastguard Worker 	int i;
3878*58e6ee5fSAndroid Build Coastguard Worker 
3879*58e6ee5fSAndroid Build Coastguard Worker 	if (!guest->task_pids)
3880*58e6ee5fSAndroid Build Coastguard Worker 		return;
3881*58e6ee5fSAndroid Build Coastguard Worker 
3882*58e6ee5fSAndroid Build Coastguard Worker 	guest->instance = tracefs_instance_create("map_guest_pids");
3883*58e6ee5fSAndroid Build Coastguard Worker 	if (!guest->instance)
3884*58e6ee5fSAndroid Build Coastguard Worker 		return;
3885*58e6ee5fSAndroid Build Coastguard Worker 
3886*58e6ee5fSAndroid Build Coastguard Worker 	for (i = 0; guest->task_pids[i] >= 0; i++) {
3887*58e6ee5fSAndroid Build Coastguard Worker 		s = snprintf(NULL, 0, "%d ", guest->task_pids[i]);
3888*58e6ee5fSAndroid Build Coastguard Worker 		t = realloc(pids, len + s + 1);
3889*58e6ee5fSAndroid Build Coastguard Worker 		if (!t) {
3890*58e6ee5fSAndroid Build Coastguard Worker 			free(pids);
3891*58e6ee5fSAndroid Build Coastguard Worker 			pids = NULL;
3892*58e6ee5fSAndroid Build Coastguard Worker 			break;
3893*58e6ee5fSAndroid Build Coastguard Worker 		}
3894*58e6ee5fSAndroid Build Coastguard Worker 		pids = t;
3895*58e6ee5fSAndroid Build Coastguard Worker 		sprintf(pids + len, "%d ", guest->task_pids[i]);
3896*58e6ee5fSAndroid Build Coastguard Worker 		len += s;
3897*58e6ee5fSAndroid Build Coastguard Worker 	}
3898*58e6ee5fSAndroid Build Coastguard Worker 	if (pids) {
3899*58e6ee5fSAndroid Build Coastguard Worker 		tracefs_instance_file_write(guest->instance, "set_event_pid", pids);
3900*58e6ee5fSAndroid Build Coastguard Worker 		free(pids);
3901*58e6ee5fSAndroid Build Coastguard Worker 	}
3902*58e6ee5fSAndroid Build Coastguard Worker 	tracefs_instance_file_write(guest->instance, "events/kvm/kvm_entry/enable", "1");
3903*58e6ee5fSAndroid Build Coastguard Worker }
3904*58e6ee5fSAndroid Build Coastguard Worker 
map_vcpus(struct tep_event * event,struct tep_record * record,int cpu,void * context)3905*58e6ee5fSAndroid Build Coastguard Worker static int map_vcpus(struct tep_event *event, struct tep_record *record,
3906*58e6ee5fSAndroid Build Coastguard Worker 		     int cpu, void *context)
3907*58e6ee5fSAndroid Build Coastguard Worker {
3908*58e6ee5fSAndroid Build Coastguard Worker 	struct trace_mapping *tmap = context;
3909*58e6ee5fSAndroid Build Coastguard Worker 	unsigned long long val;
3910*58e6ee5fSAndroid Build Coastguard Worker 	int type;
3911*58e6ee5fSAndroid Build Coastguard Worker 	int pid;
3912*58e6ee5fSAndroid Build Coastguard Worker 	int ret;
3913*58e6ee5fSAndroid Build Coastguard Worker 	int i;
3914*58e6ee5fSAndroid Build Coastguard Worker 
3915*58e6ee5fSAndroid Build Coastguard Worker 	/* Do we have junk in the buffer? */
3916*58e6ee5fSAndroid Build Coastguard Worker 	type = tep_data_type(event->tep, record);
3917*58e6ee5fSAndroid Build Coastguard Worker 	if (type != tmap->kvm_entry->id)
3918*58e6ee5fSAndroid Build Coastguard Worker 		return 0;
3919*58e6ee5fSAndroid Build Coastguard Worker 
3920*58e6ee5fSAndroid Build Coastguard Worker 	ret = tep_read_number_field(tmap->common_pid, record->data, &val);
3921*58e6ee5fSAndroid Build Coastguard Worker 	if (ret < 0)
3922*58e6ee5fSAndroid Build Coastguard Worker 		return 0;
3923*58e6ee5fSAndroid Build Coastguard Worker 	pid = (int)val;
3924*58e6ee5fSAndroid Build Coastguard Worker 
3925*58e6ee5fSAndroid Build Coastguard Worker 	for (i = 0; tmap->pids[i] >= 0; i++) {
3926*58e6ee5fSAndroid Build Coastguard Worker 		if (pid == tmap->pids[i])
3927*58e6ee5fSAndroid Build Coastguard Worker 			break;
3928*58e6ee5fSAndroid Build Coastguard Worker 	}
3929*58e6ee5fSAndroid Build Coastguard Worker 	/* Is this thread one we care about ? */
3930*58e6ee5fSAndroid Build Coastguard Worker 	if (tmap->pids[i] < 0)
3931*58e6ee5fSAndroid Build Coastguard Worker 		return 0;
3932*58e6ee5fSAndroid Build Coastguard Worker 
3933*58e6ee5fSAndroid Build Coastguard Worker 	ret = tep_read_number_field(tmap->vcpu_id, record->data, &val);
3934*58e6ee5fSAndroid Build Coastguard Worker 	if (ret < 0)
3935*58e6ee5fSAndroid Build Coastguard Worker 		return 0;
3936*58e6ee5fSAndroid Build Coastguard Worker 
3937*58e6ee5fSAndroid Build Coastguard Worker 	cpu = (int)val;
3938*58e6ee5fSAndroid Build Coastguard Worker 
3939*58e6ee5fSAndroid Build Coastguard Worker 	/* Sanity check, warn? */
3940*58e6ee5fSAndroid Build Coastguard Worker 	if (cpu >= tmap->max_cpus)
3941*58e6ee5fSAndroid Build Coastguard Worker 		return 0;
3942*58e6ee5fSAndroid Build Coastguard Worker 
3943*58e6ee5fSAndroid Build Coastguard Worker 	/* Already have this one? Should we check if it is the same? */
3944*58e6ee5fSAndroid Build Coastguard Worker 	if (tmap->map[cpu] >= 0)
3945*58e6ee5fSAndroid Build Coastguard Worker 		return 0;
3946*58e6ee5fSAndroid Build Coastguard Worker 
3947*58e6ee5fSAndroid Build Coastguard Worker 	tmap->map[cpu] = pid;
3948*58e6ee5fSAndroid Build Coastguard Worker 
3949*58e6ee5fSAndroid Build Coastguard Worker 	/* Did we get them all */
3950*58e6ee5fSAndroid Build Coastguard Worker 	for (i = 0; i < tmap->max_cpus; i++) {
3951*58e6ee5fSAndroid Build Coastguard Worker 		if (tmap->map[i] < 0)
3952*58e6ee5fSAndroid Build Coastguard Worker 			break;
3953*58e6ee5fSAndroid Build Coastguard Worker 	}
3954*58e6ee5fSAndroid Build Coastguard Worker 
3955*58e6ee5fSAndroid Build Coastguard Worker 	return i == tmap->max_cpus;
3956*58e6ee5fSAndroid Build Coastguard Worker }
3957*58e6ee5fSAndroid Build Coastguard Worker 
stop_mapping_vcpus(struct buffer_instance * instance,struct trace_guest * guest)3958*58e6ee5fSAndroid Build Coastguard Worker static void stop_mapping_vcpus(struct buffer_instance *instance,
3959*58e6ee5fSAndroid Build Coastguard Worker 			       struct trace_guest *guest)
3960*58e6ee5fSAndroid Build Coastguard Worker {
3961*58e6ee5fSAndroid Build Coastguard Worker 	struct trace_mapping tmap = { };
3962*58e6ee5fSAndroid Build Coastguard Worker 	struct tep_handle *tep;
3963*58e6ee5fSAndroid Build Coastguard Worker 	const char *systems[] = { "kvm", NULL };
3964*58e6ee5fSAndroid Build Coastguard Worker 	int i;
3965*58e6ee5fSAndroid Build Coastguard Worker 
3966*58e6ee5fSAndroid Build Coastguard Worker 	if (!guest->instance)
3967*58e6ee5fSAndroid Build Coastguard Worker 		return;
3968*58e6ee5fSAndroid Build Coastguard Worker 
3969*58e6ee5fSAndroid Build Coastguard Worker 	tmap.pids = guest->task_pids;
3970*58e6ee5fSAndroid Build Coastguard Worker 	tmap.max_cpus = instance->cpu_count;
3971*58e6ee5fSAndroid Build Coastguard Worker 
3972*58e6ee5fSAndroid Build Coastguard Worker 	tmap.map = malloc(sizeof(*tmap.map) * tmap.max_cpus);
3973*58e6ee5fSAndroid Build Coastguard Worker 	if (!tmap.map)
3974*58e6ee5fSAndroid Build Coastguard Worker 		return;
3975*58e6ee5fSAndroid Build Coastguard Worker 
3976*58e6ee5fSAndroid Build Coastguard Worker 	for (i = 0; i < tmap.max_cpus; i++)
3977*58e6ee5fSAndroid Build Coastguard Worker 		tmap.map[i] = -1;
3978*58e6ee5fSAndroid Build Coastguard Worker 
3979*58e6ee5fSAndroid Build Coastguard Worker 	tracefs_instance_file_write(guest->instance, "events/kvm/kvm_entry/enable", "0");
3980*58e6ee5fSAndroid Build Coastguard Worker 
3981*58e6ee5fSAndroid Build Coastguard Worker 	tep = tracefs_local_events_system(NULL, systems);
3982*58e6ee5fSAndroid Build Coastguard Worker 	if (!tep)
3983*58e6ee5fSAndroid Build Coastguard Worker 		goto out;
3984*58e6ee5fSAndroid Build Coastguard Worker 
3985*58e6ee5fSAndroid Build Coastguard Worker 	tmap.kvm_entry = tep_find_event_by_name(tep, "kvm", "kvm_entry");
3986*58e6ee5fSAndroid Build Coastguard Worker 	if (!tmap.kvm_entry)
3987*58e6ee5fSAndroid Build Coastguard Worker 		goto out_free;
3988*58e6ee5fSAndroid Build Coastguard Worker 
3989*58e6ee5fSAndroid Build Coastguard Worker 	tmap.vcpu_id = tep_find_field(tmap.kvm_entry, "vcpu_id");
3990*58e6ee5fSAndroid Build Coastguard Worker 	if (!tmap.vcpu_id)
3991*58e6ee5fSAndroid Build Coastguard Worker 		goto out_free;
3992*58e6ee5fSAndroid Build Coastguard Worker 
3993*58e6ee5fSAndroid Build Coastguard Worker 	tmap.common_pid = tep_find_any_field(tmap.kvm_entry, "common_pid");
3994*58e6ee5fSAndroid Build Coastguard Worker 	if (!tmap.common_pid)
3995*58e6ee5fSAndroid Build Coastguard Worker 		goto out_free;
3996*58e6ee5fSAndroid Build Coastguard Worker 
3997*58e6ee5fSAndroid Build Coastguard Worker 	tracefs_iterate_raw_events(tep, guest->instance, NULL, 0, map_vcpus, &tmap);
3998*58e6ee5fSAndroid Build Coastguard Worker 
3999*58e6ee5fSAndroid Build Coastguard Worker 	for (i = 0; i < tmap.max_cpus; i++) {
4000*58e6ee5fSAndroid Build Coastguard Worker 		if (tmap.map[i] < 0)
4001*58e6ee5fSAndroid Build Coastguard Worker 			break;
4002*58e6ee5fSAndroid Build Coastguard Worker 	}
4003*58e6ee5fSAndroid Build Coastguard Worker 	/* We found all the mapped CPUs */
4004*58e6ee5fSAndroid Build Coastguard Worker 	if (i == tmap.max_cpus) {
4005*58e6ee5fSAndroid Build Coastguard Worker 		guest->cpu_pid = tmap.map;
4006*58e6ee5fSAndroid Build Coastguard Worker 		guest->cpu_max = tmap.max_cpus;
4007*58e6ee5fSAndroid Build Coastguard Worker 		tmap.map = NULL;
4008*58e6ee5fSAndroid Build Coastguard Worker 	}
4009*58e6ee5fSAndroid Build Coastguard Worker 
4010*58e6ee5fSAndroid Build Coastguard Worker  out_free:
4011*58e6ee5fSAndroid Build Coastguard Worker 	tep_free(tep);
4012*58e6ee5fSAndroid Build Coastguard Worker  out:
4013*58e6ee5fSAndroid Build Coastguard Worker 	free(tmap.map);
4014*58e6ee5fSAndroid Build Coastguard Worker 	tracefs_instance_destroy(guest->instance);
4015*58e6ee5fSAndroid Build Coastguard Worker 	tracefs_instance_free(guest->instance);
4016*58e6ee5fSAndroid Build Coastguard Worker }
4017*58e6ee5fSAndroid Build Coastguard Worker 
host_tsync(struct common_record_context * ctx,struct buffer_instance * instance,unsigned int tsync_port,char * proto)4018*58e6ee5fSAndroid Build Coastguard Worker static int host_tsync(struct common_record_context *ctx,
4019*58e6ee5fSAndroid Build Coastguard Worker 		      struct buffer_instance *instance,
4020*58e6ee5fSAndroid Build Coastguard Worker 		      unsigned int tsync_port, char *proto)
4021*58e6ee5fSAndroid Build Coastguard Worker {
4022*58e6ee5fSAndroid Build Coastguard Worker 	struct trace_guest *guest;
4023*58e6ee5fSAndroid Build Coastguard Worker 	int guest_pid = -1;
4024*58e6ee5fSAndroid Build Coastguard Worker 	int fd;
4025*58e6ee5fSAndroid Build Coastguard Worker 
4026*58e6ee5fSAndroid Build Coastguard Worker 	if (!proto)
4027*58e6ee5fSAndroid Build Coastguard Worker 		return -1;
4028*58e6ee5fSAndroid Build Coastguard Worker 
4029*58e6ee5fSAndroid Build Coastguard Worker 	if (is_network(instance)) {
4030*58e6ee5fSAndroid Build Coastguard Worker 		fd = connect_port(instance->name, tsync_port,
4031*58e6ee5fSAndroid Build Coastguard Worker 				  instance->port_type);
4032*58e6ee5fSAndroid Build Coastguard Worker 	} else {
4033*58e6ee5fSAndroid Build Coastguard Worker 		guest = trace_get_guest(instance->cid, NULL);
4034*58e6ee5fSAndroid Build Coastguard Worker 		if (guest == NULL)
4035*58e6ee5fSAndroid Build Coastguard Worker 			return -1;
4036*58e6ee5fSAndroid Build Coastguard Worker 
4037*58e6ee5fSAndroid Build Coastguard Worker 		guest_pid = guest->pid;
4038*58e6ee5fSAndroid Build Coastguard Worker 		start_mapping_vcpus(guest);
4039*58e6ee5fSAndroid Build Coastguard Worker 		fd = trace_vsock_open(instance->cid, tsync_port);
4040*58e6ee5fSAndroid Build Coastguard Worker 	}
4041*58e6ee5fSAndroid Build Coastguard Worker 
4042*58e6ee5fSAndroid Build Coastguard Worker 	instance->tsync = tracecmd_tsync_with_guest(top_instance.trace_id,
4043*58e6ee5fSAndroid Build Coastguard Worker 						    instance->tsync_loop_interval,
4044*58e6ee5fSAndroid Build Coastguard Worker 						    fd, guest_pid,
4045*58e6ee5fSAndroid Build Coastguard Worker 						    instance->cpu_count,
4046*58e6ee5fSAndroid Build Coastguard Worker 						    proto, ctx->clock);
4047*58e6ee5fSAndroid Build Coastguard Worker 	if (!is_network(instance))
4048*58e6ee5fSAndroid Build Coastguard Worker 		stop_mapping_vcpus(instance, guest);
4049*58e6ee5fSAndroid Build Coastguard Worker 
4050*58e6ee5fSAndroid Build Coastguard Worker 	if (!instance->tsync)
4051*58e6ee5fSAndroid Build Coastguard Worker 		return -1;
4052*58e6ee5fSAndroid Build Coastguard Worker 
4053*58e6ee5fSAndroid Build Coastguard Worker 	return 0;
4054*58e6ee5fSAndroid Build Coastguard Worker }
4055*58e6ee5fSAndroid Build Coastguard Worker 
connect_to_agent(struct common_record_context * ctx,struct buffer_instance * instance)4056*58e6ee5fSAndroid Build Coastguard Worker static void connect_to_agent(struct common_record_context *ctx,
4057*58e6ee5fSAndroid Build Coastguard Worker 			     struct buffer_instance *instance)
4058*58e6ee5fSAndroid Build Coastguard Worker {
4059*58e6ee5fSAndroid Build Coastguard Worker 	struct tracecmd_tsync_protos *protos = NULL;
4060*58e6ee5fSAndroid Build Coastguard Worker 	int sd, ret, nr_fifos, nr_cpus, page_size;
4061*58e6ee5fSAndroid Build Coastguard Worker 	struct tracecmd_msg_handle *msg_handle;
4062*58e6ee5fSAndroid Build Coastguard Worker 	enum tracecmd_time_sync_role role;
4063*58e6ee5fSAndroid Build Coastguard Worker 	char *tsync_protos_reply = NULL;
4064*58e6ee5fSAndroid Build Coastguard Worker 	unsigned int tsync_port = 0;
4065*58e6ee5fSAndroid Build Coastguard Worker 	unsigned int *ports;
4066*58e6ee5fSAndroid Build Coastguard Worker 	int i, *fds = NULL;
4067*58e6ee5fSAndroid Build Coastguard Worker 	bool use_fifos = false;
4068*58e6ee5fSAndroid Build Coastguard Worker 
4069*58e6ee5fSAndroid Build Coastguard Worker 	if (!no_fifos) {
4070*58e6ee5fSAndroid Build Coastguard Worker 		nr_fifos = open_guest_fifos(instance->name, &fds);
4071*58e6ee5fSAndroid Build Coastguard Worker 		use_fifos = nr_fifos > 0;
4072*58e6ee5fSAndroid Build Coastguard Worker 	}
4073*58e6ee5fSAndroid Build Coastguard Worker 
4074*58e6ee5fSAndroid Build Coastguard Worker 	if (ctx->instance->result) {
4075*58e6ee5fSAndroid Build Coastguard Worker 		role = TRACECMD_TIME_SYNC_ROLE_CLIENT;
4076*58e6ee5fSAndroid Build Coastguard Worker 		sd = connect_addr(ctx->instance->result);
4077*58e6ee5fSAndroid Build Coastguard Worker 		if (sd < 0)
4078*58e6ee5fSAndroid Build Coastguard Worker 			die("Failed to connect to host %s:%u",
4079*58e6ee5fSAndroid Build Coastguard Worker 			    instance->name, instance->port);
4080*58e6ee5fSAndroid Build Coastguard Worker 	} else {
4081*58e6ee5fSAndroid Build Coastguard Worker 		role = TRACECMD_TIME_SYNC_ROLE_HOST;
4082*58e6ee5fSAndroid Build Coastguard Worker 		sd = trace_vsock_open(instance->cid, instance->port);
4083*58e6ee5fSAndroid Build Coastguard Worker 		if (sd < 0)
4084*58e6ee5fSAndroid Build Coastguard Worker 			die("Failed to connect to vsocket @%u:%u",
4085*58e6ee5fSAndroid Build Coastguard Worker 			    instance->cid, instance->port);
4086*58e6ee5fSAndroid Build Coastguard Worker 	}
4087*58e6ee5fSAndroid Build Coastguard Worker 
4088*58e6ee5fSAndroid Build Coastguard Worker 	msg_handle = tracecmd_msg_handle_alloc(sd, 0);
4089*58e6ee5fSAndroid Build Coastguard Worker 	if (!msg_handle)
4090*58e6ee5fSAndroid Build Coastguard Worker 		die("Failed to allocate message handle");
4091*58e6ee5fSAndroid Build Coastguard Worker 
4092*58e6ee5fSAndroid Build Coastguard Worker 	if (!instance->clock)
4093*58e6ee5fSAndroid Build Coastguard Worker 		instance->clock = tracefs_get_clock(NULL);
4094*58e6ee5fSAndroid Build Coastguard Worker 
4095*58e6ee5fSAndroid Build Coastguard Worker 	if (instance->tsync_loop_interval >= 0)
4096*58e6ee5fSAndroid Build Coastguard Worker 		tracecmd_tsync_proto_getall(&protos, instance->clock, role);
4097*58e6ee5fSAndroid Build Coastguard Worker 
4098*58e6ee5fSAndroid Build Coastguard Worker 	ret = tracecmd_msg_send_trace_req(msg_handle, instance->argc,
4099*58e6ee5fSAndroid Build Coastguard Worker 					  instance->argv, use_fifos,
4100*58e6ee5fSAndroid Build Coastguard Worker 					  top_instance.trace_id, protos);
4101*58e6ee5fSAndroid Build Coastguard Worker 	if (ret < 0)
4102*58e6ee5fSAndroid Build Coastguard Worker 		die("Failed to send trace request");
4103*58e6ee5fSAndroid Build Coastguard Worker 
4104*58e6ee5fSAndroid Build Coastguard Worker 	if (protos) {
4105*58e6ee5fSAndroid Build Coastguard Worker 		free(protos->names);
4106*58e6ee5fSAndroid Build Coastguard Worker 		free(protos);
4107*58e6ee5fSAndroid Build Coastguard Worker 	}
4108*58e6ee5fSAndroid Build Coastguard Worker 	ret = tracecmd_msg_recv_trace_resp(msg_handle, &nr_cpus, &page_size,
4109*58e6ee5fSAndroid Build Coastguard Worker 					   &ports, &use_fifos,
4110*58e6ee5fSAndroid Build Coastguard Worker 					   &instance->trace_id,
4111*58e6ee5fSAndroid Build Coastguard Worker 					   &tsync_protos_reply, &tsync_port);
4112*58e6ee5fSAndroid Build Coastguard Worker 	if (ret < 0)
4113*58e6ee5fSAndroid Build Coastguard Worker 		die("Failed to receive trace response %d", ret);
4114*58e6ee5fSAndroid Build Coastguard Worker 	if (tsync_protos_reply && tsync_protos_reply[0]) {
4115*58e6ee5fSAndroid Build Coastguard Worker 		if (tsync_proto_is_supported(tsync_protos_reply)) {
4116*58e6ee5fSAndroid Build Coastguard Worker 			printf("Negotiated %s time sync protocol with guest %s\n",
4117*58e6ee5fSAndroid Build Coastguard Worker 				tsync_protos_reply,
4118*58e6ee5fSAndroid Build Coastguard Worker 				instance->name);
4119*58e6ee5fSAndroid Build Coastguard Worker 			instance->cpu_count = nr_cpus;
4120*58e6ee5fSAndroid Build Coastguard Worker 			host_tsync(ctx, instance, tsync_port, tsync_protos_reply);
4121*58e6ee5fSAndroid Build Coastguard Worker 		} else
4122*58e6ee5fSAndroid Build Coastguard Worker 			warning("Failed to negotiate timestamps synchronization with the guest");
4123*58e6ee5fSAndroid Build Coastguard Worker 	}
4124*58e6ee5fSAndroid Build Coastguard Worker 	free(tsync_protos_reply);
4125*58e6ee5fSAndroid Build Coastguard Worker 
4126*58e6ee5fSAndroid Build Coastguard Worker 	if (use_fifos) {
4127*58e6ee5fSAndroid Build Coastguard Worker 		if (nr_cpus != nr_fifos) {
4128*58e6ee5fSAndroid Build Coastguard Worker 			warning("number of FIFOs (%d) for guest %s differs "
4129*58e6ee5fSAndroid Build Coastguard Worker 				"from number of virtual CPUs (%d)",
4130*58e6ee5fSAndroid Build Coastguard Worker 				nr_fifos, instance->name, nr_cpus);
4131*58e6ee5fSAndroid Build Coastguard Worker 			nr_cpus = nr_cpus < nr_fifos ? nr_cpus : nr_fifos;
4132*58e6ee5fSAndroid Build Coastguard Worker 		}
4133*58e6ee5fSAndroid Build Coastguard Worker 		free(ports);
4134*58e6ee5fSAndroid Build Coastguard Worker 		instance->fds = fds;
4135*58e6ee5fSAndroid Build Coastguard Worker 	} else {
4136*58e6ee5fSAndroid Build Coastguard Worker 		for (i = 0; i < nr_fifos; i++)
4137*58e6ee5fSAndroid Build Coastguard Worker 			close(fds[i]);
4138*58e6ee5fSAndroid Build Coastguard Worker 		free(fds);
4139*58e6ee5fSAndroid Build Coastguard Worker 		instance->client_ports = ports;
4140*58e6ee5fSAndroid Build Coastguard Worker 	}
4141*58e6ee5fSAndroid Build Coastguard Worker 
4142*58e6ee5fSAndroid Build Coastguard Worker 	instance->use_fifos = use_fifos;
4143*58e6ee5fSAndroid Build Coastguard Worker 	instance->cpu_count = nr_cpus;
4144*58e6ee5fSAndroid Build Coastguard Worker 
4145*58e6ee5fSAndroid Build Coastguard Worker 	/* the msg_handle now points to the guest fd */
4146*58e6ee5fSAndroid Build Coastguard Worker 	instance->msg_handle = msg_handle;
4147*58e6ee5fSAndroid Build Coastguard Worker }
4148*58e6ee5fSAndroid Build Coastguard Worker 
setup_guest(struct buffer_instance * instance)4149*58e6ee5fSAndroid Build Coastguard Worker static void setup_guest(struct buffer_instance *instance)
4150*58e6ee5fSAndroid Build Coastguard Worker {
4151*58e6ee5fSAndroid Build Coastguard Worker 	struct tracecmd_msg_handle *msg_handle = instance->msg_handle;
4152*58e6ee5fSAndroid Build Coastguard Worker 	const char *output_file = instance->output_file;
4153*58e6ee5fSAndroid Build Coastguard Worker 	char *file;
4154*58e6ee5fSAndroid Build Coastguard Worker 	int fd;
4155*58e6ee5fSAndroid Build Coastguard Worker 
4156*58e6ee5fSAndroid Build Coastguard Worker 	/* Create a place to store the guest meta data */
4157*58e6ee5fSAndroid Build Coastguard Worker 	file = trace_get_guest_file(output_file, instance->name);
4158*58e6ee5fSAndroid Build Coastguard Worker 	if (!file)
4159*58e6ee5fSAndroid Build Coastguard Worker 		die("Failed to allocate memory");
4160*58e6ee5fSAndroid Build Coastguard Worker 
4161*58e6ee5fSAndroid Build Coastguard Worker 	free(instance->output_file);
4162*58e6ee5fSAndroid Build Coastguard Worker 	instance->output_file = file;
4163*58e6ee5fSAndroid Build Coastguard Worker 
4164*58e6ee5fSAndroid Build Coastguard Worker 	fd = open(file, O_CREAT|O_WRONLY|O_TRUNC, 0644);
4165*58e6ee5fSAndroid Build Coastguard Worker 	if (fd < 0)
4166*58e6ee5fSAndroid Build Coastguard Worker 		die("Failed to open %s", file);
4167*58e6ee5fSAndroid Build Coastguard Worker 
4168*58e6ee5fSAndroid Build Coastguard Worker 	/* Start reading tracing metadata */
4169*58e6ee5fSAndroid Build Coastguard Worker 	if (tracecmd_msg_read_data(msg_handle, fd))
4170*58e6ee5fSAndroid Build Coastguard Worker 		die("Failed receiving metadata");
4171*58e6ee5fSAndroid Build Coastguard Worker 	close(fd);
4172*58e6ee5fSAndroid Build Coastguard Worker }
4173*58e6ee5fSAndroid Build Coastguard Worker 
setup_agent(struct buffer_instance * instance,struct common_record_context * ctx)4174*58e6ee5fSAndroid Build Coastguard Worker static void setup_agent(struct buffer_instance *instance,
4175*58e6ee5fSAndroid Build Coastguard Worker 			struct common_record_context *ctx)
4176*58e6ee5fSAndroid Build Coastguard Worker {
4177*58e6ee5fSAndroid Build Coastguard Worker 	struct tracecmd_output *network_handle;
4178*58e6ee5fSAndroid Build Coastguard Worker 
4179*58e6ee5fSAndroid Build Coastguard Worker 	network_handle = create_net_output(ctx, instance->msg_handle);
4180*58e6ee5fSAndroid Build Coastguard Worker 	add_options(network_handle, ctx);
4181*58e6ee5fSAndroid Build Coastguard Worker 	tracecmd_write_cmdlines(network_handle);
4182*58e6ee5fSAndroid Build Coastguard Worker 	tracecmd_write_cpus(network_handle, instance->cpu_count);
4183*58e6ee5fSAndroid Build Coastguard Worker 	tracecmd_write_buffer_info(network_handle);
4184*58e6ee5fSAndroid Build Coastguard Worker 	tracecmd_write_options(network_handle);
4185*58e6ee5fSAndroid Build Coastguard Worker 	tracecmd_write_meta_strings(network_handle);
4186*58e6ee5fSAndroid Build Coastguard Worker 	tracecmd_msg_finish_sending_data(instance->msg_handle);
4187*58e6ee5fSAndroid Build Coastguard Worker 	instance->network_handle = network_handle;
4188*58e6ee5fSAndroid Build Coastguard Worker }
4189*58e6ee5fSAndroid Build Coastguard Worker 
start_threads(enum trace_type type,struct common_record_context * ctx)4190*58e6ee5fSAndroid Build Coastguard Worker void start_threads(enum trace_type type, struct common_record_context *ctx)
4191*58e6ee5fSAndroid Build Coastguard Worker {
4192*58e6ee5fSAndroid Build Coastguard Worker 	struct buffer_instance *instance;
4193*58e6ee5fSAndroid Build Coastguard Worker 	int total_cpu_count = 0;
4194*58e6ee5fSAndroid Build Coastguard Worker 	int i = 0;
4195*58e6ee5fSAndroid Build Coastguard Worker 	int ret;
4196*58e6ee5fSAndroid Build Coastguard Worker 
4197*58e6ee5fSAndroid Build Coastguard Worker 	for_all_instances(instance) {
4198*58e6ee5fSAndroid Build Coastguard Worker 		/* Start the connection now to find out how many CPUs we need */
4199*58e6ee5fSAndroid Build Coastguard Worker 		if (is_guest(instance))
4200*58e6ee5fSAndroid Build Coastguard Worker 			connect_to_agent(ctx, instance);
4201*58e6ee5fSAndroid Build Coastguard Worker 		total_cpu_count += instance->cpu_count;
4202*58e6ee5fSAndroid Build Coastguard Worker 	}
4203*58e6ee5fSAndroid Build Coastguard Worker 
4204*58e6ee5fSAndroid Build Coastguard Worker 	/* make a thread for every CPU we have */
4205*58e6ee5fSAndroid Build Coastguard Worker 	pids = calloc(total_cpu_count * (buffers + 1), sizeof(*pids));
4206*58e6ee5fSAndroid Build Coastguard Worker 	if (!pids)
4207*58e6ee5fSAndroid Build Coastguard Worker 		die("Failed to allocate pids for %d cpus", total_cpu_count);
4208*58e6ee5fSAndroid Build Coastguard Worker 
4209*58e6ee5fSAndroid Build Coastguard Worker 	for_all_instances(instance) {
4210*58e6ee5fSAndroid Build Coastguard Worker 		int *brass = NULL;
4211*58e6ee5fSAndroid Build Coastguard Worker 		int x, pid;
4212*58e6ee5fSAndroid Build Coastguard Worker 
4213*58e6ee5fSAndroid Build Coastguard Worker 		if (is_agent(instance)) {
4214*58e6ee5fSAndroid Build Coastguard Worker 			setup_agent(instance, ctx);
4215*58e6ee5fSAndroid Build Coastguard Worker 		} else if (is_guest(instance)) {
4216*58e6ee5fSAndroid Build Coastguard Worker 			setup_guest(instance);
4217*58e6ee5fSAndroid Build Coastguard Worker 		} else if (host) {
4218*58e6ee5fSAndroid Build Coastguard Worker 			instance->msg_handle = setup_connection(instance, ctx);
4219*58e6ee5fSAndroid Build Coastguard Worker 			if (!instance->msg_handle)
4220*58e6ee5fSAndroid Build Coastguard Worker 				die("Failed to make connection");
4221*58e6ee5fSAndroid Build Coastguard Worker 		}
4222*58e6ee5fSAndroid Build Coastguard Worker 
4223*58e6ee5fSAndroid Build Coastguard Worker 		for (x = 0; x < instance->cpu_count; x++) {
4224*58e6ee5fSAndroid Build Coastguard Worker 			if (type & TRACE_TYPE_STREAM) {
4225*58e6ee5fSAndroid Build Coastguard Worker 				brass = pids[i].brass;
4226*58e6ee5fSAndroid Build Coastguard Worker 				ret = pipe(brass);
4227*58e6ee5fSAndroid Build Coastguard Worker 				if (ret < 0)
4228*58e6ee5fSAndroid Build Coastguard Worker 					die("pipe");
4229*58e6ee5fSAndroid Build Coastguard Worker 				pids[i].stream = trace_stream_init(instance, x,
4230*58e6ee5fSAndroid Build Coastguard Worker 								   brass[0],
4231*58e6ee5fSAndroid Build Coastguard Worker 								   instance->cpu_count,
4232*58e6ee5fSAndroid Build Coastguard Worker 								   hooks, handle_init,
4233*58e6ee5fSAndroid Build Coastguard Worker 								   ctx->global);
4234*58e6ee5fSAndroid Build Coastguard Worker 				if (!pids[i].stream)
4235*58e6ee5fSAndroid Build Coastguard Worker 					die("Creating stream for %d", i);
4236*58e6ee5fSAndroid Build Coastguard Worker 			} else
4237*58e6ee5fSAndroid Build Coastguard Worker 				pids[i].brass[0] = -1;
4238*58e6ee5fSAndroid Build Coastguard Worker 			pids[i].cpu = x;
4239*58e6ee5fSAndroid Build Coastguard Worker 			pids[i].instance = instance;
4240*58e6ee5fSAndroid Build Coastguard Worker 			/* Make sure all output is flushed before forking */
4241*58e6ee5fSAndroid Build Coastguard Worker 			fflush(stdout);
4242*58e6ee5fSAndroid Build Coastguard Worker 			pid = pids[i++].pid = create_recorder(instance, x, type, brass);
4243*58e6ee5fSAndroid Build Coastguard Worker 			if (brass)
4244*58e6ee5fSAndroid Build Coastguard Worker 				close(brass[1]);
4245*58e6ee5fSAndroid Build Coastguard Worker 			if (pid > 0)
4246*58e6ee5fSAndroid Build Coastguard Worker 				add_filter_pid(instance, pid, 1);
4247*58e6ee5fSAndroid Build Coastguard Worker 		}
4248*58e6ee5fSAndroid Build Coastguard Worker 	}
4249*58e6ee5fSAndroid Build Coastguard Worker 	recorder_threads = i;
4250*58e6ee5fSAndroid Build Coastguard Worker }
4251*58e6ee5fSAndroid Build Coastguard Worker 
touch_file(const char * file)4252*58e6ee5fSAndroid Build Coastguard Worker static void touch_file(const char *file)
4253*58e6ee5fSAndroid Build Coastguard Worker {
4254*58e6ee5fSAndroid Build Coastguard Worker 	int fd;
4255*58e6ee5fSAndroid Build Coastguard Worker 
4256*58e6ee5fSAndroid Build Coastguard Worker 	fd = open(file, O_WRONLY | O_CREAT | O_TRUNC, 0644);
4257*58e6ee5fSAndroid Build Coastguard Worker 	if (fd < 0)
4258*58e6ee5fSAndroid Build Coastguard Worker 		die("could not create file %s\n", file);
4259*58e6ee5fSAndroid Build Coastguard Worker 	close(fd);
4260*58e6ee5fSAndroid Build Coastguard Worker }
4261*58e6ee5fSAndroid Build Coastguard Worker 
append_buffer(struct tracecmd_output * handle,struct buffer_instance * instance,char ** temp_files)4262*58e6ee5fSAndroid Build Coastguard Worker static void append_buffer(struct tracecmd_output *handle,
4263*58e6ee5fSAndroid Build Coastguard Worker 			  struct buffer_instance *instance,
4264*58e6ee5fSAndroid Build Coastguard Worker 			  char **temp_files)
4265*58e6ee5fSAndroid Build Coastguard Worker {
4266*58e6ee5fSAndroid Build Coastguard Worker 	int cpu_count = instance->cpu_count;
4267*58e6ee5fSAndroid Build Coastguard Worker 	int i;
4268*58e6ee5fSAndroid Build Coastguard Worker 
4269*58e6ee5fSAndroid Build Coastguard Worker 	/*
4270*58e6ee5fSAndroid Build Coastguard Worker 	 * Since we can record remote and virtual machines in the same file
4271*58e6ee5fSAndroid Build Coastguard Worker 	 * as the host, the buffers may no longer have matching number of
4272*58e6ee5fSAndroid Build Coastguard Worker 	 * CPU data as the host. For backward compatibility for older
4273*58e6ee5fSAndroid Build Coastguard Worker 	 * trace-cmd versions, which will blindly read the number of CPUs
4274*58e6ee5fSAndroid Build Coastguard Worker 	 * for each buffer instance as there are for the host, if there are
4275*58e6ee5fSAndroid Build Coastguard Worker 	 * fewer CPUs on the remote machine than on the host, an "empty"
4276*58e6ee5fSAndroid Build Coastguard Worker 	 * CPU is needed for each CPU that the host has that the remote does
4277*58e6ee5fSAndroid Build Coastguard Worker 	 * not. If there are more CPUs on the remote, older executables will
4278*58e6ee5fSAndroid Build Coastguard Worker 	 * simply ignore them (which is OK, we only need to guarantee that
4279*58e6ee5fSAndroid Build Coastguard Worker 	 * old executables don't crash).
4280*58e6ee5fSAndroid Build Coastguard Worker 	 */
4281*58e6ee5fSAndroid Build Coastguard Worker 	if (instance->cpu_count < local_cpu_count)
4282*58e6ee5fSAndroid Build Coastguard Worker 		cpu_count = local_cpu_count;
4283*58e6ee5fSAndroid Build Coastguard Worker 
4284*58e6ee5fSAndroid Build Coastguard Worker 	for (i = 0; i < cpu_count; i++) {
4285*58e6ee5fSAndroid Build Coastguard Worker 		temp_files[i] = get_temp_file(instance, i);
4286*58e6ee5fSAndroid Build Coastguard Worker 		if (i >= instance->cpu_count)
4287*58e6ee5fSAndroid Build Coastguard Worker 			touch_file(temp_files[i]);
4288*58e6ee5fSAndroid Build Coastguard Worker 	}
4289*58e6ee5fSAndroid Build Coastguard Worker 
4290*58e6ee5fSAndroid Build Coastguard Worker 	tracecmd_append_buffer_cpu_data(handle, tracefs_instance_get_name(instance->tracefs),
4291*58e6ee5fSAndroid Build Coastguard Worker 					cpu_count, temp_files);
4292*58e6ee5fSAndroid Build Coastguard Worker 
4293*58e6ee5fSAndroid Build Coastguard Worker 	for (i = 0; i < instance->cpu_count; i++) {
4294*58e6ee5fSAndroid Build Coastguard Worker 		if (i >= instance->cpu_count)
4295*58e6ee5fSAndroid Build Coastguard Worker 			delete_temp_file(instance, i);
4296*58e6ee5fSAndroid Build Coastguard Worker 		put_temp_file(temp_files[i]);
4297*58e6ee5fSAndroid Build Coastguard Worker 	}
4298*58e6ee5fSAndroid Build Coastguard Worker }
4299*58e6ee5fSAndroid Build Coastguard Worker 
4300*58e6ee5fSAndroid Build Coastguard Worker static void
add_guest_info(struct tracecmd_output * handle,struct buffer_instance * instance)4301*58e6ee5fSAndroid Build Coastguard Worker add_guest_info(struct tracecmd_output *handle, struct buffer_instance *instance)
4302*58e6ee5fSAndroid Build Coastguard Worker {
4303*58e6ee5fSAndroid Build Coastguard Worker 	struct trace_guest *guest;
4304*58e6ee5fSAndroid Build Coastguard Worker 	const char *name;
4305*58e6ee5fSAndroid Build Coastguard Worker 	char *buf, *p;
4306*58e6ee5fSAndroid Build Coastguard Worker 	int size;
4307*58e6ee5fSAndroid Build Coastguard Worker 	int pid;
4308*58e6ee5fSAndroid Build Coastguard Worker 	int i;
4309*58e6ee5fSAndroid Build Coastguard Worker 
4310*58e6ee5fSAndroid Build Coastguard Worker 	if (is_network(instance)) {
4311*58e6ee5fSAndroid Build Coastguard Worker 		name = instance->name;
4312*58e6ee5fSAndroid Build Coastguard Worker 	} else {
4313*58e6ee5fSAndroid Build Coastguard Worker 		guest = trace_get_guest(instance->cid, NULL);
4314*58e6ee5fSAndroid Build Coastguard Worker 		if (!guest)
4315*58e6ee5fSAndroid Build Coastguard Worker 			return;
4316*58e6ee5fSAndroid Build Coastguard Worker 		name = guest->name;
4317*58e6ee5fSAndroid Build Coastguard Worker 	}
4318*58e6ee5fSAndroid Build Coastguard Worker 
4319*58e6ee5fSAndroid Build Coastguard Worker 	size = strlen(name) + 1;
4320*58e6ee5fSAndroid Build Coastguard Worker 	size += sizeof(long long);	/* trace_id */
4321*58e6ee5fSAndroid Build Coastguard Worker 	size += sizeof(int);		/* cpu count */
4322*58e6ee5fSAndroid Build Coastguard Worker 	size += instance->cpu_count * 2 * sizeof(int);	/* cpu,pid pair */
4323*58e6ee5fSAndroid Build Coastguard Worker 
4324*58e6ee5fSAndroid Build Coastguard Worker 	buf = calloc(1, size);
4325*58e6ee5fSAndroid Build Coastguard Worker 	if (!buf)
4326*58e6ee5fSAndroid Build Coastguard Worker 		return;
4327*58e6ee5fSAndroid Build Coastguard Worker 	p = buf;
4328*58e6ee5fSAndroid Build Coastguard Worker 	strcpy(p, name);
4329*58e6ee5fSAndroid Build Coastguard Worker 	p += strlen(name) + 1;
4330*58e6ee5fSAndroid Build Coastguard Worker 
4331*58e6ee5fSAndroid Build Coastguard Worker 	memcpy(p, &instance->trace_id, sizeof(long long));
4332*58e6ee5fSAndroid Build Coastguard Worker 	p += sizeof(long long);
4333*58e6ee5fSAndroid Build Coastguard Worker 
4334*58e6ee5fSAndroid Build Coastguard Worker 	memcpy(p, &instance->cpu_count, sizeof(int));
4335*58e6ee5fSAndroid Build Coastguard Worker 	p += sizeof(int);
4336*58e6ee5fSAndroid Build Coastguard Worker 	for (i = 0; i < instance->cpu_count; i++) {
4337*58e6ee5fSAndroid Build Coastguard Worker 		pid = -1;
4338*58e6ee5fSAndroid Build Coastguard Worker 		if (!is_network(instance)) {
4339*58e6ee5fSAndroid Build Coastguard Worker 			if (i < guest->cpu_max)
4340*58e6ee5fSAndroid Build Coastguard Worker 				pid = guest->cpu_pid[i];
4341*58e6ee5fSAndroid Build Coastguard Worker 		}
4342*58e6ee5fSAndroid Build Coastguard Worker 		memcpy(p, &i, sizeof(int));
4343*58e6ee5fSAndroid Build Coastguard Worker 		p += sizeof(int);
4344*58e6ee5fSAndroid Build Coastguard Worker 		memcpy(p, &pid, sizeof(int));
4345*58e6ee5fSAndroid Build Coastguard Worker 		p += sizeof(int);
4346*58e6ee5fSAndroid Build Coastguard Worker 	}
4347*58e6ee5fSAndroid Build Coastguard Worker 
4348*58e6ee5fSAndroid Build Coastguard Worker 	tracecmd_add_option(handle, TRACECMD_OPTION_GUEST, size, buf);
4349*58e6ee5fSAndroid Build Coastguard Worker 	free(buf);
4350*58e6ee5fSAndroid Build Coastguard Worker }
4351*58e6ee5fSAndroid Build Coastguard Worker 
4352*58e6ee5fSAndroid Build Coastguard Worker static void
add_pid_maps(struct tracecmd_output * handle,struct buffer_instance * instance)4353*58e6ee5fSAndroid Build Coastguard Worker add_pid_maps(struct tracecmd_output *handle, struct buffer_instance *instance)
4354*58e6ee5fSAndroid Build Coastguard Worker {
4355*58e6ee5fSAndroid Build Coastguard Worker 	struct pid_addr_maps *maps = instance->pid_maps;
4356*58e6ee5fSAndroid Build Coastguard Worker 	struct trace_seq s;
4357*58e6ee5fSAndroid Build Coastguard Worker 	int i;
4358*58e6ee5fSAndroid Build Coastguard Worker 
4359*58e6ee5fSAndroid Build Coastguard Worker 	trace_seq_init(&s);
4360*58e6ee5fSAndroid Build Coastguard Worker 	while (maps) {
4361*58e6ee5fSAndroid Build Coastguard Worker 		if (!maps->nr_lib_maps) {
4362*58e6ee5fSAndroid Build Coastguard Worker 			maps = maps->next;
4363*58e6ee5fSAndroid Build Coastguard Worker 			continue;
4364*58e6ee5fSAndroid Build Coastguard Worker 		}
4365*58e6ee5fSAndroid Build Coastguard Worker 		trace_seq_reset(&s);
4366*58e6ee5fSAndroid Build Coastguard Worker 		trace_seq_printf(&s, "%x %x %s\n",
4367*58e6ee5fSAndroid Build Coastguard Worker 				 maps->pid, maps->nr_lib_maps, maps->proc_name);
4368*58e6ee5fSAndroid Build Coastguard Worker 		for (i = 0; i < maps->nr_lib_maps; i++)
4369*58e6ee5fSAndroid Build Coastguard Worker 			trace_seq_printf(&s, "%llx %llx %s\n",
4370*58e6ee5fSAndroid Build Coastguard Worker 					maps->lib_maps[i].start,
4371*58e6ee5fSAndroid Build Coastguard Worker 					maps->lib_maps[i].end,
4372*58e6ee5fSAndroid Build Coastguard Worker 					maps->lib_maps[i].lib_name);
4373*58e6ee5fSAndroid Build Coastguard Worker 		trace_seq_terminate(&s);
4374*58e6ee5fSAndroid Build Coastguard Worker 		tracecmd_add_option(handle, TRACECMD_OPTION_PROCMAPS,
4375*58e6ee5fSAndroid Build Coastguard Worker 				    s.len + 1, s.buffer);
4376*58e6ee5fSAndroid Build Coastguard Worker 		maps = maps->next;
4377*58e6ee5fSAndroid Build Coastguard Worker 	}
4378*58e6ee5fSAndroid Build Coastguard Worker 	trace_seq_destroy(&s);
4379*58e6ee5fSAndroid Build Coastguard Worker }
4380*58e6ee5fSAndroid Build Coastguard Worker 
4381*58e6ee5fSAndroid Build Coastguard Worker static void
add_trace_id(struct tracecmd_output * handle,struct buffer_instance * instance)4382*58e6ee5fSAndroid Build Coastguard Worker add_trace_id(struct tracecmd_output *handle, struct buffer_instance *instance)
4383*58e6ee5fSAndroid Build Coastguard Worker {
4384*58e6ee5fSAndroid Build Coastguard Worker 	tracecmd_add_option(handle, TRACECMD_OPTION_TRACEID,
4385*58e6ee5fSAndroid Build Coastguard Worker 			    sizeof(long long), &instance->trace_id);
4386*58e6ee5fSAndroid Build Coastguard Worker }
4387*58e6ee5fSAndroid Build Coastguard Worker 
4388*58e6ee5fSAndroid Build Coastguard Worker static void
add_buffer_stat(struct tracecmd_output * handle,struct buffer_instance * instance)4389*58e6ee5fSAndroid Build Coastguard Worker add_buffer_stat(struct tracecmd_output *handle, struct buffer_instance *instance)
4390*58e6ee5fSAndroid Build Coastguard Worker {
4391*58e6ee5fSAndroid Build Coastguard Worker 	struct trace_seq s;
4392*58e6ee5fSAndroid Build Coastguard Worker 	int i;
4393*58e6ee5fSAndroid Build Coastguard Worker 
4394*58e6ee5fSAndroid Build Coastguard Worker 	trace_seq_init(&s);
4395*58e6ee5fSAndroid Build Coastguard Worker 	trace_seq_printf(&s, "\nBuffer: %s\n\n",
4396*58e6ee5fSAndroid Build Coastguard Worker 			tracefs_instance_get_name(instance->tracefs));
4397*58e6ee5fSAndroid Build Coastguard Worker 	tracecmd_add_option(handle, TRACECMD_OPTION_CPUSTAT,
4398*58e6ee5fSAndroid Build Coastguard Worker 			    s.len+1, s.buffer);
4399*58e6ee5fSAndroid Build Coastguard Worker 	trace_seq_destroy(&s);
4400*58e6ee5fSAndroid Build Coastguard Worker 
4401*58e6ee5fSAndroid Build Coastguard Worker 	for (i = 0; i < instance->cpu_count; i++)
4402*58e6ee5fSAndroid Build Coastguard Worker 		tracecmd_add_option(handle, TRACECMD_OPTION_CPUSTAT,
4403*58e6ee5fSAndroid Build Coastguard Worker 				    instance->s_save[i].len+1,
4404*58e6ee5fSAndroid Build Coastguard Worker 				    instance->s_save[i].buffer);
4405*58e6ee5fSAndroid Build Coastguard Worker }
4406*58e6ee5fSAndroid Build Coastguard Worker 
add_option_hooks(struct tracecmd_output * handle)4407*58e6ee5fSAndroid Build Coastguard Worker static void add_option_hooks(struct tracecmd_output *handle)
4408*58e6ee5fSAndroid Build Coastguard Worker {
4409*58e6ee5fSAndroid Build Coastguard Worker 	struct hook_list *hook;
4410*58e6ee5fSAndroid Build Coastguard Worker 	int len;
4411*58e6ee5fSAndroid Build Coastguard Worker 
4412*58e6ee5fSAndroid Build Coastguard Worker 	for (hook = hooks; hook; hook = hook->next) {
4413*58e6ee5fSAndroid Build Coastguard Worker 		len = strlen(hook->hook);
4414*58e6ee5fSAndroid Build Coastguard Worker 		tracecmd_add_option(handle, TRACECMD_OPTION_HOOK,
4415*58e6ee5fSAndroid Build Coastguard Worker 				    len + 1, hook->hook);
4416*58e6ee5fSAndroid Build Coastguard Worker 	}
4417*58e6ee5fSAndroid Build Coastguard Worker }
4418*58e6ee5fSAndroid Build Coastguard Worker 
add_uname(struct tracecmd_output * handle)4419*58e6ee5fSAndroid Build Coastguard Worker static void add_uname(struct tracecmd_output *handle)
4420*58e6ee5fSAndroid Build Coastguard Worker {
4421*58e6ee5fSAndroid Build Coastguard Worker 	struct utsname buf;
4422*58e6ee5fSAndroid Build Coastguard Worker 	char *str;
4423*58e6ee5fSAndroid Build Coastguard Worker 	int len;
4424*58e6ee5fSAndroid Build Coastguard Worker 	int ret;
4425*58e6ee5fSAndroid Build Coastguard Worker 
4426*58e6ee5fSAndroid Build Coastguard Worker 	ret = uname(&buf);
4427*58e6ee5fSAndroid Build Coastguard Worker 	/* if this fails for some reason, just ignore it */
4428*58e6ee5fSAndroid Build Coastguard Worker 	if (ret < 0)
4429*58e6ee5fSAndroid Build Coastguard Worker 		return;
4430*58e6ee5fSAndroid Build Coastguard Worker 
4431*58e6ee5fSAndroid Build Coastguard Worker 	len = strlen(buf.sysname) + strlen(buf.nodename) +
4432*58e6ee5fSAndroid Build Coastguard Worker 		strlen(buf.release) + strlen(buf.machine) + 4;
4433*58e6ee5fSAndroid Build Coastguard Worker 	str = malloc(len);
4434*58e6ee5fSAndroid Build Coastguard Worker 	if (!str)
4435*58e6ee5fSAndroid Build Coastguard Worker 		return;
4436*58e6ee5fSAndroid Build Coastguard Worker 	sprintf(str, "%s %s %s %s", buf.sysname, buf.nodename, buf.release, buf.machine);
4437*58e6ee5fSAndroid Build Coastguard Worker 	tracecmd_add_option(handle, TRACECMD_OPTION_UNAME, len, str);
4438*58e6ee5fSAndroid Build Coastguard Worker 	free(str);
4439*58e6ee5fSAndroid Build Coastguard Worker }
4440*58e6ee5fSAndroid Build Coastguard Worker 
add_version(struct tracecmd_output * handle)4441*58e6ee5fSAndroid Build Coastguard Worker static void add_version(struct tracecmd_output *handle)
4442*58e6ee5fSAndroid Build Coastguard Worker {
4443*58e6ee5fSAndroid Build Coastguard Worker 	char *str;
4444*58e6ee5fSAndroid Build Coastguard Worker 	int len;
4445*58e6ee5fSAndroid Build Coastguard Worker 
4446*58e6ee5fSAndroid Build Coastguard Worker 	len = asprintf(&str, "%s %s", VERSION_STRING, VERSION_GIT);
4447*58e6ee5fSAndroid Build Coastguard Worker 	if (len < 0)
4448*58e6ee5fSAndroid Build Coastguard Worker 		return;
4449*58e6ee5fSAndroid Build Coastguard Worker 
4450*58e6ee5fSAndroid Build Coastguard Worker 	tracecmd_add_option(handle, TRACECMD_OPTION_VERSION, len+1, str);
4451*58e6ee5fSAndroid Build Coastguard Worker 	free(str);
4452*58e6ee5fSAndroid Build Coastguard Worker }
4453*58e6ee5fSAndroid Build Coastguard Worker 
print_stat(struct buffer_instance * instance)4454*58e6ee5fSAndroid Build Coastguard Worker static void print_stat(struct buffer_instance *instance)
4455*58e6ee5fSAndroid Build Coastguard Worker {
4456*58e6ee5fSAndroid Build Coastguard Worker 	int cpu;
4457*58e6ee5fSAndroid Build Coastguard Worker 
4458*58e6ee5fSAndroid Build Coastguard Worker 	if (quiet)
4459*58e6ee5fSAndroid Build Coastguard Worker 		return;
4460*58e6ee5fSAndroid Build Coastguard Worker 
4461*58e6ee5fSAndroid Build Coastguard Worker 	if (!is_top_instance(instance))
4462*58e6ee5fSAndroid Build Coastguard Worker 		printf("\nBuffer: %s\n\n",
4463*58e6ee5fSAndroid Build Coastguard Worker 			tracefs_instance_get_name(instance->tracefs));
4464*58e6ee5fSAndroid Build Coastguard Worker 
4465*58e6ee5fSAndroid Build Coastguard Worker 	for (cpu = 0; cpu < instance->cpu_count; cpu++)
4466*58e6ee5fSAndroid Build Coastguard Worker 		trace_seq_do_printf(&instance->s_print[cpu]);
4467*58e6ee5fSAndroid Build Coastguard Worker }
4468*58e6ee5fSAndroid Build Coastguard Worker 
get_trace_clock(bool selected)4469*58e6ee5fSAndroid Build Coastguard Worker static char *get_trace_clock(bool selected)
4470*58e6ee5fSAndroid Build Coastguard Worker {
4471*58e6ee5fSAndroid Build Coastguard Worker 	struct buffer_instance *instance;
4472*58e6ee5fSAndroid Build Coastguard Worker 
4473*58e6ee5fSAndroid Build Coastguard Worker 	for_all_instances(instance) {
4474*58e6ee5fSAndroid Build Coastguard Worker 		if (is_guest(instance))
4475*58e6ee5fSAndroid Build Coastguard Worker 			continue;
4476*58e6ee5fSAndroid Build Coastguard Worker 		break;
4477*58e6ee5fSAndroid Build Coastguard Worker 	}
4478*58e6ee5fSAndroid Build Coastguard Worker 
4479*58e6ee5fSAndroid Build Coastguard Worker 	if (selected)
4480*58e6ee5fSAndroid Build Coastguard Worker 		return tracefs_get_clock(instance ? instance->tracefs : NULL);
4481*58e6ee5fSAndroid Build Coastguard Worker 	else
4482*58e6ee5fSAndroid Build Coastguard Worker 		return tracefs_instance_file_read(instance ? instance->tracefs : NULL,
4483*58e6ee5fSAndroid Build Coastguard Worker 						  "trace_clock", NULL);
4484*58e6ee5fSAndroid Build Coastguard Worker }
4485*58e6ee5fSAndroid Build Coastguard Worker 
4486*58e6ee5fSAndroid Build Coastguard Worker enum {
4487*58e6ee5fSAndroid Build Coastguard Worker 	DATA_FL_NONE		= 0,
4488*58e6ee5fSAndroid Build Coastguard Worker 	DATA_FL_DATE		= 1,
4489*58e6ee5fSAndroid Build Coastguard Worker 	DATA_FL_OFFSET		= 2,
4490*58e6ee5fSAndroid Build Coastguard Worker 	DATA_FL_GUEST		= 4,
4491*58e6ee5fSAndroid Build Coastguard Worker };
4492*58e6ee5fSAndroid Build Coastguard Worker 
add_options(struct tracecmd_output * handle,struct common_record_context * ctx)4493*58e6ee5fSAndroid Build Coastguard Worker static void add_options(struct tracecmd_output *handle, struct common_record_context *ctx)
4494*58e6ee5fSAndroid Build Coastguard Worker {
4495*58e6ee5fSAndroid Build Coastguard Worker 	int type = 0;
4496*58e6ee5fSAndroid Build Coastguard Worker 	char *clocks;
4497*58e6ee5fSAndroid Build Coastguard Worker 
4498*58e6ee5fSAndroid Build Coastguard Worker 	if (ctx->date2ts) {
4499*58e6ee5fSAndroid Build Coastguard Worker 		if (ctx->data_flags & DATA_FL_DATE)
4500*58e6ee5fSAndroid Build Coastguard Worker 			type = TRACECMD_OPTION_DATE;
4501*58e6ee5fSAndroid Build Coastguard Worker 		else if (ctx->data_flags & DATA_FL_OFFSET)
4502*58e6ee5fSAndroid Build Coastguard Worker 			type = TRACECMD_OPTION_OFFSET;
4503*58e6ee5fSAndroid Build Coastguard Worker 	}
4504*58e6ee5fSAndroid Build Coastguard Worker 
4505*58e6ee5fSAndroid Build Coastguard Worker 	if (type)
4506*58e6ee5fSAndroid Build Coastguard Worker 		tracecmd_add_option(handle, type, strlen(ctx->date2ts)+1, ctx->date2ts);
4507*58e6ee5fSAndroid Build Coastguard Worker 
4508*58e6ee5fSAndroid Build Coastguard Worker 	clocks = get_trace_clock(false);
4509*58e6ee5fSAndroid Build Coastguard Worker 	tracecmd_add_option(handle, TRACECMD_OPTION_TRACECLOCK,
4510*58e6ee5fSAndroid Build Coastguard Worker 			    clocks ? strlen(clocks)+1 : 0, clocks);
4511*58e6ee5fSAndroid Build Coastguard Worker 	add_option_hooks(handle);
4512*58e6ee5fSAndroid Build Coastguard Worker 	add_uname(handle);
4513*58e6ee5fSAndroid Build Coastguard Worker 	add_version(handle);
4514*58e6ee5fSAndroid Build Coastguard Worker 	if (!no_top_instance())
4515*58e6ee5fSAndroid Build Coastguard Worker 		add_trace_id(handle, &top_instance);
4516*58e6ee5fSAndroid Build Coastguard Worker 	free(clocks);
4517*58e6ee5fSAndroid Build Coastguard Worker }
4518*58e6ee5fSAndroid Build Coastguard Worker 
write_guest_file(struct buffer_instance * instance)4519*58e6ee5fSAndroid Build Coastguard Worker static void write_guest_file(struct buffer_instance *instance)
4520*58e6ee5fSAndroid Build Coastguard Worker {
4521*58e6ee5fSAndroid Build Coastguard Worker 	struct tracecmd_output *handle;
4522*58e6ee5fSAndroid Build Coastguard Worker 	int cpu_count = instance->cpu_count;
4523*58e6ee5fSAndroid Build Coastguard Worker 	char *file;
4524*58e6ee5fSAndroid Build Coastguard Worker 	char **temp_files;
4525*58e6ee5fSAndroid Build Coastguard Worker 	int i, fd;
4526*58e6ee5fSAndroid Build Coastguard Worker 
4527*58e6ee5fSAndroid Build Coastguard Worker 	file = instance->output_file;
4528*58e6ee5fSAndroid Build Coastguard Worker 	fd = open(file, O_RDWR);
4529*58e6ee5fSAndroid Build Coastguard Worker 	if (fd < 0)
4530*58e6ee5fSAndroid Build Coastguard Worker 		die("error opening %s", file);
4531*58e6ee5fSAndroid Build Coastguard Worker 
4532*58e6ee5fSAndroid Build Coastguard Worker 	handle = tracecmd_get_output_handle_fd(fd);
4533*58e6ee5fSAndroid Build Coastguard Worker 	if (!handle)
4534*58e6ee5fSAndroid Build Coastguard Worker 		die("error writing to %s", file);
4535*58e6ee5fSAndroid Build Coastguard Worker 	if (instance->flags & BUFFER_FL_TSC2NSEC)
4536*58e6ee5fSAndroid Build Coastguard Worker 		tracecmd_set_out_clock(handle, TSCNSEC_CLOCK);
4537*58e6ee5fSAndroid Build Coastguard Worker 	temp_files = malloc(sizeof(*temp_files) * cpu_count);
4538*58e6ee5fSAndroid Build Coastguard Worker 	if (!temp_files)
4539*58e6ee5fSAndroid Build Coastguard Worker 		die("failed to allocate temp_files for %d cpus",
4540*58e6ee5fSAndroid Build Coastguard Worker 		    cpu_count);
4541*58e6ee5fSAndroid Build Coastguard Worker 
4542*58e6ee5fSAndroid Build Coastguard Worker 	for (i = 0; i < cpu_count; i++) {
4543*58e6ee5fSAndroid Build Coastguard Worker 		temp_files[i] = get_temp_file(instance, i);
4544*58e6ee5fSAndroid Build Coastguard Worker 		if (!temp_files[i])
4545*58e6ee5fSAndroid Build Coastguard Worker 			die("failed to allocate memory");
4546*58e6ee5fSAndroid Build Coastguard Worker 	}
4547*58e6ee5fSAndroid Build Coastguard Worker 
4548*58e6ee5fSAndroid Build Coastguard Worker 	if (tracecmd_write_cpu_data(handle, cpu_count, temp_files, NULL) < 0)
4549*58e6ee5fSAndroid Build Coastguard Worker 		die("failed to write CPU data");
4550*58e6ee5fSAndroid Build Coastguard Worker 	tracecmd_output_close(handle);
4551*58e6ee5fSAndroid Build Coastguard Worker 
4552*58e6ee5fSAndroid Build Coastguard Worker 	for (i = 0; i < cpu_count; i++)
4553*58e6ee5fSAndroid Build Coastguard Worker 		put_temp_file(temp_files[i]);
4554*58e6ee5fSAndroid Build Coastguard Worker 	free(temp_files);
4555*58e6ee5fSAndroid Build Coastguard Worker }
4556*58e6ee5fSAndroid Build Coastguard Worker 
create_output(struct common_record_context * ctx)4557*58e6ee5fSAndroid Build Coastguard Worker static struct tracecmd_output *create_output(struct common_record_context *ctx)
4558*58e6ee5fSAndroid Build Coastguard Worker {
4559*58e6ee5fSAndroid Build Coastguard Worker 	struct tracecmd_output *out;
4560*58e6ee5fSAndroid Build Coastguard Worker 
4561*58e6ee5fSAndroid Build Coastguard Worker 	if (!ctx->output)
4562*58e6ee5fSAndroid Build Coastguard Worker 		return NULL;
4563*58e6ee5fSAndroid Build Coastguard Worker 
4564*58e6ee5fSAndroid Build Coastguard Worker 	out = tracecmd_output_create(ctx->output);
4565*58e6ee5fSAndroid Build Coastguard Worker 	if (!out)
4566*58e6ee5fSAndroid Build Coastguard Worker 		goto error;
4567*58e6ee5fSAndroid Build Coastguard Worker 	if (ctx->file_version && tracecmd_output_set_version(out, ctx->file_version))
4568*58e6ee5fSAndroid Build Coastguard Worker 		goto error;
4569*58e6ee5fSAndroid Build Coastguard Worker 
4570*58e6ee5fSAndroid Build Coastguard Worker 	if (ctx->compression) {
4571*58e6ee5fSAndroid Build Coastguard Worker 		if (tracecmd_output_set_compression(out, ctx->compression))
4572*58e6ee5fSAndroid Build Coastguard Worker 			goto error;
4573*58e6ee5fSAndroid Build Coastguard Worker 	} else if (ctx->file_version >= FILE_VERSION_COMPRESSION) {
4574*58e6ee5fSAndroid Build Coastguard Worker 		tracecmd_output_set_compression(out, "any");
4575*58e6ee5fSAndroid Build Coastguard Worker 	}
4576*58e6ee5fSAndroid Build Coastguard Worker 
4577*58e6ee5fSAndroid Build Coastguard Worker 	if (tracecmd_output_write_headers(out, listed_events))
4578*58e6ee5fSAndroid Build Coastguard Worker 		goto error;
4579*58e6ee5fSAndroid Build Coastguard Worker 
4580*58e6ee5fSAndroid Build Coastguard Worker 	return out;
4581*58e6ee5fSAndroid Build Coastguard Worker error:
4582*58e6ee5fSAndroid Build Coastguard Worker 	if (out)
4583*58e6ee5fSAndroid Build Coastguard Worker 		tracecmd_output_close(out);
4584*58e6ee5fSAndroid Build Coastguard Worker 	unlink(ctx->output);
4585*58e6ee5fSAndroid Build Coastguard Worker 	return NULL;
4586*58e6ee5fSAndroid Build Coastguard Worker }
4587*58e6ee5fSAndroid Build Coastguard Worker 
record_data(struct common_record_context * ctx)4588*58e6ee5fSAndroid Build Coastguard Worker static void record_data(struct common_record_context *ctx)
4589*58e6ee5fSAndroid Build Coastguard Worker {
4590*58e6ee5fSAndroid Build Coastguard Worker 	struct tracecmd_output *handle;
4591*58e6ee5fSAndroid Build Coastguard Worker 	struct buffer_instance *instance;
4592*58e6ee5fSAndroid Build Coastguard Worker 	bool local = false;
4593*58e6ee5fSAndroid Build Coastguard Worker 	int max_cpu_count = local_cpu_count;
4594*58e6ee5fSAndroid Build Coastguard Worker 	char **temp_files;
4595*58e6ee5fSAndroid Build Coastguard Worker 	int i;
4596*58e6ee5fSAndroid Build Coastguard Worker 
4597*58e6ee5fSAndroid Build Coastguard Worker 	for_all_instances(instance) {
4598*58e6ee5fSAndroid Build Coastguard Worker 		if (is_guest(instance))
4599*58e6ee5fSAndroid Build Coastguard Worker 			write_guest_file(instance);
4600*58e6ee5fSAndroid Build Coastguard Worker 		else if (host && instance->msg_handle)
4601*58e6ee5fSAndroid Build Coastguard Worker 			finish_network(instance->msg_handle);
4602*58e6ee5fSAndroid Build Coastguard Worker 		else
4603*58e6ee5fSAndroid Build Coastguard Worker 			local = true;
4604*58e6ee5fSAndroid Build Coastguard Worker 	}
4605*58e6ee5fSAndroid Build Coastguard Worker 
4606*58e6ee5fSAndroid Build Coastguard Worker 	if (!local)
4607*58e6ee5fSAndroid Build Coastguard Worker 		return;
4608*58e6ee5fSAndroid Build Coastguard Worker 
4609*58e6ee5fSAndroid Build Coastguard Worker 	if (latency) {
4610*58e6ee5fSAndroid Build Coastguard Worker 		handle = tracecmd_create_file_latency(ctx->output, local_cpu_count,
4611*58e6ee5fSAndroid Build Coastguard Worker 						      ctx->file_version, ctx->compression);
4612*58e6ee5fSAndroid Build Coastguard Worker 		tracecmd_set_quiet(handle, quiet);
4613*58e6ee5fSAndroid Build Coastguard Worker 	} else {
4614*58e6ee5fSAndroid Build Coastguard Worker 		if (!local_cpu_count)
4615*58e6ee5fSAndroid Build Coastguard Worker 			return;
4616*58e6ee5fSAndroid Build Coastguard Worker 
4617*58e6ee5fSAndroid Build Coastguard Worker 		/* Allocate enough temp files to handle each instance */
4618*58e6ee5fSAndroid Build Coastguard Worker 		for_all_instances(instance) {
4619*58e6ee5fSAndroid Build Coastguard Worker 			if (instance->msg_handle)
4620*58e6ee5fSAndroid Build Coastguard Worker 				continue;
4621*58e6ee5fSAndroid Build Coastguard Worker 			if (instance->cpu_count > max_cpu_count)
4622*58e6ee5fSAndroid Build Coastguard Worker 				max_cpu_count = instance->cpu_count;
4623*58e6ee5fSAndroid Build Coastguard Worker 		}
4624*58e6ee5fSAndroid Build Coastguard Worker 
4625*58e6ee5fSAndroid Build Coastguard Worker 		temp_files = malloc(sizeof(*temp_files) * max_cpu_count);
4626*58e6ee5fSAndroid Build Coastguard Worker 		if (!temp_files)
4627*58e6ee5fSAndroid Build Coastguard Worker 			die("Failed to allocate temp_files for %d cpus",
4628*58e6ee5fSAndroid Build Coastguard Worker 			    local_cpu_count);
4629*58e6ee5fSAndroid Build Coastguard Worker 
4630*58e6ee5fSAndroid Build Coastguard Worker 		for (i = 0; i < max_cpu_count; i++)
4631*58e6ee5fSAndroid Build Coastguard Worker 			temp_files[i] = get_temp_file(&top_instance, i);
4632*58e6ee5fSAndroid Build Coastguard Worker 
4633*58e6ee5fSAndroid Build Coastguard Worker 		/*
4634*58e6ee5fSAndroid Build Coastguard Worker 		 * If top_instance was not used, we still need to create
4635*58e6ee5fSAndroid Build Coastguard Worker 		 * empty trace.dat files for it.
4636*58e6ee5fSAndroid Build Coastguard Worker 		 */
4637*58e6ee5fSAndroid Build Coastguard Worker 		if (no_top_instance() || top_instance.msg_handle) {
4638*58e6ee5fSAndroid Build Coastguard Worker 			for (i = 0; i < local_cpu_count; i++)
4639*58e6ee5fSAndroid Build Coastguard Worker 				touch_file(temp_files[i]);
4640*58e6ee5fSAndroid Build Coastguard Worker 		}
4641*58e6ee5fSAndroid Build Coastguard Worker 
4642*58e6ee5fSAndroid Build Coastguard Worker 		handle = create_output(ctx);
4643*58e6ee5fSAndroid Build Coastguard Worker 		if (!handle)
4644*58e6ee5fSAndroid Build Coastguard Worker 			die("Error creating output file");
4645*58e6ee5fSAndroid Build Coastguard Worker 		tracecmd_set_quiet(handle, quiet);
4646*58e6ee5fSAndroid Build Coastguard Worker 
4647*58e6ee5fSAndroid Build Coastguard Worker 		add_options(handle, ctx);
4648*58e6ee5fSAndroid Build Coastguard Worker 
4649*58e6ee5fSAndroid Build Coastguard Worker 		/* Only record the top instance under TRACECMD_OPTION_CPUSTAT*/
4650*58e6ee5fSAndroid Build Coastguard Worker 		if (!no_top_instance() && !top_instance.msg_handle) {
4651*58e6ee5fSAndroid Build Coastguard Worker 			struct trace_seq *s = top_instance.s_save;
4652*58e6ee5fSAndroid Build Coastguard Worker 
4653*58e6ee5fSAndroid Build Coastguard Worker 			for (i = 0; i < local_cpu_count; i++)
4654*58e6ee5fSAndroid Build Coastguard Worker 				tracecmd_add_option(handle, TRACECMD_OPTION_CPUSTAT,
4655*58e6ee5fSAndroid Build Coastguard Worker 						    s[i].len+1, s[i].buffer);
4656*58e6ee5fSAndroid Build Coastguard Worker 		}
4657*58e6ee5fSAndroid Build Coastguard Worker 
4658*58e6ee5fSAndroid Build Coastguard Worker 		if (buffers) {
4659*58e6ee5fSAndroid Build Coastguard Worker 			i = 0;
4660*58e6ee5fSAndroid Build Coastguard Worker 			for_each_instance(instance) {
4661*58e6ee5fSAndroid Build Coastguard Worker 				int cpus = instance->cpu_count != local_cpu_count ?
4662*58e6ee5fSAndroid Build Coastguard Worker 					instance->cpu_count : 0;
4663*58e6ee5fSAndroid Build Coastguard Worker 
4664*58e6ee5fSAndroid Build Coastguard Worker 				if (instance->msg_handle)
4665*58e6ee5fSAndroid Build Coastguard Worker 					continue;
4666*58e6ee5fSAndroid Build Coastguard Worker 				tracecmd_add_buffer_info(handle,
4667*58e6ee5fSAndroid Build Coastguard Worker 							tracefs_instance_get_name(instance->tracefs),
4668*58e6ee5fSAndroid Build Coastguard Worker 							cpus);
4669*58e6ee5fSAndroid Build Coastguard Worker 				add_buffer_stat(handle, instance);
4670*58e6ee5fSAndroid Build Coastguard Worker 			}
4671*58e6ee5fSAndroid Build Coastguard Worker 		}
4672*58e6ee5fSAndroid Build Coastguard Worker 
4673*58e6ee5fSAndroid Build Coastguard Worker 		if (!no_top_instance() && !top_instance.msg_handle)
4674*58e6ee5fSAndroid Build Coastguard Worker 			print_stat(&top_instance);
4675*58e6ee5fSAndroid Build Coastguard Worker 
4676*58e6ee5fSAndroid Build Coastguard Worker 		for_all_instances(instance) {
4677*58e6ee5fSAndroid Build Coastguard Worker 			add_pid_maps(handle, instance);
4678*58e6ee5fSAndroid Build Coastguard Worker 		}
4679*58e6ee5fSAndroid Build Coastguard Worker 
4680*58e6ee5fSAndroid Build Coastguard Worker 		for_all_instances(instance) {
4681*58e6ee5fSAndroid Build Coastguard Worker 			if (is_guest(instance))
4682*58e6ee5fSAndroid Build Coastguard Worker 				add_guest_info(handle, instance);
4683*58e6ee5fSAndroid Build Coastguard Worker 		}
4684*58e6ee5fSAndroid Build Coastguard Worker 
4685*58e6ee5fSAndroid Build Coastguard Worker 		if (ctx->tsc2nsec.mult) {
4686*58e6ee5fSAndroid Build Coastguard Worker 			add_tsc2nsec(handle, &ctx->tsc2nsec);
4687*58e6ee5fSAndroid Build Coastguard Worker 			tracecmd_set_out_clock(handle, TSCNSEC_CLOCK);
4688*58e6ee5fSAndroid Build Coastguard Worker 		}
4689*58e6ee5fSAndroid Build Coastguard Worker 		if (tracecmd_write_cmdlines(handle))
4690*58e6ee5fSAndroid Build Coastguard Worker 			die("Writing cmdlines");
4691*58e6ee5fSAndroid Build Coastguard Worker 
4692*58e6ee5fSAndroid Build Coastguard Worker 		tracecmd_append_cpu_data(handle, local_cpu_count, temp_files);
4693*58e6ee5fSAndroid Build Coastguard Worker 
4694*58e6ee5fSAndroid Build Coastguard Worker 		for (i = 0; i < max_cpu_count; i++)
4695*58e6ee5fSAndroid Build Coastguard Worker 			put_temp_file(temp_files[i]);
4696*58e6ee5fSAndroid Build Coastguard Worker 
4697*58e6ee5fSAndroid Build Coastguard Worker 		if (buffers) {
4698*58e6ee5fSAndroid Build Coastguard Worker 			i = 0;
4699*58e6ee5fSAndroid Build Coastguard Worker 			for_each_instance(instance) {
4700*58e6ee5fSAndroid Build Coastguard Worker 				if (instance->msg_handle)
4701*58e6ee5fSAndroid Build Coastguard Worker 					continue;
4702*58e6ee5fSAndroid Build Coastguard Worker 				print_stat(instance);
4703*58e6ee5fSAndroid Build Coastguard Worker 				append_buffer(handle, instance, temp_files);
4704*58e6ee5fSAndroid Build Coastguard Worker 			}
4705*58e6ee5fSAndroid Build Coastguard Worker 		}
4706*58e6ee5fSAndroid Build Coastguard Worker 
4707*58e6ee5fSAndroid Build Coastguard Worker 		free(temp_files);
4708*58e6ee5fSAndroid Build Coastguard Worker 	}
4709*58e6ee5fSAndroid Build Coastguard Worker 	if (!handle)
4710*58e6ee5fSAndroid Build Coastguard Worker 		die("could not write to file");
4711*58e6ee5fSAndroid Build Coastguard Worker 	tracecmd_output_close(handle);
4712*58e6ee5fSAndroid Build Coastguard Worker }
4713*58e6ee5fSAndroid Build Coastguard Worker 
4714*58e6ee5fSAndroid Build Coastguard Worker enum filter_type {
4715*58e6ee5fSAndroid Build Coastguard Worker 	FUNC_FILTER,
4716*58e6ee5fSAndroid Build Coastguard Worker 	FUNC_NOTRACE,
4717*58e6ee5fSAndroid Build Coastguard Worker };
4718*58e6ee5fSAndroid Build Coastguard Worker 
filter_command(struct tracefs_instance * instance,const char * cmd)4719*58e6ee5fSAndroid Build Coastguard Worker static int filter_command(struct tracefs_instance *instance, const char *cmd)
4720*58e6ee5fSAndroid Build Coastguard Worker {
4721*58e6ee5fSAndroid Build Coastguard Worker 	return tracefs_instance_file_append(instance, "set_ftrace_filter", cmd);
4722*58e6ee5fSAndroid Build Coastguard Worker }
4723*58e6ee5fSAndroid Build Coastguard Worker 
write_func_filter(enum filter_type type,struct buffer_instance * instance,struct func_list ** list)4724*58e6ee5fSAndroid Build Coastguard Worker static int write_func_filter(enum filter_type type, struct buffer_instance *instance,
4725*58e6ee5fSAndroid Build Coastguard Worker 			     struct func_list **list)
4726*58e6ee5fSAndroid Build Coastguard Worker {
4727*58e6ee5fSAndroid Build Coastguard Worker 	struct func_list *item, *cmds = NULL;
4728*58e6ee5fSAndroid Build Coastguard Worker 	const char *file;
4729*58e6ee5fSAndroid Build Coastguard Worker 	int ret = -1;
4730*58e6ee5fSAndroid Build Coastguard Worker 	int (*filter_function)(struct tracefs_instance *instance, const char *filter,
4731*58e6ee5fSAndroid Build Coastguard Worker 			       const char *module, unsigned int flags);
4732*58e6ee5fSAndroid Build Coastguard Worker 
4733*58e6ee5fSAndroid Build Coastguard Worker 	if (!*list)
4734*58e6ee5fSAndroid Build Coastguard Worker 		return 0;
4735*58e6ee5fSAndroid Build Coastguard Worker 
4736*58e6ee5fSAndroid Build Coastguard Worker 	switch (type) {
4737*58e6ee5fSAndroid Build Coastguard Worker 	case FUNC_FILTER:
4738*58e6ee5fSAndroid Build Coastguard Worker 		filter_function = tracefs_function_filter;
4739*58e6ee5fSAndroid Build Coastguard Worker 		file = "set_ftrace_filter";
4740*58e6ee5fSAndroid Build Coastguard Worker 		break;
4741*58e6ee5fSAndroid Build Coastguard Worker 	case FUNC_NOTRACE:
4742*58e6ee5fSAndroid Build Coastguard Worker 		filter_function = tracefs_function_notrace;
4743*58e6ee5fSAndroid Build Coastguard Worker 		file = "set_ftrace_notrace";
4744*58e6ee5fSAndroid Build Coastguard Worker 		break;
4745*58e6ee5fSAndroid Build Coastguard Worker 	}
4746*58e6ee5fSAndroid Build Coastguard Worker 
4747*58e6ee5fSAndroid Build Coastguard Worker 	ret = filter_function(instance->tracefs, NULL, NULL,
4748*58e6ee5fSAndroid Build Coastguard Worker 			      TRACEFS_FL_RESET | TRACEFS_FL_CONTINUE);
4749*58e6ee5fSAndroid Build Coastguard Worker 	if (ret < 0)
4750*58e6ee5fSAndroid Build Coastguard Worker 		return ret;
4751*58e6ee5fSAndroid Build Coastguard Worker 
4752*58e6ee5fSAndroid Build Coastguard Worker 	while (*list) {
4753*58e6ee5fSAndroid Build Coastguard Worker 		item = *list;
4754*58e6ee5fSAndroid Build Coastguard Worker 		*list = item->next;
4755*58e6ee5fSAndroid Build Coastguard Worker 		/* Do commands separately at the end */
4756*58e6ee5fSAndroid Build Coastguard Worker 		if (type == FUNC_FILTER && strstr(item->func, ":")) {
4757*58e6ee5fSAndroid Build Coastguard Worker 			item->next = cmds;
4758*58e6ee5fSAndroid Build Coastguard Worker 			cmds = item;
4759*58e6ee5fSAndroid Build Coastguard Worker 			continue;
4760*58e6ee5fSAndroid Build Coastguard Worker 		}
4761*58e6ee5fSAndroid Build Coastguard Worker 		ret = filter_function(instance->tracefs, item->func, item->mod,
4762*58e6ee5fSAndroid Build Coastguard Worker 				      TRACEFS_FL_CONTINUE);
4763*58e6ee5fSAndroid Build Coastguard Worker 		if (ret < 0)
4764*58e6ee5fSAndroid Build Coastguard Worker 			goto failed;
4765*58e6ee5fSAndroid Build Coastguard Worker 		free(item);
4766*58e6ee5fSAndroid Build Coastguard Worker 	}
4767*58e6ee5fSAndroid Build Coastguard Worker 	ret = filter_function(instance->tracefs, NULL, NULL, 0);
4768*58e6ee5fSAndroid Build Coastguard Worker 
4769*58e6ee5fSAndroid Build Coastguard Worker 	/* Now add any commands */
4770*58e6ee5fSAndroid Build Coastguard Worker 	while (cmds) {
4771*58e6ee5fSAndroid Build Coastguard Worker 		item = cmds;
4772*58e6ee5fSAndroid Build Coastguard Worker 		cmds = item->next;
4773*58e6ee5fSAndroid Build Coastguard Worker 		ret = filter_command(instance->tracefs, item->func);
4774*58e6ee5fSAndroid Build Coastguard Worker 		if (ret < 0)
4775*58e6ee5fSAndroid Build Coastguard Worker 			goto failed;
4776*58e6ee5fSAndroid Build Coastguard Worker 		free(item);
4777*58e6ee5fSAndroid Build Coastguard Worker 	}
4778*58e6ee5fSAndroid Build Coastguard Worker 	return ret;
4779*58e6ee5fSAndroid Build Coastguard Worker  failed:
4780*58e6ee5fSAndroid Build Coastguard Worker 	die("Failed to write %s to %s.\n"
4781*58e6ee5fSAndroid Build Coastguard Worker 	    "Perhaps this function is not available for tracing.\n"
4782*58e6ee5fSAndroid Build Coastguard Worker 	    "run 'trace-cmd list -f %s' to see if it is.",
4783*58e6ee5fSAndroid Build Coastguard Worker 	    item->func, file, item->func);
4784*58e6ee5fSAndroid Build Coastguard Worker 	return ret;
4785*58e6ee5fSAndroid Build Coastguard Worker }
4786*58e6ee5fSAndroid Build Coastguard Worker 
write_func_file(struct buffer_instance * instance,const char * file,struct func_list ** list)4787*58e6ee5fSAndroid Build Coastguard Worker static int write_func_file(struct buffer_instance *instance,
4788*58e6ee5fSAndroid Build Coastguard Worker 			    const char *file, struct func_list **list)
4789*58e6ee5fSAndroid Build Coastguard Worker {
4790*58e6ee5fSAndroid Build Coastguard Worker 	struct func_list *item;
4791*58e6ee5fSAndroid Build Coastguard Worker 	const char *prefix = ":mod:";
4792*58e6ee5fSAndroid Build Coastguard Worker 	char *path;
4793*58e6ee5fSAndroid Build Coastguard Worker 	int fd;
4794*58e6ee5fSAndroid Build Coastguard Worker 	int ret = -1;
4795*58e6ee5fSAndroid Build Coastguard Worker 
4796*58e6ee5fSAndroid Build Coastguard Worker 	if (!*list)
4797*58e6ee5fSAndroid Build Coastguard Worker 		return 0;
4798*58e6ee5fSAndroid Build Coastguard Worker 
4799*58e6ee5fSAndroid Build Coastguard Worker 	path = tracefs_instance_get_file(instance->tracefs, file);
4800*58e6ee5fSAndroid Build Coastguard Worker 
4801*58e6ee5fSAndroid Build Coastguard Worker 	fd = open(path, O_WRONLY | O_TRUNC);
4802*58e6ee5fSAndroid Build Coastguard Worker 	if (fd < 0)
4803*58e6ee5fSAndroid Build Coastguard Worker 		goto free;
4804*58e6ee5fSAndroid Build Coastguard Worker 
4805*58e6ee5fSAndroid Build Coastguard Worker 	while (*list) {
4806*58e6ee5fSAndroid Build Coastguard Worker 		item = *list;
4807*58e6ee5fSAndroid Build Coastguard Worker 		*list = item->next;
4808*58e6ee5fSAndroid Build Coastguard Worker 		ret = write(fd, item->func, strlen(item->func));
4809*58e6ee5fSAndroid Build Coastguard Worker 		if (ret < 0)
4810*58e6ee5fSAndroid Build Coastguard Worker 			goto failed;
4811*58e6ee5fSAndroid Build Coastguard Worker 		if (item->mod) {
4812*58e6ee5fSAndroid Build Coastguard Worker 			ret = write(fd, prefix, strlen(prefix));
4813*58e6ee5fSAndroid Build Coastguard Worker 			if (ret < 0)
4814*58e6ee5fSAndroid Build Coastguard Worker 				goto failed;
4815*58e6ee5fSAndroid Build Coastguard Worker 			ret = write(fd, item->mod, strlen(item->mod));
4816*58e6ee5fSAndroid Build Coastguard Worker 			if (ret < 0)
4817*58e6ee5fSAndroid Build Coastguard Worker 				goto failed;
4818*58e6ee5fSAndroid Build Coastguard Worker 		}
4819*58e6ee5fSAndroid Build Coastguard Worker 		ret = write(fd, " ", 1);
4820*58e6ee5fSAndroid Build Coastguard Worker 		if (ret < 0)
4821*58e6ee5fSAndroid Build Coastguard Worker 			goto failed;
4822*58e6ee5fSAndroid Build Coastguard Worker 		free(item);
4823*58e6ee5fSAndroid Build Coastguard Worker 	}
4824*58e6ee5fSAndroid Build Coastguard Worker 	close(fd);
4825*58e6ee5fSAndroid Build Coastguard Worker 	ret = 0;
4826*58e6ee5fSAndroid Build Coastguard Worker  free:
4827*58e6ee5fSAndroid Build Coastguard Worker 	tracefs_put_tracing_file(path);
4828*58e6ee5fSAndroid Build Coastguard Worker 	return ret;
4829*58e6ee5fSAndroid Build Coastguard Worker  failed:
4830*58e6ee5fSAndroid Build Coastguard Worker 	die("Failed to write %s to %s.\n"
4831*58e6ee5fSAndroid Build Coastguard Worker 	    "Perhaps this function is not available for tracing.\n"
4832*58e6ee5fSAndroid Build Coastguard Worker 	    "run 'trace-cmd list -f %s' to see if it is.",
4833*58e6ee5fSAndroid Build Coastguard Worker 	    item->func, file, item->func);
4834*58e6ee5fSAndroid Build Coastguard Worker 	return ret;
4835*58e6ee5fSAndroid Build Coastguard Worker }
4836*58e6ee5fSAndroid Build Coastguard Worker 
functions_filtered(struct buffer_instance * instance)4837*58e6ee5fSAndroid Build Coastguard Worker static int functions_filtered(struct buffer_instance *instance)
4838*58e6ee5fSAndroid Build Coastguard Worker {
4839*58e6ee5fSAndroid Build Coastguard Worker 	char buf[1] = { '#' };
4840*58e6ee5fSAndroid Build Coastguard Worker 	char *path;
4841*58e6ee5fSAndroid Build Coastguard Worker 	int fd;
4842*58e6ee5fSAndroid Build Coastguard Worker 
4843*58e6ee5fSAndroid Build Coastguard Worker 	path = tracefs_instance_get_file(instance->tracefs, "set_ftrace_filter");
4844*58e6ee5fSAndroid Build Coastguard Worker 	fd = open(path, O_RDONLY);
4845*58e6ee5fSAndroid Build Coastguard Worker 	tracefs_put_tracing_file(path);
4846*58e6ee5fSAndroid Build Coastguard Worker 	if (fd < 0) {
4847*58e6ee5fSAndroid Build Coastguard Worker 		if (is_top_instance(instance))
4848*58e6ee5fSAndroid Build Coastguard Worker 			warning("Can not set set_ftrace_filter");
4849*58e6ee5fSAndroid Build Coastguard Worker 		else
4850*58e6ee5fSAndroid Build Coastguard Worker 			warning("Can not set set_ftrace_filter for %s",
4851*58e6ee5fSAndroid Build Coastguard Worker 				tracefs_instance_get_name(instance->tracefs));
4852*58e6ee5fSAndroid Build Coastguard Worker 		return 0;
4853*58e6ee5fSAndroid Build Coastguard Worker 	}
4854*58e6ee5fSAndroid Build Coastguard Worker 
4855*58e6ee5fSAndroid Build Coastguard Worker 	/*
4856*58e6ee5fSAndroid Build Coastguard Worker 	 * If functions are not filtered, than the first character
4857*58e6ee5fSAndroid Build Coastguard Worker 	 * will be '#'. Make sure it is not an '#' and also not space.
4858*58e6ee5fSAndroid Build Coastguard Worker 	 */
4859*58e6ee5fSAndroid Build Coastguard Worker 	read(fd, buf, 1);
4860*58e6ee5fSAndroid Build Coastguard Worker 	close(fd);
4861*58e6ee5fSAndroid Build Coastguard Worker 
4862*58e6ee5fSAndroid Build Coastguard Worker 	if (buf[0] == '#' || isspace(buf[0]))
4863*58e6ee5fSAndroid Build Coastguard Worker 		return 0;
4864*58e6ee5fSAndroid Build Coastguard Worker 	return 1;
4865*58e6ee5fSAndroid Build Coastguard Worker }
4866*58e6ee5fSAndroid Build Coastguard Worker 
set_funcs(struct buffer_instance * instance)4867*58e6ee5fSAndroid Build Coastguard Worker static void set_funcs(struct buffer_instance *instance)
4868*58e6ee5fSAndroid Build Coastguard Worker {
4869*58e6ee5fSAndroid Build Coastguard Worker 	int set_notrace = 0;
4870*58e6ee5fSAndroid Build Coastguard Worker 	int ret;
4871*58e6ee5fSAndroid Build Coastguard Worker 
4872*58e6ee5fSAndroid Build Coastguard Worker 	if (is_guest(instance))
4873*58e6ee5fSAndroid Build Coastguard Worker 		return;
4874*58e6ee5fSAndroid Build Coastguard Worker 
4875*58e6ee5fSAndroid Build Coastguard Worker 	ret = write_func_filter(FUNC_FILTER, instance, &instance->filter_funcs);
4876*58e6ee5fSAndroid Build Coastguard Worker 	if (ret < 0)
4877*58e6ee5fSAndroid Build Coastguard Worker 		die("set_ftrace_filter does not exist. Can not filter functions");
4878*58e6ee5fSAndroid Build Coastguard Worker 
4879*58e6ee5fSAndroid Build Coastguard Worker 	/* graph tracing currently only works for top instance */
4880*58e6ee5fSAndroid Build Coastguard Worker 	if (is_top_instance(instance)) {
4881*58e6ee5fSAndroid Build Coastguard Worker 		ret = write_func_file(instance, "set_graph_function", &graph_funcs);
4882*58e6ee5fSAndroid Build Coastguard Worker 		if (ret < 0)
4883*58e6ee5fSAndroid Build Coastguard Worker 			die("set_graph_function does not exist.");
4884*58e6ee5fSAndroid Build Coastguard Worker 		if (instance->plugin && strcmp(instance->plugin, "function_graph") == 0) {
4885*58e6ee5fSAndroid Build Coastguard Worker 			ret = write_func_file(instance, "set_graph_notrace",
4886*58e6ee5fSAndroid Build Coastguard Worker 					      &instance->notrace_funcs);
4887*58e6ee5fSAndroid Build Coastguard Worker 			if (!ret)
4888*58e6ee5fSAndroid Build Coastguard Worker 				set_notrace = 1;
4889*58e6ee5fSAndroid Build Coastguard Worker 		}
4890*58e6ee5fSAndroid Build Coastguard Worker 		if (!set_notrace) {
4891*58e6ee5fSAndroid Build Coastguard Worker 			ret = write_func_filter(FUNC_NOTRACE, instance,
4892*58e6ee5fSAndroid Build Coastguard Worker 					      &instance->notrace_funcs);
4893*58e6ee5fSAndroid Build Coastguard Worker 			if (ret < 0)
4894*58e6ee5fSAndroid Build Coastguard Worker 				die("set_ftrace_notrace does not exist. Can not filter functions");
4895*58e6ee5fSAndroid Build Coastguard Worker 		}
4896*58e6ee5fSAndroid Build Coastguard Worker 	} else
4897*58e6ee5fSAndroid Build Coastguard Worker 		write_func_filter(FUNC_NOTRACE, instance, &instance->notrace_funcs);
4898*58e6ee5fSAndroid Build Coastguard Worker 
4899*58e6ee5fSAndroid Build Coastguard Worker 	/* make sure we are filtering functions */
4900*58e6ee5fSAndroid Build Coastguard Worker 	if (func_stack && is_top_instance(instance)) {
4901*58e6ee5fSAndroid Build Coastguard Worker 		if (!functions_filtered(instance))
4902*58e6ee5fSAndroid Build Coastguard Worker 			die("Function stack trace set, but functions not filtered");
4903*58e6ee5fSAndroid Build Coastguard Worker 		save_option(instance, FUNC_STACK_TRACE);
4904*58e6ee5fSAndroid Build Coastguard Worker 	}
4905*58e6ee5fSAndroid Build Coastguard Worker 	clear_function_filters = 1;
4906*58e6ee5fSAndroid Build Coastguard Worker }
4907*58e6ee5fSAndroid Build Coastguard Worker 
add_func(struct func_list ** list,const char * mod,const char * func)4908*58e6ee5fSAndroid Build Coastguard Worker static void add_func(struct func_list **list, const char *mod, const char *func)
4909*58e6ee5fSAndroid Build Coastguard Worker {
4910*58e6ee5fSAndroid Build Coastguard Worker 	struct func_list *item;
4911*58e6ee5fSAndroid Build Coastguard Worker 
4912*58e6ee5fSAndroid Build Coastguard Worker 	item = malloc(sizeof(*item));
4913*58e6ee5fSAndroid Build Coastguard Worker 	if (!item)
4914*58e6ee5fSAndroid Build Coastguard Worker 		die("Failed to allocate function descriptor");
4915*58e6ee5fSAndroid Build Coastguard Worker 	item->func = func;
4916*58e6ee5fSAndroid Build Coastguard Worker 	item->mod = mod;
4917*58e6ee5fSAndroid Build Coastguard Worker 	item->next = *list;
4918*58e6ee5fSAndroid Build Coastguard Worker 	*list = item;
4919*58e6ee5fSAndroid Build Coastguard Worker }
4920*58e6ee5fSAndroid Build Coastguard Worker 
find_ts(struct tep_event * event,struct tep_record * record,int cpu,void * context)4921*58e6ee5fSAndroid Build Coastguard Worker static int find_ts(struct tep_event *event, struct tep_record *record,
4922*58e6ee5fSAndroid Build Coastguard Worker 		   int cpu, void *context)
4923*58e6ee5fSAndroid Build Coastguard Worker {
4924*58e6ee5fSAndroid Build Coastguard Worker 	unsigned long long *ts = (unsigned long long *)context;
4925*58e6ee5fSAndroid Build Coastguard Worker 	struct tep_format_field *field;
4926*58e6ee5fSAndroid Build Coastguard Worker 
4927*58e6ee5fSAndroid Build Coastguard Worker 	if (!ts)
4928*58e6ee5fSAndroid Build Coastguard Worker 		return -1;
4929*58e6ee5fSAndroid Build Coastguard Worker 
4930*58e6ee5fSAndroid Build Coastguard Worker 	field = tep_find_field(event, "buf");
4931*58e6ee5fSAndroid Build Coastguard Worker 	if (field && strcmp(STAMP"\n", record->data + field->offset) == 0) {
4932*58e6ee5fSAndroid Build Coastguard Worker 		*ts = record->ts;
4933*58e6ee5fSAndroid Build Coastguard Worker 		return 1;
4934*58e6ee5fSAndroid Build Coastguard Worker 	}
4935*58e6ee5fSAndroid Build Coastguard Worker 
4936*58e6ee5fSAndroid Build Coastguard Worker 	return 0;
4937*58e6ee5fSAndroid Build Coastguard Worker }
4938*58e6ee5fSAndroid Build Coastguard Worker 
find_time_stamp(struct tep_handle * tep,struct tracefs_instance * instance)4939*58e6ee5fSAndroid Build Coastguard Worker static unsigned long long find_time_stamp(struct tep_handle *tep,
4940*58e6ee5fSAndroid Build Coastguard Worker 					  struct tracefs_instance *instance)
4941*58e6ee5fSAndroid Build Coastguard Worker {
4942*58e6ee5fSAndroid Build Coastguard Worker 	unsigned long long ts = 0;
4943*58e6ee5fSAndroid Build Coastguard Worker 
4944*58e6ee5fSAndroid Build Coastguard Worker 	if (!tracefs_iterate_raw_events(tep, instance, NULL, 0, find_ts, &ts))
4945*58e6ee5fSAndroid Build Coastguard Worker 		return ts;
4946*58e6ee5fSAndroid Build Coastguard Worker 
4947*58e6ee5fSAndroid Build Coastguard Worker 	return 0;
4948*58e6ee5fSAndroid Build Coastguard Worker }
4949*58e6ee5fSAndroid Build Coastguard Worker 
4950*58e6ee5fSAndroid Build Coastguard Worker 
read_top_file(char * file,int * psize)4951*58e6ee5fSAndroid Build Coastguard Worker static char *read_top_file(char *file, int *psize)
4952*58e6ee5fSAndroid Build Coastguard Worker {
4953*58e6ee5fSAndroid Build Coastguard Worker 	return tracefs_instance_file_read(top_instance.tracefs, file, psize);
4954*58e6ee5fSAndroid Build Coastguard Worker }
4955*58e6ee5fSAndroid Build Coastguard Worker 
get_ftrace_tep(void)4956*58e6ee5fSAndroid Build Coastguard Worker static struct tep_handle *get_ftrace_tep(void)
4957*58e6ee5fSAndroid Build Coastguard Worker {
4958*58e6ee5fSAndroid Build Coastguard Worker 	const char *systems[] = {"ftrace", NULL};
4959*58e6ee5fSAndroid Build Coastguard Worker 	struct tep_handle *tep;
4960*58e6ee5fSAndroid Build Coastguard Worker 	char *buf;
4961*58e6ee5fSAndroid Build Coastguard Worker 	int size;
4962*58e6ee5fSAndroid Build Coastguard Worker 	int ret;
4963*58e6ee5fSAndroid Build Coastguard Worker 
4964*58e6ee5fSAndroid Build Coastguard Worker 	tep = tracefs_local_events_system(NULL, systems);
4965*58e6ee5fSAndroid Build Coastguard Worker 	if (!tep)
4966*58e6ee5fSAndroid Build Coastguard Worker 		return NULL;
4967*58e6ee5fSAndroid Build Coastguard Worker 	tep_set_file_bigendian(tep, tracecmd_host_bigendian());
4968*58e6ee5fSAndroid Build Coastguard Worker 	buf = read_top_file("events/header_page", &size);
4969*58e6ee5fSAndroid Build Coastguard Worker 	if (!buf)
4970*58e6ee5fSAndroid Build Coastguard Worker 		goto error;
4971*58e6ee5fSAndroid Build Coastguard Worker 	ret = tep_parse_header_page(tep, buf, size, sizeof(unsigned long));
4972*58e6ee5fSAndroid Build Coastguard Worker 	free(buf);
4973*58e6ee5fSAndroid Build Coastguard Worker 	if (ret < 0)
4974*58e6ee5fSAndroid Build Coastguard Worker 		goto error;
4975*58e6ee5fSAndroid Build Coastguard Worker 
4976*58e6ee5fSAndroid Build Coastguard Worker 	return tep;
4977*58e6ee5fSAndroid Build Coastguard Worker 
4978*58e6ee5fSAndroid Build Coastguard Worker error:
4979*58e6ee5fSAndroid Build Coastguard Worker 	tep_free(tep);
4980*58e6ee5fSAndroid Build Coastguard Worker 	return NULL;
4981*58e6ee5fSAndroid Build Coastguard Worker }
4982*58e6ee5fSAndroid Build Coastguard Worker 
4983*58e6ee5fSAndroid Build Coastguard Worker /*
4984*58e6ee5fSAndroid Build Coastguard Worker  * Try to write the date into the ftrace buffer and then
4985*58e6ee5fSAndroid Build Coastguard Worker  * read it back, mapping the timestamp to the date.
4986*58e6ee5fSAndroid Build Coastguard Worker  */
get_date_to_ts(void)4987*58e6ee5fSAndroid Build Coastguard Worker static char *get_date_to_ts(void)
4988*58e6ee5fSAndroid Build Coastguard Worker {
4989*58e6ee5fSAndroid Build Coastguard Worker 	struct tep_handle *tep;
4990*58e6ee5fSAndroid Build Coastguard Worker 	unsigned long long min = -1ULL;
4991*58e6ee5fSAndroid Build Coastguard Worker 	unsigned long long diff;
4992*58e6ee5fSAndroid Build Coastguard Worker 	unsigned long long stamp;
4993*58e6ee5fSAndroid Build Coastguard Worker 	unsigned long long min_stamp;
4994*58e6ee5fSAndroid Build Coastguard Worker 	unsigned long long min_ts;
4995*58e6ee5fSAndroid Build Coastguard Worker 	unsigned long long ts;
4996*58e6ee5fSAndroid Build Coastguard Worker 	struct timespec start;
4997*58e6ee5fSAndroid Build Coastguard Worker 	struct timespec end;
4998*58e6ee5fSAndroid Build Coastguard Worker 	char *date2ts = NULL;
4999*58e6ee5fSAndroid Build Coastguard Worker 	int tfd;
5000*58e6ee5fSAndroid Build Coastguard Worker 	int i;
5001*58e6ee5fSAndroid Build Coastguard Worker 
5002*58e6ee5fSAndroid Build Coastguard Worker 	/* Set up a tep to read the raw format */
5003*58e6ee5fSAndroid Build Coastguard Worker 	tep = get_ftrace_tep();
5004*58e6ee5fSAndroid Build Coastguard Worker 	if (!tep) {
5005*58e6ee5fSAndroid Build Coastguard Worker 		warning("failed to alloc tep, --date ignored");
5006*58e6ee5fSAndroid Build Coastguard Worker 		return NULL;
5007*58e6ee5fSAndroid Build Coastguard Worker 	}
5008*58e6ee5fSAndroid Build Coastguard Worker 	tfd = tracefs_instance_file_open(NULL, "trace_marker", O_WRONLY);
5009*58e6ee5fSAndroid Build Coastguard Worker 	if (tfd < 0) {
5010*58e6ee5fSAndroid Build Coastguard Worker 		warning("Can not open 'trace_marker', --date ignored");
5011*58e6ee5fSAndroid Build Coastguard Worker 		goto out_pevent;
5012*58e6ee5fSAndroid Build Coastguard Worker 	}
5013*58e6ee5fSAndroid Build Coastguard Worker 
5014*58e6ee5fSAndroid Build Coastguard Worker 	for (i = 0; i < date2ts_tries; i++) {
5015*58e6ee5fSAndroid Build Coastguard Worker 		tracecmd_disable_tracing();
5016*58e6ee5fSAndroid Build Coastguard Worker 		clear_trace_instances();
5017*58e6ee5fSAndroid Build Coastguard Worker 		tracecmd_enable_tracing();
5018*58e6ee5fSAndroid Build Coastguard Worker 
5019*58e6ee5fSAndroid Build Coastguard Worker 		clock_gettime(CLOCK_REALTIME, &start);
5020*58e6ee5fSAndroid Build Coastguard Worker 		write(tfd, STAMP, 5);
5021*58e6ee5fSAndroid Build Coastguard Worker 		clock_gettime(CLOCK_REALTIME, &end);
5022*58e6ee5fSAndroid Build Coastguard Worker 
5023*58e6ee5fSAndroid Build Coastguard Worker 		tracecmd_disable_tracing();
5024*58e6ee5fSAndroid Build Coastguard Worker 		ts = find_time_stamp(tep, NULL);
5025*58e6ee5fSAndroid Build Coastguard Worker 		if (!ts)
5026*58e6ee5fSAndroid Build Coastguard Worker 			continue;
5027*58e6ee5fSAndroid Build Coastguard Worker 
5028*58e6ee5fSAndroid Build Coastguard Worker 		diff = (unsigned long long)end.tv_sec * 1000000000LL;
5029*58e6ee5fSAndroid Build Coastguard Worker 		diff += (unsigned long long)end.tv_nsec;
5030*58e6ee5fSAndroid Build Coastguard Worker 		stamp = diff;
5031*58e6ee5fSAndroid Build Coastguard Worker 		diff -= (unsigned long long)start.tv_sec * 1000000000LL;
5032*58e6ee5fSAndroid Build Coastguard Worker 		diff -= (unsigned long long)start.tv_nsec;
5033*58e6ee5fSAndroid Build Coastguard Worker 
5034*58e6ee5fSAndroid Build Coastguard Worker 		if (diff < min) {
5035*58e6ee5fSAndroid Build Coastguard Worker 			min_ts = ts;
5036*58e6ee5fSAndroid Build Coastguard Worker 			min_stamp = stamp - diff / 2;
5037*58e6ee5fSAndroid Build Coastguard Worker 			min = diff;
5038*58e6ee5fSAndroid Build Coastguard Worker 		}
5039*58e6ee5fSAndroid Build Coastguard Worker 	}
5040*58e6ee5fSAndroid Build Coastguard Worker 
5041*58e6ee5fSAndroid Build Coastguard Worker 	close(tfd);
5042*58e6ee5fSAndroid Build Coastguard Worker 
5043*58e6ee5fSAndroid Build Coastguard Worker 	if (min == -1ULL) {
5044*58e6ee5fSAndroid Build Coastguard Worker 		warning("Failed to make date offset, --date ignored");
5045*58e6ee5fSAndroid Build Coastguard Worker 		goto out_pevent;
5046*58e6ee5fSAndroid Build Coastguard Worker 	}
5047*58e6ee5fSAndroid Build Coastguard Worker 
5048*58e6ee5fSAndroid Build Coastguard Worker 	/* 16 hex chars + 0x + \0 */
5049*58e6ee5fSAndroid Build Coastguard Worker 	date2ts = malloc(19);
5050*58e6ee5fSAndroid Build Coastguard Worker 	if (!date2ts)
5051*58e6ee5fSAndroid Build Coastguard Worker 		goto out_pevent;
5052*58e6ee5fSAndroid Build Coastguard Worker 
5053*58e6ee5fSAndroid Build Coastguard Worker 	/*
5054*58e6ee5fSAndroid Build Coastguard Worker 	 * The difference between the timestamp and the gtod is
5055*58e6ee5fSAndroid Build Coastguard Worker 	 * stored as an ASCII string in hex.
5056*58e6ee5fSAndroid Build Coastguard Worker 	 */
5057*58e6ee5fSAndroid Build Coastguard Worker 	diff = min_stamp - min_ts;
5058*58e6ee5fSAndroid Build Coastguard Worker 	snprintf(date2ts, 19, "0x%llx", diff/1000);
5059*58e6ee5fSAndroid Build Coastguard Worker  out_pevent:
5060*58e6ee5fSAndroid Build Coastguard Worker 	tep_free(tep);
5061*58e6ee5fSAndroid Build Coastguard Worker 
5062*58e6ee5fSAndroid Build Coastguard Worker 	return date2ts;
5063*58e6ee5fSAndroid Build Coastguard Worker }
5064*58e6ee5fSAndroid Build Coastguard Worker 
set_buffer_size_instance(struct buffer_instance * instance)5065*58e6ee5fSAndroid Build Coastguard Worker static void set_buffer_size_instance(struct buffer_instance *instance)
5066*58e6ee5fSAndroid Build Coastguard Worker {
5067*58e6ee5fSAndroid Build Coastguard Worker 	int buffer_size = instance->buffer_size;
5068*58e6ee5fSAndroid Build Coastguard Worker 	char buf[BUFSIZ];
5069*58e6ee5fSAndroid Build Coastguard Worker 	char *path;
5070*58e6ee5fSAndroid Build Coastguard Worker 	int ret;
5071*58e6ee5fSAndroid Build Coastguard Worker 	int fd;
5072*58e6ee5fSAndroid Build Coastguard Worker 
5073*58e6ee5fSAndroid Build Coastguard Worker 	if (is_guest(instance))
5074*58e6ee5fSAndroid Build Coastguard Worker 		return;
5075*58e6ee5fSAndroid Build Coastguard Worker 
5076*58e6ee5fSAndroid Build Coastguard Worker 	if (!buffer_size)
5077*58e6ee5fSAndroid Build Coastguard Worker 		return;
5078*58e6ee5fSAndroid Build Coastguard Worker 
5079*58e6ee5fSAndroid Build Coastguard Worker 	if (buffer_size < 0)
5080*58e6ee5fSAndroid Build Coastguard Worker 		die("buffer size must be positive");
5081*58e6ee5fSAndroid Build Coastguard Worker 
5082*58e6ee5fSAndroid Build Coastguard Worker 	snprintf(buf, BUFSIZ, "%d", buffer_size);
5083*58e6ee5fSAndroid Build Coastguard Worker 
5084*58e6ee5fSAndroid Build Coastguard Worker 	path = tracefs_instance_get_file(instance->tracefs, "buffer_size_kb");
5085*58e6ee5fSAndroid Build Coastguard Worker 	fd = open(path, O_WRONLY);
5086*58e6ee5fSAndroid Build Coastguard Worker 	if (fd < 0) {
5087*58e6ee5fSAndroid Build Coastguard Worker 		warning("can't open %s", path);
5088*58e6ee5fSAndroid Build Coastguard Worker 		goto out;
5089*58e6ee5fSAndroid Build Coastguard Worker 	}
5090*58e6ee5fSAndroid Build Coastguard Worker 
5091*58e6ee5fSAndroid Build Coastguard Worker 	ret = write(fd, buf, strlen(buf));
5092*58e6ee5fSAndroid Build Coastguard Worker 	if (ret < 0)
5093*58e6ee5fSAndroid Build Coastguard Worker 		warning("Can't write to %s", path);
5094*58e6ee5fSAndroid Build Coastguard Worker 	close(fd);
5095*58e6ee5fSAndroid Build Coastguard Worker  out:
5096*58e6ee5fSAndroid Build Coastguard Worker 	tracefs_put_tracing_file(path);
5097*58e6ee5fSAndroid Build Coastguard Worker }
5098*58e6ee5fSAndroid Build Coastguard Worker 
set_buffer_size(void)5099*58e6ee5fSAndroid Build Coastguard Worker void set_buffer_size(void)
5100*58e6ee5fSAndroid Build Coastguard Worker {
5101*58e6ee5fSAndroid Build Coastguard Worker 	struct buffer_instance *instance;
5102*58e6ee5fSAndroid Build Coastguard Worker 
5103*58e6ee5fSAndroid Build Coastguard Worker 	for_all_instances(instance)
5104*58e6ee5fSAndroid Build Coastguard Worker 		set_buffer_size_instance(instance);
5105*58e6ee5fSAndroid Build Coastguard Worker }
5106*58e6ee5fSAndroid Build Coastguard Worker 
5107*58e6ee5fSAndroid Build Coastguard Worker static int
process_event_trigger(char * path,struct event_iter * iter)5108*58e6ee5fSAndroid Build Coastguard Worker process_event_trigger(char *path, struct event_iter *iter)
5109*58e6ee5fSAndroid Build Coastguard Worker {
5110*58e6ee5fSAndroid Build Coastguard Worker 	const char *system = iter->system_dent->d_name;
5111*58e6ee5fSAndroid Build Coastguard Worker 	const char *event = iter->event_dent->d_name;
5112*58e6ee5fSAndroid Build Coastguard Worker 	struct stat st;
5113*58e6ee5fSAndroid Build Coastguard Worker 	char *trigger = NULL;
5114*58e6ee5fSAndroid Build Coastguard Worker 	char *file;
5115*58e6ee5fSAndroid Build Coastguard Worker 	int ret;
5116*58e6ee5fSAndroid Build Coastguard Worker 
5117*58e6ee5fSAndroid Build Coastguard Worker 	path = append_file(path, system);
5118*58e6ee5fSAndroid Build Coastguard Worker 	file = append_file(path, event);
5119*58e6ee5fSAndroid Build Coastguard Worker 	free(path);
5120*58e6ee5fSAndroid Build Coastguard Worker 
5121*58e6ee5fSAndroid Build Coastguard Worker 	ret = stat(file, &st);
5122*58e6ee5fSAndroid Build Coastguard Worker 	if (ret < 0 || !S_ISDIR(st.st_mode))
5123*58e6ee5fSAndroid Build Coastguard Worker 		goto out;
5124*58e6ee5fSAndroid Build Coastguard Worker 
5125*58e6ee5fSAndroid Build Coastguard Worker 	trigger = append_file(file, "trigger");
5126*58e6ee5fSAndroid Build Coastguard Worker 
5127*58e6ee5fSAndroid Build Coastguard Worker 	ret = stat(trigger, &st);
5128*58e6ee5fSAndroid Build Coastguard Worker 	if (ret < 0)
5129*58e6ee5fSAndroid Build Coastguard Worker 		goto out;
5130*58e6ee5fSAndroid Build Coastguard Worker 
5131*58e6ee5fSAndroid Build Coastguard Worker 	ret = clear_trigger(trigger);
5132*58e6ee5fSAndroid Build Coastguard Worker  out:
5133*58e6ee5fSAndroid Build Coastguard Worker 	free(trigger);
5134*58e6ee5fSAndroid Build Coastguard Worker 	free(file);
5135*58e6ee5fSAndroid Build Coastguard Worker 	return ret;
5136*58e6ee5fSAndroid Build Coastguard Worker }
5137*58e6ee5fSAndroid Build Coastguard Worker 
clear_instance_triggers(struct buffer_instance * instance)5138*58e6ee5fSAndroid Build Coastguard Worker static void clear_instance_triggers(struct buffer_instance *instance)
5139*58e6ee5fSAndroid Build Coastguard Worker {
5140*58e6ee5fSAndroid Build Coastguard Worker 	enum event_iter_type type;
5141*58e6ee5fSAndroid Build Coastguard Worker 	struct event_iter *iter;
5142*58e6ee5fSAndroid Build Coastguard Worker 	char *system;
5143*58e6ee5fSAndroid Build Coastguard Worker 	char *path;
5144*58e6ee5fSAndroid Build Coastguard Worker 	int retry = 0;
5145*58e6ee5fSAndroid Build Coastguard Worker 	int ret;
5146*58e6ee5fSAndroid Build Coastguard Worker 
5147*58e6ee5fSAndroid Build Coastguard Worker 	path = tracefs_instance_get_file(instance->tracefs, "events");
5148*58e6ee5fSAndroid Build Coastguard Worker 	if (!path)
5149*58e6ee5fSAndroid Build Coastguard Worker 		die("malloc");
5150*58e6ee5fSAndroid Build Coastguard Worker 
5151*58e6ee5fSAndroid Build Coastguard Worker 	iter = trace_event_iter_alloc(path);
5152*58e6ee5fSAndroid Build Coastguard Worker 
5153*58e6ee5fSAndroid Build Coastguard Worker 	system = NULL;
5154*58e6ee5fSAndroid Build Coastguard Worker 	while ((type = trace_event_iter_next(iter, path, system))) {
5155*58e6ee5fSAndroid Build Coastguard Worker 
5156*58e6ee5fSAndroid Build Coastguard Worker 		if (type == EVENT_ITER_SYSTEM) {
5157*58e6ee5fSAndroid Build Coastguard Worker 			system = iter->system_dent->d_name;
5158*58e6ee5fSAndroid Build Coastguard Worker 			continue;
5159*58e6ee5fSAndroid Build Coastguard Worker 		}
5160*58e6ee5fSAndroid Build Coastguard Worker 
5161*58e6ee5fSAndroid Build Coastguard Worker 		ret = process_event_trigger(path, iter);
5162*58e6ee5fSAndroid Build Coastguard Worker 		if (ret > 0)
5163*58e6ee5fSAndroid Build Coastguard Worker 			retry++;
5164*58e6ee5fSAndroid Build Coastguard Worker 	}
5165*58e6ee5fSAndroid Build Coastguard Worker 
5166*58e6ee5fSAndroid Build Coastguard Worker 	trace_event_iter_free(iter);
5167*58e6ee5fSAndroid Build Coastguard Worker 
5168*58e6ee5fSAndroid Build Coastguard Worker 	if (retry) {
5169*58e6ee5fSAndroid Build Coastguard Worker 		int i;
5170*58e6ee5fSAndroid Build Coastguard Worker 
5171*58e6ee5fSAndroid Build Coastguard Worker 		/* Order matters for some triggers */
5172*58e6ee5fSAndroid Build Coastguard Worker 		for (i = 0; i < retry; i++) {
5173*58e6ee5fSAndroid Build Coastguard Worker 			int tries = 0;
5174*58e6ee5fSAndroid Build Coastguard Worker 
5175*58e6ee5fSAndroid Build Coastguard Worker 			iter = trace_event_iter_alloc(path);
5176*58e6ee5fSAndroid Build Coastguard Worker 			system = NULL;
5177*58e6ee5fSAndroid Build Coastguard Worker 			while ((type = trace_event_iter_next(iter, path, system))) {
5178*58e6ee5fSAndroid Build Coastguard Worker 
5179*58e6ee5fSAndroid Build Coastguard Worker 				if (type == EVENT_ITER_SYSTEM) {
5180*58e6ee5fSAndroid Build Coastguard Worker 					system = iter->system_dent->d_name;
5181*58e6ee5fSAndroid Build Coastguard Worker 					continue;
5182*58e6ee5fSAndroid Build Coastguard Worker 				}
5183*58e6ee5fSAndroid Build Coastguard Worker 
5184*58e6ee5fSAndroid Build Coastguard Worker 				ret = process_event_trigger(path, iter);
5185*58e6ee5fSAndroid Build Coastguard Worker 				if (ret > 0)
5186*58e6ee5fSAndroid Build Coastguard Worker 					tries++;
5187*58e6ee5fSAndroid Build Coastguard Worker 			}
5188*58e6ee5fSAndroid Build Coastguard Worker 			trace_event_iter_free(iter);
5189*58e6ee5fSAndroid Build Coastguard Worker 			if (!tries)
5190*58e6ee5fSAndroid Build Coastguard Worker 				break;
5191*58e6ee5fSAndroid Build Coastguard Worker 		}
5192*58e6ee5fSAndroid Build Coastguard Worker 	}
5193*58e6ee5fSAndroid Build Coastguard Worker 
5194*58e6ee5fSAndroid Build Coastguard Worker 	tracefs_put_tracing_file(path);
5195*58e6ee5fSAndroid Build Coastguard Worker }
5196*58e6ee5fSAndroid Build Coastguard Worker 
5197*58e6ee5fSAndroid Build Coastguard Worker static void
process_event_filter(char * path,struct event_iter * iter,enum event_process * processed)5198*58e6ee5fSAndroid Build Coastguard Worker process_event_filter(char *path, struct event_iter *iter, enum event_process *processed)
5199*58e6ee5fSAndroid Build Coastguard Worker {
5200*58e6ee5fSAndroid Build Coastguard Worker 	const char *system = iter->system_dent->d_name;
5201*58e6ee5fSAndroid Build Coastguard Worker 	const char *event = iter->event_dent->d_name;
5202*58e6ee5fSAndroid Build Coastguard Worker 	struct stat st;
5203*58e6ee5fSAndroid Build Coastguard Worker 	char *filter = NULL;
5204*58e6ee5fSAndroid Build Coastguard Worker 	char *file;
5205*58e6ee5fSAndroid Build Coastguard Worker 	int ret;
5206*58e6ee5fSAndroid Build Coastguard Worker 
5207*58e6ee5fSAndroid Build Coastguard Worker 	path = append_file(path, system);
5208*58e6ee5fSAndroid Build Coastguard Worker 	file = append_file(path, event);
5209*58e6ee5fSAndroid Build Coastguard Worker 	free(path);
5210*58e6ee5fSAndroid Build Coastguard Worker 
5211*58e6ee5fSAndroid Build Coastguard Worker 	ret = stat(file, &st);
5212*58e6ee5fSAndroid Build Coastguard Worker 	if (ret < 0 || !S_ISDIR(st.st_mode))
5213*58e6ee5fSAndroid Build Coastguard Worker 		goto out;
5214*58e6ee5fSAndroid Build Coastguard Worker 
5215*58e6ee5fSAndroid Build Coastguard Worker 	filter = append_file(file, "filter");
5216*58e6ee5fSAndroid Build Coastguard Worker 
5217*58e6ee5fSAndroid Build Coastguard Worker 	ret = stat(filter, &st);
5218*58e6ee5fSAndroid Build Coastguard Worker 	if (ret < 0)
5219*58e6ee5fSAndroid Build Coastguard Worker 		goto out;
5220*58e6ee5fSAndroid Build Coastguard Worker 
5221*58e6ee5fSAndroid Build Coastguard Worker 	clear_filter(filter);
5222*58e6ee5fSAndroid Build Coastguard Worker  out:
5223*58e6ee5fSAndroid Build Coastguard Worker 	free(filter);
5224*58e6ee5fSAndroid Build Coastguard Worker 	free(file);
5225*58e6ee5fSAndroid Build Coastguard Worker }
5226*58e6ee5fSAndroid Build Coastguard Worker 
clear_instance_filters(struct buffer_instance * instance)5227*58e6ee5fSAndroid Build Coastguard Worker static void clear_instance_filters(struct buffer_instance *instance)
5228*58e6ee5fSAndroid Build Coastguard Worker {
5229*58e6ee5fSAndroid Build Coastguard Worker 	struct event_iter *iter;
5230*58e6ee5fSAndroid Build Coastguard Worker 	char *path;
5231*58e6ee5fSAndroid Build Coastguard Worker 	char *system;
5232*58e6ee5fSAndroid Build Coastguard Worker 	enum event_iter_type type;
5233*58e6ee5fSAndroid Build Coastguard Worker 	enum event_process processed = PROCESSED_NONE;
5234*58e6ee5fSAndroid Build Coastguard Worker 
5235*58e6ee5fSAndroid Build Coastguard Worker 	path = tracefs_instance_get_file(instance->tracefs, "events");
5236*58e6ee5fSAndroid Build Coastguard Worker 	if (!path)
5237*58e6ee5fSAndroid Build Coastguard Worker 		die("malloc");
5238*58e6ee5fSAndroid Build Coastguard Worker 
5239*58e6ee5fSAndroid Build Coastguard Worker 	iter = trace_event_iter_alloc(path);
5240*58e6ee5fSAndroid Build Coastguard Worker 
5241*58e6ee5fSAndroid Build Coastguard Worker 	processed = PROCESSED_NONE;
5242*58e6ee5fSAndroid Build Coastguard Worker 	system = NULL;
5243*58e6ee5fSAndroid Build Coastguard Worker 	while ((type = trace_event_iter_next(iter, path, system))) {
5244*58e6ee5fSAndroid Build Coastguard Worker 
5245*58e6ee5fSAndroid Build Coastguard Worker 		if (type == EVENT_ITER_SYSTEM) {
5246*58e6ee5fSAndroid Build Coastguard Worker 			system = iter->system_dent->d_name;
5247*58e6ee5fSAndroid Build Coastguard Worker 			continue;
5248*58e6ee5fSAndroid Build Coastguard Worker 		}
5249*58e6ee5fSAndroid Build Coastguard Worker 
5250*58e6ee5fSAndroid Build Coastguard Worker 		process_event_filter(path, iter, &processed);
5251*58e6ee5fSAndroid Build Coastguard Worker 	}
5252*58e6ee5fSAndroid Build Coastguard Worker 
5253*58e6ee5fSAndroid Build Coastguard Worker 	trace_event_iter_free(iter);
5254*58e6ee5fSAndroid Build Coastguard Worker 
5255*58e6ee5fSAndroid Build Coastguard Worker 	tracefs_put_tracing_file(path);
5256*58e6ee5fSAndroid Build Coastguard Worker }
5257*58e6ee5fSAndroid Build Coastguard Worker 
clear_filters(void)5258*58e6ee5fSAndroid Build Coastguard Worker static void clear_filters(void)
5259*58e6ee5fSAndroid Build Coastguard Worker {
5260*58e6ee5fSAndroid Build Coastguard Worker 	struct buffer_instance *instance;
5261*58e6ee5fSAndroid Build Coastguard Worker 
5262*58e6ee5fSAndroid Build Coastguard Worker 	for_all_instances(instance)
5263*58e6ee5fSAndroid Build Coastguard Worker 		clear_instance_filters(instance);
5264*58e6ee5fSAndroid Build Coastguard Worker }
5265*58e6ee5fSAndroid Build Coastguard Worker 
reset_clock(void)5266*58e6ee5fSAndroid Build Coastguard Worker static void reset_clock(void)
5267*58e6ee5fSAndroid Build Coastguard Worker {
5268*58e6ee5fSAndroid Build Coastguard Worker 	struct buffer_instance *instance;
5269*58e6ee5fSAndroid Build Coastguard Worker 
5270*58e6ee5fSAndroid Build Coastguard Worker 	for_all_instances(instance)
5271*58e6ee5fSAndroid Build Coastguard Worker 		tracefs_instance_file_write(instance->tracefs,
5272*58e6ee5fSAndroid Build Coastguard Worker 					    "trace_clock", "local");
5273*58e6ee5fSAndroid Build Coastguard Worker }
5274*58e6ee5fSAndroid Build Coastguard Worker 
reset_cpu_mask(void)5275*58e6ee5fSAndroid Build Coastguard Worker static void reset_cpu_mask(void)
5276*58e6ee5fSAndroid Build Coastguard Worker {
5277*58e6ee5fSAndroid Build Coastguard Worker 	struct buffer_instance *instance;
5278*58e6ee5fSAndroid Build Coastguard Worker 	int cpus = tracecmd_count_cpus();
5279*58e6ee5fSAndroid Build Coastguard Worker 	int fullwords = (cpus - 1) / 32;
5280*58e6ee5fSAndroid Build Coastguard Worker 	int bits = (cpus - 1) % 32 + 1;
5281*58e6ee5fSAndroid Build Coastguard Worker 	int len = (fullwords + 1) * 9;
5282*58e6ee5fSAndroid Build Coastguard Worker 	char buf[len + 1];
5283*58e6ee5fSAndroid Build Coastguard Worker 
5284*58e6ee5fSAndroid Build Coastguard Worker 	buf[0] = '\0';
5285*58e6ee5fSAndroid Build Coastguard Worker 
5286*58e6ee5fSAndroid Build Coastguard Worker 	sprintf(buf, "%x", (unsigned int)((1ULL << bits) - 1));
5287*58e6ee5fSAndroid Build Coastguard Worker 	while (fullwords-- > 0)
5288*58e6ee5fSAndroid Build Coastguard Worker 		strcat(buf, ",ffffffff");
5289*58e6ee5fSAndroid Build Coastguard Worker 
5290*58e6ee5fSAndroid Build Coastguard Worker 	for_all_instances(instance)
5291*58e6ee5fSAndroid Build Coastguard Worker 		tracefs_instance_file_write(instance->tracefs,
5292*58e6ee5fSAndroid Build Coastguard Worker 					    "tracing_cpumask", buf);
5293*58e6ee5fSAndroid Build Coastguard Worker }
5294*58e6ee5fSAndroid Build Coastguard Worker 
reset_event_pid(void)5295*58e6ee5fSAndroid Build Coastguard Worker static void reset_event_pid(void)
5296*58e6ee5fSAndroid Build Coastguard Worker {
5297*58e6ee5fSAndroid Build Coastguard Worker 	struct buffer_instance *instance;
5298*58e6ee5fSAndroid Build Coastguard Worker 
5299*58e6ee5fSAndroid Build Coastguard Worker 	for_all_instances(instance)
5300*58e6ee5fSAndroid Build Coastguard Worker 		add_event_pid(instance, "");
5301*58e6ee5fSAndroid Build Coastguard Worker }
5302*58e6ee5fSAndroid Build Coastguard Worker 
clear_triggers(void)5303*58e6ee5fSAndroid Build Coastguard Worker static void clear_triggers(void)
5304*58e6ee5fSAndroid Build Coastguard Worker {
5305*58e6ee5fSAndroid Build Coastguard Worker 	struct buffer_instance *instance;
5306*58e6ee5fSAndroid Build Coastguard Worker 
5307*58e6ee5fSAndroid Build Coastguard Worker 	for_all_instances(instance)
5308*58e6ee5fSAndroid Build Coastguard Worker 		clear_instance_triggers(instance);
5309*58e6ee5fSAndroid Build Coastguard Worker }
5310*58e6ee5fSAndroid Build Coastguard Worker 
clear_instance_error_log(struct buffer_instance * instance)5311*58e6ee5fSAndroid Build Coastguard Worker static void clear_instance_error_log(struct buffer_instance *instance)
5312*58e6ee5fSAndroid Build Coastguard Worker {
5313*58e6ee5fSAndroid Build Coastguard Worker 	char *file;
5314*58e6ee5fSAndroid Build Coastguard Worker 
5315*58e6ee5fSAndroid Build Coastguard Worker 	if (!tracefs_file_exists(instance->tracefs, "error_log"))
5316*58e6ee5fSAndroid Build Coastguard Worker 		return;
5317*58e6ee5fSAndroid Build Coastguard Worker 
5318*58e6ee5fSAndroid Build Coastguard Worker 	file = tracefs_instance_get_file(instance->tracefs, "error_log");
5319*58e6ee5fSAndroid Build Coastguard Worker 	if (!file)
5320*58e6ee5fSAndroid Build Coastguard Worker 		return;
5321*58e6ee5fSAndroid Build Coastguard Worker 	write_file(file, " ");
5322*58e6ee5fSAndroid Build Coastguard Worker 	tracefs_put_tracing_file(file);
5323*58e6ee5fSAndroid Build Coastguard Worker }
5324*58e6ee5fSAndroid Build Coastguard Worker 
clear_error_log(void)5325*58e6ee5fSAndroid Build Coastguard Worker static void clear_error_log(void)
5326*58e6ee5fSAndroid Build Coastguard Worker {
5327*58e6ee5fSAndroid Build Coastguard Worker 	struct buffer_instance *instance;
5328*58e6ee5fSAndroid Build Coastguard Worker 
5329*58e6ee5fSAndroid Build Coastguard Worker 	for_all_instances(instance)
5330*58e6ee5fSAndroid Build Coastguard Worker 		clear_instance_error_log(instance);
5331*58e6ee5fSAndroid Build Coastguard Worker }
5332*58e6ee5fSAndroid Build Coastguard Worker 
clear_all_dynamic_events(void)5333*58e6ee5fSAndroid Build Coastguard Worker static void clear_all_dynamic_events(void)
5334*58e6ee5fSAndroid Build Coastguard Worker {
5335*58e6ee5fSAndroid Build Coastguard Worker 	/* Clear event probes first, as they may be attached to other dynamic event */
5336*58e6ee5fSAndroid Build Coastguard Worker 	tracefs_dynevent_destroy_all(TRACEFS_DYNEVENT_EPROBE, true);
5337*58e6ee5fSAndroid Build Coastguard Worker 	tracefs_dynevent_destroy_all(TRACEFS_DYNEVENT_ALL, true);
5338*58e6ee5fSAndroid Build Coastguard Worker }
5339*58e6ee5fSAndroid Build Coastguard Worker 
clear_func_filters(void)5340*58e6ee5fSAndroid Build Coastguard Worker static void clear_func_filters(void)
5341*58e6ee5fSAndroid Build Coastguard Worker {
5342*58e6ee5fSAndroid Build Coastguard Worker 	struct buffer_instance *instance;
5343*58e6ee5fSAndroid Build Coastguard Worker 	char *path;
5344*58e6ee5fSAndroid Build Coastguard Worker 	int i;
5345*58e6ee5fSAndroid Build Coastguard Worker 	const char * const files[] = { "set_ftrace_filter",
5346*58e6ee5fSAndroid Build Coastguard Worker 				      "set_ftrace_notrace",
5347*58e6ee5fSAndroid Build Coastguard Worker 				      "set_graph_function",
5348*58e6ee5fSAndroid Build Coastguard Worker 				      "set_graph_notrace",
5349*58e6ee5fSAndroid Build Coastguard Worker 				      NULL };
5350*58e6ee5fSAndroid Build Coastguard Worker 
5351*58e6ee5fSAndroid Build Coastguard Worker 	for_all_instances(instance) {
5352*58e6ee5fSAndroid Build Coastguard Worker 		for (i = 0; files[i]; i++) {
5353*58e6ee5fSAndroid Build Coastguard Worker 			path = tracefs_instance_get_file(instance->tracefs, files[i]);
5354*58e6ee5fSAndroid Build Coastguard Worker 			clear_func_filter(path);
5355*58e6ee5fSAndroid Build Coastguard Worker 			tracefs_put_tracing_file(path);
5356*58e6ee5fSAndroid Build Coastguard Worker 		}
5357*58e6ee5fSAndroid Build Coastguard Worker 	}
5358*58e6ee5fSAndroid Build Coastguard Worker }
5359*58e6ee5fSAndroid Build Coastguard Worker 
make_instances(void)5360*58e6ee5fSAndroid Build Coastguard Worker static void make_instances(void)
5361*58e6ee5fSAndroid Build Coastguard Worker {
5362*58e6ee5fSAndroid Build Coastguard Worker 	struct buffer_instance *instance;
5363*58e6ee5fSAndroid Build Coastguard Worker 
5364*58e6ee5fSAndroid Build Coastguard Worker 	for_each_instance(instance) {
5365*58e6ee5fSAndroid Build Coastguard Worker 		if (is_guest(instance))
5366*58e6ee5fSAndroid Build Coastguard Worker 			continue;
5367*58e6ee5fSAndroid Build Coastguard Worker 		if (instance->name && !instance->tracefs) {
5368*58e6ee5fSAndroid Build Coastguard Worker 			instance->tracefs = tracefs_instance_create(instance->name);
5369*58e6ee5fSAndroid Build Coastguard Worker 			/* Don't delete instances that already exist */
5370*58e6ee5fSAndroid Build Coastguard Worker 			if (instance->tracefs && !tracefs_instance_is_new(instance->tracefs))
5371*58e6ee5fSAndroid Build Coastguard Worker 				instance->flags |= BUFFER_FL_KEEP;
5372*58e6ee5fSAndroid Build Coastguard Worker 		}
5373*58e6ee5fSAndroid Build Coastguard Worker 	}
5374*58e6ee5fSAndroid Build Coastguard Worker }
5375*58e6ee5fSAndroid Build Coastguard Worker 
tracecmd_remove_instances(void)5376*58e6ee5fSAndroid Build Coastguard Worker void tracecmd_remove_instances(void)
5377*58e6ee5fSAndroid Build Coastguard Worker {
5378*58e6ee5fSAndroid Build Coastguard Worker 	struct buffer_instance *instance;
5379*58e6ee5fSAndroid Build Coastguard Worker 
5380*58e6ee5fSAndroid Build Coastguard Worker 	for_each_instance(instance) {
5381*58e6ee5fSAndroid Build Coastguard Worker 		/* Only delete what we created */
5382*58e6ee5fSAndroid Build Coastguard Worker 		if (is_guest(instance) || (instance->flags & BUFFER_FL_KEEP))
5383*58e6ee5fSAndroid Build Coastguard Worker 			continue;
5384*58e6ee5fSAndroid Build Coastguard Worker 		if (instance->tracing_on_fd > 0) {
5385*58e6ee5fSAndroid Build Coastguard Worker 			close(instance->tracing_on_fd);
5386*58e6ee5fSAndroid Build Coastguard Worker 			instance->tracing_on_fd = 0;
5387*58e6ee5fSAndroid Build Coastguard Worker 		}
5388*58e6ee5fSAndroid Build Coastguard Worker 		tracefs_instance_destroy(instance->tracefs);
5389*58e6ee5fSAndroid Build Coastguard Worker 	}
5390*58e6ee5fSAndroid Build Coastguard Worker }
5391*58e6ee5fSAndroid Build Coastguard Worker 
check_plugin(const char * plugin)5392*58e6ee5fSAndroid Build Coastguard Worker static void check_plugin(const char *plugin)
5393*58e6ee5fSAndroid Build Coastguard Worker {
5394*58e6ee5fSAndroid Build Coastguard Worker 	char *buf;
5395*58e6ee5fSAndroid Build Coastguard Worker 	char *str;
5396*58e6ee5fSAndroid Build Coastguard Worker 	char *tok;
5397*58e6ee5fSAndroid Build Coastguard Worker 
5398*58e6ee5fSAndroid Build Coastguard Worker 	/*
5399*58e6ee5fSAndroid Build Coastguard Worker 	 * nop is special. We may want to just trace
5400*58e6ee5fSAndroid Build Coastguard Worker 	 * trace_printks, that are in the kernel.
5401*58e6ee5fSAndroid Build Coastguard Worker 	 */
5402*58e6ee5fSAndroid Build Coastguard Worker 	if (strcmp(plugin, "nop") == 0)
5403*58e6ee5fSAndroid Build Coastguard Worker 		return;
5404*58e6ee5fSAndroid Build Coastguard Worker 
5405*58e6ee5fSAndroid Build Coastguard Worker 	buf = read_top_file("available_tracers", NULL);
5406*58e6ee5fSAndroid Build Coastguard Worker 	if (!buf)
5407*58e6ee5fSAndroid Build Coastguard Worker 		die("No plugins available");
5408*58e6ee5fSAndroid Build Coastguard Worker 
5409*58e6ee5fSAndroid Build Coastguard Worker 	str = buf;
5410*58e6ee5fSAndroid Build Coastguard Worker 	while ((tok = strtok(str, " "))) {
5411*58e6ee5fSAndroid Build Coastguard Worker 		str = NULL;
5412*58e6ee5fSAndroid Build Coastguard Worker 		if (strcmp(tok, plugin) == 0)
5413*58e6ee5fSAndroid Build Coastguard Worker 			goto out;
5414*58e6ee5fSAndroid Build Coastguard Worker 	}
5415*58e6ee5fSAndroid Build Coastguard Worker 	die ("Plugin '%s' does not exist", plugin);
5416*58e6ee5fSAndroid Build Coastguard Worker  out:
5417*58e6ee5fSAndroid Build Coastguard Worker 	if (!quiet)
5418*58e6ee5fSAndroid Build Coastguard Worker 		fprintf(stderr, "  plugin '%s'\n", plugin);
5419*58e6ee5fSAndroid Build Coastguard Worker 	free(buf);
5420*58e6ee5fSAndroid Build Coastguard Worker }
5421*58e6ee5fSAndroid Build Coastguard Worker 
check_function_plugin(void)5422*58e6ee5fSAndroid Build Coastguard Worker static void check_function_plugin(void)
5423*58e6ee5fSAndroid Build Coastguard Worker {
5424*58e6ee5fSAndroid Build Coastguard Worker 	const char *plugin;
5425*58e6ee5fSAndroid Build Coastguard Worker 
5426*58e6ee5fSAndroid Build Coastguard Worker 	/* We only care about the top_instance */
5427*58e6ee5fSAndroid Build Coastguard Worker 	if (no_top_instance())
5428*58e6ee5fSAndroid Build Coastguard Worker 		return;
5429*58e6ee5fSAndroid Build Coastguard Worker 
5430*58e6ee5fSAndroid Build Coastguard Worker 	plugin = top_instance.plugin;
5431*58e6ee5fSAndroid Build Coastguard Worker 	if (!plugin)
5432*58e6ee5fSAndroid Build Coastguard Worker 		return;
5433*58e6ee5fSAndroid Build Coastguard Worker 
5434*58e6ee5fSAndroid Build Coastguard Worker 	if (plugin && strncmp(plugin, "function", 8) == 0 &&
5435*58e6ee5fSAndroid Build Coastguard Worker 	    func_stack && !top_instance.filter_funcs)
5436*58e6ee5fSAndroid Build Coastguard Worker 		die("Must supply function filtering with --func-stack\n");
5437*58e6ee5fSAndroid Build Coastguard Worker }
5438*58e6ee5fSAndroid Build Coastguard Worker 
__check_doing_something(struct buffer_instance * instance)5439*58e6ee5fSAndroid Build Coastguard Worker static int __check_doing_something(struct buffer_instance *instance)
5440*58e6ee5fSAndroid Build Coastguard Worker {
5441*58e6ee5fSAndroid Build Coastguard Worker 	return is_guest(instance) || (instance->flags & BUFFER_FL_PROFILE) ||
5442*58e6ee5fSAndroid Build Coastguard Worker 		instance->plugin || instance->events || instance->get_procmap;
5443*58e6ee5fSAndroid Build Coastguard Worker }
5444*58e6ee5fSAndroid Build Coastguard Worker 
check_doing_something(void)5445*58e6ee5fSAndroid Build Coastguard Worker static void check_doing_something(void)
5446*58e6ee5fSAndroid Build Coastguard Worker {
5447*58e6ee5fSAndroid Build Coastguard Worker 	struct buffer_instance *instance;
5448*58e6ee5fSAndroid Build Coastguard Worker 
5449*58e6ee5fSAndroid Build Coastguard Worker 	for_all_instances(instance) {
5450*58e6ee5fSAndroid Build Coastguard Worker 		if (__check_doing_something(instance))
5451*58e6ee5fSAndroid Build Coastguard Worker 			return;
5452*58e6ee5fSAndroid Build Coastguard Worker 	}
5453*58e6ee5fSAndroid Build Coastguard Worker 
5454*58e6ee5fSAndroid Build Coastguard Worker 	die("no event or plugin was specified... aborting");
5455*58e6ee5fSAndroid Build Coastguard Worker }
5456*58e6ee5fSAndroid Build Coastguard Worker 
5457*58e6ee5fSAndroid Build Coastguard Worker static void
update_plugin_instance(struct buffer_instance * instance,enum trace_type type)5458*58e6ee5fSAndroid Build Coastguard Worker update_plugin_instance(struct buffer_instance *instance,
5459*58e6ee5fSAndroid Build Coastguard Worker 		       enum trace_type type)
5460*58e6ee5fSAndroid Build Coastguard Worker {
5461*58e6ee5fSAndroid Build Coastguard Worker 	const char *plugin = instance->plugin;
5462*58e6ee5fSAndroid Build Coastguard Worker 
5463*58e6ee5fSAndroid Build Coastguard Worker 	if (is_guest(instance))
5464*58e6ee5fSAndroid Build Coastguard Worker 		return;
5465*58e6ee5fSAndroid Build Coastguard Worker 
5466*58e6ee5fSAndroid Build Coastguard Worker 	if (!plugin)
5467*58e6ee5fSAndroid Build Coastguard Worker 		return;
5468*58e6ee5fSAndroid Build Coastguard Worker 
5469*58e6ee5fSAndroid Build Coastguard Worker 	check_plugin(plugin);
5470*58e6ee5fSAndroid Build Coastguard Worker 
5471*58e6ee5fSAndroid Build Coastguard Worker 	/*
5472*58e6ee5fSAndroid Build Coastguard Worker 	 * Latency tracers just save the trace and kill
5473*58e6ee5fSAndroid Build Coastguard Worker 	 * the threads.
5474*58e6ee5fSAndroid Build Coastguard Worker 	 */
5475*58e6ee5fSAndroid Build Coastguard Worker 	if (strcmp(plugin, "irqsoff") == 0 ||
5476*58e6ee5fSAndroid Build Coastguard Worker 	    strcmp(plugin, "preemptoff") == 0 ||
5477*58e6ee5fSAndroid Build Coastguard Worker 	    strcmp(plugin, "preemptirqsoff") == 0 ||
5478*58e6ee5fSAndroid Build Coastguard Worker 	    strcmp(plugin, "wakeup") == 0 ||
5479*58e6ee5fSAndroid Build Coastguard Worker 	    strcmp(plugin, "wakeup_rt") == 0) {
5480*58e6ee5fSAndroid Build Coastguard Worker 		latency = 1;
5481*58e6ee5fSAndroid Build Coastguard Worker 		if (host)
5482*58e6ee5fSAndroid Build Coastguard Worker 			die("Network tracing not available with latency tracer plugins");
5483*58e6ee5fSAndroid Build Coastguard Worker 		if (type & TRACE_TYPE_STREAM)
5484*58e6ee5fSAndroid Build Coastguard Worker 			die("Streaming is not available with latency tracer plugins");
5485*58e6ee5fSAndroid Build Coastguard Worker 	} else if (type == TRACE_TYPE_RECORD) {
5486*58e6ee5fSAndroid Build Coastguard Worker 		if (latency)
5487*58e6ee5fSAndroid Build Coastguard Worker 			die("Can not record latency tracer and non latency trace together");
5488*58e6ee5fSAndroid Build Coastguard Worker 	}
5489*58e6ee5fSAndroid Build Coastguard Worker 
5490*58e6ee5fSAndroid Build Coastguard Worker 	if (fset < 0 && (strcmp(plugin, "function") == 0 ||
5491*58e6ee5fSAndroid Build Coastguard Worker 			 strcmp(plugin, "function_graph") == 0))
5492*58e6ee5fSAndroid Build Coastguard Worker 		die("function tracing not configured on this kernel");
5493*58e6ee5fSAndroid Build Coastguard Worker 
5494*58e6ee5fSAndroid Build Coastguard Worker 	if (type != TRACE_TYPE_EXTRACT)
5495*58e6ee5fSAndroid Build Coastguard Worker 		set_plugin_instance(instance, plugin);
5496*58e6ee5fSAndroid Build Coastguard Worker }
5497*58e6ee5fSAndroid Build Coastguard Worker 
update_plugins(enum trace_type type)5498*58e6ee5fSAndroid Build Coastguard Worker static void update_plugins(enum trace_type type)
5499*58e6ee5fSAndroid Build Coastguard Worker {
5500*58e6ee5fSAndroid Build Coastguard Worker 	struct buffer_instance *instance;
5501*58e6ee5fSAndroid Build Coastguard Worker 
5502*58e6ee5fSAndroid Build Coastguard Worker 	for_all_instances(instance)
5503*58e6ee5fSAndroid Build Coastguard Worker 		update_plugin_instance(instance, type);
5504*58e6ee5fSAndroid Build Coastguard Worker }
5505*58e6ee5fSAndroid Build Coastguard Worker 
allocate_seq(void)5506*58e6ee5fSAndroid Build Coastguard Worker static void allocate_seq(void)
5507*58e6ee5fSAndroid Build Coastguard Worker {
5508*58e6ee5fSAndroid Build Coastguard Worker 	struct buffer_instance *instance;
5509*58e6ee5fSAndroid Build Coastguard Worker 
5510*58e6ee5fSAndroid Build Coastguard Worker 	for_all_instances(instance) {
5511*58e6ee5fSAndroid Build Coastguard Worker 		instance->s_save = malloc(sizeof(struct trace_seq) * instance->cpu_count);
5512*58e6ee5fSAndroid Build Coastguard Worker 		instance->s_print = malloc(sizeof(struct trace_seq) * instance->cpu_count);
5513*58e6ee5fSAndroid Build Coastguard Worker 		if (!instance->s_save || !instance->s_print)
5514*58e6ee5fSAndroid Build Coastguard Worker 			die("Failed to allocate instance info");
5515*58e6ee5fSAndroid Build Coastguard Worker 	}
5516*58e6ee5fSAndroid Build Coastguard Worker }
5517*58e6ee5fSAndroid Build Coastguard Worker 
5518*58e6ee5fSAndroid Build Coastguard Worker /* Find the overrun output, and add it to the print seq */
add_overrun(int cpu,struct trace_seq * src,struct trace_seq * dst)5519*58e6ee5fSAndroid Build Coastguard Worker static void add_overrun(int cpu, struct trace_seq *src, struct trace_seq *dst)
5520*58e6ee5fSAndroid Build Coastguard Worker {
5521*58e6ee5fSAndroid Build Coastguard Worker 	const char overrun_str[] = "overrun: ";
5522*58e6ee5fSAndroid Build Coastguard Worker 	const char commit_overrun_str[] = "commit overrun: ";
5523*58e6ee5fSAndroid Build Coastguard Worker 	const char *p;
5524*58e6ee5fSAndroid Build Coastguard Worker 	int overrun;
5525*58e6ee5fSAndroid Build Coastguard Worker 	int commit_overrun;
5526*58e6ee5fSAndroid Build Coastguard Worker 
5527*58e6ee5fSAndroid Build Coastguard Worker 	p = strstr(src->buffer, overrun_str);
5528*58e6ee5fSAndroid Build Coastguard Worker 	if (!p) {
5529*58e6ee5fSAndroid Build Coastguard Worker 		/* Warn? */
5530*58e6ee5fSAndroid Build Coastguard Worker 		trace_seq_printf(dst, "CPU %d: no overrun found?\n", cpu);
5531*58e6ee5fSAndroid Build Coastguard Worker 		return;
5532*58e6ee5fSAndroid Build Coastguard Worker 	}
5533*58e6ee5fSAndroid Build Coastguard Worker 
5534*58e6ee5fSAndroid Build Coastguard Worker 	overrun = atoi(p + strlen(overrun_str));
5535*58e6ee5fSAndroid Build Coastguard Worker 
5536*58e6ee5fSAndroid Build Coastguard Worker 	p = strstr(p + 9, commit_overrun_str);
5537*58e6ee5fSAndroid Build Coastguard Worker 	if (p)
5538*58e6ee5fSAndroid Build Coastguard Worker 		commit_overrun = atoi(p + strlen(commit_overrun_str));
5539*58e6ee5fSAndroid Build Coastguard Worker 	else
5540*58e6ee5fSAndroid Build Coastguard Worker 		commit_overrun = -1;
5541*58e6ee5fSAndroid Build Coastguard Worker 
5542*58e6ee5fSAndroid Build Coastguard Worker 	if (!overrun && !commit_overrun)
5543*58e6ee5fSAndroid Build Coastguard Worker 		return;
5544*58e6ee5fSAndroid Build Coastguard Worker 
5545*58e6ee5fSAndroid Build Coastguard Worker 	trace_seq_printf(dst, "CPU %d:", cpu);
5546*58e6ee5fSAndroid Build Coastguard Worker 
5547*58e6ee5fSAndroid Build Coastguard Worker 	if (overrun)
5548*58e6ee5fSAndroid Build Coastguard Worker 		trace_seq_printf(dst, " %d events lost", overrun);
5549*58e6ee5fSAndroid Build Coastguard Worker 
5550*58e6ee5fSAndroid Build Coastguard Worker 	if (commit_overrun)
5551*58e6ee5fSAndroid Build Coastguard Worker 		trace_seq_printf(dst, " %d events lost due to commit overrun",
5552*58e6ee5fSAndroid Build Coastguard Worker 				 commit_overrun);
5553*58e6ee5fSAndroid Build Coastguard Worker 
5554*58e6ee5fSAndroid Build Coastguard Worker 	trace_seq_putc(dst, '\n');
5555*58e6ee5fSAndroid Build Coastguard Worker }
5556*58e6ee5fSAndroid Build Coastguard Worker 
record_stats(void)5557*58e6ee5fSAndroid Build Coastguard Worker static void record_stats(void)
5558*58e6ee5fSAndroid Build Coastguard Worker {
5559*58e6ee5fSAndroid Build Coastguard Worker 	struct buffer_instance *instance;
5560*58e6ee5fSAndroid Build Coastguard Worker 	struct trace_seq *s_save;
5561*58e6ee5fSAndroid Build Coastguard Worker 	struct trace_seq *s_print;
5562*58e6ee5fSAndroid Build Coastguard Worker 	int cpu;
5563*58e6ee5fSAndroid Build Coastguard Worker 
5564*58e6ee5fSAndroid Build Coastguard Worker 	for_all_instances(instance) {
5565*58e6ee5fSAndroid Build Coastguard Worker 		if (is_guest(instance))
5566*58e6ee5fSAndroid Build Coastguard Worker 			continue;
5567*58e6ee5fSAndroid Build Coastguard Worker 
5568*58e6ee5fSAndroid Build Coastguard Worker 		s_save = instance->s_save;
5569*58e6ee5fSAndroid Build Coastguard Worker 		s_print = instance->s_print;
5570*58e6ee5fSAndroid Build Coastguard Worker 		for (cpu = 0; cpu < instance->cpu_count; cpu++) {
5571*58e6ee5fSAndroid Build Coastguard Worker 			trace_seq_init(&s_save[cpu]);
5572*58e6ee5fSAndroid Build Coastguard Worker 			trace_seq_init(&s_print[cpu]);
5573*58e6ee5fSAndroid Build Coastguard Worker 			trace_seq_printf(&s_save[cpu], "CPU: %d\n", cpu);
5574*58e6ee5fSAndroid Build Coastguard Worker 			tracecmd_stat_cpu_instance(instance, &s_save[cpu], cpu);
5575*58e6ee5fSAndroid Build Coastguard Worker 			add_overrun(cpu, &s_save[cpu], &s_print[cpu]);
5576*58e6ee5fSAndroid Build Coastguard Worker 		}
5577*58e6ee5fSAndroid Build Coastguard Worker 	}
5578*58e6ee5fSAndroid Build Coastguard Worker }
5579*58e6ee5fSAndroid Build Coastguard Worker 
print_stats(void)5580*58e6ee5fSAndroid Build Coastguard Worker static void print_stats(void)
5581*58e6ee5fSAndroid Build Coastguard Worker {
5582*58e6ee5fSAndroid Build Coastguard Worker 	struct buffer_instance *instance;
5583*58e6ee5fSAndroid Build Coastguard Worker 
5584*58e6ee5fSAndroid Build Coastguard Worker 	for_all_instances(instance)
5585*58e6ee5fSAndroid Build Coastguard Worker 		print_stat(instance);
5586*58e6ee5fSAndroid Build Coastguard Worker }
5587*58e6ee5fSAndroid Build Coastguard Worker 
destroy_stats(void)5588*58e6ee5fSAndroid Build Coastguard Worker static void destroy_stats(void)
5589*58e6ee5fSAndroid Build Coastguard Worker {
5590*58e6ee5fSAndroid Build Coastguard Worker 	struct buffer_instance *instance;
5591*58e6ee5fSAndroid Build Coastguard Worker 	int cpu;
5592*58e6ee5fSAndroid Build Coastguard Worker 
5593*58e6ee5fSAndroid Build Coastguard Worker 	for_all_instances(instance) {
5594*58e6ee5fSAndroid Build Coastguard Worker 		if (is_guest(instance))
5595*58e6ee5fSAndroid Build Coastguard Worker 			continue;
5596*58e6ee5fSAndroid Build Coastguard Worker 
5597*58e6ee5fSAndroid Build Coastguard Worker 		for (cpu = 0; cpu < instance->cpu_count; cpu++) {
5598*58e6ee5fSAndroid Build Coastguard Worker 			trace_seq_destroy(&instance->s_save[cpu]);
5599*58e6ee5fSAndroid Build Coastguard Worker 			trace_seq_destroy(&instance->s_print[cpu]);
5600*58e6ee5fSAndroid Build Coastguard Worker 		}
5601*58e6ee5fSAndroid Build Coastguard Worker 	}
5602*58e6ee5fSAndroid Build Coastguard Worker }
5603*58e6ee5fSAndroid Build Coastguard Worker 
list_event(const char * event)5604*58e6ee5fSAndroid Build Coastguard Worker static void list_event(const char *event)
5605*58e6ee5fSAndroid Build Coastguard Worker {
5606*58e6ee5fSAndroid Build Coastguard Worker 	struct tracecmd_event_list *list;
5607*58e6ee5fSAndroid Build Coastguard Worker 
5608*58e6ee5fSAndroid Build Coastguard Worker 	list = malloc(sizeof(*list));
5609*58e6ee5fSAndroid Build Coastguard Worker 	if (!list)
5610*58e6ee5fSAndroid Build Coastguard Worker 		die("Failed to allocate list for event");
5611*58e6ee5fSAndroid Build Coastguard Worker 	list->next = listed_events;
5612*58e6ee5fSAndroid Build Coastguard Worker 	list->glob = event;
5613*58e6ee5fSAndroid Build Coastguard Worker 	listed_events = list;
5614*58e6ee5fSAndroid Build Coastguard Worker }
5615*58e6ee5fSAndroid Build Coastguard Worker 
5616*58e6ee5fSAndroid Build Coastguard Worker #define ALL_EVENTS "*/*"
5617*58e6ee5fSAndroid Build Coastguard Worker 
record_all_events(void)5618*58e6ee5fSAndroid Build Coastguard Worker static void record_all_events(void)
5619*58e6ee5fSAndroid Build Coastguard Worker {
5620*58e6ee5fSAndroid Build Coastguard Worker 	struct tracecmd_event_list *list;
5621*58e6ee5fSAndroid Build Coastguard Worker 
5622*58e6ee5fSAndroid Build Coastguard Worker 	while (listed_events) {
5623*58e6ee5fSAndroid Build Coastguard Worker 		list = listed_events;
5624*58e6ee5fSAndroid Build Coastguard Worker 		listed_events = list->next;
5625*58e6ee5fSAndroid Build Coastguard Worker 		free(list);
5626*58e6ee5fSAndroid Build Coastguard Worker 	}
5627*58e6ee5fSAndroid Build Coastguard Worker 	list = malloc(sizeof(*list));
5628*58e6ee5fSAndroid Build Coastguard Worker 	if (!list)
5629*58e6ee5fSAndroid Build Coastguard Worker 		die("Failed to allocate list for all events");
5630*58e6ee5fSAndroid Build Coastguard Worker 	list->next = NULL;
5631*58e6ee5fSAndroid Build Coastguard Worker 	list->glob = ALL_EVENTS;
5632*58e6ee5fSAndroid Build Coastguard Worker 	listed_events = list;
5633*58e6ee5fSAndroid Build Coastguard Worker }
5634*58e6ee5fSAndroid Build Coastguard Worker 
recording_all_events(void)5635*58e6ee5fSAndroid Build Coastguard Worker static int recording_all_events(void)
5636*58e6ee5fSAndroid Build Coastguard Worker {
5637*58e6ee5fSAndroid Build Coastguard Worker 	return listed_events && strcmp(listed_events->glob, ALL_EVENTS) == 0;
5638*58e6ee5fSAndroid Build Coastguard Worker }
5639*58e6ee5fSAndroid Build Coastguard Worker 
add_trigger(struct event_list * event,const char * trigger)5640*58e6ee5fSAndroid Build Coastguard Worker static void add_trigger(struct event_list *event, const char *trigger)
5641*58e6ee5fSAndroid Build Coastguard Worker {
5642*58e6ee5fSAndroid Build Coastguard Worker 	int ret;
5643*58e6ee5fSAndroid Build Coastguard Worker 
5644*58e6ee5fSAndroid Build Coastguard Worker 	if (event->trigger) {
5645*58e6ee5fSAndroid Build Coastguard Worker 		event->trigger = realloc(event->trigger,
5646*58e6ee5fSAndroid Build Coastguard Worker 					 strlen(event->trigger) + strlen("\n") +
5647*58e6ee5fSAndroid Build Coastguard Worker 					 strlen(trigger) + 1);
5648*58e6ee5fSAndroid Build Coastguard Worker 		strcat(event->trigger, "\n");
5649*58e6ee5fSAndroid Build Coastguard Worker 		strcat(event->trigger, trigger);
5650*58e6ee5fSAndroid Build Coastguard Worker 	} else {
5651*58e6ee5fSAndroid Build Coastguard Worker 		ret = asprintf(&event->trigger, "%s", trigger);
5652*58e6ee5fSAndroid Build Coastguard Worker 		if (ret < 0)
5653*58e6ee5fSAndroid Build Coastguard Worker 			die("Failed to allocate event trigger");
5654*58e6ee5fSAndroid Build Coastguard Worker 	}
5655*58e6ee5fSAndroid Build Coastguard Worker }
5656*58e6ee5fSAndroid Build Coastguard Worker 
test_stacktrace_trigger(struct buffer_instance * instance)5657*58e6ee5fSAndroid Build Coastguard Worker static int test_stacktrace_trigger(struct buffer_instance *instance)
5658*58e6ee5fSAndroid Build Coastguard Worker {
5659*58e6ee5fSAndroid Build Coastguard Worker 	char *path;
5660*58e6ee5fSAndroid Build Coastguard Worker 	int ret = 0;
5661*58e6ee5fSAndroid Build Coastguard Worker 	int fd;
5662*58e6ee5fSAndroid Build Coastguard Worker 
5663*58e6ee5fSAndroid Build Coastguard Worker 	path = tracefs_instance_get_file(instance->tracefs,
5664*58e6ee5fSAndroid Build Coastguard Worker 					 "events/sched/sched_switch/trigger");
5665*58e6ee5fSAndroid Build Coastguard Worker 
5666*58e6ee5fSAndroid Build Coastguard Worker 	clear_trigger(path);
5667*58e6ee5fSAndroid Build Coastguard Worker 
5668*58e6ee5fSAndroid Build Coastguard Worker 	fd = open(path, O_WRONLY);
5669*58e6ee5fSAndroid Build Coastguard Worker 	if (fd < 0)
5670*58e6ee5fSAndroid Build Coastguard Worker 		goto out;
5671*58e6ee5fSAndroid Build Coastguard Worker 
5672*58e6ee5fSAndroid Build Coastguard Worker 	ret = write(fd, "stacktrace", 10);
5673*58e6ee5fSAndroid Build Coastguard Worker 	if (ret != 10)
5674*58e6ee5fSAndroid Build Coastguard Worker 		ret = 0;
5675*58e6ee5fSAndroid Build Coastguard Worker 	else
5676*58e6ee5fSAndroid Build Coastguard Worker 		ret = 1;
5677*58e6ee5fSAndroid Build Coastguard Worker 	close(fd);
5678*58e6ee5fSAndroid Build Coastguard Worker  out:
5679*58e6ee5fSAndroid Build Coastguard Worker 	tracefs_put_tracing_file(path);
5680*58e6ee5fSAndroid Build Coastguard Worker 
5681*58e6ee5fSAndroid Build Coastguard Worker 	return ret;
5682*58e6ee5fSAndroid Build Coastguard Worker }
5683*58e6ee5fSAndroid Build Coastguard Worker 
5684*58e6ee5fSAndroid Build Coastguard Worker static int
profile_add_event(struct buffer_instance * instance,const char * event_str,int stack)5685*58e6ee5fSAndroid Build Coastguard Worker profile_add_event(struct buffer_instance *instance, const char *event_str, int stack)
5686*58e6ee5fSAndroid Build Coastguard Worker {
5687*58e6ee5fSAndroid Build Coastguard Worker 	struct event_list *event;
5688*58e6ee5fSAndroid Build Coastguard Worker 	char buf[BUFSIZ];
5689*58e6ee5fSAndroid Build Coastguard Worker 	char *p;
5690*58e6ee5fSAndroid Build Coastguard Worker 
5691*58e6ee5fSAndroid Build Coastguard Worker 	strcpy(buf, "events/");
5692*58e6ee5fSAndroid Build Coastguard Worker 	strncpy(buf + 7, event_str, BUFSIZ - 7);
5693*58e6ee5fSAndroid Build Coastguard Worker 	buf[BUFSIZ-1] = 0;
5694*58e6ee5fSAndroid Build Coastguard Worker 
5695*58e6ee5fSAndroid Build Coastguard Worker 	if ((p = strstr(buf, ":"))) {
5696*58e6ee5fSAndroid Build Coastguard Worker 		*p = '/';
5697*58e6ee5fSAndroid Build Coastguard Worker 		p++;
5698*58e6ee5fSAndroid Build Coastguard Worker 	}
5699*58e6ee5fSAndroid Build Coastguard Worker 
5700*58e6ee5fSAndroid Build Coastguard Worker 	if (!trace_check_file_exists(instance, buf))
5701*58e6ee5fSAndroid Build Coastguard Worker 		return -1;
5702*58e6ee5fSAndroid Build Coastguard Worker 
5703*58e6ee5fSAndroid Build Coastguard Worker 	/* Only add event if it isn't already added */
5704*58e6ee5fSAndroid Build Coastguard Worker 	for (event = instance->events; event; event = event->next) {
5705*58e6ee5fSAndroid Build Coastguard Worker 		if (p && strcmp(event->event, p) == 0)
5706*58e6ee5fSAndroid Build Coastguard Worker 			break;
5707*58e6ee5fSAndroid Build Coastguard Worker 		if (strcmp(event->event, event_str) == 0)
5708*58e6ee5fSAndroid Build Coastguard Worker 			break;
5709*58e6ee5fSAndroid Build Coastguard Worker 	}
5710*58e6ee5fSAndroid Build Coastguard Worker 
5711*58e6ee5fSAndroid Build Coastguard Worker 	if (!event) {
5712*58e6ee5fSAndroid Build Coastguard Worker 		event = malloc(sizeof(*event));
5713*58e6ee5fSAndroid Build Coastguard Worker 		if (!event)
5714*58e6ee5fSAndroid Build Coastguard Worker 			die("Failed to allocate event");
5715*58e6ee5fSAndroid Build Coastguard Worker 		memset(event, 0, sizeof(*event));
5716*58e6ee5fSAndroid Build Coastguard Worker 		event->event = event_str;
5717*58e6ee5fSAndroid Build Coastguard Worker 		add_event(instance, event);
5718*58e6ee5fSAndroid Build Coastguard Worker 	}
5719*58e6ee5fSAndroid Build Coastguard Worker 
5720*58e6ee5fSAndroid Build Coastguard Worker 	if (!recording_all_events())
5721*58e6ee5fSAndroid Build Coastguard Worker 		list_event(event_str);
5722*58e6ee5fSAndroid Build Coastguard Worker 
5723*58e6ee5fSAndroid Build Coastguard Worker 	if (stack) {
5724*58e6ee5fSAndroid Build Coastguard Worker 		if (!event->trigger || !strstr(event->trigger, "stacktrace"))
5725*58e6ee5fSAndroid Build Coastguard Worker 			add_trigger(event, "stacktrace");
5726*58e6ee5fSAndroid Build Coastguard Worker 	}
5727*58e6ee5fSAndroid Build Coastguard Worker 
5728*58e6ee5fSAndroid Build Coastguard Worker 	return 0;
5729*58e6ee5fSAndroid Build Coastguard Worker }
5730*58e6ee5fSAndroid Build Coastguard Worker 
tracecmd_add_event(const char * event_str,int stack)5731*58e6ee5fSAndroid Build Coastguard Worker int tracecmd_add_event(const char *event_str, int stack)
5732*58e6ee5fSAndroid Build Coastguard Worker {
5733*58e6ee5fSAndroid Build Coastguard Worker 	return profile_add_event(first_instance, event_str, stack);
5734*58e6ee5fSAndroid Build Coastguard Worker }
5735*58e6ee5fSAndroid Build Coastguard Worker 
enable_profile(struct buffer_instance * instance)5736*58e6ee5fSAndroid Build Coastguard Worker static void enable_profile(struct buffer_instance *instance)
5737*58e6ee5fSAndroid Build Coastguard Worker {
5738*58e6ee5fSAndroid Build Coastguard Worker 	int stacktrace = 0;
5739*58e6ee5fSAndroid Build Coastguard Worker 	int i;
5740*58e6ee5fSAndroid Build Coastguard Worker 	char *trigger_events[] = {
5741*58e6ee5fSAndroid Build Coastguard Worker 		"sched:sched_switch",
5742*58e6ee5fSAndroid Build Coastguard Worker 		"sched:sched_wakeup",
5743*58e6ee5fSAndroid Build Coastguard Worker 		NULL,
5744*58e6ee5fSAndroid Build Coastguard Worker 	};
5745*58e6ee5fSAndroid Build Coastguard Worker 	char *events[] = {
5746*58e6ee5fSAndroid Build Coastguard Worker 		"exceptions:page_fault_user",
5747*58e6ee5fSAndroid Build Coastguard Worker 		"irq:irq_handler_entry",
5748*58e6ee5fSAndroid Build Coastguard Worker 		"irq:irq_handler_exit",
5749*58e6ee5fSAndroid Build Coastguard Worker 		"irq:softirq_entry",
5750*58e6ee5fSAndroid Build Coastguard Worker 		"irq:softirq_exit",
5751*58e6ee5fSAndroid Build Coastguard Worker 		"irq:softirq_raise",
5752*58e6ee5fSAndroid Build Coastguard Worker 		"sched:sched_process_exec",
5753*58e6ee5fSAndroid Build Coastguard Worker 		"raw_syscalls",
5754*58e6ee5fSAndroid Build Coastguard Worker 		NULL,
5755*58e6ee5fSAndroid Build Coastguard Worker 	};
5756*58e6ee5fSAndroid Build Coastguard Worker 
5757*58e6ee5fSAndroid Build Coastguard Worker 	if (!instance->plugin) {
5758*58e6ee5fSAndroid Build Coastguard Worker 		if (trace_check_file_exists(instance, "max_graph_depth")) {
5759*58e6ee5fSAndroid Build Coastguard Worker 			instance->plugin = "function_graph";
5760*58e6ee5fSAndroid Build Coastguard Worker 			set_max_graph_depth(instance, "1");
5761*58e6ee5fSAndroid Build Coastguard Worker 		} else
5762*58e6ee5fSAndroid Build Coastguard Worker 			warning("Kernel does not support max_graph_depth\n"
5763*58e6ee5fSAndroid Build Coastguard Worker 				" Skipping user/kernel profiling");
5764*58e6ee5fSAndroid Build Coastguard Worker 	}
5765*58e6ee5fSAndroid Build Coastguard Worker 
5766*58e6ee5fSAndroid Build Coastguard Worker 	if (test_stacktrace_trigger(instance))
5767*58e6ee5fSAndroid Build Coastguard Worker 		stacktrace = 1;
5768*58e6ee5fSAndroid Build Coastguard Worker 	else
5769*58e6ee5fSAndroid Build Coastguard Worker 		/*
5770*58e6ee5fSAndroid Build Coastguard Worker 		 * The stacktrace trigger is not implemented with this
5771*58e6ee5fSAndroid Build Coastguard Worker 		 * kernel, then we need to default to the stack trace option.
5772*58e6ee5fSAndroid Build Coastguard Worker 		 * This is less efficient but still works.
5773*58e6ee5fSAndroid Build Coastguard Worker 		 */
5774*58e6ee5fSAndroid Build Coastguard Worker 		save_option(instance, "stacktrace");
5775*58e6ee5fSAndroid Build Coastguard Worker 
5776*58e6ee5fSAndroid Build Coastguard Worker 
5777*58e6ee5fSAndroid Build Coastguard Worker 	for (i = 0; trigger_events[i]; i++)
5778*58e6ee5fSAndroid Build Coastguard Worker 		profile_add_event(instance, trigger_events[i], stacktrace);
5779*58e6ee5fSAndroid Build Coastguard Worker 
5780*58e6ee5fSAndroid Build Coastguard Worker 	for (i = 0; events[i]; i++)
5781*58e6ee5fSAndroid Build Coastguard Worker 		profile_add_event(instance, events[i], 0);
5782*58e6ee5fSAndroid Build Coastguard Worker }
5783*58e6ee5fSAndroid Build Coastguard Worker 
5784*58e6ee5fSAndroid Build Coastguard Worker static struct event_list *
create_hook_event(struct buffer_instance * instance,const char * system,const char * event)5785*58e6ee5fSAndroid Build Coastguard Worker create_hook_event(struct buffer_instance *instance,
5786*58e6ee5fSAndroid Build Coastguard Worker 		  const char *system, const char *event)
5787*58e6ee5fSAndroid Build Coastguard Worker {
5788*58e6ee5fSAndroid Build Coastguard Worker 	struct event_list *event_list;
5789*58e6ee5fSAndroid Build Coastguard Worker 	char *event_name;
5790*58e6ee5fSAndroid Build Coastguard Worker 	int len;
5791*58e6ee5fSAndroid Build Coastguard Worker 
5792*58e6ee5fSAndroid Build Coastguard Worker 	if (!system)
5793*58e6ee5fSAndroid Build Coastguard Worker 		system = "*";
5794*58e6ee5fSAndroid Build Coastguard Worker 
5795*58e6ee5fSAndroid Build Coastguard Worker 	len = strlen(event);
5796*58e6ee5fSAndroid Build Coastguard Worker 	len += strlen(system) + 2;
5797*58e6ee5fSAndroid Build Coastguard Worker 
5798*58e6ee5fSAndroid Build Coastguard Worker 	event_name = malloc(len);
5799*58e6ee5fSAndroid Build Coastguard Worker 	if (!event_name)
5800*58e6ee5fSAndroid Build Coastguard Worker 		die("Failed to allocate %s/%s", system, event);
5801*58e6ee5fSAndroid Build Coastguard Worker 	sprintf(event_name, "%s:%s", system, event);
5802*58e6ee5fSAndroid Build Coastguard Worker 
5803*58e6ee5fSAndroid Build Coastguard Worker 	event_list = malloc(sizeof(*event_list));
5804*58e6ee5fSAndroid Build Coastguard Worker 	if (!event_list)
5805*58e6ee5fSAndroid Build Coastguard Worker 		die("Failed to allocate event list for %s", event_name);
5806*58e6ee5fSAndroid Build Coastguard Worker 	memset(event_list, 0, sizeof(*event_list));
5807*58e6ee5fSAndroid Build Coastguard Worker 	event_list->event = event_name;
5808*58e6ee5fSAndroid Build Coastguard Worker 	add_event(instance, event_list);
5809*58e6ee5fSAndroid Build Coastguard Worker 
5810*58e6ee5fSAndroid Build Coastguard Worker 	list_event(event_name);
5811*58e6ee5fSAndroid Build Coastguard Worker 
5812*58e6ee5fSAndroid Build Coastguard Worker 	return event_list;
5813*58e6ee5fSAndroid Build Coastguard Worker }
5814*58e6ee5fSAndroid Build Coastguard Worker 
add_hook(struct buffer_instance * instance,const char * arg)5815*58e6ee5fSAndroid Build Coastguard Worker static void add_hook(struct buffer_instance *instance, const char *arg)
5816*58e6ee5fSAndroid Build Coastguard Worker {
5817*58e6ee5fSAndroid Build Coastguard Worker 	struct event_list *event;
5818*58e6ee5fSAndroid Build Coastguard Worker 	struct hook_list *hook;
5819*58e6ee5fSAndroid Build Coastguard Worker 
5820*58e6ee5fSAndroid Build Coastguard Worker 	hook = tracecmd_create_event_hook(arg);
5821*58e6ee5fSAndroid Build Coastguard Worker 	if (!hook)
5822*58e6ee5fSAndroid Build Coastguard Worker 		die("Failed to create event hook %s", arg);
5823*58e6ee5fSAndroid Build Coastguard Worker 
5824*58e6ee5fSAndroid Build Coastguard Worker 	hook->instance = instance;
5825*58e6ee5fSAndroid Build Coastguard Worker 	hook->next = hooks;
5826*58e6ee5fSAndroid Build Coastguard Worker 	hooks = hook;
5827*58e6ee5fSAndroid Build Coastguard Worker 
5828*58e6ee5fSAndroid Build Coastguard Worker 	/* Make sure the event is enabled */
5829*58e6ee5fSAndroid Build Coastguard Worker 	event = create_hook_event(instance, hook->start_system, hook->start_event);
5830*58e6ee5fSAndroid Build Coastguard Worker 	create_hook_event(instance, hook->end_system, hook->end_event);
5831*58e6ee5fSAndroid Build Coastguard Worker 
5832*58e6ee5fSAndroid Build Coastguard Worker 	if (hook->stack) {
5833*58e6ee5fSAndroid Build Coastguard Worker 		if (!event->trigger || !strstr(event->trigger, "stacktrace"))
5834*58e6ee5fSAndroid Build Coastguard Worker 			add_trigger(event, "stacktrace");
5835*58e6ee5fSAndroid Build Coastguard Worker 	}
5836*58e6ee5fSAndroid Build Coastguard Worker }
5837*58e6ee5fSAndroid Build Coastguard Worker 
update_first_instance(struct buffer_instance * instance,int topt)5838*58e6ee5fSAndroid Build Coastguard Worker void update_first_instance(struct buffer_instance *instance, int topt)
5839*58e6ee5fSAndroid Build Coastguard Worker {
5840*58e6ee5fSAndroid Build Coastguard Worker 	if (topt || instance == &top_instance)
5841*58e6ee5fSAndroid Build Coastguard Worker 		first_instance = &top_instance;
5842*58e6ee5fSAndroid Build Coastguard Worker 	else
5843*58e6ee5fSAndroid Build Coastguard Worker 		first_instance = buffer_instances;
5844*58e6ee5fSAndroid Build Coastguard Worker }
5845*58e6ee5fSAndroid Build Coastguard Worker 
init_top_instance(void)5846*58e6ee5fSAndroid Build Coastguard Worker void init_top_instance(void)
5847*58e6ee5fSAndroid Build Coastguard Worker {
5848*58e6ee5fSAndroid Build Coastguard Worker 	if (!top_instance.tracefs)
5849*58e6ee5fSAndroid Build Coastguard Worker 		top_instance.tracefs = tracefs_instance_create(NULL);
5850*58e6ee5fSAndroid Build Coastguard Worker 	top_instance.cpu_count = tracecmd_count_cpus();
5851*58e6ee5fSAndroid Build Coastguard Worker 	top_instance.flags = BUFFER_FL_KEEP;
5852*58e6ee5fSAndroid Build Coastguard Worker 	top_instance.trace_id = tracecmd_generate_traceid();
5853*58e6ee5fSAndroid Build Coastguard Worker 	init_instance(&top_instance);
5854*58e6ee5fSAndroid Build Coastguard Worker }
5855*58e6ee5fSAndroid Build Coastguard Worker 
5856*58e6ee5fSAndroid Build Coastguard Worker enum {
5857*58e6ee5fSAndroid Build Coastguard Worker 	OPT_compression		= 237,
5858*58e6ee5fSAndroid Build Coastguard Worker 	OPT_file_ver		= 238,
5859*58e6ee5fSAndroid Build Coastguard Worker 	OPT_verbose		= 239,
5860*58e6ee5fSAndroid Build Coastguard Worker 	OPT_tsc2nsec		= 240,
5861*58e6ee5fSAndroid Build Coastguard Worker 	OPT_fork		= 241,
5862*58e6ee5fSAndroid Build Coastguard Worker 	OPT_tsyncinterval	= 242,
5863*58e6ee5fSAndroid Build Coastguard Worker 	OPT_user		= 243,
5864*58e6ee5fSAndroid Build Coastguard Worker 	OPT_procmap		= 244,
5865*58e6ee5fSAndroid Build Coastguard Worker 	OPT_quiet		= 245,
5866*58e6ee5fSAndroid Build Coastguard Worker 	OPT_debug		= 246,
5867*58e6ee5fSAndroid Build Coastguard Worker 	OPT_no_filter		= 247,
5868*58e6ee5fSAndroid Build Coastguard Worker 	OPT_max_graph_depth	= 248,
5869*58e6ee5fSAndroid Build Coastguard Worker 	OPT_tsoffset		= 249,
5870*58e6ee5fSAndroid Build Coastguard Worker 	OPT_bycomm		= 250,
5871*58e6ee5fSAndroid Build Coastguard Worker 	OPT_stderr		= 251,
5872*58e6ee5fSAndroid Build Coastguard Worker 	OPT_profile		= 252,
5873*58e6ee5fSAndroid Build Coastguard Worker 	OPT_nosplice		= 253,
5874*58e6ee5fSAndroid Build Coastguard Worker 	OPT_funcstack		= 254,
5875*58e6ee5fSAndroid Build Coastguard Worker 	OPT_date		= 255,
5876*58e6ee5fSAndroid Build Coastguard Worker 	OPT_module		= 256,
5877*58e6ee5fSAndroid Build Coastguard Worker 	OPT_nofifos		= 257,
5878*58e6ee5fSAndroid Build Coastguard Worker 	OPT_cmdlines_size	= 258,
5879*58e6ee5fSAndroid Build Coastguard Worker 	OPT_poll		= 259,
5880*58e6ee5fSAndroid Build Coastguard Worker 	OPT_name		= 260,
5881*58e6ee5fSAndroid Build Coastguard Worker };
5882*58e6ee5fSAndroid Build Coastguard Worker 
trace_stop(int argc,char ** argv)5883*58e6ee5fSAndroid Build Coastguard Worker void trace_stop(int argc, char **argv)
5884*58e6ee5fSAndroid Build Coastguard Worker {
5885*58e6ee5fSAndroid Build Coastguard Worker 	int topt = 0;
5886*58e6ee5fSAndroid Build Coastguard Worker 	struct buffer_instance *instance = &top_instance;
5887*58e6ee5fSAndroid Build Coastguard Worker 
5888*58e6ee5fSAndroid Build Coastguard Worker 	init_top_instance();
5889*58e6ee5fSAndroid Build Coastguard Worker 
5890*58e6ee5fSAndroid Build Coastguard Worker 	for (;;) {
5891*58e6ee5fSAndroid Build Coastguard Worker 		int c;
5892*58e6ee5fSAndroid Build Coastguard Worker 
5893*58e6ee5fSAndroid Build Coastguard Worker 		c = getopt(argc-1, argv+1, "hatB:");
5894*58e6ee5fSAndroid Build Coastguard Worker 		if (c == -1)
5895*58e6ee5fSAndroid Build Coastguard Worker 			break;
5896*58e6ee5fSAndroid Build Coastguard Worker 
5897*58e6ee5fSAndroid Build Coastguard Worker 		switch (c) {
5898*58e6ee5fSAndroid Build Coastguard Worker 		case 'h':
5899*58e6ee5fSAndroid Build Coastguard Worker 			usage(argv);
5900*58e6ee5fSAndroid Build Coastguard Worker 			break;
5901*58e6ee5fSAndroid Build Coastguard Worker 		case 'B':
5902*58e6ee5fSAndroid Build Coastguard Worker 			instance = allocate_instance(optarg);
5903*58e6ee5fSAndroid Build Coastguard Worker 			if (!instance)
5904*58e6ee5fSAndroid Build Coastguard Worker 				die("Failed to create instance");
5905*58e6ee5fSAndroid Build Coastguard Worker 			add_instance(instance, local_cpu_count);
5906*58e6ee5fSAndroid Build Coastguard Worker 			break;
5907*58e6ee5fSAndroid Build Coastguard Worker 		case 'a':
5908*58e6ee5fSAndroid Build Coastguard Worker 			add_all_instances();
5909*58e6ee5fSAndroid Build Coastguard Worker 			break;
5910*58e6ee5fSAndroid Build Coastguard Worker 		case 't':
5911*58e6ee5fSAndroid Build Coastguard Worker 			/* Force to use top instance */
5912*58e6ee5fSAndroid Build Coastguard Worker 			topt = 1;
5913*58e6ee5fSAndroid Build Coastguard Worker 			instance = &top_instance;
5914*58e6ee5fSAndroid Build Coastguard Worker 			break;
5915*58e6ee5fSAndroid Build Coastguard Worker 		default:
5916*58e6ee5fSAndroid Build Coastguard Worker 			usage(argv);
5917*58e6ee5fSAndroid Build Coastguard Worker 		}
5918*58e6ee5fSAndroid Build Coastguard Worker 	}
5919*58e6ee5fSAndroid Build Coastguard Worker 	update_first_instance(instance, topt);
5920*58e6ee5fSAndroid Build Coastguard Worker 	tracecmd_disable_tracing();
5921*58e6ee5fSAndroid Build Coastguard Worker 	exit(0);
5922*58e6ee5fSAndroid Build Coastguard Worker }
5923*58e6ee5fSAndroid Build Coastguard Worker 
trace_restart(int argc,char ** argv)5924*58e6ee5fSAndroid Build Coastguard Worker void trace_restart(int argc, char **argv)
5925*58e6ee5fSAndroid Build Coastguard Worker {
5926*58e6ee5fSAndroid Build Coastguard Worker 	int topt = 0;
5927*58e6ee5fSAndroid Build Coastguard Worker 	struct buffer_instance *instance = &top_instance;
5928*58e6ee5fSAndroid Build Coastguard Worker 
5929*58e6ee5fSAndroid Build Coastguard Worker 	init_top_instance();
5930*58e6ee5fSAndroid Build Coastguard Worker 
5931*58e6ee5fSAndroid Build Coastguard Worker 	for (;;) {
5932*58e6ee5fSAndroid Build Coastguard Worker 		int c;
5933*58e6ee5fSAndroid Build Coastguard Worker 
5934*58e6ee5fSAndroid Build Coastguard Worker 		c = getopt(argc-1, argv+1, "hatB:");
5935*58e6ee5fSAndroid Build Coastguard Worker 		if (c == -1)
5936*58e6ee5fSAndroid Build Coastguard Worker 			break;
5937*58e6ee5fSAndroid Build Coastguard Worker 		switch (c) {
5938*58e6ee5fSAndroid Build Coastguard Worker 		case 'h':
5939*58e6ee5fSAndroid Build Coastguard Worker 			usage(argv);
5940*58e6ee5fSAndroid Build Coastguard Worker 			break;
5941*58e6ee5fSAndroid Build Coastguard Worker 		case 'B':
5942*58e6ee5fSAndroid Build Coastguard Worker 			instance = allocate_instance(optarg);
5943*58e6ee5fSAndroid Build Coastguard Worker 			if (!instance)
5944*58e6ee5fSAndroid Build Coastguard Worker 				die("Failed to create instance");
5945*58e6ee5fSAndroid Build Coastguard Worker 			add_instance(instance, local_cpu_count);
5946*58e6ee5fSAndroid Build Coastguard Worker 			break;
5947*58e6ee5fSAndroid Build Coastguard Worker 		case 'a':
5948*58e6ee5fSAndroid Build Coastguard Worker 			add_all_instances();
5949*58e6ee5fSAndroid Build Coastguard Worker 			break;
5950*58e6ee5fSAndroid Build Coastguard Worker 		case 't':
5951*58e6ee5fSAndroid Build Coastguard Worker 			/* Force to use top instance */
5952*58e6ee5fSAndroid Build Coastguard Worker 			topt = 1;
5953*58e6ee5fSAndroid Build Coastguard Worker 			instance = &top_instance;
5954*58e6ee5fSAndroid Build Coastguard Worker 			break;
5955*58e6ee5fSAndroid Build Coastguard Worker 		default:
5956*58e6ee5fSAndroid Build Coastguard Worker 			usage(argv);
5957*58e6ee5fSAndroid Build Coastguard Worker 		}
5958*58e6ee5fSAndroid Build Coastguard Worker 
5959*58e6ee5fSAndroid Build Coastguard Worker 	}
5960*58e6ee5fSAndroid Build Coastguard Worker 	update_first_instance(instance, topt);
5961*58e6ee5fSAndroid Build Coastguard Worker 	tracecmd_enable_tracing();
5962*58e6ee5fSAndroid Build Coastguard Worker 	exit(0);
5963*58e6ee5fSAndroid Build Coastguard Worker }
5964*58e6ee5fSAndroid Build Coastguard Worker 
trace_reset(int argc,char ** argv)5965*58e6ee5fSAndroid Build Coastguard Worker void trace_reset(int argc, char **argv)
5966*58e6ee5fSAndroid Build Coastguard Worker {
5967*58e6ee5fSAndroid Build Coastguard Worker 	int c;
5968*58e6ee5fSAndroid Build Coastguard Worker 	int topt = 0;
5969*58e6ee5fSAndroid Build Coastguard Worker 	struct buffer_instance *instance = &top_instance;
5970*58e6ee5fSAndroid Build Coastguard Worker 
5971*58e6ee5fSAndroid Build Coastguard Worker 	init_top_instance();
5972*58e6ee5fSAndroid Build Coastguard Worker 
5973*58e6ee5fSAndroid Build Coastguard Worker 	/* if last arg is -a, then -b and -d apply to all instances */
5974*58e6ee5fSAndroid Build Coastguard Worker 	int last_specified_all = 0;
5975*58e6ee5fSAndroid Build Coastguard Worker 	struct buffer_instance *inst; /* iterator */
5976*58e6ee5fSAndroid Build Coastguard Worker 
5977*58e6ee5fSAndroid Build Coastguard Worker 	while ((c = getopt(argc-1, argv+1, "hab:B:td")) >= 0) {
5978*58e6ee5fSAndroid Build Coastguard Worker 
5979*58e6ee5fSAndroid Build Coastguard Worker 		switch (c) {
5980*58e6ee5fSAndroid Build Coastguard Worker 		case 'h':
5981*58e6ee5fSAndroid Build Coastguard Worker 			usage(argv);
5982*58e6ee5fSAndroid Build Coastguard Worker 			break;
5983*58e6ee5fSAndroid Build Coastguard Worker 		case 'b':
5984*58e6ee5fSAndroid Build Coastguard Worker 		{
5985*58e6ee5fSAndroid Build Coastguard Worker 			int size = atoi(optarg);
5986*58e6ee5fSAndroid Build Coastguard Worker 			/* Min buffer size is 1 */
5987*58e6ee5fSAndroid Build Coastguard Worker 			if (size <= 1)
5988*58e6ee5fSAndroid Build Coastguard Worker 				size = 1;
5989*58e6ee5fSAndroid Build Coastguard Worker 			if (last_specified_all) {
5990*58e6ee5fSAndroid Build Coastguard Worker 				for_each_instance(inst) {
5991*58e6ee5fSAndroid Build Coastguard Worker 					inst->buffer_size = size;
5992*58e6ee5fSAndroid Build Coastguard Worker 				}
5993*58e6ee5fSAndroid Build Coastguard Worker 			} else {
5994*58e6ee5fSAndroid Build Coastguard Worker 				instance->buffer_size = size;
5995*58e6ee5fSAndroid Build Coastguard Worker 			}
5996*58e6ee5fSAndroid Build Coastguard Worker 			break;
5997*58e6ee5fSAndroid Build Coastguard Worker 		}
5998*58e6ee5fSAndroid Build Coastguard Worker 		case 'B':
5999*58e6ee5fSAndroid Build Coastguard Worker 			last_specified_all = 0;
6000*58e6ee5fSAndroid Build Coastguard Worker 			instance = allocate_instance(optarg);
6001*58e6ee5fSAndroid Build Coastguard Worker 			if (!instance)
6002*58e6ee5fSAndroid Build Coastguard Worker 				die("Failed to create instance");
6003*58e6ee5fSAndroid Build Coastguard Worker 			add_instance(instance, local_cpu_count);
6004*58e6ee5fSAndroid Build Coastguard Worker 			/* -d will remove keep */
6005*58e6ee5fSAndroid Build Coastguard Worker 			instance->flags |= BUFFER_FL_KEEP;
6006*58e6ee5fSAndroid Build Coastguard Worker 			break;
6007*58e6ee5fSAndroid Build Coastguard Worker 		case 't':
6008*58e6ee5fSAndroid Build Coastguard Worker 			/* Force to use top instance */
6009*58e6ee5fSAndroid Build Coastguard Worker 			last_specified_all = 0;
6010*58e6ee5fSAndroid Build Coastguard Worker 			topt = 1;
6011*58e6ee5fSAndroid Build Coastguard Worker 			instance = &top_instance;
6012*58e6ee5fSAndroid Build Coastguard Worker 			break;
6013*58e6ee5fSAndroid Build Coastguard Worker 		case 'a':
6014*58e6ee5fSAndroid Build Coastguard Worker 			last_specified_all = 1;
6015*58e6ee5fSAndroid Build Coastguard Worker 			add_all_instances();
6016*58e6ee5fSAndroid Build Coastguard Worker 			for_each_instance(inst) {
6017*58e6ee5fSAndroid Build Coastguard Worker 				inst->flags |= BUFFER_FL_KEEP;
6018*58e6ee5fSAndroid Build Coastguard Worker 			}
6019*58e6ee5fSAndroid Build Coastguard Worker 			break;
6020*58e6ee5fSAndroid Build Coastguard Worker 		case 'd':
6021*58e6ee5fSAndroid Build Coastguard Worker 			if (last_specified_all) {
6022*58e6ee5fSAndroid Build Coastguard Worker 				for_each_instance(inst) {
6023*58e6ee5fSAndroid Build Coastguard Worker 					inst->flags &= ~BUFFER_FL_KEEP;
6024*58e6ee5fSAndroid Build Coastguard Worker 				}
6025*58e6ee5fSAndroid Build Coastguard Worker 			} else {
6026*58e6ee5fSAndroid Build Coastguard Worker 				if (is_top_instance(instance))
6027*58e6ee5fSAndroid Build Coastguard Worker 					die("Can not delete top level buffer");
6028*58e6ee5fSAndroid Build Coastguard Worker 				instance->flags &= ~BUFFER_FL_KEEP;
6029*58e6ee5fSAndroid Build Coastguard Worker 			}
6030*58e6ee5fSAndroid Build Coastguard Worker 			break;
6031*58e6ee5fSAndroid Build Coastguard Worker 		}
6032*58e6ee5fSAndroid Build Coastguard Worker 	}
6033*58e6ee5fSAndroid Build Coastguard Worker 	update_first_instance(instance, topt);
6034*58e6ee5fSAndroid Build Coastguard Worker 	tracecmd_disable_all_tracing(1);
6035*58e6ee5fSAndroid Build Coastguard Worker 	set_buffer_size();
6036*58e6ee5fSAndroid Build Coastguard Worker 	clear_filters();
6037*58e6ee5fSAndroid Build Coastguard Worker 	clear_triggers();
6038*58e6ee5fSAndroid Build Coastguard Worker 	clear_all_dynamic_events();
6039*58e6ee5fSAndroid Build Coastguard Worker 	clear_error_log();
6040*58e6ee5fSAndroid Build Coastguard Worker 	/* set clock to "local" */
6041*58e6ee5fSAndroid Build Coastguard Worker 	reset_clock();
6042*58e6ee5fSAndroid Build Coastguard Worker 	reset_event_pid();
6043*58e6ee5fSAndroid Build Coastguard Worker 	reset_max_latency_instance();
6044*58e6ee5fSAndroid Build Coastguard Worker 	reset_cpu_mask();
6045*58e6ee5fSAndroid Build Coastguard Worker 	tracecmd_remove_instances();
6046*58e6ee5fSAndroid Build Coastguard Worker 	clear_func_filters();
6047*58e6ee5fSAndroid Build Coastguard Worker 	/* restore tracing_on to 1 */
6048*58e6ee5fSAndroid Build Coastguard Worker 	tracecmd_enable_tracing();
6049*58e6ee5fSAndroid Build Coastguard Worker 	exit(0);
6050*58e6ee5fSAndroid Build Coastguard Worker }
6051*58e6ee5fSAndroid Build Coastguard Worker 
init_common_record_context(struct common_record_context * ctx,enum trace_cmd curr_cmd)6052*58e6ee5fSAndroid Build Coastguard Worker static void init_common_record_context(struct common_record_context *ctx,
6053*58e6ee5fSAndroid Build Coastguard Worker 				       enum trace_cmd curr_cmd)
6054*58e6ee5fSAndroid Build Coastguard Worker {
6055*58e6ee5fSAndroid Build Coastguard Worker 	memset(ctx, 0, sizeof(*ctx));
6056*58e6ee5fSAndroid Build Coastguard Worker 	ctx->instance = &top_instance;
6057*58e6ee5fSAndroid Build Coastguard Worker 	ctx->curr_cmd = curr_cmd;
6058*58e6ee5fSAndroid Build Coastguard Worker 	local_cpu_count = tracecmd_count_cpus();
6059*58e6ee5fSAndroid Build Coastguard Worker 	ctx->file_version = tracecmd_default_file_version();
6060*58e6ee5fSAndroid Build Coastguard Worker 	init_top_instance();
6061*58e6ee5fSAndroid Build Coastguard Worker }
6062*58e6ee5fSAndroid Build Coastguard Worker 
6063*58e6ee5fSAndroid Build Coastguard Worker #define IS_EXTRACT(ctx) ((ctx)->curr_cmd == CMD_extract)
6064*58e6ee5fSAndroid Build Coastguard Worker #define IS_START(ctx) ((ctx)->curr_cmd == CMD_start)
6065*58e6ee5fSAndroid Build Coastguard Worker #define IS_CMDSET(ctx) ((ctx)->curr_cmd == CMD_set)
6066*58e6ee5fSAndroid Build Coastguard Worker #define IS_STREAM(ctx) ((ctx)->curr_cmd == CMD_stream)
6067*58e6ee5fSAndroid Build Coastguard Worker #define IS_PROFILE(ctx) ((ctx)->curr_cmd == CMD_profile)
6068*58e6ee5fSAndroid Build Coastguard Worker #define IS_RECORD(ctx) ((ctx)->curr_cmd == CMD_record)
6069*58e6ee5fSAndroid Build Coastguard Worker #define IS_RECORD_AGENT(ctx) ((ctx)->curr_cmd == CMD_record_agent)
6070*58e6ee5fSAndroid Build Coastguard Worker 
add_argv(struct buffer_instance * instance,char * arg,bool prepend)6071*58e6ee5fSAndroid Build Coastguard Worker static void add_argv(struct buffer_instance *instance, char *arg, bool prepend)
6072*58e6ee5fSAndroid Build Coastguard Worker {
6073*58e6ee5fSAndroid Build Coastguard Worker 	instance->argv = realloc(instance->argv,
6074*58e6ee5fSAndroid Build Coastguard Worker 				 (instance->argc + 1) * sizeof(char *));
6075*58e6ee5fSAndroid Build Coastguard Worker 	if (!instance->argv)
6076*58e6ee5fSAndroid Build Coastguard Worker 		die("Can not allocate instance args");
6077*58e6ee5fSAndroid Build Coastguard Worker 	if (prepend) {
6078*58e6ee5fSAndroid Build Coastguard Worker 		memmove(instance->argv + 1, instance->argv,
6079*58e6ee5fSAndroid Build Coastguard Worker 			instance->argc * sizeof(*instance->argv));
6080*58e6ee5fSAndroid Build Coastguard Worker 		instance->argv[0] = arg;
6081*58e6ee5fSAndroid Build Coastguard Worker 	} else {
6082*58e6ee5fSAndroid Build Coastguard Worker 		instance->argv[instance->argc] = arg;
6083*58e6ee5fSAndroid Build Coastguard Worker 	}
6084*58e6ee5fSAndroid Build Coastguard Worker 	instance->argc++;
6085*58e6ee5fSAndroid Build Coastguard Worker }
6086*58e6ee5fSAndroid Build Coastguard Worker 
add_arg(struct buffer_instance * instance,int c,const char * opts,struct option * long_options,char * optarg)6087*58e6ee5fSAndroid Build Coastguard Worker static void add_arg(struct buffer_instance *instance,
6088*58e6ee5fSAndroid Build Coastguard Worker 		    int c, const char *opts,
6089*58e6ee5fSAndroid Build Coastguard Worker 		    struct option *long_options, char *optarg)
6090*58e6ee5fSAndroid Build Coastguard Worker {
6091*58e6ee5fSAndroid Build Coastguard Worker 	char *ptr, *arg;
6092*58e6ee5fSAndroid Build Coastguard Worker 	int i, ret;
6093*58e6ee5fSAndroid Build Coastguard Worker 
6094*58e6ee5fSAndroid Build Coastguard Worker 	/* Short or long arg */
6095*58e6ee5fSAndroid Build Coastguard Worker 	if (!(c & 0x80)) {
6096*58e6ee5fSAndroid Build Coastguard Worker 		ptr = strchr(opts, c);
6097*58e6ee5fSAndroid Build Coastguard Worker 		if (!ptr)
6098*58e6ee5fSAndroid Build Coastguard Worker 			return; /* Not found? */
6099*58e6ee5fSAndroid Build Coastguard Worker 		ret = asprintf(&arg, "-%c", c);
6100*58e6ee5fSAndroid Build Coastguard Worker 		if (ret < 0)
6101*58e6ee5fSAndroid Build Coastguard Worker 			die("Can not allocate argument");
6102*58e6ee5fSAndroid Build Coastguard Worker 		add_argv(instance, arg, false);
6103*58e6ee5fSAndroid Build Coastguard Worker 		if (ptr[1] == ':') {
6104*58e6ee5fSAndroid Build Coastguard Worker 			arg = strdup(optarg);
6105*58e6ee5fSAndroid Build Coastguard Worker 			if (!arg)
6106*58e6ee5fSAndroid Build Coastguard Worker 				die("Can not allocate arguments");
6107*58e6ee5fSAndroid Build Coastguard Worker 			add_argv(instance, arg, false);
6108*58e6ee5fSAndroid Build Coastguard Worker 		}
6109*58e6ee5fSAndroid Build Coastguard Worker 		return;
6110*58e6ee5fSAndroid Build Coastguard Worker 	}
6111*58e6ee5fSAndroid Build Coastguard Worker 	for (i = 0; long_options[i].name; i++) {
6112*58e6ee5fSAndroid Build Coastguard Worker 		if (c != long_options[i].val)
6113*58e6ee5fSAndroid Build Coastguard Worker 			continue;
6114*58e6ee5fSAndroid Build Coastguard Worker 		ret = asprintf(&arg, "--%s", long_options[i].name);
6115*58e6ee5fSAndroid Build Coastguard Worker 		if (ret < 0)
6116*58e6ee5fSAndroid Build Coastguard Worker 			die("Can not allocate argument");
6117*58e6ee5fSAndroid Build Coastguard Worker 		add_argv(instance, arg, false);
6118*58e6ee5fSAndroid Build Coastguard Worker 		if (long_options[i].has_arg) {
6119*58e6ee5fSAndroid Build Coastguard Worker 			arg = strdup(optarg);
6120*58e6ee5fSAndroid Build Coastguard Worker 			if (!arg)
6121*58e6ee5fSAndroid Build Coastguard Worker 				die("Can not allocate arguments");
6122*58e6ee5fSAndroid Build Coastguard Worker 			add_argv(instance, arg, false);
6123*58e6ee5fSAndroid Build Coastguard Worker 		}
6124*58e6ee5fSAndroid Build Coastguard Worker 		return;
6125*58e6ee5fSAndroid Build Coastguard Worker 	}
6126*58e6ee5fSAndroid Build Coastguard Worker 	/* Not found? */
6127*58e6ee5fSAndroid Build Coastguard Worker }
6128*58e6ee5fSAndroid Build Coastguard Worker 
cmd_check_die(struct common_record_context * ctx,enum trace_cmd id,char * cmd,char * param)6129*58e6ee5fSAndroid Build Coastguard Worker static inline void cmd_check_die(struct common_record_context *ctx,
6130*58e6ee5fSAndroid Build Coastguard Worker 				 enum trace_cmd id, char *cmd, char *param)
6131*58e6ee5fSAndroid Build Coastguard Worker {
6132*58e6ee5fSAndroid Build Coastguard Worker 	if (ctx->curr_cmd == id)
6133*58e6ee5fSAndroid Build Coastguard Worker 		die("%s has no effect with the command %s\n"
6134*58e6ee5fSAndroid Build Coastguard Worker 		    "Did you mean 'record'?", param, cmd);
6135*58e6ee5fSAndroid Build Coastguard Worker }
6136*58e6ee5fSAndroid Build Coastguard Worker 
remove_instances(struct buffer_instance * instances)6137*58e6ee5fSAndroid Build Coastguard Worker static inline void remove_instances(struct buffer_instance *instances)
6138*58e6ee5fSAndroid Build Coastguard Worker {
6139*58e6ee5fSAndroid Build Coastguard Worker 	struct buffer_instance *del;
6140*58e6ee5fSAndroid Build Coastguard Worker 
6141*58e6ee5fSAndroid Build Coastguard Worker 	while (instances) {
6142*58e6ee5fSAndroid Build Coastguard Worker 		del = instances;
6143*58e6ee5fSAndroid Build Coastguard Worker 		instances = instances->next;
6144*58e6ee5fSAndroid Build Coastguard Worker 		free(del->name);
6145*58e6ee5fSAndroid Build Coastguard Worker 		tracefs_instance_destroy(del->tracefs);
6146*58e6ee5fSAndroid Build Coastguard Worker 		tracefs_instance_free(del->tracefs);
6147*58e6ee5fSAndroid Build Coastguard Worker 		free(del);
6148*58e6ee5fSAndroid Build Coastguard Worker 	}
6149*58e6ee5fSAndroid Build Coastguard Worker }
6150*58e6ee5fSAndroid Build Coastguard Worker 
6151*58e6ee5fSAndroid Build Coastguard Worker static inline void
check_instance_die(struct buffer_instance * instance,char * param)6152*58e6ee5fSAndroid Build Coastguard Worker check_instance_die(struct buffer_instance *instance, char *param)
6153*58e6ee5fSAndroid Build Coastguard Worker {
6154*58e6ee5fSAndroid Build Coastguard Worker 	if (instance->delete)
6155*58e6ee5fSAndroid Build Coastguard Worker 		die("Instance %s is marked for deletion, invalid option %s",
6156*58e6ee5fSAndroid Build Coastguard Worker 		    tracefs_instance_get_name(instance->tracefs), param);
6157*58e6ee5fSAndroid Build Coastguard Worker }
6158*58e6ee5fSAndroid Build Coastguard Worker 
clock_is_supported(struct tracefs_instance * instance,const char * clock)6159*58e6ee5fSAndroid Build Coastguard Worker static bool clock_is_supported(struct tracefs_instance *instance, const char *clock)
6160*58e6ee5fSAndroid Build Coastguard Worker {
6161*58e6ee5fSAndroid Build Coastguard Worker 	char *all_clocks = NULL;
6162*58e6ee5fSAndroid Build Coastguard Worker 	char *ret = NULL;
6163*58e6ee5fSAndroid Build Coastguard Worker 
6164*58e6ee5fSAndroid Build Coastguard Worker 	all_clocks  = tracefs_instance_file_read(instance, "trace_clock", NULL);
6165*58e6ee5fSAndroid Build Coastguard Worker 	if (!all_clocks)
6166*58e6ee5fSAndroid Build Coastguard Worker 		return false;
6167*58e6ee5fSAndroid Build Coastguard Worker 
6168*58e6ee5fSAndroid Build Coastguard Worker 	ret = strstr(all_clocks, clock);
6169*58e6ee5fSAndroid Build Coastguard Worker 	if (ret && (ret == all_clocks || ret[-1] == ' ' || ret[-1] == '[')) {
6170*58e6ee5fSAndroid Build Coastguard Worker 		switch (ret[strlen(clock)]) {
6171*58e6ee5fSAndroid Build Coastguard Worker 		case ' ':
6172*58e6ee5fSAndroid Build Coastguard Worker 		case '\0':
6173*58e6ee5fSAndroid Build Coastguard Worker 		case ']':
6174*58e6ee5fSAndroid Build Coastguard Worker 		case '\n':
6175*58e6ee5fSAndroid Build Coastguard Worker 			break;
6176*58e6ee5fSAndroid Build Coastguard Worker 		default:
6177*58e6ee5fSAndroid Build Coastguard Worker 			ret = NULL;
6178*58e6ee5fSAndroid Build Coastguard Worker 		}
6179*58e6ee5fSAndroid Build Coastguard Worker 	} else {
6180*58e6ee5fSAndroid Build Coastguard Worker 		ret = NULL;
6181*58e6ee5fSAndroid Build Coastguard Worker 	}
6182*58e6ee5fSAndroid Build Coastguard Worker 	free(all_clocks);
6183*58e6ee5fSAndroid Build Coastguard Worker 
6184*58e6ee5fSAndroid Build Coastguard Worker 	return ret != NULL;
6185*58e6ee5fSAndroid Build Coastguard Worker }
6186*58e6ee5fSAndroid Build Coastguard Worker 
6187*58e6ee5fSAndroid Build Coastguard Worker #ifdef PERF
get_tsc_nsec(int * shift,int * mult)6188*58e6ee5fSAndroid Build Coastguard Worker static int get_tsc_nsec(int *shift, int *mult)
6189*58e6ee5fSAndroid Build Coastguard Worker {
6190*58e6ee5fSAndroid Build Coastguard Worker 	static int cpu_shift, cpu_mult;
6191*58e6ee5fSAndroid Build Coastguard Worker 	static int supported;
6192*58e6ee5fSAndroid Build Coastguard Worker 	int cpus = tracecmd_count_cpus();
6193*58e6ee5fSAndroid Build Coastguard Worker 	struct trace_perf perf;
6194*58e6ee5fSAndroid Build Coastguard Worker 	int i;
6195*58e6ee5fSAndroid Build Coastguard Worker 
6196*58e6ee5fSAndroid Build Coastguard Worker 	if (supported)
6197*58e6ee5fSAndroid Build Coastguard Worker 		goto out;
6198*58e6ee5fSAndroid Build Coastguard Worker 
6199*58e6ee5fSAndroid Build Coastguard Worker 	supported = -1;
6200*58e6ee5fSAndroid Build Coastguard Worker 	if (trace_perf_init(&perf, 1, 0, getpid()))
6201*58e6ee5fSAndroid Build Coastguard Worker 		return -1;
6202*58e6ee5fSAndroid Build Coastguard Worker 	if (trace_perf_open(&perf))
6203*58e6ee5fSAndroid Build Coastguard Worker 		return -1;
6204*58e6ee5fSAndroid Build Coastguard Worker 	cpu_shift = perf.mmap->time_shift;
6205*58e6ee5fSAndroid Build Coastguard Worker 	cpu_mult = perf.mmap->time_mult;
6206*58e6ee5fSAndroid Build Coastguard Worker 	for (i = 1; i < cpus; i++) {
6207*58e6ee5fSAndroid Build Coastguard Worker 		trace_perf_close(&perf);
6208*58e6ee5fSAndroid Build Coastguard Worker 		if (trace_perf_init(&perf, 1, i, getpid()))
6209*58e6ee5fSAndroid Build Coastguard Worker 			break;
6210*58e6ee5fSAndroid Build Coastguard Worker 		if (trace_perf_open(&perf))
6211*58e6ee5fSAndroid Build Coastguard Worker 			break;
6212*58e6ee5fSAndroid Build Coastguard Worker 		if (perf.mmap->time_shift != cpu_shift ||
6213*58e6ee5fSAndroid Build Coastguard Worker 		    perf.mmap->time_mult != cpu_mult) {
6214*58e6ee5fSAndroid Build Coastguard Worker 			warning("Found different TSC multiplier and shift for CPU %d: %d;%d instead of %d;%d",
6215*58e6ee5fSAndroid Build Coastguard Worker 				i, perf.mmap->time_mult, perf.mmap->time_shift, cpu_mult, cpu_shift);
6216*58e6ee5fSAndroid Build Coastguard Worker 			break;
6217*58e6ee5fSAndroid Build Coastguard Worker 		}
6218*58e6ee5fSAndroid Build Coastguard Worker 	}
6219*58e6ee5fSAndroid Build Coastguard Worker 	trace_perf_close(&perf);
6220*58e6ee5fSAndroid Build Coastguard Worker 	if (i < cpus)
6221*58e6ee5fSAndroid Build Coastguard Worker 		return -1;
6222*58e6ee5fSAndroid Build Coastguard Worker 
6223*58e6ee5fSAndroid Build Coastguard Worker 	if (cpu_shift || cpu_mult)
6224*58e6ee5fSAndroid Build Coastguard Worker 		supported = 1;
6225*58e6ee5fSAndroid Build Coastguard Worker out:
6226*58e6ee5fSAndroid Build Coastguard Worker 	if (supported < 0)
6227*58e6ee5fSAndroid Build Coastguard Worker 		return -1;
6228*58e6ee5fSAndroid Build Coastguard Worker 
6229*58e6ee5fSAndroid Build Coastguard Worker 	if (shift)
6230*58e6ee5fSAndroid Build Coastguard Worker 		*shift = cpu_shift;
6231*58e6ee5fSAndroid Build Coastguard Worker 	if (mult)
6232*58e6ee5fSAndroid Build Coastguard Worker 		*mult = cpu_mult;
6233*58e6ee5fSAndroid Build Coastguard Worker 
6234*58e6ee5fSAndroid Build Coastguard Worker 	return 0;
6235*58e6ee5fSAndroid Build Coastguard Worker }
6236*58e6ee5fSAndroid Build Coastguard Worker #else
get_tsc_nsec(int * shift,int * mult)6237*58e6ee5fSAndroid Build Coastguard Worker static int get_tsc_nsec(int *shift, int *mult)
6238*58e6ee5fSAndroid Build Coastguard Worker {
6239*58e6ee5fSAndroid Build Coastguard Worker 	return -1;
6240*58e6ee5fSAndroid Build Coastguard Worker }
6241*58e6ee5fSAndroid Build Coastguard Worker #endif
6242*58e6ee5fSAndroid Build Coastguard Worker 
trace_tsc2nsec_is_supported(void)6243*58e6ee5fSAndroid Build Coastguard Worker bool trace_tsc2nsec_is_supported(void)
6244*58e6ee5fSAndroid Build Coastguard Worker {
6245*58e6ee5fSAndroid Build Coastguard Worker 	return get_tsc_nsec(NULL, NULL) == 0;
6246*58e6ee5fSAndroid Build Coastguard Worker }
6247*58e6ee5fSAndroid Build Coastguard Worker 
parse_record_options(int argc,char ** argv,enum trace_cmd curr_cmd,struct common_record_context * ctx)6248*58e6ee5fSAndroid Build Coastguard Worker static void parse_record_options(int argc,
6249*58e6ee5fSAndroid Build Coastguard Worker 				 char **argv,
6250*58e6ee5fSAndroid Build Coastguard Worker 				 enum trace_cmd curr_cmd,
6251*58e6ee5fSAndroid Build Coastguard Worker 				 struct common_record_context *ctx)
6252*58e6ee5fSAndroid Build Coastguard Worker {
6253*58e6ee5fSAndroid Build Coastguard Worker 	const char *plugin = NULL;
6254*58e6ee5fSAndroid Build Coastguard Worker 	const char *option;
6255*58e6ee5fSAndroid Build Coastguard Worker 	struct event_list *event = NULL;
6256*58e6ee5fSAndroid Build Coastguard Worker 	struct event_list *last_event = NULL;
6257*58e6ee5fSAndroid Build Coastguard Worker 	struct addrinfo *result;
6258*58e6ee5fSAndroid Build Coastguard Worker 	char *pids;
6259*58e6ee5fSAndroid Build Coastguard Worker 	char *pid;
6260*58e6ee5fSAndroid Build Coastguard Worker 	char *sav;
6261*58e6ee5fSAndroid Build Coastguard Worker 	int name_counter = 0;
6262*58e6ee5fSAndroid Build Coastguard Worker 	int negative = 0;
6263*58e6ee5fSAndroid Build Coastguard Worker 	struct buffer_instance *instance, *del_list = NULL;
6264*58e6ee5fSAndroid Build Coastguard Worker 	int do_children = 0;
6265*58e6ee5fSAndroid Build Coastguard Worker 	int fpids_count = 0;
6266*58e6ee5fSAndroid Build Coastguard Worker 
6267*58e6ee5fSAndroid Build Coastguard Worker 	init_common_record_context(ctx, curr_cmd);
6268*58e6ee5fSAndroid Build Coastguard Worker 
6269*58e6ee5fSAndroid Build Coastguard Worker 	if (IS_CMDSET(ctx))
6270*58e6ee5fSAndroid Build Coastguard Worker 		keep = 1;
6271*58e6ee5fSAndroid Build Coastguard Worker 
6272*58e6ee5fSAndroid Build Coastguard Worker 	for (;;) {
6273*58e6ee5fSAndroid Build Coastguard Worker 		int option_index = 0;
6274*58e6ee5fSAndroid Build Coastguard Worker 		int ret;
6275*58e6ee5fSAndroid Build Coastguard Worker 		int c;
6276*58e6ee5fSAndroid Build Coastguard Worker 		const char *opts;
6277*58e6ee5fSAndroid Build Coastguard Worker 		static struct option long_options[] = {
6278*58e6ee5fSAndroid Build Coastguard Worker 			{"date", no_argument, NULL, OPT_date},
6279*58e6ee5fSAndroid Build Coastguard Worker 			{"func-stack", no_argument, NULL, OPT_funcstack},
6280*58e6ee5fSAndroid Build Coastguard Worker 			{"nosplice", no_argument, NULL, OPT_nosplice},
6281*58e6ee5fSAndroid Build Coastguard Worker 			{"nofifos", no_argument, NULL, OPT_nofifos},
6282*58e6ee5fSAndroid Build Coastguard Worker 			{"profile", no_argument, NULL, OPT_profile},
6283*58e6ee5fSAndroid Build Coastguard Worker 			{"stderr", no_argument, NULL, OPT_stderr},
6284*58e6ee5fSAndroid Build Coastguard Worker 			{"by-comm", no_argument, NULL, OPT_bycomm},
6285*58e6ee5fSAndroid Build Coastguard Worker 			{"ts-offset", required_argument, NULL, OPT_tsoffset},
6286*58e6ee5fSAndroid Build Coastguard Worker 			{"max-graph-depth", required_argument, NULL, OPT_max_graph_depth},
6287*58e6ee5fSAndroid Build Coastguard Worker 			{"cmdlines-size", required_argument, NULL, OPT_cmdlines_size},
6288*58e6ee5fSAndroid Build Coastguard Worker 			{"no-filter", no_argument, NULL, OPT_no_filter},
6289*58e6ee5fSAndroid Build Coastguard Worker 			{"debug", no_argument, NULL, OPT_debug},
6290*58e6ee5fSAndroid Build Coastguard Worker 			{"quiet", no_argument, NULL, OPT_quiet},
6291*58e6ee5fSAndroid Build Coastguard Worker 			{"help", no_argument, NULL, '?'},
6292*58e6ee5fSAndroid Build Coastguard Worker 			{"proc-map", no_argument, NULL, OPT_procmap},
6293*58e6ee5fSAndroid Build Coastguard Worker 			{"user", required_argument, NULL, OPT_user},
6294*58e6ee5fSAndroid Build Coastguard Worker 			{"module", required_argument, NULL, OPT_module},
6295*58e6ee5fSAndroid Build Coastguard Worker 			{"tsync-interval", required_argument, NULL, OPT_tsyncinterval},
6296*58e6ee5fSAndroid Build Coastguard Worker 			{"fork", no_argument, NULL, OPT_fork},
6297*58e6ee5fSAndroid Build Coastguard Worker 			{"tsc2nsec", no_argument, NULL, OPT_tsc2nsec},
6298*58e6ee5fSAndroid Build Coastguard Worker 			{"poll", no_argument, NULL, OPT_poll},
6299*58e6ee5fSAndroid Build Coastguard Worker 			{"name", required_argument, NULL, OPT_name},
6300*58e6ee5fSAndroid Build Coastguard Worker 			{"verbose", optional_argument, NULL, OPT_verbose},
6301*58e6ee5fSAndroid Build Coastguard Worker 			{"compression", required_argument, NULL, OPT_compression},
6302*58e6ee5fSAndroid Build Coastguard Worker 			{"file-version", required_argument, NULL, OPT_file_ver},
6303*58e6ee5fSAndroid Build Coastguard Worker 			{NULL, 0, NULL, 0}
6304*58e6ee5fSAndroid Build Coastguard Worker 		};
6305*58e6ee5fSAndroid Build Coastguard Worker 
6306*58e6ee5fSAndroid Build Coastguard Worker 		if (IS_EXTRACT(ctx))
6307*58e6ee5fSAndroid Build Coastguard Worker 			opts = "+haf:Fp:co:O:sr:g:l:n:P:N:tb:B:ksiT";
6308*58e6ee5fSAndroid Build Coastguard Worker 		else
6309*58e6ee5fSAndroid Build Coastguard Worker 			opts = "+hae:f:FA:p:cC:dDGo:O:s:r:V:vg:l:n:P:N:tb:R:B:ksSiTm:M:H:q";
6310*58e6ee5fSAndroid Build Coastguard Worker 		c = getopt_long (argc-1, argv+1, opts, long_options, &option_index);
6311*58e6ee5fSAndroid Build Coastguard Worker 		if (c == -1)
6312*58e6ee5fSAndroid Build Coastguard Worker 			break;
6313*58e6ee5fSAndroid Build Coastguard Worker 
6314*58e6ee5fSAndroid Build Coastguard Worker 		/*
6315*58e6ee5fSAndroid Build Coastguard Worker 		 * If the current instance is to record a guest, then save
6316*58e6ee5fSAndroid Build Coastguard Worker 		 * all the arguments for this instance.
6317*58e6ee5fSAndroid Build Coastguard Worker 		 */
6318*58e6ee5fSAndroid Build Coastguard Worker 		if (c != 'B' && c != 'A' && c != OPT_name && is_guest(ctx->instance)) {
6319*58e6ee5fSAndroid Build Coastguard Worker 			add_arg(ctx->instance, c, opts, long_options, optarg);
6320*58e6ee5fSAndroid Build Coastguard Worker 			if (c == 'C')
6321*58e6ee5fSAndroid Build Coastguard Worker 				ctx->instance->flags |= BUFFER_FL_HAS_CLOCK;
6322*58e6ee5fSAndroid Build Coastguard Worker 			continue;
6323*58e6ee5fSAndroid Build Coastguard Worker 		}
6324*58e6ee5fSAndroid Build Coastguard Worker 
6325*58e6ee5fSAndroid Build Coastguard Worker 		switch (c) {
6326*58e6ee5fSAndroid Build Coastguard Worker 		case 'h':
6327*58e6ee5fSAndroid Build Coastguard Worker 			usage(argv);
6328*58e6ee5fSAndroid Build Coastguard Worker 			break;
6329*58e6ee5fSAndroid Build Coastguard Worker 		case 'a':
6330*58e6ee5fSAndroid Build Coastguard Worker 			cmd_check_die(ctx, CMD_set, *(argv+1), "-a");
6331*58e6ee5fSAndroid Build Coastguard Worker 			if (IS_EXTRACT(ctx)) {
6332*58e6ee5fSAndroid Build Coastguard Worker 				add_all_instances();
6333*58e6ee5fSAndroid Build Coastguard Worker 			} else {
6334*58e6ee5fSAndroid Build Coastguard Worker 				ctx->record_all = 1;
6335*58e6ee5fSAndroid Build Coastguard Worker 				record_all_events();
6336*58e6ee5fSAndroid Build Coastguard Worker 			}
6337*58e6ee5fSAndroid Build Coastguard Worker 			break;
6338*58e6ee5fSAndroid Build Coastguard Worker 		case 'e':
6339*58e6ee5fSAndroid Build Coastguard Worker 			check_instance_die(ctx->instance, "-e");
6340*58e6ee5fSAndroid Build Coastguard Worker 			ctx->events = 1;
6341*58e6ee5fSAndroid Build Coastguard Worker 			event = malloc(sizeof(*event));
6342*58e6ee5fSAndroid Build Coastguard Worker 			if (!event)
6343*58e6ee5fSAndroid Build Coastguard Worker 				die("Failed to allocate event %s", optarg);
6344*58e6ee5fSAndroid Build Coastguard Worker 			memset(event, 0, sizeof(*event));
6345*58e6ee5fSAndroid Build Coastguard Worker 			event->event = optarg;
6346*58e6ee5fSAndroid Build Coastguard Worker 			add_event(ctx->instance, event);
6347*58e6ee5fSAndroid Build Coastguard Worker 			event->neg = negative;
6348*58e6ee5fSAndroid Build Coastguard Worker 			event->filter = NULL;
6349*58e6ee5fSAndroid Build Coastguard Worker 			last_event = event;
6350*58e6ee5fSAndroid Build Coastguard Worker 
6351*58e6ee5fSAndroid Build Coastguard Worker 			if (!ctx->record_all)
6352*58e6ee5fSAndroid Build Coastguard Worker 				list_event(optarg);
6353*58e6ee5fSAndroid Build Coastguard Worker 			break;
6354*58e6ee5fSAndroid Build Coastguard Worker 		case 'f':
6355*58e6ee5fSAndroid Build Coastguard Worker 			if (!last_event)
6356*58e6ee5fSAndroid Build Coastguard Worker 				die("filter must come after event");
6357*58e6ee5fSAndroid Build Coastguard Worker 			if (last_event->filter) {
6358*58e6ee5fSAndroid Build Coastguard Worker 				last_event->filter =
6359*58e6ee5fSAndroid Build Coastguard Worker 					realloc(last_event->filter,
6360*58e6ee5fSAndroid Build Coastguard Worker 						strlen(last_event->filter) +
6361*58e6ee5fSAndroid Build Coastguard Worker 						strlen("&&()") +
6362*58e6ee5fSAndroid Build Coastguard Worker 						strlen(optarg) + 1);
6363*58e6ee5fSAndroid Build Coastguard Worker 				strcat(last_event->filter, "&&(");
6364*58e6ee5fSAndroid Build Coastguard Worker 				strcat(last_event->filter, optarg);
6365*58e6ee5fSAndroid Build Coastguard Worker 				strcat(last_event->filter, ")");
6366*58e6ee5fSAndroid Build Coastguard Worker 			} else {
6367*58e6ee5fSAndroid Build Coastguard Worker 				ret = asprintf(&last_event->filter, "(%s)", optarg);
6368*58e6ee5fSAndroid Build Coastguard Worker 				if (ret < 0)
6369*58e6ee5fSAndroid Build Coastguard Worker 					die("Failed to allocate filter %s", optarg);
6370*58e6ee5fSAndroid Build Coastguard Worker 			}
6371*58e6ee5fSAndroid Build Coastguard Worker 			break;
6372*58e6ee5fSAndroid Build Coastguard Worker 
6373*58e6ee5fSAndroid Build Coastguard Worker 		case 'R':
6374*58e6ee5fSAndroid Build Coastguard Worker 			if (!last_event)
6375*58e6ee5fSAndroid Build Coastguard Worker 				die("trigger must come after event");
6376*58e6ee5fSAndroid Build Coastguard Worker 			add_trigger(event, optarg);
6377*58e6ee5fSAndroid Build Coastguard Worker 			break;
6378*58e6ee5fSAndroid Build Coastguard Worker 
6379*58e6ee5fSAndroid Build Coastguard Worker 		case OPT_name:
6380*58e6ee5fSAndroid Build Coastguard Worker 			if (!ctx->instance)
6381*58e6ee5fSAndroid Build Coastguard Worker 				die("No instance defined for name option\n");
6382*58e6ee5fSAndroid Build Coastguard Worker 			if (!is_guest(ctx->instance))
6383*58e6ee5fSAndroid Build Coastguard Worker 				die("  --name is only used for -A options\n");
6384*58e6ee5fSAndroid Build Coastguard Worker 			free(ctx->instance->name);
6385*58e6ee5fSAndroid Build Coastguard Worker 			ctx->instance->name = strdup(optarg);
6386*58e6ee5fSAndroid Build Coastguard Worker 			if (!ctx->instance->name)
6387*58e6ee5fSAndroid Build Coastguard Worker 				die("Failed to allocate name");
6388*58e6ee5fSAndroid Build Coastguard Worker 			break;
6389*58e6ee5fSAndroid Build Coastguard Worker 
6390*58e6ee5fSAndroid Build Coastguard Worker 		case 'A': {
6391*58e6ee5fSAndroid Build Coastguard Worker 			char *name = NULL;
6392*58e6ee5fSAndroid Build Coastguard Worker 			int cid = -1, port = -1;
6393*58e6ee5fSAndroid Build Coastguard Worker 
6394*58e6ee5fSAndroid Build Coastguard Worker 			if (!IS_RECORD(ctx))
6395*58e6ee5fSAndroid Build Coastguard Worker 				die("-A is only allowed for record operations");
6396*58e6ee5fSAndroid Build Coastguard Worker 
6397*58e6ee5fSAndroid Build Coastguard Worker 			name = parse_guest_name(optarg, &cid, &port, &result);
6398*58e6ee5fSAndroid Build Coastguard Worker 			if (cid == -1 && !result)
6399*58e6ee5fSAndroid Build Coastguard Worker 				die("guest %s not found", optarg);
6400*58e6ee5fSAndroid Build Coastguard Worker 			if (port == -1)
6401*58e6ee5fSAndroid Build Coastguard Worker 				port = TRACE_AGENT_DEFAULT_PORT;
6402*58e6ee5fSAndroid Build Coastguard Worker 			if (!name || !*name) {
6403*58e6ee5fSAndroid Build Coastguard Worker 				ret = asprintf(&name, "unnamed-%d", name_counter++);
6404*58e6ee5fSAndroid Build Coastguard Worker 				if (ret < 0)
6405*58e6ee5fSAndroid Build Coastguard Worker 					name = NULL;
6406*58e6ee5fSAndroid Build Coastguard Worker 			} else {
6407*58e6ee5fSAndroid Build Coastguard Worker 				/* Needs to be allocate */
6408*58e6ee5fSAndroid Build Coastguard Worker 				name = strdup(name);
6409*58e6ee5fSAndroid Build Coastguard Worker 			}
6410*58e6ee5fSAndroid Build Coastguard Worker 			if (!name)
6411*58e6ee5fSAndroid Build Coastguard Worker 				die("Failed to allocate guest name");
6412*58e6ee5fSAndroid Build Coastguard Worker 
6413*58e6ee5fSAndroid Build Coastguard Worker 			ctx->instance = allocate_instance(name);
6414*58e6ee5fSAndroid Build Coastguard Worker 			if (!ctx->instance)
6415*58e6ee5fSAndroid Build Coastguard Worker 				die("Failed to allocate instance");
6416*58e6ee5fSAndroid Build Coastguard Worker 
6417*58e6ee5fSAndroid Build Coastguard Worker 			if (result) {
6418*58e6ee5fSAndroid Build Coastguard Worker 				ctx->instance->flags |= BUFFER_FL_NETWORK;
6419*58e6ee5fSAndroid Build Coastguard Worker 				ctx->instance->port_type = USE_TCP;
6420*58e6ee5fSAndroid Build Coastguard Worker 			}
6421*58e6ee5fSAndroid Build Coastguard Worker 
6422*58e6ee5fSAndroid Build Coastguard Worker 			ctx->instance->flags |= BUFFER_FL_GUEST;
6423*58e6ee5fSAndroid Build Coastguard Worker 			ctx->instance->result = result;
6424*58e6ee5fSAndroid Build Coastguard Worker 			ctx->instance->cid = cid;
6425*58e6ee5fSAndroid Build Coastguard Worker 			ctx->instance->port = port;
6426*58e6ee5fSAndroid Build Coastguard Worker 			ctx->instance->name = name;
6427*58e6ee5fSAndroid Build Coastguard Worker 			add_instance(ctx->instance, 0);
6428*58e6ee5fSAndroid Build Coastguard Worker 			ctx->data_flags |= DATA_FL_GUEST;
6429*58e6ee5fSAndroid Build Coastguard Worker 			break;
6430*58e6ee5fSAndroid Build Coastguard Worker 		}
6431*58e6ee5fSAndroid Build Coastguard Worker 		case 'F':
6432*58e6ee5fSAndroid Build Coastguard Worker 			test_set_event_pid(ctx->instance);
6433*58e6ee5fSAndroid Build Coastguard Worker 			filter_task = 1;
6434*58e6ee5fSAndroid Build Coastguard Worker 			break;
6435*58e6ee5fSAndroid Build Coastguard Worker 		case 'G':
6436*58e6ee5fSAndroid Build Coastguard Worker 			cmd_check_die(ctx, CMD_set, *(argv+1), "-G");
6437*58e6ee5fSAndroid Build Coastguard Worker 			ctx->global = 1;
6438*58e6ee5fSAndroid Build Coastguard Worker 			break;
6439*58e6ee5fSAndroid Build Coastguard Worker 		case 'P':
6440*58e6ee5fSAndroid Build Coastguard Worker 			check_instance_die(ctx->instance, "-P");
6441*58e6ee5fSAndroid Build Coastguard Worker 			test_set_event_pid(ctx->instance);
6442*58e6ee5fSAndroid Build Coastguard Worker 			pids = strdup(optarg);
6443*58e6ee5fSAndroid Build Coastguard Worker 			if (!pids)
6444*58e6ee5fSAndroid Build Coastguard Worker 				die("strdup");
6445*58e6ee5fSAndroid Build Coastguard Worker 			pid = strtok_r(pids, ",", &sav);
6446*58e6ee5fSAndroid Build Coastguard Worker 			while (pid) {
6447*58e6ee5fSAndroid Build Coastguard Worker 				fpids_count += add_filter_pid(ctx->instance,
6448*58e6ee5fSAndroid Build Coastguard Worker 							      atoi(pid), 0);
6449*58e6ee5fSAndroid Build Coastguard Worker 				pid = strtok_r(NULL, ",", &sav);
6450*58e6ee5fSAndroid Build Coastguard Worker 				ctx->instance->nr_process_pids++;
6451*58e6ee5fSAndroid Build Coastguard Worker 			}
6452*58e6ee5fSAndroid Build Coastguard Worker 			ctx->instance->process_pids = ctx->instance->filter_pids;
6453*58e6ee5fSAndroid Build Coastguard Worker 			free(pids);
6454*58e6ee5fSAndroid Build Coastguard Worker 			break;
6455*58e6ee5fSAndroid Build Coastguard Worker 		case 'c':
6456*58e6ee5fSAndroid Build Coastguard Worker 			check_instance_die(ctx->instance, "-c");
6457*58e6ee5fSAndroid Build Coastguard Worker 			test_set_event_pid(ctx->instance);
6458*58e6ee5fSAndroid Build Coastguard Worker 			do_children = 1;
6459*58e6ee5fSAndroid Build Coastguard Worker 			if (!ctx->instance->have_event_fork) {
6460*58e6ee5fSAndroid Build Coastguard Worker #ifdef NO_PTRACE
6461*58e6ee5fSAndroid Build Coastguard Worker 				die("-c invalid: ptrace not supported");
6462*58e6ee5fSAndroid Build Coastguard Worker #endif
6463*58e6ee5fSAndroid Build Coastguard Worker 				do_ptrace = 1;
6464*58e6ee5fSAndroid Build Coastguard Worker 				ctx->instance->ptrace_child = 1;
6465*58e6ee5fSAndroid Build Coastguard Worker 
6466*58e6ee5fSAndroid Build Coastguard Worker 			} else {
6467*58e6ee5fSAndroid Build Coastguard Worker 				save_option(ctx->instance, "event-fork");
6468*58e6ee5fSAndroid Build Coastguard Worker 			}
6469*58e6ee5fSAndroid Build Coastguard Worker 			if (ctx->instance->have_func_fork)
6470*58e6ee5fSAndroid Build Coastguard Worker 				save_option(ctx->instance, "function-fork");
6471*58e6ee5fSAndroid Build Coastguard Worker 			break;
6472*58e6ee5fSAndroid Build Coastguard Worker 		case 'C':
6473*58e6ee5fSAndroid Build Coastguard Worker 			check_instance_die(ctx->instance, "-C");
6474*58e6ee5fSAndroid Build Coastguard Worker 			if (strcmp(optarg, TSCNSEC_CLOCK) == 0) {
6475*58e6ee5fSAndroid Build Coastguard Worker 				ret = get_tsc_nsec(&ctx->tsc2nsec.shift,
6476*58e6ee5fSAndroid Build Coastguard Worker 						   &ctx->tsc2nsec.mult);
6477*58e6ee5fSAndroid Build Coastguard Worker 				if (ret)
6478*58e6ee5fSAndroid Build Coastguard Worker 					die("TSC to nanosecond is not supported");
6479*58e6ee5fSAndroid Build Coastguard Worker 				ctx->instance->flags |= BUFFER_FL_TSC2NSEC;
6480*58e6ee5fSAndroid Build Coastguard Worker 				ctx->instance->clock = TSC_CLOCK;
6481*58e6ee5fSAndroid Build Coastguard Worker 			} else {
6482*58e6ee5fSAndroid Build Coastguard Worker 				ctx->instance->clock = optarg;
6483*58e6ee5fSAndroid Build Coastguard Worker 			}
6484*58e6ee5fSAndroid Build Coastguard Worker 			if (!clock_is_supported(NULL, ctx->instance->clock))
6485*58e6ee5fSAndroid Build Coastguard Worker 				die("Clock %s is not supported", ctx->instance->clock);
6486*58e6ee5fSAndroid Build Coastguard Worker 			ctx->instance->clock = strdup(ctx->instance->clock);
6487*58e6ee5fSAndroid Build Coastguard Worker 			if (!ctx->instance->clock)
6488*58e6ee5fSAndroid Build Coastguard Worker 				die("Failed allocation");
6489*58e6ee5fSAndroid Build Coastguard Worker 			ctx->instance->flags |= BUFFER_FL_HAS_CLOCK;
6490*58e6ee5fSAndroid Build Coastguard Worker 			if (!ctx->clock && !is_guest(ctx->instance))
6491*58e6ee5fSAndroid Build Coastguard Worker 				ctx->clock = ctx->instance->clock;
6492*58e6ee5fSAndroid Build Coastguard Worker 			break;
6493*58e6ee5fSAndroid Build Coastguard Worker 		case 'v':
6494*58e6ee5fSAndroid Build Coastguard Worker 			negative = 1;
6495*58e6ee5fSAndroid Build Coastguard Worker 			break;
6496*58e6ee5fSAndroid Build Coastguard Worker 		case 'l':
6497*58e6ee5fSAndroid Build Coastguard Worker 			add_func(&ctx->instance->filter_funcs,
6498*58e6ee5fSAndroid Build Coastguard Worker 				 ctx->instance->filter_mod, optarg);
6499*58e6ee5fSAndroid Build Coastguard Worker 			ctx->filtered = 1;
6500*58e6ee5fSAndroid Build Coastguard Worker 			break;
6501*58e6ee5fSAndroid Build Coastguard Worker 		case 'n':
6502*58e6ee5fSAndroid Build Coastguard Worker 			check_instance_die(ctx->instance, "-n");
6503*58e6ee5fSAndroid Build Coastguard Worker 			add_func(&ctx->instance->notrace_funcs,
6504*58e6ee5fSAndroid Build Coastguard Worker 				 ctx->instance->filter_mod, optarg);
6505*58e6ee5fSAndroid Build Coastguard Worker 			ctx->filtered = 1;
6506*58e6ee5fSAndroid Build Coastguard Worker 			break;
6507*58e6ee5fSAndroid Build Coastguard Worker 		case 'g':
6508*58e6ee5fSAndroid Build Coastguard Worker 			check_instance_die(ctx->instance, "-g");
6509*58e6ee5fSAndroid Build Coastguard Worker 			add_func(&graph_funcs, ctx->instance->filter_mod, optarg);
6510*58e6ee5fSAndroid Build Coastguard Worker 			ctx->filtered = 1;
6511*58e6ee5fSAndroid Build Coastguard Worker 			break;
6512*58e6ee5fSAndroid Build Coastguard Worker 		case 'p':
6513*58e6ee5fSAndroid Build Coastguard Worker 			check_instance_die(ctx->instance, "-p");
6514*58e6ee5fSAndroid Build Coastguard Worker 			if (ctx->instance->plugin)
6515*58e6ee5fSAndroid Build Coastguard Worker 				die("only one plugin allowed");
6516*58e6ee5fSAndroid Build Coastguard Worker 			for (plugin = optarg; isspace(*plugin); plugin++)
6517*58e6ee5fSAndroid Build Coastguard Worker 				;
6518*58e6ee5fSAndroid Build Coastguard Worker 			ctx->instance->plugin = plugin;
6519*58e6ee5fSAndroid Build Coastguard Worker 			for (optarg += strlen(optarg) - 1;
6520*58e6ee5fSAndroid Build Coastguard Worker 			     optarg > plugin && isspace(*optarg); optarg--)
6521*58e6ee5fSAndroid Build Coastguard Worker 				;
6522*58e6ee5fSAndroid Build Coastguard Worker 			optarg++;
6523*58e6ee5fSAndroid Build Coastguard Worker 			optarg[0] = '\0';
6524*58e6ee5fSAndroid Build Coastguard Worker 			break;
6525*58e6ee5fSAndroid Build Coastguard Worker 		case 'D':
6526*58e6ee5fSAndroid Build Coastguard Worker 			ctx->total_disable = 1;
6527*58e6ee5fSAndroid Build Coastguard Worker 			/* fall through */
6528*58e6ee5fSAndroid Build Coastguard Worker 		case 'd':
6529*58e6ee5fSAndroid Build Coastguard Worker 			ctx->disable = 1;
6530*58e6ee5fSAndroid Build Coastguard Worker 			break;
6531*58e6ee5fSAndroid Build Coastguard Worker 		case 'o':
6532*58e6ee5fSAndroid Build Coastguard Worker 			cmd_check_die(ctx, CMD_set, *(argv+1), "-o");
6533*58e6ee5fSAndroid Build Coastguard Worker 			if (IS_RECORD_AGENT(ctx))
6534*58e6ee5fSAndroid Build Coastguard Worker 				die("-o incompatible with agent recording");
6535*58e6ee5fSAndroid Build Coastguard Worker 			if (host)
6536*58e6ee5fSAndroid Build Coastguard Worker 				die("-o incompatible with -N");
6537*58e6ee5fSAndroid Build Coastguard Worker 			if (IS_START(ctx))
6538*58e6ee5fSAndroid Build Coastguard Worker 				die("start does not take output\n"
6539*58e6ee5fSAndroid Build Coastguard Worker 				    "Did you mean 'record'?");
6540*58e6ee5fSAndroid Build Coastguard Worker 			if (IS_STREAM(ctx))
6541*58e6ee5fSAndroid Build Coastguard Worker 				die("stream does not take output\n"
6542*58e6ee5fSAndroid Build Coastguard Worker 				    "Did you mean 'record'?");
6543*58e6ee5fSAndroid Build Coastguard Worker 			if (ctx->output)
6544*58e6ee5fSAndroid Build Coastguard Worker 				die("only one output file allowed");
6545*58e6ee5fSAndroid Build Coastguard Worker 			ctx->output = optarg;
6546*58e6ee5fSAndroid Build Coastguard Worker 
6547*58e6ee5fSAndroid Build Coastguard Worker 			if (IS_PROFILE(ctx)) {
6548*58e6ee5fSAndroid Build Coastguard Worker 				int fd;
6549*58e6ee5fSAndroid Build Coastguard Worker 
6550*58e6ee5fSAndroid Build Coastguard Worker 				/* pipe the output to this file instead of stdout */
6551*58e6ee5fSAndroid Build Coastguard Worker 				save_stdout = dup(1);
6552*58e6ee5fSAndroid Build Coastguard Worker 				close(1);
6553*58e6ee5fSAndroid Build Coastguard Worker 				fd = open(optarg, O_WRONLY | O_CREAT | O_TRUNC, 0644);
6554*58e6ee5fSAndroid Build Coastguard Worker 				if (fd < 0)
6555*58e6ee5fSAndroid Build Coastguard Worker 					die("can't write to %s", optarg);
6556*58e6ee5fSAndroid Build Coastguard Worker 				if (fd != 1) {
6557*58e6ee5fSAndroid Build Coastguard Worker 					dup2(fd, 1);
6558*58e6ee5fSAndroid Build Coastguard Worker 					close(fd);
6559*58e6ee5fSAndroid Build Coastguard Worker 				}
6560*58e6ee5fSAndroid Build Coastguard Worker 			}
6561*58e6ee5fSAndroid Build Coastguard Worker 			break;
6562*58e6ee5fSAndroid Build Coastguard Worker 		case 'O':
6563*58e6ee5fSAndroid Build Coastguard Worker 			check_instance_die(ctx->instance, "-O");
6564*58e6ee5fSAndroid Build Coastguard Worker 			option = optarg;
6565*58e6ee5fSAndroid Build Coastguard Worker 			save_option(ctx->instance, option);
6566*58e6ee5fSAndroid Build Coastguard Worker 			break;
6567*58e6ee5fSAndroid Build Coastguard Worker 		case 'T':
6568*58e6ee5fSAndroid Build Coastguard Worker 			check_instance_die(ctx->instance, "-T");
6569*58e6ee5fSAndroid Build Coastguard Worker 			save_option(ctx->instance, "stacktrace");
6570*58e6ee5fSAndroid Build Coastguard Worker 			break;
6571*58e6ee5fSAndroid Build Coastguard Worker 		case 'H':
6572*58e6ee5fSAndroid Build Coastguard Worker 			cmd_check_die(ctx, CMD_set, *(argv+1), "-H");
6573*58e6ee5fSAndroid Build Coastguard Worker 			check_instance_die(ctx->instance, "-H");
6574*58e6ee5fSAndroid Build Coastguard Worker 			add_hook(ctx->instance, optarg);
6575*58e6ee5fSAndroid Build Coastguard Worker 			ctx->events = 1;
6576*58e6ee5fSAndroid Build Coastguard Worker 			break;
6577*58e6ee5fSAndroid Build Coastguard Worker 		case 's':
6578*58e6ee5fSAndroid Build Coastguard Worker 			cmd_check_die(ctx, CMD_set, *(argv+1), "-s");
6579*58e6ee5fSAndroid Build Coastguard Worker 			if (IS_EXTRACT(ctx)) {
6580*58e6ee5fSAndroid Build Coastguard Worker 				if (optarg)
6581*58e6ee5fSAndroid Build Coastguard Worker 					usage(argv);
6582*58e6ee5fSAndroid Build Coastguard Worker 				recorder_flags |= TRACECMD_RECORD_SNAPSHOT;
6583*58e6ee5fSAndroid Build Coastguard Worker 				break;
6584*58e6ee5fSAndroid Build Coastguard Worker 			}
6585*58e6ee5fSAndroid Build Coastguard Worker 			if (!optarg)
6586*58e6ee5fSAndroid Build Coastguard Worker 				usage(argv);
6587*58e6ee5fSAndroid Build Coastguard Worker 			sleep_time = atoi(optarg);
6588*58e6ee5fSAndroid Build Coastguard Worker 			break;
6589*58e6ee5fSAndroid Build Coastguard Worker 		case 'S':
6590*58e6ee5fSAndroid Build Coastguard Worker 			cmd_check_die(ctx, CMD_set, *(argv+1), "-S");
6591*58e6ee5fSAndroid Build Coastguard Worker 			ctx->manual = 1;
6592*58e6ee5fSAndroid Build Coastguard Worker 			/* User sets events for profiling */
6593*58e6ee5fSAndroid Build Coastguard Worker 			if (!event)
6594*58e6ee5fSAndroid Build Coastguard Worker 				ctx->events = 0;
6595*58e6ee5fSAndroid Build Coastguard Worker 			break;
6596*58e6ee5fSAndroid Build Coastguard Worker 		case 'r':
6597*58e6ee5fSAndroid Build Coastguard Worker 			cmd_check_die(ctx, CMD_set, *(argv+1), "-r");
6598*58e6ee5fSAndroid Build Coastguard Worker 			rt_prio = atoi(optarg);
6599*58e6ee5fSAndroid Build Coastguard Worker 			break;
6600*58e6ee5fSAndroid Build Coastguard Worker 		case 'N':
6601*58e6ee5fSAndroid Build Coastguard Worker 			cmd_check_die(ctx, CMD_set, *(argv+1), "-N");
6602*58e6ee5fSAndroid Build Coastguard Worker 			if (!IS_RECORD(ctx))
6603*58e6ee5fSAndroid Build Coastguard Worker 				die("-N only available with record");
6604*58e6ee5fSAndroid Build Coastguard Worker 			if (IS_RECORD_AGENT(ctx))
6605*58e6ee5fSAndroid Build Coastguard Worker 				die("-N incompatible with agent recording");
6606*58e6ee5fSAndroid Build Coastguard Worker 			if (ctx->output)
6607*58e6ee5fSAndroid Build Coastguard Worker 				die("-N incompatible with -o");
6608*58e6ee5fSAndroid Build Coastguard Worker 			host = optarg;
6609*58e6ee5fSAndroid Build Coastguard Worker 			break;
6610*58e6ee5fSAndroid Build Coastguard Worker 		case 'V':
6611*58e6ee5fSAndroid Build Coastguard Worker 			cmd_check_die(ctx, CMD_set, *(argv+1), "-V");
6612*58e6ee5fSAndroid Build Coastguard Worker 			if (!IS_RECORD(ctx))
6613*58e6ee5fSAndroid Build Coastguard Worker 				die("-V only available with record");
6614*58e6ee5fSAndroid Build Coastguard Worker 			if (IS_RECORD_AGENT(ctx))
6615*58e6ee5fSAndroid Build Coastguard Worker 				die("-V incompatible with agent recording");
6616*58e6ee5fSAndroid Build Coastguard Worker 			if (ctx->output)
6617*58e6ee5fSAndroid Build Coastguard Worker 				die("-V incompatible with -o");
6618*58e6ee5fSAndroid Build Coastguard Worker 			host = optarg;
6619*58e6ee5fSAndroid Build Coastguard Worker 			ctx->instance->port_type = USE_VSOCK;
6620*58e6ee5fSAndroid Build Coastguard Worker 			break;
6621*58e6ee5fSAndroid Build Coastguard Worker 		case 'm':
6622*58e6ee5fSAndroid Build Coastguard Worker 			if (max_kb)
6623*58e6ee5fSAndroid Build Coastguard Worker 				die("-m can only be specified once");
6624*58e6ee5fSAndroid Build Coastguard Worker 			if (!IS_RECORD(ctx))
6625*58e6ee5fSAndroid Build Coastguard Worker 				die("only record take 'm' option");
6626*58e6ee5fSAndroid Build Coastguard Worker 			max_kb = atoi(optarg);
6627*58e6ee5fSAndroid Build Coastguard Worker 			break;
6628*58e6ee5fSAndroid Build Coastguard Worker 		case 'M':
6629*58e6ee5fSAndroid Build Coastguard Worker 			check_instance_die(ctx->instance, "-M");
6630*58e6ee5fSAndroid Build Coastguard Worker 			ctx->instance->cpumask = alloc_mask_from_hex(ctx->instance, optarg);
6631*58e6ee5fSAndroid Build Coastguard Worker 			break;
6632*58e6ee5fSAndroid Build Coastguard Worker 		case 't':
6633*58e6ee5fSAndroid Build Coastguard Worker 			cmd_check_die(ctx, CMD_set, *(argv+1), "-t");
6634*58e6ee5fSAndroid Build Coastguard Worker 			if (IS_EXTRACT(ctx))
6635*58e6ee5fSAndroid Build Coastguard Worker 				ctx->topt = 1; /* Extract top instance also */
6636*58e6ee5fSAndroid Build Coastguard Worker 			else
6637*58e6ee5fSAndroid Build Coastguard Worker 				ctx->instance->port_type = USE_TCP;
6638*58e6ee5fSAndroid Build Coastguard Worker 			break;
6639*58e6ee5fSAndroid Build Coastguard Worker 		case 'b':
6640*58e6ee5fSAndroid Build Coastguard Worker 			check_instance_die(ctx->instance, "-b");
6641*58e6ee5fSAndroid Build Coastguard Worker 			ctx->instance->buffer_size = atoi(optarg);
6642*58e6ee5fSAndroid Build Coastguard Worker 			break;
6643*58e6ee5fSAndroid Build Coastguard Worker 		case 'B':
6644*58e6ee5fSAndroid Build Coastguard Worker 			ctx->instance = allocate_instance(optarg);
6645*58e6ee5fSAndroid Build Coastguard Worker 			if (!ctx->instance)
6646*58e6ee5fSAndroid Build Coastguard Worker 				die("Failed to create instance");
6647*58e6ee5fSAndroid Build Coastguard Worker 			ctx->instance->delete = negative;
6648*58e6ee5fSAndroid Build Coastguard Worker 			negative = 0;
6649*58e6ee5fSAndroid Build Coastguard Worker 			if (ctx->instance->delete) {
6650*58e6ee5fSAndroid Build Coastguard Worker 				ctx->instance->next = del_list;
6651*58e6ee5fSAndroid Build Coastguard Worker 				del_list = ctx->instance;
6652*58e6ee5fSAndroid Build Coastguard Worker 			} else
6653*58e6ee5fSAndroid Build Coastguard Worker 				add_instance(ctx->instance, local_cpu_count);
6654*58e6ee5fSAndroid Build Coastguard Worker 			if (IS_PROFILE(ctx))
6655*58e6ee5fSAndroid Build Coastguard Worker 				ctx->instance->flags |= BUFFER_FL_PROFILE;
6656*58e6ee5fSAndroid Build Coastguard Worker 			break;
6657*58e6ee5fSAndroid Build Coastguard Worker 		case 'k':
6658*58e6ee5fSAndroid Build Coastguard Worker 			cmd_check_die(ctx, CMD_set, *(argv+1), "-k");
6659*58e6ee5fSAndroid Build Coastguard Worker 			keep = 1;
6660*58e6ee5fSAndroid Build Coastguard Worker 			break;
6661*58e6ee5fSAndroid Build Coastguard Worker 		case 'i':
6662*58e6ee5fSAndroid Build Coastguard Worker 			ignore_event_not_found = 1;
6663*58e6ee5fSAndroid Build Coastguard Worker 			break;
6664*58e6ee5fSAndroid Build Coastguard Worker 		case OPT_user:
6665*58e6ee5fSAndroid Build Coastguard Worker 			ctx->user = strdup(optarg);
6666*58e6ee5fSAndroid Build Coastguard Worker 			if (!ctx->user)
6667*58e6ee5fSAndroid Build Coastguard Worker 				die("Failed to allocate user name");
6668*58e6ee5fSAndroid Build Coastguard Worker 			break;
6669*58e6ee5fSAndroid Build Coastguard Worker 		case OPT_procmap:
6670*58e6ee5fSAndroid Build Coastguard Worker 			cmd_check_die(ctx, CMD_start, *(argv+1), "--proc-map");
6671*58e6ee5fSAndroid Build Coastguard Worker 			cmd_check_die(ctx, CMD_set, *(argv+1), "--proc-map");
6672*58e6ee5fSAndroid Build Coastguard Worker 			check_instance_die(ctx->instance, "--proc-map");
6673*58e6ee5fSAndroid Build Coastguard Worker 			ctx->instance->get_procmap = 1;
6674*58e6ee5fSAndroid Build Coastguard Worker 			break;
6675*58e6ee5fSAndroid Build Coastguard Worker 		case OPT_date:
6676*58e6ee5fSAndroid Build Coastguard Worker 			cmd_check_die(ctx, CMD_set, *(argv+1), "--date");
6677*58e6ee5fSAndroid Build Coastguard Worker 			ctx->date = 1;
6678*58e6ee5fSAndroid Build Coastguard Worker 			if (ctx->data_flags & DATA_FL_OFFSET)
6679*58e6ee5fSAndroid Build Coastguard Worker 				die("Can not use both --date and --ts-offset");
6680*58e6ee5fSAndroid Build Coastguard Worker 			ctx->data_flags |= DATA_FL_DATE;
6681*58e6ee5fSAndroid Build Coastguard Worker 			break;
6682*58e6ee5fSAndroid Build Coastguard Worker 		case OPT_funcstack:
6683*58e6ee5fSAndroid Build Coastguard Worker 			func_stack = 1;
6684*58e6ee5fSAndroid Build Coastguard Worker 			break;
6685*58e6ee5fSAndroid Build Coastguard Worker 		case OPT_nosplice:
6686*58e6ee5fSAndroid Build Coastguard Worker 			cmd_check_die(ctx, CMD_set, *(argv+1), "--nosplice");
6687*58e6ee5fSAndroid Build Coastguard Worker 			recorder_flags |= TRACECMD_RECORD_NOSPLICE;
6688*58e6ee5fSAndroid Build Coastguard Worker 			break;
6689*58e6ee5fSAndroid Build Coastguard Worker 		case OPT_nofifos:
6690*58e6ee5fSAndroid Build Coastguard Worker 			cmd_check_die(ctx, CMD_set, *(argv+1), "--nofifos");
6691*58e6ee5fSAndroid Build Coastguard Worker 			no_fifos = true;
6692*58e6ee5fSAndroid Build Coastguard Worker 			break;
6693*58e6ee5fSAndroid Build Coastguard Worker 		case OPT_profile:
6694*58e6ee5fSAndroid Build Coastguard Worker 			cmd_check_die(ctx, CMD_set, *(argv+1), "--profile");
6695*58e6ee5fSAndroid Build Coastguard Worker 			check_instance_die(ctx->instance, "--profile");
6696*58e6ee5fSAndroid Build Coastguard Worker 			handle_init = trace_init_profile;
6697*58e6ee5fSAndroid Build Coastguard Worker 			ctx->instance->flags |= BUFFER_FL_PROFILE;
6698*58e6ee5fSAndroid Build Coastguard Worker 			ctx->events = 1;
6699*58e6ee5fSAndroid Build Coastguard Worker 			break;
6700*58e6ee5fSAndroid Build Coastguard Worker 		case OPT_stderr:
6701*58e6ee5fSAndroid Build Coastguard Worker 			/* if -o was used (for profile), ignore this */
6702*58e6ee5fSAndroid Build Coastguard Worker 			if (save_stdout >= 0)
6703*58e6ee5fSAndroid Build Coastguard Worker 				break;
6704*58e6ee5fSAndroid Build Coastguard Worker 			save_stdout = dup(1);
6705*58e6ee5fSAndroid Build Coastguard Worker 			close(1);
6706*58e6ee5fSAndroid Build Coastguard Worker 			dup2(2, 1);
6707*58e6ee5fSAndroid Build Coastguard Worker 			break;
6708*58e6ee5fSAndroid Build Coastguard Worker 		case OPT_bycomm:
6709*58e6ee5fSAndroid Build Coastguard Worker 			cmd_check_die(ctx, CMD_set, *(argv+1), "--by-comm");
6710*58e6ee5fSAndroid Build Coastguard Worker 			trace_profile_set_merge_like_comms();
6711*58e6ee5fSAndroid Build Coastguard Worker 			break;
6712*58e6ee5fSAndroid Build Coastguard Worker 		case OPT_tsoffset:
6713*58e6ee5fSAndroid Build Coastguard Worker 			cmd_check_die(ctx, CMD_set, *(argv+1), "--ts-offset");
6714*58e6ee5fSAndroid Build Coastguard Worker 			ctx->date2ts = strdup(optarg);
6715*58e6ee5fSAndroid Build Coastguard Worker 			if (ctx->data_flags & DATA_FL_DATE)
6716*58e6ee5fSAndroid Build Coastguard Worker 				die("Can not use both --date and --ts-offset");
6717*58e6ee5fSAndroid Build Coastguard Worker 			ctx->data_flags |= DATA_FL_OFFSET;
6718*58e6ee5fSAndroid Build Coastguard Worker 			break;
6719*58e6ee5fSAndroid Build Coastguard Worker 		case OPT_max_graph_depth:
6720*58e6ee5fSAndroid Build Coastguard Worker 			check_instance_die(ctx->instance, "--max-graph-depth");
6721*58e6ee5fSAndroid Build Coastguard Worker 			free(ctx->instance->max_graph_depth);
6722*58e6ee5fSAndroid Build Coastguard Worker 			ctx->instance->max_graph_depth = strdup(optarg);
6723*58e6ee5fSAndroid Build Coastguard Worker 			if (!ctx->instance->max_graph_depth)
6724*58e6ee5fSAndroid Build Coastguard Worker 				die("Could not allocate option");
6725*58e6ee5fSAndroid Build Coastguard Worker 			break;
6726*58e6ee5fSAndroid Build Coastguard Worker 		case OPT_cmdlines_size:
6727*58e6ee5fSAndroid Build Coastguard Worker 			ctx->saved_cmdlines_size = atoi(optarg);
6728*58e6ee5fSAndroid Build Coastguard Worker 			break;
6729*58e6ee5fSAndroid Build Coastguard Worker 		case OPT_no_filter:
6730*58e6ee5fSAndroid Build Coastguard Worker 			cmd_check_die(ctx, CMD_set, *(argv+1), "--no-filter");
6731*58e6ee5fSAndroid Build Coastguard Worker 			no_filter = true;
6732*58e6ee5fSAndroid Build Coastguard Worker 			break;
6733*58e6ee5fSAndroid Build Coastguard Worker 		case OPT_debug:
6734*58e6ee5fSAndroid Build Coastguard Worker 			tracecmd_set_debug(true);
6735*58e6ee5fSAndroid Build Coastguard Worker 			break;
6736*58e6ee5fSAndroid Build Coastguard Worker 		case OPT_module:
6737*58e6ee5fSAndroid Build Coastguard Worker 			check_instance_die(ctx->instance, "--module");
6738*58e6ee5fSAndroid Build Coastguard Worker 			if (ctx->instance->filter_mod)
6739*58e6ee5fSAndroid Build Coastguard Worker 				add_func(&ctx->instance->filter_funcs,
6740*58e6ee5fSAndroid Build Coastguard Worker 					 ctx->instance->filter_mod, "*");
6741*58e6ee5fSAndroid Build Coastguard Worker 			ctx->instance->filter_mod = optarg;
6742*58e6ee5fSAndroid Build Coastguard Worker 			ctx->filtered = 0;
6743*58e6ee5fSAndroid Build Coastguard Worker 			break;
6744*58e6ee5fSAndroid Build Coastguard Worker 		case OPT_tsyncinterval:
6745*58e6ee5fSAndroid Build Coastguard Worker 			cmd_check_die(ctx, CMD_set, *(argv+1), "--tsync-interval");
6746*58e6ee5fSAndroid Build Coastguard Worker 			ctx->tsync_loop_interval = atoi(optarg);
6747*58e6ee5fSAndroid Build Coastguard Worker 			break;
6748*58e6ee5fSAndroid Build Coastguard Worker 		case OPT_fork:
6749*58e6ee5fSAndroid Build Coastguard Worker 			if (!IS_START(ctx))
6750*58e6ee5fSAndroid Build Coastguard Worker 				die("--fork option used for 'start' command only");
6751*58e6ee5fSAndroid Build Coastguard Worker 			fork_process = true;
6752*58e6ee5fSAndroid Build Coastguard Worker 			break;
6753*58e6ee5fSAndroid Build Coastguard Worker 		case OPT_tsc2nsec:
6754*58e6ee5fSAndroid Build Coastguard Worker 			ret = get_tsc_nsec(&ctx->tsc2nsec.shift,
6755*58e6ee5fSAndroid Build Coastguard Worker 					   &ctx->tsc2nsec.mult);
6756*58e6ee5fSAndroid Build Coastguard Worker 			if (ret)
6757*58e6ee5fSAndroid Build Coastguard Worker 				die("TSC to nanosecond is not supported");
6758*58e6ee5fSAndroid Build Coastguard Worker 			ctx->instance->flags |= BUFFER_FL_TSC2NSEC;
6759*58e6ee5fSAndroid Build Coastguard Worker 			break;
6760*58e6ee5fSAndroid Build Coastguard Worker 		case OPT_poll:
6761*58e6ee5fSAndroid Build Coastguard Worker 			cmd_check_die(ctx, CMD_set, *(argv+1), "--poll");
6762*58e6ee5fSAndroid Build Coastguard Worker 			recorder_flags |= TRACECMD_RECORD_POLL;
6763*58e6ee5fSAndroid Build Coastguard Worker 			break;
6764*58e6ee5fSAndroid Build Coastguard Worker 		case OPT_compression:
6765*58e6ee5fSAndroid Build Coastguard Worker 			cmd_check_die(ctx, CMD_start, *(argv+1), "--compression");
6766*58e6ee5fSAndroid Build Coastguard Worker 			cmd_check_die(ctx, CMD_set, *(argv+1), "--compression");
6767*58e6ee5fSAndroid Build Coastguard Worker 			cmd_check_die(ctx, CMD_extract, *(argv+1), "--compression");
6768*58e6ee5fSAndroid Build Coastguard Worker 			cmd_check_die(ctx, CMD_stream, *(argv+1), "--compression");
6769*58e6ee5fSAndroid Build Coastguard Worker 			cmd_check_die(ctx, CMD_profile, *(argv+1), "--compression");
6770*58e6ee5fSAndroid Build Coastguard Worker 			if (strcmp(optarg, "any") && strcmp(optarg, "none") &&
6771*58e6ee5fSAndroid Build Coastguard Worker 			    !tracecmd_compress_is_supported(optarg, NULL))
6772*58e6ee5fSAndroid Build Coastguard Worker 				die("Compression algorithm  %s is not supported", optarg);
6773*58e6ee5fSAndroid Build Coastguard Worker 			ctx->compression = strdup(optarg);
6774*58e6ee5fSAndroid Build Coastguard Worker 			break;
6775*58e6ee5fSAndroid Build Coastguard Worker 		case OPT_file_ver:
6776*58e6ee5fSAndroid Build Coastguard Worker 			if (ctx->curr_cmd != CMD_record && ctx->curr_cmd != CMD_record_agent)
6777*58e6ee5fSAndroid Build Coastguard Worker 				die("--file_version has no effect with the command %s\n",
6778*58e6ee5fSAndroid Build Coastguard Worker 				    *(argv+1));
6779*58e6ee5fSAndroid Build Coastguard Worker 			ctx->file_version = atoi(optarg);
6780*58e6ee5fSAndroid Build Coastguard Worker 			if (ctx->file_version < FILE_VERSION_MIN ||
6781*58e6ee5fSAndroid Build Coastguard Worker 			    ctx->file_version > FILE_VERSION_MAX)
6782*58e6ee5fSAndroid Build Coastguard Worker 				die("Unsupported file version %d, "
6783*58e6ee5fSAndroid Build Coastguard Worker 				    "supported versions are from %d to %d",
6784*58e6ee5fSAndroid Build Coastguard Worker 				    ctx->file_version, FILE_VERSION_MIN, FILE_VERSION_MAX);
6785*58e6ee5fSAndroid Build Coastguard Worker 			break;
6786*58e6ee5fSAndroid Build Coastguard Worker 		case OPT_quiet:
6787*58e6ee5fSAndroid Build Coastguard Worker 		case 'q':
6788*58e6ee5fSAndroid Build Coastguard Worker 			quiet = true;
6789*58e6ee5fSAndroid Build Coastguard Worker 			break;
6790*58e6ee5fSAndroid Build Coastguard Worker 		case OPT_verbose:
6791*58e6ee5fSAndroid Build Coastguard Worker 			if (trace_set_verbose(optarg) < 0)
6792*58e6ee5fSAndroid Build Coastguard Worker 				die("invalid verbose level %s", optarg);
6793*58e6ee5fSAndroid Build Coastguard Worker 			break;
6794*58e6ee5fSAndroid Build Coastguard Worker 		default:
6795*58e6ee5fSAndroid Build Coastguard Worker 			usage(argv);
6796*58e6ee5fSAndroid Build Coastguard Worker 		}
6797*58e6ee5fSAndroid Build Coastguard Worker 	}
6798*58e6ee5fSAndroid Build Coastguard Worker 
6799*58e6ee5fSAndroid Build Coastguard Worker 	remove_instances(del_list);
6800*58e6ee5fSAndroid Build Coastguard Worker 
6801*58e6ee5fSAndroid Build Coastguard Worker 	/* If --date is specified, prepend it to all guest VM flags */
6802*58e6ee5fSAndroid Build Coastguard Worker 	if (ctx->date) {
6803*58e6ee5fSAndroid Build Coastguard Worker 		struct buffer_instance *instance;
6804*58e6ee5fSAndroid Build Coastguard Worker 
6805*58e6ee5fSAndroid Build Coastguard Worker 		for_all_instances(instance) {
6806*58e6ee5fSAndroid Build Coastguard Worker 			if (is_guest(instance))
6807*58e6ee5fSAndroid Build Coastguard Worker 				add_argv(instance, "--date", true);
6808*58e6ee5fSAndroid Build Coastguard Worker 		}
6809*58e6ee5fSAndroid Build Coastguard Worker 	}
6810*58e6ee5fSAndroid Build Coastguard Worker 
6811*58e6ee5fSAndroid Build Coastguard Worker 	if (!ctx->filtered && ctx->instance->filter_mod)
6812*58e6ee5fSAndroid Build Coastguard Worker 		add_func(&ctx->instance->filter_funcs,
6813*58e6ee5fSAndroid Build Coastguard Worker 			 ctx->instance->filter_mod, "*");
6814*58e6ee5fSAndroid Build Coastguard Worker 
6815*58e6ee5fSAndroid Build Coastguard Worker 	if (do_children && !filter_task && !fpids_count)
6816*58e6ee5fSAndroid Build Coastguard Worker 		die(" -c can only be used with -F (or -P with event-fork support)");
6817*58e6ee5fSAndroid Build Coastguard Worker 
6818*58e6ee5fSAndroid Build Coastguard Worker 	if ((argc - optind) >= 2) {
6819*58e6ee5fSAndroid Build Coastguard Worker 		if (IS_EXTRACT(ctx))
6820*58e6ee5fSAndroid Build Coastguard Worker 			die("Command extract does not take any commands\n"
6821*58e6ee5fSAndroid Build Coastguard Worker 			    "Did you mean 'record'?");
6822*58e6ee5fSAndroid Build Coastguard Worker 		ctx->run_command = 1;
6823*58e6ee5fSAndroid Build Coastguard Worker 	}
6824*58e6ee5fSAndroid Build Coastguard Worker 	if (ctx->user && !ctx->run_command)
6825*58e6ee5fSAndroid Build Coastguard Worker 		warning("--user %s is ignored, no command is specified",
6826*58e6ee5fSAndroid Build Coastguard Worker 			ctx->user);
6827*58e6ee5fSAndroid Build Coastguard Worker 
6828*58e6ee5fSAndroid Build Coastguard Worker 	if (top_instance.get_procmap) {
6829*58e6ee5fSAndroid Build Coastguard Worker 		 /* use ptrace to get procmap on the command exit */
6830*58e6ee5fSAndroid Build Coastguard Worker 		if (ctx->run_command) {
6831*58e6ee5fSAndroid Build Coastguard Worker 			do_ptrace = 1;
6832*58e6ee5fSAndroid Build Coastguard Worker 		} else if (!top_instance.nr_filter_pids) {
6833*58e6ee5fSAndroid Build Coastguard Worker 			warning("--proc-map is ignored for top instance, "
6834*58e6ee5fSAndroid Build Coastguard Worker 				"no command or filtered PIDs are specified.");
6835*58e6ee5fSAndroid Build Coastguard Worker 			top_instance.get_procmap = 0;
6836*58e6ee5fSAndroid Build Coastguard Worker 		}
6837*58e6ee5fSAndroid Build Coastguard Worker 	}
6838*58e6ee5fSAndroid Build Coastguard Worker 
6839*58e6ee5fSAndroid Build Coastguard Worker 	for_all_instances(instance) {
6840*58e6ee5fSAndroid Build Coastguard Worker 		if (instance->get_procmap && !instance->nr_filter_pids) {
6841*58e6ee5fSAndroid Build Coastguard Worker 			warning("--proc-map is ignored for instance %s, "
6842*58e6ee5fSAndroid Build Coastguard Worker 				"no filtered PIDs are specified.",
6843*58e6ee5fSAndroid Build Coastguard Worker 				tracefs_instance_get_name(instance->tracefs));
6844*58e6ee5fSAndroid Build Coastguard Worker 			instance->get_procmap = 0;
6845*58e6ee5fSAndroid Build Coastguard Worker 		}
6846*58e6ee5fSAndroid Build Coastguard Worker 	}
6847*58e6ee5fSAndroid Build Coastguard Worker }
6848*58e6ee5fSAndroid Build Coastguard Worker 
get_trace_cmd_type(enum trace_cmd cmd)6849*58e6ee5fSAndroid Build Coastguard Worker static enum trace_type get_trace_cmd_type(enum trace_cmd cmd)
6850*58e6ee5fSAndroid Build Coastguard Worker {
6851*58e6ee5fSAndroid Build Coastguard Worker 	const static struct {
6852*58e6ee5fSAndroid Build Coastguard Worker 		enum trace_cmd cmd;
6853*58e6ee5fSAndroid Build Coastguard Worker 		enum trace_type ttype;
6854*58e6ee5fSAndroid Build Coastguard Worker 	} trace_type_per_command[] = {
6855*58e6ee5fSAndroid Build Coastguard Worker 		{CMD_record, TRACE_TYPE_RECORD},
6856*58e6ee5fSAndroid Build Coastguard Worker 		{CMD_stream, TRACE_TYPE_STREAM},
6857*58e6ee5fSAndroid Build Coastguard Worker 		{CMD_extract, TRACE_TYPE_EXTRACT},
6858*58e6ee5fSAndroid Build Coastguard Worker 		{CMD_profile, TRACE_TYPE_STREAM},
6859*58e6ee5fSAndroid Build Coastguard Worker 		{CMD_start, TRACE_TYPE_START},
6860*58e6ee5fSAndroid Build Coastguard Worker 		{CMD_record_agent, TRACE_TYPE_RECORD},
6861*58e6ee5fSAndroid Build Coastguard Worker 		{CMD_set, TRACE_TYPE_SET}
6862*58e6ee5fSAndroid Build Coastguard Worker 	};
6863*58e6ee5fSAndroid Build Coastguard Worker 
6864*58e6ee5fSAndroid Build Coastguard Worker 	for (int i = 0; i < ARRAY_SIZE(trace_type_per_command); i++) {
6865*58e6ee5fSAndroid Build Coastguard Worker 		if (trace_type_per_command[i].cmd == cmd)
6866*58e6ee5fSAndroid Build Coastguard Worker 			return trace_type_per_command[i].ttype;
6867*58e6ee5fSAndroid Build Coastguard Worker 	}
6868*58e6ee5fSAndroid Build Coastguard Worker 
6869*58e6ee5fSAndroid Build Coastguard Worker 	die("Trace type UNKNOWN for the given cmd_fun");
6870*58e6ee5fSAndroid Build Coastguard Worker }
6871*58e6ee5fSAndroid Build Coastguard Worker 
finalize_record_trace(struct common_record_context * ctx)6872*58e6ee5fSAndroid Build Coastguard Worker static void finalize_record_trace(struct common_record_context *ctx)
6873*58e6ee5fSAndroid Build Coastguard Worker {
6874*58e6ee5fSAndroid Build Coastguard Worker 	struct buffer_instance *instance;
6875*58e6ee5fSAndroid Build Coastguard Worker 
6876*58e6ee5fSAndroid Build Coastguard Worker 	if (keep)
6877*58e6ee5fSAndroid Build Coastguard Worker 		return;
6878*58e6ee5fSAndroid Build Coastguard Worker 
6879*58e6ee5fSAndroid Build Coastguard Worker 	update_reset_files();
6880*58e6ee5fSAndroid Build Coastguard Worker 	update_reset_triggers();
6881*58e6ee5fSAndroid Build Coastguard Worker 	if (clear_function_filters)
6882*58e6ee5fSAndroid Build Coastguard Worker 		clear_func_filters();
6883*58e6ee5fSAndroid Build Coastguard Worker 
6884*58e6ee5fSAndroid Build Coastguard Worker 	set_plugin("nop");
6885*58e6ee5fSAndroid Build Coastguard Worker 
6886*58e6ee5fSAndroid Build Coastguard Worker 	tracecmd_remove_instances();
6887*58e6ee5fSAndroid Build Coastguard Worker 
6888*58e6ee5fSAndroid Build Coastguard Worker 	/* If tracing_on was enabled before we started, set it on now */
6889*58e6ee5fSAndroid Build Coastguard Worker 	for_all_instances(instance) {
6890*58e6ee5fSAndroid Build Coastguard Worker 		if (instance->flags & BUFFER_FL_KEEP)
6891*58e6ee5fSAndroid Build Coastguard Worker 			write_tracing_on(instance,
6892*58e6ee5fSAndroid Build Coastguard Worker 					 instance->tracing_on_init_val);
6893*58e6ee5fSAndroid Build Coastguard Worker 		if (is_agent(instance)) {
6894*58e6ee5fSAndroid Build Coastguard Worker 			tracecmd_msg_send_close_resp_msg(instance->msg_handle);
6895*58e6ee5fSAndroid Build Coastguard Worker 			tracecmd_output_close(instance->network_handle);
6896*58e6ee5fSAndroid Build Coastguard Worker 		}
6897*58e6ee5fSAndroid Build Coastguard Worker 	}
6898*58e6ee5fSAndroid Build Coastguard Worker 
6899*58e6ee5fSAndroid Build Coastguard Worker 	if (host)
6900*58e6ee5fSAndroid Build Coastguard Worker 		tracecmd_output_close(ctx->instance->network_handle);
6901*58e6ee5fSAndroid Build Coastguard Worker }
6902*58e6ee5fSAndroid Build Coastguard Worker 
has_local_instances(void)6903*58e6ee5fSAndroid Build Coastguard Worker static bool has_local_instances(void)
6904*58e6ee5fSAndroid Build Coastguard Worker {
6905*58e6ee5fSAndroid Build Coastguard Worker 	struct buffer_instance *instance;
6906*58e6ee5fSAndroid Build Coastguard Worker 
6907*58e6ee5fSAndroid Build Coastguard Worker 	for_all_instances(instance) {
6908*58e6ee5fSAndroid Build Coastguard Worker 		if (is_guest(instance))
6909*58e6ee5fSAndroid Build Coastguard Worker 			continue;
6910*58e6ee5fSAndroid Build Coastguard Worker 		if (host && instance->msg_handle)
6911*58e6ee5fSAndroid Build Coastguard Worker 			continue;
6912*58e6ee5fSAndroid Build Coastguard Worker 		return true;
6913*58e6ee5fSAndroid Build Coastguard Worker 	}
6914*58e6ee5fSAndroid Build Coastguard Worker 	return false;
6915*58e6ee5fSAndroid Build Coastguard Worker }
6916*58e6ee5fSAndroid Build Coastguard Worker 
set_tsync_params(struct common_record_context * ctx)6917*58e6ee5fSAndroid Build Coastguard Worker static void set_tsync_params(struct common_record_context *ctx)
6918*58e6ee5fSAndroid Build Coastguard Worker {
6919*58e6ee5fSAndroid Build Coastguard Worker 	struct buffer_instance *instance;
6920*58e6ee5fSAndroid Build Coastguard Worker 	int shift, mult;
6921*58e6ee5fSAndroid Build Coastguard Worker 	bool force_tsc = false;
6922*58e6ee5fSAndroid Build Coastguard Worker 	char *clock = NULL;
6923*58e6ee5fSAndroid Build Coastguard Worker 
6924*58e6ee5fSAndroid Build Coastguard Worker 	if (!ctx->clock) {
6925*58e6ee5fSAndroid Build Coastguard Worker 	/*
6926*58e6ee5fSAndroid Build Coastguard Worker 	 * If no clock is configured &&
6927*58e6ee5fSAndroid Build Coastguard Worker 	 * KVM time sync protocol is available &&
6928*58e6ee5fSAndroid Build Coastguard Worker 	 * there is information of each guest PID process &&
6929*58e6ee5fSAndroid Build Coastguard Worker 	 * tsc-x86 clock is supported &&
6930*58e6ee5fSAndroid Build Coastguard Worker 	 * TSC to nsec multiplier and shift are available:
6931*58e6ee5fSAndroid Build Coastguard Worker 	 * force using the x86-tsc clock for this host-guest tracing session
6932*58e6ee5fSAndroid Build Coastguard Worker 	 * and store TSC to nsec multiplier and shift.
6933*58e6ee5fSAndroid Build Coastguard Worker 	 */
6934*58e6ee5fSAndroid Build Coastguard Worker 		if (tsync_proto_is_supported("kvm") &&
6935*58e6ee5fSAndroid Build Coastguard Worker 		    trace_have_guests_pid() &&
6936*58e6ee5fSAndroid Build Coastguard Worker 		    clock_is_supported(NULL, TSC_CLOCK) &&
6937*58e6ee5fSAndroid Build Coastguard Worker 		    !get_tsc_nsec(&shift, &mult) && mult) {
6938*58e6ee5fSAndroid Build Coastguard Worker 			clock = strdup(TSC_CLOCK);
6939*58e6ee5fSAndroid Build Coastguard Worker 			if (!clock)
6940*58e6ee5fSAndroid Build Coastguard Worker 				die("Cannot not allocate clock");
6941*58e6ee5fSAndroid Build Coastguard Worker 			ctx->tsc2nsec.mult = mult;
6942*58e6ee5fSAndroid Build Coastguard Worker 			ctx->tsc2nsec.shift = shift;
6943*58e6ee5fSAndroid Build Coastguard Worker 			force_tsc = true;
6944*58e6ee5fSAndroid Build Coastguard Worker 		} else { /* Use the current clock of the first host instance */
6945*58e6ee5fSAndroid Build Coastguard Worker 			clock = get_trace_clock(true);
6946*58e6ee5fSAndroid Build Coastguard Worker 		}
6947*58e6ee5fSAndroid Build Coastguard Worker 	} else {
6948*58e6ee5fSAndroid Build Coastguard Worker 		clock = strdup(ctx->clock);
6949*58e6ee5fSAndroid Build Coastguard Worker 		if (!clock)
6950*58e6ee5fSAndroid Build Coastguard Worker 			die("Cannot not allocate clock");
6951*58e6ee5fSAndroid Build Coastguard Worker 	}
6952*58e6ee5fSAndroid Build Coastguard Worker 
6953*58e6ee5fSAndroid Build Coastguard Worker 	if (!clock && !ctx->tsync_loop_interval)
6954*58e6ee5fSAndroid Build Coastguard Worker 		goto out;
6955*58e6ee5fSAndroid Build Coastguard Worker 	for_all_instances(instance) {
6956*58e6ee5fSAndroid Build Coastguard Worker 		if (clock && !(instance->flags & BUFFER_FL_HAS_CLOCK)) {
6957*58e6ee5fSAndroid Build Coastguard Worker 			/* use the same clock in all tracing peers */
6958*58e6ee5fSAndroid Build Coastguard Worker 			if (is_guest(instance)) {
6959*58e6ee5fSAndroid Build Coastguard Worker 				if (!instance->clock) {
6960*58e6ee5fSAndroid Build Coastguard Worker 					instance->clock = strdup(clock);
6961*58e6ee5fSAndroid Build Coastguard Worker 					if (!instance->clock)
6962*58e6ee5fSAndroid Build Coastguard Worker 						die("Can not allocate instance clock");
6963*58e6ee5fSAndroid Build Coastguard Worker 				}
6964*58e6ee5fSAndroid Build Coastguard Worker 				add_argv(instance, (char *)instance->clock, true);
6965*58e6ee5fSAndroid Build Coastguard Worker 				add_argv(instance, "-C", true);
6966*58e6ee5fSAndroid Build Coastguard Worker 				if (ctx->tsc2nsec.mult)
6967*58e6ee5fSAndroid Build Coastguard Worker 					instance->flags |= BUFFER_FL_TSC2NSEC;
6968*58e6ee5fSAndroid Build Coastguard Worker 			} else if (force_tsc && !instance->clock) {
6969*58e6ee5fSAndroid Build Coastguard Worker 				instance->clock = strdup(clock);
6970*58e6ee5fSAndroid Build Coastguard Worker 				if (!instance->clock)
6971*58e6ee5fSAndroid Build Coastguard Worker 					die("Can not allocate instance clock");
6972*58e6ee5fSAndroid Build Coastguard Worker 			}
6973*58e6ee5fSAndroid Build Coastguard Worker 		}
6974*58e6ee5fSAndroid Build Coastguard Worker 		instance->tsync_loop_interval = ctx->tsync_loop_interval;
6975*58e6ee5fSAndroid Build Coastguard Worker 	}
6976*58e6ee5fSAndroid Build Coastguard Worker out:
6977*58e6ee5fSAndroid Build Coastguard Worker 	free(clock);
6978*58e6ee5fSAndroid Build Coastguard Worker }
6979*58e6ee5fSAndroid Build Coastguard Worker 
record_trace(int argc,char ** argv,struct common_record_context * ctx)6980*58e6ee5fSAndroid Build Coastguard Worker static void record_trace(int argc, char **argv,
6981*58e6ee5fSAndroid Build Coastguard Worker 			 struct common_record_context *ctx)
6982*58e6ee5fSAndroid Build Coastguard Worker {
6983*58e6ee5fSAndroid Build Coastguard Worker 	enum trace_type type = get_trace_cmd_type(ctx->curr_cmd);
6984*58e6ee5fSAndroid Build Coastguard Worker 	struct buffer_instance *instance;
6985*58e6ee5fSAndroid Build Coastguard Worker 	struct filter_pids *pid;
6986*58e6ee5fSAndroid Build Coastguard Worker 
6987*58e6ee5fSAndroid Build Coastguard Worker 	/*
6988*58e6ee5fSAndroid Build Coastguard Worker 	 * If top_instance doesn't have any plugins or events, then
6989*58e6ee5fSAndroid Build Coastguard Worker 	 * remove it from being processed.
6990*58e6ee5fSAndroid Build Coastguard Worker 	 */
6991*58e6ee5fSAndroid Build Coastguard Worker 	if (!__check_doing_something(&top_instance) && !filter_task)
6992*58e6ee5fSAndroid Build Coastguard Worker 		first_instance = buffer_instances;
6993*58e6ee5fSAndroid Build Coastguard Worker 	else
6994*58e6ee5fSAndroid Build Coastguard Worker 		ctx->topt = 1;
6995*58e6ee5fSAndroid Build Coastguard Worker 
6996*58e6ee5fSAndroid Build Coastguard Worker 	update_first_instance(ctx->instance, ctx->topt);
6997*58e6ee5fSAndroid Build Coastguard Worker 	if (!IS_CMDSET(ctx)) {
6998*58e6ee5fSAndroid Build Coastguard Worker 		check_doing_something();
6999*58e6ee5fSAndroid Build Coastguard Worker 		check_function_plugin();
7000*58e6ee5fSAndroid Build Coastguard Worker 	}
7001*58e6ee5fSAndroid Build Coastguard Worker 
7002*58e6ee5fSAndroid Build Coastguard Worker 	if (!ctx->output)
7003*58e6ee5fSAndroid Build Coastguard Worker 		ctx->output = DEFAULT_INPUT_FILE;
7004*58e6ee5fSAndroid Build Coastguard Worker 
7005*58e6ee5fSAndroid Build Coastguard Worker 	if (ctx->data_flags & DATA_FL_GUEST)
7006*58e6ee5fSAndroid Build Coastguard Worker 		set_tsync_params(ctx);
7007*58e6ee5fSAndroid Build Coastguard Worker 
7008*58e6ee5fSAndroid Build Coastguard Worker 	make_instances();
7009*58e6ee5fSAndroid Build Coastguard Worker 
7010*58e6ee5fSAndroid Build Coastguard Worker 	/* Save the state of tracing_on before starting */
7011*58e6ee5fSAndroid Build Coastguard Worker 	for_all_instances(instance) {
7012*58e6ee5fSAndroid Build Coastguard Worker 		instance->output_file = strdup(ctx->output);
7013*58e6ee5fSAndroid Build Coastguard Worker 		if (!instance->output_file)
7014*58e6ee5fSAndroid Build Coastguard Worker 			die("Failed to allocate output file name for instance");
7015*58e6ee5fSAndroid Build Coastguard Worker 		if (!ctx->manual && instance->flags & BUFFER_FL_PROFILE)
7016*58e6ee5fSAndroid Build Coastguard Worker 			enable_profile(instance);
7017*58e6ee5fSAndroid Build Coastguard Worker 
7018*58e6ee5fSAndroid Build Coastguard Worker 		instance->tracing_on_init_val = read_tracing_on(instance);
7019*58e6ee5fSAndroid Build Coastguard Worker 		/* Some instances may not be created yet */
7020*58e6ee5fSAndroid Build Coastguard Worker 		if (instance->tracing_on_init_val < 0)
7021*58e6ee5fSAndroid Build Coastguard Worker 			instance->tracing_on_init_val = 1;
7022*58e6ee5fSAndroid Build Coastguard Worker 	}
7023*58e6ee5fSAndroid Build Coastguard Worker 
7024*58e6ee5fSAndroid Build Coastguard Worker 	if (ctx->events)
7025*58e6ee5fSAndroid Build Coastguard Worker 		expand_event_list();
7026*58e6ee5fSAndroid Build Coastguard Worker 
7027*58e6ee5fSAndroid Build Coastguard Worker 	page_size = getpagesize();
7028*58e6ee5fSAndroid Build Coastguard Worker 
7029*58e6ee5fSAndroid Build Coastguard Worker 	if (!is_guest(ctx->instance))
7030*58e6ee5fSAndroid Build Coastguard Worker 		fset = set_ftrace(ctx->instance, !ctx->disable, ctx->total_disable);
7031*58e6ee5fSAndroid Build Coastguard Worker 	if (!IS_CMDSET(ctx))
7032*58e6ee5fSAndroid Build Coastguard Worker 		tracecmd_disable_all_tracing(1);
7033*58e6ee5fSAndroid Build Coastguard Worker 
7034*58e6ee5fSAndroid Build Coastguard Worker 	for_all_instances(instance)
7035*58e6ee5fSAndroid Build Coastguard Worker 		set_clock(ctx, instance);
7036*58e6ee5fSAndroid Build Coastguard Worker 
7037*58e6ee5fSAndroid Build Coastguard Worker 
7038*58e6ee5fSAndroid Build Coastguard Worker 	/* Record records the date first */
7039*58e6ee5fSAndroid Build Coastguard Worker 	if (ctx->date &&
7040*58e6ee5fSAndroid Build Coastguard Worker 	    ((IS_RECORD(ctx) && has_local_instances()) || IS_RECORD_AGENT(ctx)))
7041*58e6ee5fSAndroid Build Coastguard Worker 		ctx->date2ts = get_date_to_ts();
7042*58e6ee5fSAndroid Build Coastguard Worker 
7043*58e6ee5fSAndroid Build Coastguard Worker 	for_all_instances(instance) {
7044*58e6ee5fSAndroid Build Coastguard Worker 		set_funcs(instance);
7045*58e6ee5fSAndroid Build Coastguard Worker 		set_mask(instance);
7046*58e6ee5fSAndroid Build Coastguard Worker 	}
7047*58e6ee5fSAndroid Build Coastguard Worker 
7048*58e6ee5fSAndroid Build Coastguard Worker 	if (ctx->events) {
7049*58e6ee5fSAndroid Build Coastguard Worker 		for_all_instances(instance)
7050*58e6ee5fSAndroid Build Coastguard Worker 			enable_events(instance);
7051*58e6ee5fSAndroid Build Coastguard Worker 	}
7052*58e6ee5fSAndroid Build Coastguard Worker 
7053*58e6ee5fSAndroid Build Coastguard Worker 	set_saved_cmdlines_size(ctx);
7054*58e6ee5fSAndroid Build Coastguard Worker 	set_buffer_size();
7055*58e6ee5fSAndroid Build Coastguard Worker 	update_plugins(type);
7056*58e6ee5fSAndroid Build Coastguard Worker 	set_options();
7057*58e6ee5fSAndroid Build Coastguard Worker 
7058*58e6ee5fSAndroid Build Coastguard Worker 	for_all_instances(instance) {
7059*58e6ee5fSAndroid Build Coastguard Worker 		if (instance->max_graph_depth) {
7060*58e6ee5fSAndroid Build Coastguard Worker 			set_max_graph_depth(instance, instance->max_graph_depth);
7061*58e6ee5fSAndroid Build Coastguard Worker 			free(instance->max_graph_depth);
7062*58e6ee5fSAndroid Build Coastguard Worker 			instance->max_graph_depth = NULL;
7063*58e6ee5fSAndroid Build Coastguard Worker 		}
7064*58e6ee5fSAndroid Build Coastguard Worker 	}
7065*58e6ee5fSAndroid Build Coastguard Worker 
7066*58e6ee5fSAndroid Build Coastguard Worker 	allocate_seq();
7067*58e6ee5fSAndroid Build Coastguard Worker 
7068*58e6ee5fSAndroid Build Coastguard Worker 	if (type & (TRACE_TYPE_RECORD | TRACE_TYPE_STREAM)) {
7069*58e6ee5fSAndroid Build Coastguard Worker 		signal(SIGINT, finish);
7070*58e6ee5fSAndroid Build Coastguard Worker 		if (!latency)
7071*58e6ee5fSAndroid Build Coastguard Worker 			start_threads(type, ctx);
7072*58e6ee5fSAndroid Build Coastguard Worker 	}
7073*58e6ee5fSAndroid Build Coastguard Worker 
7074*58e6ee5fSAndroid Build Coastguard Worker 	if (ctx->run_command) {
7075*58e6ee5fSAndroid Build Coastguard Worker 		run_cmd(type, ctx->user, (argc - optind) - 1, &argv[optind + 1]);
7076*58e6ee5fSAndroid Build Coastguard Worker 	} else if (ctx->instance && is_agent(ctx->instance)) {
7077*58e6ee5fSAndroid Build Coastguard Worker 		update_task_filter();
7078*58e6ee5fSAndroid Build Coastguard Worker 		tracecmd_enable_tracing();
7079*58e6ee5fSAndroid Build Coastguard Worker 		tracecmd_msg_wait_close(ctx->instance->msg_handle);
7080*58e6ee5fSAndroid Build Coastguard Worker 	} else {
7081*58e6ee5fSAndroid Build Coastguard Worker 		bool pwait = false;
7082*58e6ee5fSAndroid Build Coastguard Worker 		bool wait_indefinitely = false;
7083*58e6ee5fSAndroid Build Coastguard Worker 
7084*58e6ee5fSAndroid Build Coastguard Worker 		update_task_filter();
7085*58e6ee5fSAndroid Build Coastguard Worker 
7086*58e6ee5fSAndroid Build Coastguard Worker 		if (!IS_CMDSET(ctx))
7087*58e6ee5fSAndroid Build Coastguard Worker 			tracecmd_enable_tracing();
7088*58e6ee5fSAndroid Build Coastguard Worker 
7089*58e6ee5fSAndroid Build Coastguard Worker 		if (type & (TRACE_TYPE_START | TRACE_TYPE_SET))
7090*58e6ee5fSAndroid Build Coastguard Worker 			exit(0);
7091*58e6ee5fSAndroid Build Coastguard Worker 
7092*58e6ee5fSAndroid Build Coastguard Worker 		/* We don't ptrace ourself */
7093*58e6ee5fSAndroid Build Coastguard Worker 		if (do_ptrace) {
7094*58e6ee5fSAndroid Build Coastguard Worker 			for_all_instances(instance) {
7095*58e6ee5fSAndroid Build Coastguard Worker 				for (pid = instance->filter_pids; pid; pid = pid->next) {
7096*58e6ee5fSAndroid Build Coastguard Worker 					if (!pid->exclude && instance->ptrace_child) {
7097*58e6ee5fSAndroid Build Coastguard Worker 						ptrace_attach(instance, pid->pid);
7098*58e6ee5fSAndroid Build Coastguard Worker 						pwait = true;
7099*58e6ee5fSAndroid Build Coastguard Worker 					}
7100*58e6ee5fSAndroid Build Coastguard Worker 				}
7101*58e6ee5fSAndroid Build Coastguard Worker 			}
7102*58e6ee5fSAndroid Build Coastguard Worker 		}
7103*58e6ee5fSAndroid Build Coastguard Worker 		/* sleep till we are woken with Ctrl^C */
7104*58e6ee5fSAndroid Build Coastguard Worker 		printf("Hit Ctrl^C to stop recording\n");
7105*58e6ee5fSAndroid Build Coastguard Worker 		for_all_instances(instance) {
7106*58e6ee5fSAndroid Build Coastguard Worker 			/* If an instance is not tracing individual processes
7107*58e6ee5fSAndroid Build Coastguard Worker 			 * or there is an error while waiting for a process to
7108*58e6ee5fSAndroid Build Coastguard Worker 			 * exit, fallback to waiting indefinitely.
7109*58e6ee5fSAndroid Build Coastguard Worker 			 */
7110*58e6ee5fSAndroid Build Coastguard Worker 			if (!instance->nr_process_pids ||
7111*58e6ee5fSAndroid Build Coastguard Worker 			    trace_wait_for_processes(instance))
7112*58e6ee5fSAndroid Build Coastguard Worker 				wait_indefinitely = true;
7113*58e6ee5fSAndroid Build Coastguard Worker 		}
7114*58e6ee5fSAndroid Build Coastguard Worker 		while (!finished && wait_indefinitely)
7115*58e6ee5fSAndroid Build Coastguard Worker 			trace_or_sleep(type, pwait);
7116*58e6ee5fSAndroid Build Coastguard Worker 	}
7117*58e6ee5fSAndroid Build Coastguard Worker 
7118*58e6ee5fSAndroid Build Coastguard Worker 	tell_guests_to_stop(ctx);
7119*58e6ee5fSAndroid Build Coastguard Worker 	tracecmd_disable_tracing();
7120*58e6ee5fSAndroid Build Coastguard Worker 	if (!latency)
7121*58e6ee5fSAndroid Build Coastguard Worker 		stop_threads(type);
7122*58e6ee5fSAndroid Build Coastguard Worker 
7123*58e6ee5fSAndroid Build Coastguard Worker 	record_stats();
7124*58e6ee5fSAndroid Build Coastguard Worker 
7125*58e6ee5fSAndroid Build Coastguard Worker 	if (!latency)
7126*58e6ee5fSAndroid Build Coastguard Worker 		wait_threads();
7127*58e6ee5fSAndroid Build Coastguard Worker 
7128*58e6ee5fSAndroid Build Coastguard Worker 	if (IS_RECORD(ctx)) {
7129*58e6ee5fSAndroid Build Coastguard Worker 		record_data(ctx);
7130*58e6ee5fSAndroid Build Coastguard Worker 		delete_thread_data();
7131*58e6ee5fSAndroid Build Coastguard Worker 	} else
7132*58e6ee5fSAndroid Build Coastguard Worker 		print_stats();
7133*58e6ee5fSAndroid Build Coastguard Worker 
7134*58e6ee5fSAndroid Build Coastguard Worker 	if (!keep)
7135*58e6ee5fSAndroid Build Coastguard Worker 		tracecmd_disable_all_tracing(0);
7136*58e6ee5fSAndroid Build Coastguard Worker 
7137*58e6ee5fSAndroid Build Coastguard Worker 	destroy_stats();
7138*58e6ee5fSAndroid Build Coastguard Worker 	finalize_record_trace(ctx);
7139*58e6ee5fSAndroid Build Coastguard Worker }
7140*58e6ee5fSAndroid Build Coastguard Worker 
7141*58e6ee5fSAndroid Build Coastguard Worker /*
7142*58e6ee5fSAndroid Build Coastguard Worker  * This function contains common code for the following commands:
7143*58e6ee5fSAndroid Build Coastguard Worker  * record, start, stream, profile.
7144*58e6ee5fSAndroid Build Coastguard Worker  */
record_trace_command(int argc,char ** argv,struct common_record_context * ctx)7145*58e6ee5fSAndroid Build Coastguard Worker static void record_trace_command(int argc, char **argv,
7146*58e6ee5fSAndroid Build Coastguard Worker 				 struct common_record_context *ctx)
7147*58e6ee5fSAndroid Build Coastguard Worker {
7148*58e6ee5fSAndroid Build Coastguard Worker 	tracecmd_tsync_init();
7149*58e6ee5fSAndroid Build Coastguard Worker 	record_trace(argc, argv, ctx);
7150*58e6ee5fSAndroid Build Coastguard Worker }
7151*58e6ee5fSAndroid Build Coastguard Worker 
trace_start(int argc,char ** argv)7152*58e6ee5fSAndroid Build Coastguard Worker void trace_start(int argc, char **argv)
7153*58e6ee5fSAndroid Build Coastguard Worker {
7154*58e6ee5fSAndroid Build Coastguard Worker 	struct common_record_context ctx;
7155*58e6ee5fSAndroid Build Coastguard Worker 
7156*58e6ee5fSAndroid Build Coastguard Worker 	parse_record_options(argc, argv, CMD_start, &ctx);
7157*58e6ee5fSAndroid Build Coastguard Worker 	record_trace_command(argc, argv, &ctx);
7158*58e6ee5fSAndroid Build Coastguard Worker 	exit(0);
7159*58e6ee5fSAndroid Build Coastguard Worker }
7160*58e6ee5fSAndroid Build Coastguard Worker 
trace_set(int argc,char ** argv)7161*58e6ee5fSAndroid Build Coastguard Worker void trace_set(int argc, char **argv)
7162*58e6ee5fSAndroid Build Coastguard Worker {
7163*58e6ee5fSAndroid Build Coastguard Worker 	struct common_record_context ctx;
7164*58e6ee5fSAndroid Build Coastguard Worker 
7165*58e6ee5fSAndroid Build Coastguard Worker 	parse_record_options(argc, argv, CMD_set, &ctx);
7166*58e6ee5fSAndroid Build Coastguard Worker 	record_trace_command(argc, argv, &ctx);
7167*58e6ee5fSAndroid Build Coastguard Worker 	exit(0);
7168*58e6ee5fSAndroid Build Coastguard Worker }
7169*58e6ee5fSAndroid Build Coastguard Worker 
trace_extract(int argc,char ** argv)7170*58e6ee5fSAndroid Build Coastguard Worker void trace_extract(int argc, char **argv)
7171*58e6ee5fSAndroid Build Coastguard Worker {
7172*58e6ee5fSAndroid Build Coastguard Worker 	struct common_record_context ctx;
7173*58e6ee5fSAndroid Build Coastguard Worker 	struct buffer_instance *instance;
7174*58e6ee5fSAndroid Build Coastguard Worker 	enum trace_type type;
7175*58e6ee5fSAndroid Build Coastguard Worker 
7176*58e6ee5fSAndroid Build Coastguard Worker 	parse_record_options(argc, argv, CMD_extract, &ctx);
7177*58e6ee5fSAndroid Build Coastguard Worker 
7178*58e6ee5fSAndroid Build Coastguard Worker 	type = get_trace_cmd_type(ctx.curr_cmd);
7179*58e6ee5fSAndroid Build Coastguard Worker 
7180*58e6ee5fSAndroid Build Coastguard Worker 	update_first_instance(ctx.instance, 1);
7181*58e6ee5fSAndroid Build Coastguard Worker 	check_function_plugin();
7182*58e6ee5fSAndroid Build Coastguard Worker 
7183*58e6ee5fSAndroid Build Coastguard Worker 	if (!ctx.output)
7184*58e6ee5fSAndroid Build Coastguard Worker 		ctx.output = DEFAULT_INPUT_FILE;
7185*58e6ee5fSAndroid Build Coastguard Worker 
7186*58e6ee5fSAndroid Build Coastguard Worker 	/* Save the state of tracing_on before starting */
7187*58e6ee5fSAndroid Build Coastguard Worker 	for_all_instances(instance) {
7188*58e6ee5fSAndroid Build Coastguard Worker 		instance->output_file = strdup(ctx.output);
7189*58e6ee5fSAndroid Build Coastguard Worker 		if (!instance->output_file)
7190*58e6ee5fSAndroid Build Coastguard Worker 			die("Failed to allocate output file name for instance");
7191*58e6ee5fSAndroid Build Coastguard Worker 
7192*58e6ee5fSAndroid Build Coastguard Worker 		if (!ctx.manual && instance->flags & BUFFER_FL_PROFILE)
7193*58e6ee5fSAndroid Build Coastguard Worker 			enable_profile(ctx.instance);
7194*58e6ee5fSAndroid Build Coastguard Worker 
7195*58e6ee5fSAndroid Build Coastguard Worker 		instance->tracing_on_init_val = read_tracing_on(instance);
7196*58e6ee5fSAndroid Build Coastguard Worker 		/* Some instances may not be created yet */
7197*58e6ee5fSAndroid Build Coastguard Worker 		if (instance->tracing_on_init_val < 0)
7198*58e6ee5fSAndroid Build Coastguard Worker 			instance->tracing_on_init_val = 1;
7199*58e6ee5fSAndroid Build Coastguard Worker 	}
7200*58e6ee5fSAndroid Build Coastguard Worker 
7201*58e6ee5fSAndroid Build Coastguard Worker 	/* Extracting data records all events in the system. */
7202*58e6ee5fSAndroid Build Coastguard Worker 	if (!ctx.record_all)
7203*58e6ee5fSAndroid Build Coastguard Worker 		record_all_events();
7204*58e6ee5fSAndroid Build Coastguard Worker 
7205*58e6ee5fSAndroid Build Coastguard Worker 	if (ctx.events)
7206*58e6ee5fSAndroid Build Coastguard Worker 		expand_event_list();
7207*58e6ee5fSAndroid Build Coastguard Worker 
7208*58e6ee5fSAndroid Build Coastguard Worker 	page_size = getpagesize();
7209*58e6ee5fSAndroid Build Coastguard Worker 	update_plugins(type);
7210*58e6ee5fSAndroid Build Coastguard Worker 	set_options();
7211*58e6ee5fSAndroid Build Coastguard Worker 
7212*58e6ee5fSAndroid Build Coastguard Worker 	for_all_instances(instance) {
7213*58e6ee5fSAndroid Build Coastguard Worker 		if (instance->max_graph_depth) {
7214*58e6ee5fSAndroid Build Coastguard Worker 			set_max_graph_depth(instance, instance->max_graph_depth);
7215*58e6ee5fSAndroid Build Coastguard Worker 			free(instance->max_graph_depth);
7216*58e6ee5fSAndroid Build Coastguard Worker 			instance->max_graph_depth = NULL;
7217*58e6ee5fSAndroid Build Coastguard Worker 		}
7218*58e6ee5fSAndroid Build Coastguard Worker 	}
7219*58e6ee5fSAndroid Build Coastguard Worker 
7220*58e6ee5fSAndroid Build Coastguard Worker 	allocate_seq();
7221*58e6ee5fSAndroid Build Coastguard Worker 	flush_threads();
7222*58e6ee5fSAndroid Build Coastguard Worker 	record_stats();
7223*58e6ee5fSAndroid Build Coastguard Worker 
7224*58e6ee5fSAndroid Build Coastguard Worker 	if (!keep)
7225*58e6ee5fSAndroid Build Coastguard Worker 		tracecmd_disable_all_tracing(0);
7226*58e6ee5fSAndroid Build Coastguard Worker 
7227*58e6ee5fSAndroid Build Coastguard Worker 	/* extract records the date after extraction */
7228*58e6ee5fSAndroid Build Coastguard Worker 	if (ctx.date) {
7229*58e6ee5fSAndroid Build Coastguard Worker 		/*
7230*58e6ee5fSAndroid Build Coastguard Worker 		 * We need to start tracing, don't let other traces
7231*58e6ee5fSAndroid Build Coastguard Worker 		 * screw with our trace_marker.
7232*58e6ee5fSAndroid Build Coastguard Worker 		 */
7233*58e6ee5fSAndroid Build Coastguard Worker 		tracecmd_disable_all_tracing(1);
7234*58e6ee5fSAndroid Build Coastguard Worker 		ctx.date2ts = get_date_to_ts();
7235*58e6ee5fSAndroid Build Coastguard Worker 	}
7236*58e6ee5fSAndroid Build Coastguard Worker 
7237*58e6ee5fSAndroid Build Coastguard Worker 	record_data(&ctx);
7238*58e6ee5fSAndroid Build Coastguard Worker 	delete_thread_data();
7239*58e6ee5fSAndroid Build Coastguard Worker 	destroy_stats();
7240*58e6ee5fSAndroid Build Coastguard Worker 	finalize_record_trace(&ctx);
7241*58e6ee5fSAndroid Build Coastguard Worker 	exit(0);
7242*58e6ee5fSAndroid Build Coastguard Worker }
7243*58e6ee5fSAndroid Build Coastguard Worker 
trace_stream(int argc,char ** argv)7244*58e6ee5fSAndroid Build Coastguard Worker void trace_stream(int argc, char **argv)
7245*58e6ee5fSAndroid Build Coastguard Worker {
7246*58e6ee5fSAndroid Build Coastguard Worker 	struct common_record_context ctx;
7247*58e6ee5fSAndroid Build Coastguard Worker 
7248*58e6ee5fSAndroid Build Coastguard Worker 	parse_record_options(argc, argv, CMD_stream, &ctx);
7249*58e6ee5fSAndroid Build Coastguard Worker 	record_trace_command(argc, argv, &ctx);
7250*58e6ee5fSAndroid Build Coastguard Worker 	exit(0);
7251*58e6ee5fSAndroid Build Coastguard Worker }
7252*58e6ee5fSAndroid Build Coastguard Worker 
trace_profile(int argc,char ** argv)7253*58e6ee5fSAndroid Build Coastguard Worker void trace_profile(int argc, char **argv)
7254*58e6ee5fSAndroid Build Coastguard Worker {
7255*58e6ee5fSAndroid Build Coastguard Worker 	struct common_record_context ctx;
7256*58e6ee5fSAndroid Build Coastguard Worker 
7257*58e6ee5fSAndroid Build Coastguard Worker 	parse_record_options(argc, argv, CMD_profile, &ctx);
7258*58e6ee5fSAndroid Build Coastguard Worker 
7259*58e6ee5fSAndroid Build Coastguard Worker 	handle_init = trace_init_profile;
7260*58e6ee5fSAndroid Build Coastguard Worker 	ctx.events = 1;
7261*58e6ee5fSAndroid Build Coastguard Worker 
7262*58e6ee5fSAndroid Build Coastguard Worker 	/*
7263*58e6ee5fSAndroid Build Coastguard Worker 	 * If no instances were set, then enable profiling on the top instance.
7264*58e6ee5fSAndroid Build Coastguard Worker 	 */
7265*58e6ee5fSAndroid Build Coastguard Worker 	if (!buffer_instances)
7266*58e6ee5fSAndroid Build Coastguard Worker 		top_instance.flags |= BUFFER_FL_PROFILE;
7267*58e6ee5fSAndroid Build Coastguard Worker 
7268*58e6ee5fSAndroid Build Coastguard Worker 	record_trace_command(argc, argv, &ctx);
7269*58e6ee5fSAndroid Build Coastguard Worker 	do_trace_profile();
7270*58e6ee5fSAndroid Build Coastguard Worker 	exit(0);
7271*58e6ee5fSAndroid Build Coastguard Worker }
7272*58e6ee5fSAndroid Build Coastguard Worker 
trace_record(int argc,char ** argv)7273*58e6ee5fSAndroid Build Coastguard Worker void trace_record(int argc, char **argv)
7274*58e6ee5fSAndroid Build Coastguard Worker {
7275*58e6ee5fSAndroid Build Coastguard Worker 	struct common_record_context ctx;
7276*58e6ee5fSAndroid Build Coastguard Worker 
7277*58e6ee5fSAndroid Build Coastguard Worker 	parse_record_options(argc, argv, CMD_record, &ctx);
7278*58e6ee5fSAndroid Build Coastguard Worker 	record_trace_command(argc, argv, &ctx);
7279*58e6ee5fSAndroid Build Coastguard Worker 	exit(0);
7280*58e6ee5fSAndroid Build Coastguard Worker }
7281*58e6ee5fSAndroid Build Coastguard Worker 
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,const char * host)7282*58e6ee5fSAndroid Build Coastguard Worker int trace_record_agent(struct tracecmd_msg_handle *msg_handle,
7283*58e6ee5fSAndroid Build Coastguard Worker 		       int cpus, int *fds,
7284*58e6ee5fSAndroid Build Coastguard Worker 		       int argc, char **argv,
7285*58e6ee5fSAndroid Build Coastguard Worker 		       bool use_fifos,
7286*58e6ee5fSAndroid Build Coastguard Worker 		       unsigned long long trace_id, const char *host)
7287*58e6ee5fSAndroid Build Coastguard Worker {
7288*58e6ee5fSAndroid Build Coastguard Worker 	struct common_record_context ctx;
7289*58e6ee5fSAndroid Build Coastguard Worker 	char **argv_plus;
7290*58e6ee5fSAndroid Build Coastguard Worker 
7291*58e6ee5fSAndroid Build Coastguard Worker 	/* Reset optind for getopt_long */
7292*58e6ee5fSAndroid Build Coastguard Worker 	optind = 1;
7293*58e6ee5fSAndroid Build Coastguard Worker 	/*
7294*58e6ee5fSAndroid Build Coastguard Worker 	 * argc is the number of elements in argv, but we need to convert
7295*58e6ee5fSAndroid Build Coastguard Worker 	 * argc and argv into "trace-cmd", "record", argv.
7296*58e6ee5fSAndroid Build Coastguard Worker 	 * where argc needs to grow by two.
7297*58e6ee5fSAndroid Build Coastguard Worker 	 */
7298*58e6ee5fSAndroid Build Coastguard Worker 	argv_plus = calloc(argc + 2, sizeof(char *));
7299*58e6ee5fSAndroid Build Coastguard Worker 	if (!argv_plus)
7300*58e6ee5fSAndroid Build Coastguard Worker 		die("Failed to allocate record arguments");
7301*58e6ee5fSAndroid Build Coastguard Worker 
7302*58e6ee5fSAndroid Build Coastguard Worker 	argv_plus[0] = "trace-cmd";
7303*58e6ee5fSAndroid Build Coastguard Worker 	argv_plus[1] = "record";
7304*58e6ee5fSAndroid Build Coastguard Worker 	memmove(argv_plus + 2, argv, argc * sizeof(char *));
7305*58e6ee5fSAndroid Build Coastguard Worker 	argc += 2;
7306*58e6ee5fSAndroid Build Coastguard Worker 
7307*58e6ee5fSAndroid Build Coastguard Worker 	parse_record_options(argc, argv_plus, CMD_record_agent, &ctx);
7308*58e6ee5fSAndroid Build Coastguard Worker 	if (ctx.run_command)
7309*58e6ee5fSAndroid Build Coastguard Worker 		return -EINVAL;
7310*58e6ee5fSAndroid Build Coastguard Worker 
7311*58e6ee5fSAndroid Build Coastguard Worker 	ctx.instance->fds = fds;
7312*58e6ee5fSAndroid Build Coastguard Worker 	ctx.instance->use_fifos = use_fifos;
7313*58e6ee5fSAndroid Build Coastguard Worker 	ctx.instance->flags |= BUFFER_FL_AGENT;
7314*58e6ee5fSAndroid Build Coastguard Worker 	ctx.instance->msg_handle = msg_handle;
7315*58e6ee5fSAndroid Build Coastguard Worker 	ctx.instance->host = host;
7316*58e6ee5fSAndroid Build Coastguard Worker 	msg_handle->version = V3_PROTOCOL;
7317*58e6ee5fSAndroid Build Coastguard Worker 	top_instance.trace_id = trace_id;
7318*58e6ee5fSAndroid Build Coastguard Worker 	record_trace(argc, argv, &ctx);
7319*58e6ee5fSAndroid Build Coastguard Worker 
7320*58e6ee5fSAndroid Build Coastguard Worker 	free(argv_plus);
7321*58e6ee5fSAndroid Build Coastguard Worker 	return 0;
7322*58e6ee5fSAndroid Build Coastguard Worker }
7323