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
tracecmd_debug(const char * fmt,...)53 void tracecmd_debug(const char *fmt, ...)
54 {
55 va_list ap;
56
57 if (!tracecmd_get_debug())
58 return;
59
60 va_start(ap, fmt);
61 printf("[%d] ", (int)gettid());
62 vprintf(fmt, ap);
63 va_end(ap);
64 }
65
66 static struct trace_log_severity {
67 int id;
68 const char *name;
69 } log_severity[] = {
70 { .id = TEP_LOG_NONE, .name = "none" },
71 { .id = TEP_LOG_CRITICAL, .name = "crit" },
72 { .id = TEP_LOG_ERROR, .name = "err" },
73 { .id = TEP_LOG_WARNING, .name = "warn" },
74 { .id = TEP_LOG_INFO, .name = "info" },
75 { .id = TEP_LOG_DEBUG, .name = "debug" },
76 { .id = TEP_LOG_ALL, .name = "all" },
77 };
78
trace_set_verbose(char * level)79 int trace_set_verbose(char *level)
80 {
81 int id;
82
83 /* Default level is info */
84 if (!level)
85 level = "info";
86
87 if (isdigit(level[0])) {
88 id = atoi(level);
89 if (id >= TEP_LOG_NONE) {
90 if (id > TEP_LOG_ALL)
91 id = TEP_LOG_ALL;
92 tracecmd_set_loglevel(id);
93 return 0;
94 }
95 } else {
96 int size = ARRAY_SIZE(log_severity);
97 int i;
98
99 for (i = 0; i < size; i++) {
100 if (!strncmp(level, log_severity[i].name, strlen(log_severity[i].name))) {
101 tracecmd_set_loglevel(log_severity[i].id);
102 return 0;
103 }
104 }
105 }
106
107 return -1;
108 }
109
110 /**
111 * struct command
112 * @name command name
113 * @run function to execute on command `name`
114 */
115 struct command {
116 char *name;
117 void (*run)(int argc, char **argv);
118 };
119
120
121 /**
122 * Lookup table that maps command names to functions
123 */
124 struct command commands[] = {
125 {"report", trace_report},
126 {"snapshot", trace_snapshot},
127 {"hist", trace_hist},
128 {"mem", trace_mem},
129 {"listen", trace_listen},
130 {"agent", trace_agent},
131 {"setup-guest", trace_setup_guest},
132 {"split", trace_split},
133 {"restore", trace_restore},
134 {"stack", trace_stack},
135 {"check-events", trace_check_events},
136 {"record", trace_record},
137 {"start", trace_start},
138 {"set", trace_set},
139 {"extract", trace_extract},
140 {"stop", trace_stop},
141 {"stream", trace_stream},
142 {"profile", trace_profile},
143 {"restart", trace_restart},
144 {"clear", trace_clear},
145 {"reset", trace_reset},
146 {"stat", trace_stat},
147 {"options", trace_option},
148 {"show", trace_show},
149 {"list", trace_list},
150 {"help", trace_usage},
151 {"dump", trace_dump},
152 {"convert", trace_convert},
153 {"-h", trace_usage},
154 };
155
main(int argc,char ** argv)156 int main (int argc, char **argv)
157 {
158 int i;
159
160 errno = 0;
161
162 if (argc < 2)
163 trace_usage(argc, argv);
164
165 for (i = 0; i < ARRAY_SIZE(commands); ++i) {
166 if (strcmp(argv[1], commands[i].name) == 0 ){
167 commands[i].run(argc, argv);
168 goto out;
169 }
170 }
171
172 /* No valid command found, show help */
173 trace_usage(argc, argv);
174 out:
175 exit(0);
176 }
177