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