1 // SPDX-License-Identifier: LGPL-2.1
2 /*
3 * Copyright (C) 2008, 2009, 2010 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
4 *
5 * Updates:
6 * Copyright (C) 2021, VMware, Tzvetomir Stoyanov <tz.stoyanov@gmail.com>
7 *
8 */
9 #include <stdlib.h>
10 #include <stdarg.h>
11 #include <unistd.h>
12 #include <fcntl.h>
13 #include <sys/types.h>
14 #include <sys/stat.h>
15 #include <regex.h>
16 #include <dirent.h>
17 #include <limits.h>
18 #include <pthread.h>
19 #include <errno.h>
20
21 #include "tracefs.h"
22 #include "tracefs-local.h"
23
24 __hidden pthread_mutex_t toplevel_lock = PTHREAD_MUTEX_INITIALIZER;
25
26 #define TRACE_CTRL "tracing_on"
27 #define TRACE_FILTER "set_ftrace_filter"
28 #define TRACE_NOTRACE "set_ftrace_notrace"
29 #define TRACE_FILTER_LIST "available_filter_functions"
30 #define CUR_TRACER "current_tracer"
31
32 #define TRACERS \
33 C(NOP, "nop"), \
34 C(CUSTOM, "CUSTOM"), \
35 C(FUNCTION, "function"), \
36 C(FUNCTION_GRAPH, "function_graph"), \
37 C(IRQSOFF, "irqsoff"), \
38 C(PREEMPTOFF, "preemptoff"), \
39 C(PREEMPTIRQSOFF, "preemptirqsoff"), \
40 C(WAKEUP, "wakeup"), \
41 C(WAKEUP_RT, "wakeup_rt"), \
42 C(WAKEUP_DL, "wakeup_dl"), \
43 C(MMIOTRACE, "mmiotrace"), \
44 C(HWLAT, "hwlat"), \
45 C(BRANCH, "branch"), \
46 C(BLOCK, "block")
47
48 #undef C
49 #define C(a, b) b
50 const char *tracers[] = { TRACERS };
51
52 #undef C
53 #define C(a, b) TRACEFS_TRACER_##a
54 const int tracer_enums[] = { TRACERS };
55
56 /* File descriptor for Top level set_ftrace_filter */
57 static int ftrace_filter_fd = -1;
58 static int ftrace_notrace_fd = -1;
59
60 static const char * const options_map[] = {
61 "unknown",
62 "annotate",
63 "bin",
64 "blk_cgname",
65 "blk_cgroup",
66 "blk_classic",
67 "block",
68 "context-info",
69 "disable_on_free",
70 "display-graph",
71 "event-fork",
72 "funcgraph-abstime",
73 "funcgraph-cpu",
74 "funcgraph-duration",
75 "funcgraph-irqs",
76 "funcgraph-overhead",
77 "funcgraph-overrun",
78 "funcgraph-proc",
79 "funcgraph-tail",
80 "func_stack_trace",
81 "function-fork",
82 "function-trace",
83 "graph-time",
84 "hex",
85 "irq-info",
86 "latency-format",
87 "markers",
88 "overwrite",
89 "pause-on-trace",
90 "printk-msg-only",
91 "print-parent",
92 "raw",
93 "record-cmd",
94 "record-tgid",
95 "sleep-time",
96 "stacktrace",
97 "sym-addr",
98 "sym-offset",
99 "sym-userobj",
100 "trace_printk",
101 "userstacktrace",
102 "verbose" };
103
trace_on_off(int fd,bool on)104 static int trace_on_off(int fd, bool on)
105 {
106 const char *val = on ? "1" : "0";
107 int ret;
108
109 ret = write(fd, val, 1);
110 if (ret == 1)
111 return 0;
112
113 return -1;
114 }
115
trace_on_off_file(struct tracefs_instance * instance,bool on)116 static int trace_on_off_file(struct tracefs_instance *instance, bool on)
117 {
118 int ret;
119 int fd;
120
121 fd = tracefs_instance_file_open(instance, TRACE_CTRL, O_WRONLY);
122 if (fd < 0)
123 return -1;
124 ret = trace_on_off(fd, on);
125 close(fd);
126
127 return ret;
128 }
129
130 /**
131 * tracefs_trace_is_on - Check if writing traces to the ring buffer is enabled
132 * @instance: ftrace instance, can be NULL for the top instance
133 *
134 * Returns -1 in case of an error, 0 if tracing is disable or 1 if tracing
135 * is enabled.
136 */
tracefs_trace_is_on(struct tracefs_instance * instance)137 int tracefs_trace_is_on(struct tracefs_instance *instance)
138 {
139 long long res;
140
141 if (tracefs_instance_file_read_number(instance, TRACE_CTRL, &res) == 0)
142 return (int)res;
143
144 return -1;
145 }
146
147 /**
148 * tracefs_trace_on - Enable writing traces to the ring buffer of the given instance
149 * @instance: ftrace instance, can be NULL for the top instance
150 *
151 * Returns -1 in case of an error or 0 otherwise
152 */
tracefs_trace_on(struct tracefs_instance * instance)153 int tracefs_trace_on(struct tracefs_instance *instance)
154 {
155 return trace_on_off_file(instance, true);
156 }
157
158 /**
159 * tracefs_trace_off - Disable writing traces to the ring buffer of the given instance
160 * @instance: ftrace instance, can be NULL for the top instance
161 *
162 * Returns -1 in case of an error or 0 otherwise
163 */
tracefs_trace_off(struct tracefs_instance * instance)164 int tracefs_trace_off(struct tracefs_instance *instance)
165 {
166 return trace_on_off_file(instance, false);
167 }
168
169 /**
170 * tracefs_trace_on_fd - Enable writing traces to the ring buffer
171 * @fd: File descriptor to ftrace tracing_on file, previously opened
172 * with tracefs_trace_on_get_fd()
173 *
174 * Returns -1 in case of an error or 0 otherwise
175 */
tracefs_trace_on_fd(int fd)176 int tracefs_trace_on_fd(int fd)
177 {
178 if (fd < 0)
179 return -1;
180 return trace_on_off(fd, true);
181 }
182
183 /**
184 * tracefs_trace_off_fd - Disable writing traces to the ring buffer
185 * @fd: File descriptor to ftrace tracing_on file, previously opened
186 * with tracefs_trace_on_get_fd()
187 *
188 * Returns -1 in case of an error or 0 otherwise
189 */
tracefs_trace_off_fd(int fd)190 int tracefs_trace_off_fd(int fd)
191 {
192 if (fd < 0)
193 return -1;
194 return trace_on_off(fd, false);
195 }
196
197 /**
198 * tracefs_option_name - Get trace option name from id
199 * @id: trace option id
200 *
201 * Returns string with option name, or "unknown" in case of not known option id.
202 * The returned string must *not* be freed.
203 */
tracefs_option_name(enum tracefs_option_id id)204 const char *tracefs_option_name(enum tracefs_option_id id)
205 {
206 /* Make sure options map contains all the options */
207 BUILD_BUG_ON(ARRAY_SIZE(options_map) != TRACEFS_OPTION_MAX);
208
209 if (id < TRACEFS_OPTION_MAX)
210 return options_map[id];
211
212 return options_map[0];
213 }
214
215 /**
216 * tracefs_option_id - Get trace option ID from name
217 * @name: trace option name
218 *
219 * Returns trace option ID or TRACEFS_OPTION_INVALID in case of an error or
220 * unknown option name.
221 */
tracefs_option_id(const char * name)222 enum tracefs_option_id tracefs_option_id(const char *name)
223 {
224 int i;
225
226 if (!name)
227 return TRACEFS_OPTION_INVALID;
228
229 for (i = 0; i < TRACEFS_OPTION_MAX; i++) {
230 if (strlen(name) == strlen(options_map[i]) &&
231 !strcmp(options_map[i], name))
232 return i;
233 }
234
235 return TRACEFS_OPTION_INVALID;
236 }
237
238 const static struct tracefs_options_mask *
trace_get_options(struct tracefs_instance * instance,bool enabled)239 trace_get_options(struct tracefs_instance *instance, bool enabled)
240 {
241 pthread_mutex_t *lock = trace_get_lock(instance);
242 struct tracefs_options_mask *bitmask;
243 enum tracefs_option_id id;
244 unsigned long long set;
245 char file[PATH_MAX];
246 struct stat st;
247 long long val;
248 char *path;
249 int ret;
250
251 bitmask = enabled ? enabled_opts_mask(instance) :
252 supported_opts_mask(instance);
253
254 for (id = 1; id < TRACEFS_OPTION_MAX; id++) {
255 snprintf(file, PATH_MAX, "options/%s", options_map[id]);
256 path = tracefs_instance_get_file(instance, file);
257 if (!path)
258 return NULL;
259
260 set = 1;
261 ret = stat(path, &st);
262 if (ret < 0 || !S_ISREG(st.st_mode)) {
263 set = 0;
264 } else if (enabled) {
265 ret = tracefs_instance_file_read_number(instance, file, &val);
266 if (ret != 0 || val != 1)
267 set = 0;
268 }
269
270 pthread_mutex_lock(lock);
271 bitmask->mask = (bitmask->mask & ~(1ULL << (id - 1))) | (set << (id - 1));
272 pthread_mutex_unlock(lock);
273
274 tracefs_put_tracing_file(path);
275 }
276
277
278 return bitmask;
279 }
280
281 /**
282 * tracefs_options_get_supported - Get all supported trace options in given instance
283 * @instance: ftrace instance, can be NULL for the top instance
284 *
285 * Returns bitmask structure with all trace options, supported in given instance,
286 * or NULL in case of an error.
287 */
288 const struct tracefs_options_mask *
tracefs_options_get_supported(struct tracefs_instance * instance)289 tracefs_options_get_supported(struct tracefs_instance *instance)
290 {
291 return trace_get_options(instance, false);
292 }
293
294 /**
295 * tracefs_options_get_enabled - Get all currently enabled trace options in given instance
296 * @instance: ftrace instance, can be NULL for the top instance
297 *
298 * Returns bitmask structure with all trace options, enabled in given instance,
299 * or NULL in case of an error.
300 */
301 const struct tracefs_options_mask *
tracefs_options_get_enabled(struct tracefs_instance * instance)302 tracefs_options_get_enabled(struct tracefs_instance *instance)
303 {
304 return trace_get_options(instance, true);
305 }
306
trace_config_option(struct tracefs_instance * instance,enum tracefs_option_id id,bool set)307 static int trace_config_option(struct tracefs_instance *instance,
308 enum tracefs_option_id id, bool set)
309 {
310 const char *set_str = set ? "1" : "0";
311 char file[PATH_MAX];
312 const char *name;
313
314 name = tracefs_option_name(id);
315 if (!name)
316 return -1;
317
318 snprintf(file, PATH_MAX, "options/%s", name);
319 if (strlen(set_str) != tracefs_instance_file_write(instance, file, set_str))
320 return -1;
321 return 0;
322 }
323
324 /**
325 * tracefs_option_enable - Enable trace option
326 * @instance: ftrace instance, can be NULL for the top instance
327 * @id: trace option id
328 *
329 * Returns -1 in case of an error or 0 otherwise
330 */
tracefs_option_enable(struct tracefs_instance * instance,enum tracefs_option_id id)331 int tracefs_option_enable(struct tracefs_instance *instance, enum tracefs_option_id id)
332 {
333 return trace_config_option(instance, id, true);
334 }
335
336 /**
337 * tracefs_option_disable - Disable trace option
338 * @instance: ftrace instance, can be NULL for the top instance
339 * @id: trace option id
340 *
341 * Returns -1 in case of an error or 0 otherwise
342 */
tracefs_option_disable(struct tracefs_instance * instance,enum tracefs_option_id id)343 int tracefs_option_disable(struct tracefs_instance *instance, enum tracefs_option_id id)
344 {
345 return trace_config_option(instance, id, false);
346 }
347
348 /**
349 * tracefs_option_is_supported - Check if an option is supported
350 * @instance: ftrace instance, can be NULL for the top instance
351 * @id: trace option id
352 *
353 * Returns true if an option with given id is supported by the system, false if
354 * it is not supported.
355 */
tracefs_option_is_supported(struct tracefs_instance * instance,enum tracefs_option_id id)356 bool tracefs_option_is_supported(struct tracefs_instance *instance, enum tracefs_option_id id)
357 {
358 const char *name = tracefs_option_name(id);
359 char file[PATH_MAX];
360
361 if (!name)
362 return false;
363 snprintf(file, PATH_MAX, "options/%s", name);
364 return tracefs_file_exists(instance, file);
365 }
366
367 /**
368 * tracefs_option_is_enabled - Check if an option is enabled in given instance
369 * @instance: ftrace instance, can be NULL for the top instance
370 * @id: trace option id
371 *
372 * Returns true if an option with given id is enabled in the given instance,
373 * false if it is not enabled.
374 */
tracefs_option_is_enabled(struct tracefs_instance * instance,enum tracefs_option_id id)375 bool tracefs_option_is_enabled(struct tracefs_instance *instance, enum tracefs_option_id id)
376 {
377 const char *name = tracefs_option_name(id);
378 char file[PATH_MAX];
379 long long res;
380
381 if (!name)
382 return false;
383 snprintf(file, PATH_MAX, "options/%s", name);
384 if (!tracefs_instance_file_read_number(instance, file, &res) && res)
385 return true;
386
387 return false;
388 }
389
390 /**
391 * tracefs_option_mask_is_set - Check if given option is set in the bitmask
392 * @options: Options bitmask
393 * @id: trace option id
394 *
395 * Returns true if an option with given id is set in the bitmask,
396 * false if it is not set.
397 */
tracefs_option_mask_is_set(const struct tracefs_options_mask * options,enum tracefs_option_id id)398 bool tracefs_option_mask_is_set(const struct tracefs_options_mask *options,
399 enum tracefs_option_id id)
400 {
401 if (id > TRACEFS_OPTION_INVALID)
402 return options->mask & (1ULL << (id - 1));
403 return false;
404 }
405
406 struct func_list {
407 struct func_list *next;
408 char *func;
409 unsigned int start;
410 unsigned int end;
411 };
412
413 struct func_filter {
414 const char *filter;
415 regex_t re;
416 bool set;
417 bool is_regex;
418 };
419
is_regex(const char * str)420 static bool is_regex(const char *str)
421 {
422 int i;
423
424 for (i = 0; str[i]; i++) {
425 switch (str[i]) {
426 case 'a' ... 'z':
427 case 'A'...'Z':
428 case '_':
429 case '0'...'9':
430 case '*':
431 case '.':
432 /* Dots can be part of a function name */
433 case '?':
434 continue;
435 default:
436 return true;
437 }
438 }
439 return false;
440 }
441
update_regex(const char * reg)442 static char *update_regex(const char *reg)
443 {
444 int len = strlen(reg);
445 char *str;
446
447 if (reg[0] == '^' && reg[len - 1] == '$')
448 return strdup(reg);
449
450 str = malloc(len + 3);
451 if (reg[0] == '^') {
452 strcpy(str, reg);
453 } else {
454 str[0] = '^';
455 strcpy(str + 1, reg);
456 len++; /* add ^ */
457 }
458 if (str[len - 1] != '$')
459 str[len++]= '$';
460 str[len] = '\0';
461 return str;
462 }
463
464 /*
465 * Convert a glob into a regular expression.
466 */
make_regex(const char * glob)467 static char *make_regex(const char *glob)
468 {
469 char *str;
470 int cnt = 0;
471 int i, j;
472
473 for (i = 0; glob[i]; i++) {
474 if (glob[i] == '*'|| glob[i] == '.')
475 cnt++;
476 }
477
478 /* '^' + ('*'->'.*' or '.' -> '\.') + '$' + '\0' */
479 str = malloc(i + cnt + 3);
480 if (!str)
481 return NULL;
482
483 str[0] = '^';
484 for (i = 0, j = 1; glob[i]; i++, j++) {
485 if (glob[i] == '*')
486 str[j++] = '.';
487 /* Dots can be part of a function name */
488 if (glob[i] == '.')
489 str[j++] = '\\';
490 str[j] = glob[i];
491 }
492 str[j++] = '$';
493 str[j] = '\0';
494 return str;
495 }
496
match(const char * str,struct func_filter * func_filter)497 static bool match(const char *str, struct func_filter *func_filter)
498 {
499 return regexec(&func_filter->re, str, 0, NULL, 0) == 0;
500 }
501
502 /*
503 * Return 0 on success, -1 error writing, 1 on other errors.
504 */
write_filter(int fd,const char * filter,const char * module)505 static int write_filter(int fd, const char *filter, const char *module)
506 {
507 char *each_str = NULL;
508 int write_size;
509 int size;
510
511 if (module)
512 write_size = asprintf(&each_str, "%s:mod:%s ", filter, module);
513 else
514 write_size = asprintf(&each_str, "%s ", filter);
515
516 if (write_size < 0)
517 return 1;
518
519 size = write(fd, each_str, write_size);
520 free(each_str);
521
522 /* compare written bytes*/
523 if (size < write_size)
524 return -1;
525
526 return 0;
527 }
528
add_func(struct func_list *** next_func_ptr,unsigned int index)529 static int add_func(struct func_list ***next_func_ptr, unsigned int index)
530 {
531 struct func_list **next_func = *next_func_ptr;
532 struct func_list *func_list = *next_func;
533
534 if (!func_list) {
535 func_list = calloc(1, sizeof(*func_list));
536 if (!func_list)
537 return -1;
538 func_list->start = index;
539 func_list->end = index;
540 *next_func = func_list;
541 return 0;
542 }
543
544 if (index == func_list->end + 1) {
545 func_list->end = index;
546 return 0;
547 }
548 *next_func_ptr = &func_list->next;
549 return add_func(next_func_ptr, index);
550 }
551
add_func_str(struct func_list *** next_func_ptr,const char * func)552 static int add_func_str(struct func_list ***next_func_ptr, const char *func)
553 {
554 struct func_list **next_func = *next_func_ptr;
555 struct func_list *func_list = *next_func;
556
557 if (!func_list) {
558 func_list = calloc(1, sizeof(*func_list));
559 if (!func_list)
560 return -1;
561 func_list->func = strdup(func);
562 if (!func_list->func) {
563 free(func_list);
564 return -1;
565 }
566 *next_func = func_list;
567 return 0;
568 }
569 *next_func_ptr = &func_list->next;
570 return add_func_str(next_func_ptr, func);
571 }
572
free_func_list(struct func_list * func_list)573 static void free_func_list(struct func_list *func_list)
574 {
575 struct func_list *f;
576
577 while (func_list) {
578 f = func_list;
579 func_list = f->next;
580 free(f->func);
581 free(f);
582 }
583 }
584
585 enum match_type {
586 FILTER_CHECK = (1 << 0),
587 FILTER_WRITE = (1 << 1),
588 FILTER_FUTURE = (1 << 2),
589 SAVE_STRING = (1 << 2),
590 };
591
match_filters(int fd,struct func_filter * func_filter,const char * module,struct func_list ** func_list,int flags)592 static int match_filters(int fd, struct func_filter *func_filter,
593 const char *module, struct func_list **func_list,
594 int flags)
595 {
596 enum match_type type = flags & (FILTER_CHECK | FILTER_WRITE);
597 bool save_str = flags & SAVE_STRING;
598 bool future = flags & FILTER_FUTURE;
599 bool mod_match = false;
600 char *line = NULL;
601 size_t size = 0;
602 char *path;
603 FILE *fp;
604 int index = 0;
605 int ret = 1;
606 int mlen;
607
608 path = tracefs_get_tracing_file(TRACE_FILTER_LIST);
609 if (!path)
610 return 1;
611
612 fp = fopen(path, "r");
613 tracefs_put_tracing_file(path);
614
615 if (!fp)
616 return 1;
617
618 if (module)
619 mlen = strlen(module);
620
621 while (getline(&line, &size, fp) >= 0) {
622 char *saveptr = NULL;
623 char *tok, *mtok;
624 int len = strlen(line);
625
626 if (line[len - 1] == '\n')
627 line[len - 1] = '\0';
628 tok = strtok_r(line, " ", &saveptr);
629 if (!tok)
630 goto next;
631
632 index++;
633
634 if (module) {
635 mtok = strtok_r(NULL, " ", &saveptr);
636 if (!mtok)
637 goto next;
638 if ((strncmp(mtok + 1, module, mlen) != 0) ||
639 (mtok[mlen + 1] != ']'))
640 goto next;
641 if (future)
642 mod_match = true;
643 }
644 switch (type) {
645 case FILTER_CHECK:
646 if (match(tok, func_filter)) {
647 func_filter->set = true;
648 if (save_str)
649 ret = add_func_str(&func_list, tok);
650 else
651 ret = add_func(&func_list, index);
652 if (ret)
653 goto out;
654 }
655 break;
656 case FILTER_WRITE:
657 /* Writes only have one filter */
658 if (match(tok, func_filter)) {
659 ret = write_filter(fd, tok, module);
660 if (ret)
661 goto out;
662 }
663 break;
664 default:
665 /* Should never happen */
666 ret = -1;
667 goto out;
668
669 }
670 next:
671 free(line);
672 line = NULL;
673 len = 0;
674 }
675 out:
676 free(line);
677 fclose(fp);
678
679 /* If there was no matches and future was set, this is a success */
680 if (future && !mod_match)
681 ret = 0;
682
683 return ret;
684 }
685
check_available_filters(struct func_filter * func_filter,const char * module,struct func_list ** func_list,bool future)686 static int check_available_filters(struct func_filter *func_filter,
687 const char *module,
688 struct func_list **func_list,
689 bool future)
690 {
691 int flags = FILTER_CHECK | (future ? FILTER_FUTURE : 0);
692
693 return match_filters(-1, func_filter, module, func_list, flags);
694 }
695
696
list_available_filters(struct func_filter * func_filter,const char * module,struct func_list ** func_list)697 static int list_available_filters(struct func_filter *func_filter,
698 const char *module,
699 struct func_list **func_list)
700 {
701 int flags = FILTER_CHECK | SAVE_STRING;
702
703 return match_filters(-1, func_filter, module, func_list, flags);
704 }
705
set_regex_filter(int fd,struct func_filter * func_filter,const char * module)706 static int set_regex_filter(int fd, struct func_filter *func_filter,
707 const char *module)
708 {
709 return match_filters(fd, func_filter, module, NULL, FILTER_WRITE);
710 }
711
controlled_write(int fd,struct func_filter * func_filter,const char * module)712 static int controlled_write(int fd, struct func_filter *func_filter,
713 const char *module)
714 {
715 const char *filter = func_filter->filter;
716 int ret;
717
718 if (func_filter->is_regex)
719 ret = set_regex_filter(fd, func_filter, module);
720 else
721 ret = write_filter(fd, filter, module);
722
723 return ret;
724 }
725
init_func_filter(struct func_filter * func_filter,const char * filter)726 static int init_func_filter(struct func_filter *func_filter, const char *filter)
727 {
728 char *str;
729 int ret;
730
731 if (!(func_filter->is_regex = is_regex(filter)))
732 str = make_regex(filter);
733 else
734 str = update_regex(filter);
735
736 if (!str)
737 return -1;
738
739 ret = regcomp(&func_filter->re, str, REG_ICASE|REG_NOSUB);
740 free(str);
741
742 if (ret < 0)
743 return -1;
744
745 func_filter->filter = filter;
746 return 0;
747 }
748
write_number(int fd,unsigned int start,unsigned int end)749 static int write_number(int fd, unsigned int start, unsigned int end)
750 {
751 char buf[64];
752 unsigned int i;
753 int n, ret;
754
755 for (i = start; i <= end; i++) {
756 n = snprintf(buf, 64, "%d ", i);
757 ret = write(fd, buf, n);
758 if (ret < 0)
759 return ret;
760 }
761
762 return 0;
763 }
764
765 /*
766 * This will try to write the first number, if that fails, it
767 * will assume that it is not supported and return 1.
768 * If the first write succeeds, but a following write fails, then
769 * the kernel does support this, but something else went wrong,
770 * in this case, return -1.
771 */
write_func_list(int fd,struct func_list * list)772 static int write_func_list(int fd, struct func_list *list)
773 {
774 int ret;
775
776 if (!list)
777 return 0;
778
779 ret = write_number(fd, list->start, list->end);
780 if (ret)
781 return 1; // try a different way
782 list = list->next;
783 while (list) {
784 ret = write_number(fd, list->start, list->end);
785 if (ret)
786 return -1;
787 list = list->next;
788 }
789 return 0;
790 }
791
update_filter(const char * filter_path,int * fd,struct tracefs_instance * instance,const char * filter,const char * module,unsigned int flags)792 static int update_filter(const char *filter_path, int *fd,
793 struct tracefs_instance *instance, const char *filter,
794 const char *module, unsigned int flags)
795 {
796 struct func_filter func_filter;
797 struct func_list *func_list = NULL;
798 bool reset = flags & TRACEFS_FL_RESET;
799 bool cont = flags & TRACEFS_FL_CONTINUE;
800 bool future = flags & TRACEFS_FL_FUTURE;
801 pthread_mutex_t *lock = trace_get_lock(instance);
802 int open_flags;
803 int ret = 1;
804
805 /* future flag is only applicable to modules */
806 if (future && !module) {
807 errno = EINVAL;
808 return 1;
809 }
810
811 pthread_mutex_lock(lock);
812
813 /* RESET is only allowed if the file is not opened yet */
814 if (reset && *fd >= 0) {
815 errno = EBUSY;
816 ret = -1;
817 goto out;
818 }
819
820 /*
821 * Set EINVAL on no matching filter. But errno may still be modified
822 * on another type of failure (allocation or opening a file).
823 */
824 errno = EINVAL;
825
826 /* module set with NULL filter means to enable all functions in a module */
827 if (module && !filter)
828 filter = "*";
829
830 if (!filter) {
831 /* OK to call without filters if this is closing the opened file */
832 if (!cont && *fd >= 0) {
833 errno = 0;
834 ret = 0;
835 close(*fd);
836 *fd = -1;
837 }
838 /* Also OK to call if reset flag is set */
839 if (reset)
840 goto open_file;
841
842 goto out;
843 }
844
845 if (init_func_filter(&func_filter, filter) < 0)
846 goto out;
847
848 ret = check_available_filters(&func_filter, module, &func_list, future);
849 if (ret)
850 goto out_free;
851
852 open_file:
853 ret = 1;
854
855 open_flags = reset ? O_TRUNC : O_APPEND;
856
857 if (*fd < 0)
858 *fd = open(filter_path, O_WRONLY | O_CLOEXEC | open_flags);
859 if (*fd < 0)
860 goto out_free;
861
862 errno = 0;
863 ret = 0;
864
865 if (filter) {
866 /*
867 * If future is set, and no functions were found, then
868 * set it directly.
869 */
870 if (func_list)
871 ret = write_func_list(*fd, func_list);
872 else
873 ret = 1;
874 if (ret > 0)
875 ret = controlled_write(*fd, &func_filter, module);
876 }
877
878 if (!cont) {
879 close(*fd);
880 *fd = -1;
881 }
882
883 out_free:
884 if (filter)
885 regfree(&func_filter.re);
886 free_func_list(func_list);
887 out:
888 pthread_mutex_unlock(lock);
889
890 return ret;
891 }
892
893 /**
894 * tracefs_function_filter - filter the functions that are traced
895 * @instance: ftrace instance, can be NULL for top tracing instance.
896 * @filter: The filter to filter what functions are to be traced
897 * @module: Module to be traced or NULL if all functions are to be examined.
898 * @flags: flags on modifying the filter file
899 *
900 * @filter may be a full function name, a glob, or a regex. It will be
901 * considered a regex, if there's any characters that are not normally in
902 * function names or "*" or "?" for a glob.
903 *
904 * @flags:
905 * TRACEFS_FL_RESET - will clear the functions in the filter file
906 * before applying the @filter. This will error with -1
907 * and errno of EBUSY if this flag is set and a previous
908 * call had the same instance and TRACEFS_FL_CONTINUE set.
909 * TRACEFS_FL_CONTINUE - will keep the filter file open on return.
910 * The filter is updated on closing of the filter file.
911 * With this flag set, the file is not closed, and more filters
912 * may be added before they take effect. The last call of this
913 * function must be called without this flag for the filter
914 * to take effect.
915 * TRACEFS_FL_FUTURE - only applicable if "module" is set. If no match
916 * is made, and the module is not yet loaded, it will still attempt
917 * to write the filter plus the module; "<filter>:mod:<module>"
918 * to the filter file. Starting with Linux kernels 4.13, it is possible
919 * to load the filter file with module functions for a module that
920 * is not yet loaded, and when the module is loaded, it will then
921 * activate the module.
922 *
923 * Returns 0 on success, 1 if there was an error but the filtering has not
924 * yet started, -1 if there was an error but the filtering has started.
925 * If -1 is returned and TRACEFS_FL_CONTINUE was set, then this function
926 * needs to be called again without the TRACEFS_FL_CONTINUE flag to commit
927 * the changes and close the filter file.
928 */
tracefs_function_filter(struct tracefs_instance * instance,const char * filter,const char * module,unsigned int flags)929 int tracefs_function_filter(struct tracefs_instance *instance, const char *filter,
930 const char *module, unsigned int flags)
931 {
932 char *filter_path;
933 int *fd;
934 int ret;
935
936 filter_path = tracefs_instance_get_file(instance, TRACE_FILTER);
937 if (!filter_path)
938 return -1;
939
940 if (instance)
941 fd = &instance->ftrace_filter_fd;
942 else
943 fd = &ftrace_filter_fd;
944
945 ret = update_filter(filter_path, fd, instance, filter, module, flags);
946 tracefs_put_tracing_file(filter_path);
947 return ret;
948 }
949
950 /**
951 * tracefs_function_notrace - filter the functions that are not to be traced
952 * @instance: ftrace instance, can be NULL for top tracing instance.
953 * @filter: The filter to filter what functions are not to be traced
954 * @module: Module to be traced or NULL if all functions are to be examined.
955 * @flags: flags on modifying the filter file
956 *
957 * See tracefs_function_filter, as this has the same functionality but
958 * for adding to the "notrace" filter.
959 */
tracefs_function_notrace(struct tracefs_instance * instance,const char * filter,const char * module,unsigned int flags)960 int tracefs_function_notrace(struct tracefs_instance *instance, const char *filter,
961 const char *module, unsigned int flags)
962 {
963 char *filter_path;
964 int *fd;
965 int ret;
966
967 filter_path = tracefs_instance_get_file(instance, TRACE_NOTRACE);
968 if (!filter_path)
969 return -1;
970
971 if (instance)
972 fd = &instance->ftrace_notrace_fd;
973 else
974 fd = &ftrace_notrace_fd;
975
976 ret = update_filter(filter_path, fd, instance, filter, module, flags);
977 tracefs_put_tracing_file(filter_path);
978 return ret;
979 }
980
write_tracer(int fd,const char * tracer)981 int write_tracer(int fd, const char *tracer)
982 {
983 int ret;
984
985 ret = write(fd, tracer, strlen(tracer));
986 if (ret < strlen(tracer))
987 return -1;
988 return ret;
989 }
990
991 /**
992 * tracefs_set_tracer - function to set the tracer
993 * @instance: ftrace instance, can be NULL for top tracing instance
994 * @tracer: The tracer enum that defines the tracer to be set
995 * @t: A tracer name if TRACEFS_TRACER_CUSTOM is passed in for @tracer
996 *
997 * Set the tracer for the instance based on the tracefs_tracer enums.
998 * If the user wishes to enable a tracer that is not defined by
999 * the enum (new or custom kernel), the tracer can be set to
1000 * TRACEFS_TRACER_CUSTOM, and pass in a const char * name for
1001 * the tracer to set.
1002 *
1003 * Returns 0 on succes, negative on error.
1004 */
1005
tracefs_tracer_set(struct tracefs_instance * instance,enum tracefs_tracers tracer,...)1006 int tracefs_tracer_set(struct tracefs_instance *instance,
1007 enum tracefs_tracers tracer, ...)
1008 {
1009 char *tracer_path = NULL;
1010 const char *t = NULL;
1011 int ret = -1;
1012 int fd = -1;
1013 int i;
1014
1015 if (tracer < 0 || tracer > ARRAY_SIZE(tracers)) {
1016 errno = EINVAL;
1017 return -1;
1018 }
1019
1020 tracer_path = tracefs_instance_get_file(instance, CUR_TRACER);
1021 if (!tracer_path)
1022 return -1;
1023
1024 fd = open(tracer_path, O_WRONLY);
1025 if (fd < 0) {
1026 errno = ENOENT;
1027 goto out;
1028 }
1029
1030 if (tracer == TRACEFS_TRACER_CUSTOM) {
1031 va_list ap;
1032
1033 va_start(ap, tracer);
1034 t = va_arg(ap, const char *);
1035 va_end(ap);
1036 } else if (tracer == tracer_enums[tracer]) {
1037 t = tracers[tracer];
1038 } else {
1039 for (i = 0; i < ARRAY_SIZE(tracer_enums); i++) {
1040 if (tracer == tracer_enums[i]) {
1041 t = tracers[i];
1042 break;
1043 }
1044 }
1045 }
1046 if (!t) {
1047 errno = EINVAL;
1048 goto out;
1049 }
1050 ret = write_tracer(fd, t);
1051 /*
1052 * If the tracer does not exist, EINVAL is returned,
1053 * but let the user know this as ENODEV.
1054 */
1055 if (ret < 0 && errno == EINVAL)
1056 errno = ENODEV;
1057 out:
1058 tracefs_put_tracing_file(tracer_path);
1059 close(fd);
1060 return ret > 0 ? 0 : ret;
1061 }
1062
tracefs_tracer_clear(struct tracefs_instance * instance)1063 int tracefs_tracer_clear(struct tracefs_instance *instance)
1064 {
1065 return tracefs_tracer_set(instance, TRACEFS_TRACER_NOP);
1066 }
1067
splice_safe(int fd,int pfd)1068 static bool splice_safe(int fd, int pfd)
1069 {
1070 int ret;
1071
1072 errno = 0;
1073 ret = splice(pfd, NULL, fd, NULL,
1074 10, SPLICE_F_NONBLOCK | SPLICE_F_MOVE);
1075
1076 return !ret || (ret < 0 && errno == EAGAIN);
1077 }
1078
read_trace_pipe(bool * keep_going,int in_fd,int out_fd)1079 static ssize_t read_trace_pipe(bool *keep_going, int in_fd, int out_fd)
1080 {
1081 char buf[BUFSIZ];
1082 ssize_t bread = 0;
1083 int ret;
1084
1085 while (*(volatile bool *)keep_going) {
1086 int r;
1087 ret = read(in_fd, buf, BUFSIZ);
1088 if (ret <= 0)
1089 break;
1090 r = ret;
1091 ret = write(out_fd, buf, r);
1092 if (ret < 0)
1093 break;
1094 bread += ret;
1095 /*
1096 * If the write does a partial write, then
1097 * the iteration should stop. This can happen if
1098 * the destination file system ran out of disk space.
1099 * Sure, it probably lost a little from the read
1100 * but there's not much more that can be
1101 * done. Just return what was transferred.
1102 */
1103 if (ret < r)
1104 break;
1105 }
1106
1107 if (ret < 0 && (errno == EAGAIN || errno == EINTR))
1108 ret = 0;
1109
1110 return ret < 0 ? ret : bread;
1111 }
1112
1113 static bool top_pipe_keep_going;
1114
1115 /**
1116 * tracefs_trace_pipe_stream - redirect the stream of trace data to an output
1117 * file. The "splice" system call is used to moves the data without copying
1118 * between kernel address space and user address space. The user can interrupt
1119 * the streaming of the data by pressing Ctrl-c.
1120 * @fd: The file descriptor of the output file.
1121 * @instance: ftrace instance, can be NULL for top tracing instance.
1122 * @flags: flags for opening the trace_pipe file.
1123 *
1124 * Returns -1 in case of an error or number of bytes transferred otherwise.
1125 */
tracefs_trace_pipe_stream(int fd,struct tracefs_instance * instance,int flags)1126 ssize_t tracefs_trace_pipe_stream(int fd, struct tracefs_instance *instance,
1127 int flags)
1128 {
1129 bool *keep_going = instance ? &instance->pipe_keep_going :
1130 &top_pipe_keep_going;
1131 const char *file = "trace_pipe";
1132 int brass[2], in_fd, ret = -1;
1133 int sflags = flags & O_NONBLOCK ? SPLICE_F_NONBLOCK : 0;
1134 off_t data_size;
1135 ssize_t bread = 0;
1136
1137 (*(volatile bool *)keep_going) = true;
1138
1139 in_fd = tracefs_instance_file_open(instance, file, O_RDONLY | flags);
1140 if (in_fd < 0) {
1141 tracefs_warning("Failed to open 'trace_pipe'.");
1142 return ret;
1143 }
1144
1145 if(pipe(brass) < 0) {
1146 tracefs_warning("Failed to open pipe.");
1147 goto close_file;
1148 }
1149
1150 data_size = fcntl(brass[0], F_GETPIPE_SZ);
1151 if (data_size <= 0) {
1152 tracefs_warning("Failed to open pipe (size=0).");
1153 goto close_all;
1154 }
1155
1156 /* Test if the output is splice safe */
1157 if (!splice_safe(fd, brass[0])) {
1158 bread = read_trace_pipe(keep_going, in_fd, fd);
1159 ret = 0; /* Force return of bread */
1160 goto close_all;
1161 }
1162
1163 errno = 0;
1164
1165 while (*(volatile bool *)keep_going) {
1166 ret = splice(in_fd, NULL,
1167 brass[1], NULL,
1168 data_size, sflags);
1169 if (ret < 0)
1170 break;
1171
1172 ret = splice(brass[0], NULL,
1173 fd, NULL,
1174 data_size, sflags);
1175 if (ret < 0)
1176 break;
1177 bread += ret;
1178 }
1179
1180 /*
1181 * Do not return error in the case when the "splice" system call
1182 * was interrupted by the user (pressing Ctrl-c).
1183 * Or if NONBLOCK was specified.
1184 */
1185 if (!keep_going || errno == EAGAIN || errno == EINTR)
1186 ret = 0;
1187
1188 close_all:
1189 close(brass[0]);
1190 close(brass[1]);
1191 close_file:
1192 close(in_fd);
1193
1194 return ret ? ret : bread;
1195 }
1196
1197 /**
1198 * tracefs_trace_pipe_print - redirect the stream of trace data to "stdout".
1199 * The "splice" system call is used to moves the data without copying
1200 * between kernel address space and user address space.
1201 * @instance: ftrace instance, can be NULL for top tracing instance.
1202 * @flags: flags for opening the trace_pipe file.
1203 *
1204 * Returns -1 in case of an error or number of bytes transferred otherwise.
1205 */
1206
tracefs_trace_pipe_print(struct tracefs_instance * instance,int flags)1207 ssize_t tracefs_trace_pipe_print(struct tracefs_instance *instance, int flags)
1208 {
1209 return tracefs_trace_pipe_stream(STDOUT_FILENO, instance, flags);
1210 }
1211
1212 /**
1213 * tracefs_trace_pipe_stop - stop the streaming of trace data.
1214 * @instance: ftrace instance, can be NULL for top tracing instance.
1215 */
tracefs_trace_pipe_stop(struct tracefs_instance * instance)1216 void tracefs_trace_pipe_stop(struct tracefs_instance *instance)
1217 {
1218 if (instance)
1219 instance->pipe_keep_going = false;
1220 else
1221 top_pipe_keep_going = false;
1222 }
1223
1224 /**
1225 * tracefs_filter_functions - return a list of available functons that can be filtered
1226 * @filter: The filter to filter what functions to list (can be NULL for all)
1227 * @module: Module to be traced or NULL if all functions are to be examined.
1228 * @list: The list to return the list from (freed by tracefs_list_free() on success)
1229 *
1230 * Returns a list of function names that match @filter and @module. If both
1231 * @filter and @module is NULL, then all available functions that can be filtered
1232 * will be returned. (Note, there can be duplicates, if there are more than
1233 * one function with the same name.
1234 *
1235 * On success, zero is returned, and @list contains a list of functions that were
1236 * found, and must be freed with tracefs_list_free().
1237 * On failure, a negative number is returned, and @list is ignored.
1238 */
tracefs_filter_functions(const char * filter,const char * module,char *** list)1239 int tracefs_filter_functions(const char *filter, const char *module, char ***list)
1240 {
1241 struct func_filter func_filter;
1242 struct func_list *func_list = NULL, *f;
1243 char **funcs = NULL;
1244 int ret;
1245
1246 if (!filter)
1247 filter = ".*";
1248
1249 ret = init_func_filter(&func_filter, filter);
1250 if (ret < 0)
1251 return ret;
1252
1253 ret = list_available_filters(&func_filter, module, &func_list);
1254 if (ret < 0)
1255 goto out;
1256
1257 ret = -1;
1258 for (f = func_list; f; f = f->next) {
1259 char **tmp;
1260
1261 tmp = tracefs_list_add(funcs, f->func);
1262 if (!tmp) {
1263 tracefs_list_free(funcs);
1264 goto out;
1265 }
1266 funcs = tmp;
1267 }
1268
1269 *list = funcs;
1270 ret = 0;
1271 out:
1272 regfree(&func_filter.re);
1273 free_func_list(func_list);
1274 return ret;
1275 }
1276