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 return -1;
564 *next_func = func_list;
565 return 0;
566 }
567 *next_func_ptr = &func_list->next;
568 return add_func_str(next_func_ptr, func);
569 }
570
free_func_list(struct func_list * func_list)571 static void free_func_list(struct func_list *func_list)
572 {
573 struct func_list *f;
574
575 while (func_list) {
576 f = func_list;
577 func_list = f->next;
578 free(f->func);
579 free(f);
580 }
581 }
582
583 enum match_type {
584 FILTER_CHECK = (1 << 0),
585 FILTER_WRITE = (1 << 1),
586 FILTER_FUTURE = (1 << 2),
587 SAVE_STRING = (1 << 2),
588 };
589
match_filters(int fd,struct func_filter * func_filter,const char * module,struct func_list ** func_list,int flags)590 static int match_filters(int fd, struct func_filter *func_filter,
591 const char *module, struct func_list **func_list,
592 int flags)
593 {
594 enum match_type type = flags & (FILTER_CHECK | FILTER_WRITE);
595 bool save_str = flags & SAVE_STRING;
596 bool future = flags & FILTER_FUTURE;
597 bool mod_match = false;
598 char *line = NULL;
599 size_t size = 0;
600 char *path;
601 FILE *fp;
602 int index = 0;
603 int ret = 1;
604 int mlen;
605
606 path = tracefs_get_tracing_file(TRACE_FILTER_LIST);
607 if (!path)
608 return 1;
609
610 fp = fopen(path, "r");
611 tracefs_put_tracing_file(path);
612
613 if (!fp)
614 return 1;
615
616 if (module)
617 mlen = strlen(module);
618
619 while (getline(&line, &size, fp) >= 0) {
620 char *saveptr = NULL;
621 char *tok, *mtok;
622 int len = strlen(line);
623
624 if (line[len - 1] == '\n')
625 line[len - 1] = '\0';
626 tok = strtok_r(line, " ", &saveptr);
627 if (!tok)
628 goto next;
629
630 index++;
631
632 if (module) {
633 mtok = strtok_r(NULL, " ", &saveptr);
634 if (!mtok)
635 goto next;
636 if ((strncmp(mtok + 1, module, mlen) != 0) ||
637 (mtok[mlen + 1] != ']'))
638 goto next;
639 if (future)
640 mod_match = true;
641 }
642 switch (type) {
643 case FILTER_CHECK:
644 if (match(tok, func_filter)) {
645 func_filter->set = true;
646 if (save_str)
647 ret = add_func_str(&func_list, tok);
648 else
649 ret = add_func(&func_list, index);
650 if (ret)
651 goto out;
652 }
653 break;
654 case FILTER_WRITE:
655 /* Writes only have one filter */
656 if (match(tok, func_filter)) {
657 ret = write_filter(fd, tok, module);
658 if (ret)
659 goto out;
660 }
661 break;
662 default:
663 /* Should never happen */
664 ret = -1;
665 goto out;
666
667 }
668 next:
669 free(line);
670 line = NULL;
671 len = 0;
672 }
673 out:
674 free(line);
675 fclose(fp);
676
677 /* If there was no matches and future was set, this is a success */
678 if (future && !mod_match)
679 ret = 0;
680
681 return ret;
682 }
683
check_available_filters(struct func_filter * func_filter,const char * module,struct func_list ** func_list,bool future)684 static int check_available_filters(struct func_filter *func_filter,
685 const char *module,
686 struct func_list **func_list,
687 bool future)
688 {
689 int flags = FILTER_CHECK | (future ? FILTER_FUTURE : 0);
690
691 return match_filters(-1, func_filter, module, func_list, flags);
692 }
693
694
list_available_filters(struct func_filter * func_filter,const char * module,struct func_list ** func_list)695 static int list_available_filters(struct func_filter *func_filter,
696 const char *module,
697 struct func_list **func_list)
698 {
699 int flags = FILTER_CHECK | SAVE_STRING;
700
701 return match_filters(-1, func_filter, module, func_list, flags);
702 }
703
set_regex_filter(int fd,struct func_filter * func_filter,const char * module)704 static int set_regex_filter(int fd, struct func_filter *func_filter,
705 const char *module)
706 {
707 return match_filters(fd, func_filter, module, NULL, FILTER_WRITE);
708 }
709
controlled_write(int fd,struct func_filter * func_filter,const char * module)710 static int controlled_write(int fd, struct func_filter *func_filter,
711 const char *module)
712 {
713 const char *filter = func_filter->filter;
714 int ret;
715
716 if (func_filter->is_regex)
717 ret = set_regex_filter(fd, func_filter, module);
718 else
719 ret = write_filter(fd, filter, module);
720
721 return ret;
722 }
723
init_func_filter(struct func_filter * func_filter,const char * filter)724 static int init_func_filter(struct func_filter *func_filter, const char *filter)
725 {
726 char *str;
727 int ret;
728
729 if (!(func_filter->is_regex = is_regex(filter)))
730 str = make_regex(filter);
731 else
732 str = update_regex(filter);
733
734 if (!str)
735 return -1;
736
737 ret = regcomp(&func_filter->re, str, REG_ICASE|REG_NOSUB);
738 free(str);
739
740 if (ret < 0)
741 return -1;
742
743 func_filter->filter = filter;
744 return 0;
745 }
746
write_number(int fd,unsigned int start,unsigned int end)747 static int write_number(int fd, unsigned int start, unsigned int end)
748 {
749 char buf[64];
750 unsigned int i;
751 int n, ret;
752
753 for (i = start; i <= end; i++) {
754 n = snprintf(buf, 64, "%d ", i);
755 ret = write(fd, buf, n);
756 if (ret < 0)
757 return ret;
758 }
759
760 return 0;
761 }
762
763 /*
764 * This will try to write the first number, if that fails, it
765 * will assume that it is not supported and return 1.
766 * If the first write succeeds, but a following write fails, then
767 * the kernel does support this, but something else went wrong,
768 * in this case, return -1.
769 */
write_func_list(int fd,struct func_list * list)770 static int write_func_list(int fd, struct func_list *list)
771 {
772 int ret;
773
774 if (!list)
775 return 0;
776
777 ret = write_number(fd, list->start, list->end);
778 if (ret)
779 return 1; // try a different way
780 list = list->next;
781 while (list) {
782 ret = write_number(fd, list->start, list->end);
783 if (ret)
784 return -1;
785 list = list->next;
786 }
787 return 0;
788 }
789
update_filter(const char * filter_path,int * fd,struct tracefs_instance * instance,const char * filter,const char * module,unsigned int flags)790 static int update_filter(const char *filter_path, int *fd,
791 struct tracefs_instance *instance, const char *filter,
792 const char *module, unsigned int flags)
793 {
794 struct func_filter func_filter;
795 struct func_list *func_list = NULL;
796 bool reset = flags & TRACEFS_FL_RESET;
797 bool cont = flags & TRACEFS_FL_CONTINUE;
798 bool future = flags & TRACEFS_FL_FUTURE;
799 pthread_mutex_t *lock = trace_get_lock(instance);
800 int open_flags;
801 int ret = 1;
802
803 /* future flag is only applicable to modules */
804 if (future && !module) {
805 errno = EINVAL;
806 return 1;
807 }
808
809 pthread_mutex_lock(lock);
810
811 /* RESET is only allowed if the file is not opened yet */
812 if (reset && *fd >= 0) {
813 errno = EBUSY;
814 ret = -1;
815 goto out;
816 }
817
818 /*
819 * Set EINVAL on no matching filter. But errno may still be modified
820 * on another type of failure (allocation or opening a file).
821 */
822 errno = EINVAL;
823
824 /* module set with NULL filter means to enable all functions in a module */
825 if (module && !filter)
826 filter = "*";
827
828 if (!filter) {
829 /* OK to call without filters if this is closing the opened file */
830 if (!cont && *fd >= 0) {
831 errno = 0;
832 ret = 0;
833 close(*fd);
834 *fd = -1;
835 }
836 /* Also OK to call if reset flag is set */
837 if (reset)
838 goto open_file;
839
840 goto out;
841 }
842
843 if (init_func_filter(&func_filter, filter) < 0)
844 goto out;
845
846 ret = check_available_filters(&func_filter, module, &func_list, future);
847 if (ret)
848 goto out_free;
849
850 open_file:
851 ret = 1;
852
853 open_flags = reset ? O_TRUNC : O_APPEND;
854
855 if (*fd < 0)
856 *fd = open(filter_path, O_WRONLY | O_CLOEXEC | open_flags);
857 if (*fd < 0)
858 goto out_free;
859
860 errno = 0;
861 ret = 0;
862
863 if (filter) {
864 /*
865 * If future is set, and no functions were found, then
866 * set it directly.
867 */
868 if (func_list)
869 ret = write_func_list(*fd, func_list);
870 else
871 ret = 1;
872 if (ret > 0)
873 ret = controlled_write(*fd, &func_filter, module);
874 }
875
876 if (!cont) {
877 close(*fd);
878 *fd = -1;
879 }
880
881 out_free:
882 if (filter)
883 regfree(&func_filter.re);
884 free_func_list(func_list);
885 out:
886 pthread_mutex_unlock(lock);
887
888 return ret;
889 }
890
891 /**
892 * tracefs_function_filter - filter the functions that are traced
893 * @instance: ftrace instance, can be NULL for top tracing instance.
894 * @filter: The filter to filter what functions are to be traced
895 * @module: Module to be traced or NULL if all functions are to be examined.
896 * @flags: flags on modifying the filter file
897 *
898 * @filter may be a full function name, a glob, or a regex. It will be
899 * considered a regex, if there's any characters that are not normally in
900 * function names or "*" or "?" for a glob.
901 *
902 * @flags:
903 * TRACEFS_FL_RESET - will clear the functions in the filter file
904 * before applying the @filter. This will error with -1
905 * and errno of EBUSY if this flag is set and a previous
906 * call had the same instance and TRACEFS_FL_CONTINUE set.
907 * TRACEFS_FL_CONTINUE - will keep the filter file open on return.
908 * The filter is updated on closing of the filter file.
909 * With this flag set, the file is not closed, and more filters
910 * may be added before they take effect. The last call of this
911 * function must be called without this flag for the filter
912 * to take effect.
913 * TRACEFS_FL_FUTURE - only applicable if "module" is set. If no match
914 * is made, and the module is not yet loaded, it will still attempt
915 * to write the filter plus the module; "<filter>:mod:<module>"
916 * to the filter file. Starting with Linux kernels 4.13, it is possible
917 * to load the filter file with module functions for a module that
918 * is not yet loaded, and when the module is loaded, it will then
919 * activate the module.
920 *
921 * Returns 0 on success, 1 if there was an error but the filtering has not
922 * yet started, -1 if there was an error but the filtering has started.
923 * If -1 is returned and TRACEFS_FL_CONTINUE was set, then this function
924 * needs to be called again without the TRACEFS_FL_CONTINUE flag to commit
925 * the changes and close the filter file.
926 */
tracefs_function_filter(struct tracefs_instance * instance,const char * filter,const char * module,unsigned int flags)927 int tracefs_function_filter(struct tracefs_instance *instance, const char *filter,
928 const char *module, unsigned int flags)
929 {
930 char *filter_path;
931 int *fd;
932 int ret;
933
934 filter_path = tracefs_instance_get_file(instance, TRACE_FILTER);
935 if (!filter_path)
936 return -1;
937
938 if (instance)
939 fd = &instance->ftrace_filter_fd;
940 else
941 fd = &ftrace_filter_fd;
942
943 ret = update_filter(filter_path, fd, instance, filter, module, flags);
944 tracefs_put_tracing_file(filter_path);
945 return ret;
946 }
947
948 /**
949 * tracefs_function_notrace - filter the functions that are not to be traced
950 * @instance: ftrace instance, can be NULL for top tracing instance.
951 * @filter: The filter to filter what functions are not to be traced
952 * @module: Module to be traced or NULL if all functions are to be examined.
953 * @flags: flags on modifying the filter file
954 *
955 * See tracefs_function_filter, as this has the same functionality but
956 * for adding to the "notrace" filter.
957 */
tracefs_function_notrace(struct tracefs_instance * instance,const char * filter,const char * module,unsigned int flags)958 int tracefs_function_notrace(struct tracefs_instance *instance, const char *filter,
959 const char *module, unsigned int flags)
960 {
961 char *filter_path;
962 int *fd;
963 int ret;
964
965 filter_path = tracefs_instance_get_file(instance, TRACE_NOTRACE);
966 if (!filter_path)
967 return -1;
968
969 if (instance)
970 fd = &instance->ftrace_notrace_fd;
971 else
972 fd = &ftrace_notrace_fd;
973
974 ret = update_filter(filter_path, fd, instance, filter, module, flags);
975 tracefs_put_tracing_file(filter_path);
976 return ret;
977 }
978
write_tracer(int fd,const char * tracer)979 int write_tracer(int fd, const char *tracer)
980 {
981 int ret;
982
983 ret = write(fd, tracer, strlen(tracer));
984 if (ret < strlen(tracer))
985 return -1;
986 return ret;
987 }
988
989 /**
990 * tracefs_set_tracer - function to set the tracer
991 * @instance: ftrace instance, can be NULL for top tracing instance
992 * @tracer: The tracer enum that defines the tracer to be set
993 * @t: A tracer name if TRACEFS_TRACER_CUSTOM is passed in for @tracer
994 *
995 * Set the tracer for the instance based on the tracefs_tracer enums.
996 * If the user wishes to enable a tracer that is not defined by
997 * the enum (new or custom kernel), the tracer can be set to
998 * TRACEFS_TRACER_CUSTOM, and pass in a const char * name for
999 * the tracer to set.
1000 *
1001 * Returns 0 on succes, negative on error.
1002 */
1003
tracefs_tracer_set(struct tracefs_instance * instance,enum tracefs_tracers tracer,...)1004 int tracefs_tracer_set(struct tracefs_instance *instance,
1005 enum tracefs_tracers tracer, ...)
1006 {
1007 char *tracer_path = NULL;
1008 const char *t = NULL;
1009 int ret = -1;
1010 int fd = -1;
1011 int i;
1012
1013 if (tracer < 0 || tracer > ARRAY_SIZE(tracers)) {
1014 errno = EINVAL;
1015 return -1;
1016 }
1017
1018 tracer_path = tracefs_instance_get_file(instance, CUR_TRACER);
1019 if (!tracer_path)
1020 return -1;
1021
1022 fd = open(tracer_path, O_WRONLY);
1023 if (fd < 0) {
1024 errno = ENOENT;
1025 goto out;
1026 }
1027
1028 if (tracer == TRACEFS_TRACER_CUSTOM) {
1029 va_list ap;
1030
1031 va_start(ap, tracer);
1032 t = va_arg(ap, const char *);
1033 va_end(ap);
1034 } else if (tracer == tracer_enums[tracer]) {
1035 t = tracers[tracer];
1036 } else {
1037 for (i = 0; i < ARRAY_SIZE(tracer_enums); i++) {
1038 if (tracer == tracer_enums[i]) {
1039 t = tracers[i];
1040 break;
1041 }
1042 }
1043 }
1044 if (!t) {
1045 errno = EINVAL;
1046 goto out;
1047 }
1048 ret = write_tracer(fd, t);
1049 /*
1050 * If the tracer does not exist, EINVAL is returned,
1051 * but let the user know this as ENODEV.
1052 */
1053 if (ret < 0 && errno == EINVAL)
1054 errno = ENODEV;
1055 out:
1056 tracefs_put_tracing_file(tracer_path);
1057 close(fd);
1058 return ret > 0 ? 0 : ret;
1059 }
1060
tracefs_tracer_clear(struct tracefs_instance * instance)1061 int tracefs_tracer_clear(struct tracefs_instance *instance)
1062 {
1063 return tracefs_tracer_set(instance, TRACEFS_TRACER_NOP);
1064 }
1065
splice_safe(int fd,int pfd)1066 static bool splice_safe(int fd, int pfd)
1067 {
1068 int ret;
1069
1070 errno = 0;
1071 ret = splice(pfd, NULL, fd, NULL,
1072 10, SPLICE_F_NONBLOCK | SPLICE_F_MOVE);
1073
1074 return !ret || (ret < 0 && errno == EAGAIN);
1075 }
1076
read_trace_pipe(bool * keep_going,int in_fd,int out_fd)1077 static ssize_t read_trace_pipe(bool *keep_going, int in_fd, int out_fd)
1078 {
1079 char buf[BUFSIZ];
1080 ssize_t bread = 0;
1081 int ret;
1082
1083 while (*(volatile bool *)keep_going) {
1084 int r;
1085 ret = read(in_fd, buf, BUFSIZ);
1086 if (ret <= 0)
1087 break;
1088 r = ret;
1089 ret = write(out_fd, buf, r);
1090 if (ret < 0)
1091 break;
1092 bread += ret;
1093 /*
1094 * If the write does a partial write, then
1095 * the iteration should stop. This can happen if
1096 * the destination file system ran out of disk space.
1097 * Sure, it probably lost a little from the read
1098 * but there's not much more that can be
1099 * done. Just return what was transferred.
1100 */
1101 if (ret < r)
1102 break;
1103 }
1104
1105 if (ret < 0 && (errno == EAGAIN || errno == EINTR))
1106 ret = 0;
1107
1108 return ret < 0 ? ret : bread;
1109 }
1110
1111 static bool top_pipe_keep_going;
1112
1113 /**
1114 * tracefs_trace_pipe_stream - redirect the stream of trace data to an output
1115 * file. The "splice" system call is used to moves the data without copying
1116 * between kernel address space and user address space. The user can interrupt
1117 * the streaming of the data by pressing Ctrl-c.
1118 * @fd: The file descriptor of the output file.
1119 * @instance: ftrace instance, can be NULL for top tracing instance.
1120 * @flags: flags for opening the trace_pipe file.
1121 *
1122 * Returns -1 in case of an error or number of bytes transferred otherwise.
1123 */
tracefs_trace_pipe_stream(int fd,struct tracefs_instance * instance,int flags)1124 ssize_t tracefs_trace_pipe_stream(int fd, struct tracefs_instance *instance,
1125 int flags)
1126 {
1127 bool *keep_going = instance ? &instance->pipe_keep_going :
1128 &top_pipe_keep_going;
1129 const char *file = "trace_pipe";
1130 int brass[2], in_fd, ret = -1;
1131 int sflags = flags & O_NONBLOCK ? SPLICE_F_NONBLOCK : 0;
1132 off_t data_size;
1133 ssize_t bread = 0;
1134
1135 (*(volatile bool *)keep_going) = true;
1136
1137 in_fd = tracefs_instance_file_open(instance, file, O_RDONLY | flags);
1138 if (in_fd < 0) {
1139 tracefs_warning("Failed to open 'trace_pipe'.");
1140 return ret;
1141 }
1142
1143 if(pipe(brass) < 0) {
1144 tracefs_warning("Failed to open pipe.");
1145 goto close_file;
1146 }
1147
1148 data_size = fcntl(brass[0], F_GETPIPE_SZ);
1149 if (data_size <= 0) {
1150 tracefs_warning("Failed to open pipe (size=0).");
1151 goto close_all;
1152 }
1153
1154 /* Test if the output is splice safe */
1155 if (!splice_safe(fd, brass[0])) {
1156 bread = read_trace_pipe(keep_going, in_fd, fd);
1157 ret = 0; /* Force return of bread */
1158 goto close_all;
1159 }
1160
1161 errno = 0;
1162
1163 while (*(volatile bool *)keep_going) {
1164 ret = splice(in_fd, NULL,
1165 brass[1], NULL,
1166 data_size, sflags);
1167 if (ret < 0)
1168 break;
1169
1170 ret = splice(brass[0], NULL,
1171 fd, NULL,
1172 data_size, sflags);
1173 if (ret < 0)
1174 break;
1175 bread += ret;
1176 }
1177
1178 /*
1179 * Do not return error in the case when the "splice" system call
1180 * was interrupted by the user (pressing Ctrl-c).
1181 * Or if NONBLOCK was specified.
1182 */
1183 if (!keep_going || errno == EAGAIN || errno == EINTR)
1184 ret = 0;
1185
1186 close_all:
1187 close(brass[0]);
1188 close(brass[1]);
1189 close_file:
1190 close(in_fd);
1191
1192 return ret ? ret : bread;
1193 }
1194
1195 /**
1196 * tracefs_trace_pipe_print - redirect the stream of trace data to "stdout".
1197 * The "splice" system call is used to moves the data without copying
1198 * between kernel address space and user address space.
1199 * @instance: ftrace instance, can be NULL for top tracing instance.
1200 * @flags: flags for opening the trace_pipe file.
1201 *
1202 * Returns -1 in case of an error or number of bytes transferred otherwise.
1203 */
1204
tracefs_trace_pipe_print(struct tracefs_instance * instance,int flags)1205 ssize_t tracefs_trace_pipe_print(struct tracefs_instance *instance, int flags)
1206 {
1207 return tracefs_trace_pipe_stream(STDOUT_FILENO, instance, flags);
1208 }
1209
1210 /**
1211 * tracefs_trace_pipe_stop - stop the streaming of trace data.
1212 * @instance: ftrace instance, can be NULL for top tracing instance.
1213 */
tracefs_trace_pipe_stop(struct tracefs_instance * instance)1214 void tracefs_trace_pipe_stop(struct tracefs_instance *instance)
1215 {
1216 if (instance)
1217 instance->pipe_keep_going = false;
1218 else
1219 top_pipe_keep_going = false;
1220 }
1221
1222 /**
1223 * tracefs_filter_functions - return a list of available functons that can be filtered
1224 * @filter: The filter to filter what functions to list (can be NULL for all)
1225 * @module: Module to be traced or NULL if all functions are to be examined.
1226 * @list: The list to return the list from (freed by tracefs_list_free() on success)
1227 *
1228 * Returns a list of function names that match @filter and @module. If both
1229 * @filter and @module is NULL, then all available functions that can be filtered
1230 * will be returned. (Note, there can be duplicates, if there are more than
1231 * one function with the same name.
1232 *
1233 * On success, zero is returned, and @list contains a list of functions that were
1234 * found, and must be freed with tracefs_list_free().
1235 * On failure, a negative number is returned, and @list is ignored.
1236 */
tracefs_filter_functions(const char * filter,const char * module,char *** list)1237 int tracefs_filter_functions(const char *filter, const char *module, char ***list)
1238 {
1239 struct func_filter func_filter;
1240 struct func_list *func_list = NULL, *f;
1241 char **funcs = NULL;
1242 int ret;
1243
1244 if (!filter)
1245 filter = ".*";
1246
1247 ret = init_func_filter(&func_filter, filter);
1248 if (ret < 0)
1249 return ret;
1250
1251 ret = list_available_filters(&func_filter, module, &func_list);
1252 if (ret < 0)
1253 goto out;
1254
1255 ret = -1;
1256 for (f = func_list; f; f = f->next) {
1257 char **tmp;
1258
1259 tmp = tracefs_list_add(funcs, f->func);
1260 if (!tmp) {
1261 tracefs_list_free(funcs);
1262 goto out;
1263 }
1264 funcs = tmp;
1265 }
1266
1267 *list = funcs;
1268 ret = 0;
1269 out:
1270 regfree(&func_filter.re);
1271 free_func_list(func_list);
1272 return ret;
1273 }
1274