• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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