• 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 			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