• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) 2008, 2009, 2010 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
4  *
5  */
6 #include <stdio.h>
7 #include <string.h>
8 #include <getopt.h>
9 #include <unistd.h>
10 #include <dirent.h>
11 #include <errno.h>
12 #include <stdlib.h>
13 #include <sys/syscall.h>
14 
15 #include "trace-local.h"
16 
17 int silence_warnings;
18 int show_status;
19 
20 #ifndef gettid
21 #define gettid() syscall(__NR_gettid)
22 #endif
23 
warning(const char * fmt,...)24 void warning(const char *fmt, ...)
25 {
26 	va_list ap;
27 
28 	if (silence_warnings)
29 		return;
30 
31 	if (errno)
32 		perror("trace-cmd");
33 	errno = 0;
34 
35 	va_start(ap, fmt);
36 	fprintf(stderr, "  ");
37 	vfprintf(stderr, fmt, ap);
38 	va_end(ap);
39 
40 	fprintf(stderr, "\n");
41 }
42 
malloc_or_die(unsigned int size)43 void *malloc_or_die(unsigned int size)
44 {
45 	void *data;
46 
47 	data = malloc(size);
48 	if (!data)
49 		die("malloc");
50 	return data;
51 }
52 
53 /* Same as strtok_r(), but allows empty tokens */
strparse(char * str,char delim,char ** save)54 char *strparse(char *str, char delim, char **save)
55 {
56 	char *next;
57 
58 	if (!str) {
59 		str = *save;
60 		if ((*save)[0] == '\0')
61 			return NULL;
62 	}
63 
64 	next = strchr(str, delim);
65 	if (next) {
66 		*next = '\0';
67 		*save = next + 1;
68 	} else {
69 		*save = str + strlen(str);
70 	}
71 	return str;
72 }
73 
tracecmd_debug(const char * fmt,...)74 void tracecmd_debug(const char *fmt, ...)
75 {
76 	va_list ap;
77 
78 	if (!tracecmd_get_debug())
79 		return;
80 
81 	va_start(ap, fmt);
82 	printf("[%d] ", (int)gettid());
83 	vprintf(fmt, ap);
84 	va_end(ap);
85 }
86 
87 static struct trace_log_severity {
88 	int		id;
89 	const char	*name;
90 } log_severity[] = {
91 	{ .id = TEP_LOG_NONE, .name = "none" },
92 	{ .id = TEP_LOG_CRITICAL, .name = "crit" },
93 	{ .id = TEP_LOG_ERROR, .name = "err" },
94 	{ .id = TEP_LOG_WARNING, .name = "warn" },
95 	{ .id = TEP_LOG_INFO, .name = "info" },
96 	{ .id = TEP_LOG_DEBUG, .name = "debug" },
97 	{ .id = TEP_LOG_ALL, .name = "all" },
98 };
99 
trace_set_loglevel(int level)100 void trace_set_loglevel(int level)
101 {
102 	tracecmd_set_loglevel(level);
103 	tracefs_set_loglevel(level);
104 	tep_set_loglevel(level);
105 }
106 
trace_set_verbose(char * level)107 int trace_set_verbose(char *level)
108 {
109 	int id;
110 
111 	/* Default level is info */
112 	if (!level)
113 		level = "info";
114 
115 	if (isdigit(level[0])) {
116 		id = atoi(level);
117 		if (id >= TEP_LOG_NONE) {
118 			if (id > TEP_LOG_ALL)
119 				id = TEP_LOG_ALL;
120 			trace_set_loglevel(id);
121 			return 0;
122 		}
123 	} else {
124 		int size = ARRAY_SIZE(log_severity);
125 		int i;
126 
127 		for (i = 0; i < size; i++) {
128 			if (!strncmp(level, log_severity[i].name, strlen(log_severity[i].name))) {
129 				trace_set_loglevel(log_severity[i].id);
130 				return 0;
131 			}
132 		}
133 	}
134 
135 	return -1;
136 }
137 
138 /**
139  * struct command
140  * @name command name
141  * @run function to execute on command `name`
142  */
143 struct command {
144 	char *name;
145 	void (*run)(int argc, char **argv);
146 };
147 
148 
149 /**
150  * Lookup table that maps command names to functions
151  */
152 struct command commands[] = {
153 	{"report", trace_report},
154 	{"snapshot", trace_snapshot},
155 	{"hist", trace_hist},
156 	{"mem", trace_mem},
157 	{"listen", trace_listen},
158 	{"agent", trace_agent},
159 	{"setup-guest", trace_setup_guest},
160 	{"split", trace_split},
161 	{"restore", trace_restore},
162 	{"stack", trace_stack},
163 	{"check-events", trace_check_events},
164 	{"record", trace_record},
165 	{"start", trace_start},
166 	{"set", trace_set},
167 	{"extract", trace_extract},
168 	{"stop", trace_stop},
169 	{"stream", trace_stream},
170 	{"profile", trace_profile},
171 	{"restart", trace_restart},
172 	{"clear", trace_clear},
173 	{"reset", trace_reset},
174 	{"stat", trace_stat},
175 	{"options", trace_option},
176 	{"show", trace_show},
177 	{"list", trace_list},
178 	{"help", trace_usage},
179 	{"dump", trace_dump},
180 	{"attach", trace_attach},
181 	{"convert", trace_convert},
182 	{"sqlhist", trace_sqlhist},
183 	{"-h", trace_usage},
184 };
185 
main(int argc,char ** argv)186 int main (int argc, char **argv)
187 {
188 	int i;
189 
190 	errno = 0;
191 
192 	if (argc < 2)
193 		trace_usage(argc, argv);
194 
195 	for (i = 0; i < ARRAY_SIZE(commands); ++i) {
196 		if (strcmp(argv[1], commands[i].name) == 0 ){
197 			commands[i].run(argc, argv);
198 			goto out;
199 		}
200 	}
201 
202 	/* No valid command found, show help */
203 	trace_usage(argc, argv);
204 out:
205 	exit(0);
206 }
207