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