Update version to 0.16
[ust.git] / ustctl / ustctl.c
1 /* Copyright (C) 2009 Pierre-Marc Fournier
2 * Copyright (C) 2011 Ericsson AB, Nils Carlson <nils.carlson@ericsson.com>
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19 #define _GNU_SOURCE
20 #include <stdio.h>
21 #include <unistd.h>
22 #include <getopt.h>
23 #include <stdlib.h>
24 #include <fcntl.h>
25
26 #include "ust/ustctl.h"
27 #include "usterr.h"
28 #include "cli.h"
29 #include "scanning_functions.h"
30
31 void usage(const char *process_name)
32 {
33 fprintf(stderr, "Usage: %s COMMAND [ARGS]...\n", process_name);
34 fprintf(stderr,
35 "Control tracing within a process that supports UST,\n"
36 " the Userspace Tracing libary\n"
37 "Options:\n"
38 " -h[<cmd>], --help[=<cmd>] "
39 "help, for a command if provided\n"
40 " -l, --list "
41 "short list of commands\n"
42 " -e, --extended-list "
43 "extented list of commands with help\n"
44 "Commands:\n");
45 list_cli_cmds(CLI_DESCRIPTIVE_LIST);
46 }
47
48 /*
49 * Provide backward compatibility for scripts that make use of the
50 * --commands in ustctl version <= 0.11
51 */
52 enum command {
53 CREATE_TRACE=1000,
54 ALLOC_TRACE,
55 START_TRACE,
56 STOP_TRACE,
57 DESTROY_TRACE,
58 LIST_MARKERS,
59 LIST_TRACE_EVENTS,
60 ENABLE_MARKER,
61 DISABLE_MARKER,
62 };
63
64 struct option options[] =
65 {
66 { "create-trace", 0, 0, CREATE_TRACE },
67 { "alloc-trace", 0, 0, ALLOC_TRACE },
68 { "start-trace", 0, 0, START_TRACE },
69 { "stop-trace", 0, 0, STOP_TRACE },
70 { "destroy-trace", 0, 0, DESTROY_TRACE },
71 { "list-markers", 0, 0, LIST_MARKERS },
72 { "list-trace-events", 0, 0, LIST_TRACE_EVENTS},
73 { "enable-marker", 0, 0, ENABLE_MARKER },
74 { "disable-marker", 0, 0, DISABLE_MARKER },
75 {"help", 2, NULL, 'h'},
76 {"list", 0, NULL, 'l'},
77 {"extended-list", 0, NULL, 'e'},
78 {NULL, 0, NULL, 0},
79 };
80
81 int main(int argc, char *argv[])
82 {
83 struct cli_cmd *cli_cmd;
84 char **args = argv;
85 int opt;
86 int i;
87
88 if(argc <= 1) {
89 fprintf(stderr, "No operation specified.\n");
90 usage(argv[0]);
91 exit(EXIT_FAILURE);
92 }
93
94 while ((opt = getopt_long(argc, argv, "+h::le",
95 options, NULL)) != -1) {
96 switch (opt) {
97 case 'h':
98 if (!optarg) {
99 usage(argv[0]);
100 } else {
101 if (cli_print_help(optarg)) {
102 fprintf(stderr, "No such command %s\n",
103 optarg);
104 }
105 }
106 exit(EXIT_FAILURE);
107 break;
108 case 'l':
109 list_cli_cmds(CLI_SIMPLE_LIST);
110 exit(EXIT_FAILURE);
111 break;
112 case 'e':
113 list_cli_cmds(CLI_EXTENDED_LIST);
114 exit(EXIT_FAILURE);
115 case LIST_MARKERS:
116 case LIST_TRACE_EVENTS:
117 case CREATE_TRACE:
118 case ALLOC_TRACE:
119 case START_TRACE:
120 case STOP_TRACE:
121 case DESTROY_TRACE:
122 case ENABLE_MARKER:
123 case DISABLE_MARKER:
124 args = (char **)malloc(sizeof(char *) * (argc + 3));
125 optind--;
126 args[optind] = strdup(&argv[optind][2]);
127 for (i = optind + 1; i < argc; i++) {
128 args[i] = argv[i];
129 }
130 if (opt >= CREATE_TRACE && opt <= DESTROY_TRACE) {
131 args[argc] = strdup("auto");
132 argc++;
133 }
134 if (opt >= ENABLE_MARKER && opt <= DISABLE_MARKER) {
135 args[argc] = args[argc - 2];
136 args[argc - 2] = args[argc - 1];
137 args[argc - 1] = strdup("auto");
138 argc++;
139 }
140 args[argc] = NULL;
141 goto do_cli;
142 default:
143 fprintf(stderr, "Unknown option\n");
144 break;
145 }
146 }
147
148 do_cli:
149 cli_cmd = find_cli_cmd(args[optind]);
150 if (!cli_cmd) {
151 fprintf(stderr, "No such command %s\n",
152 args[optind]);
153 exit(EXIT_FAILURE);
154 }
155
156 cli_dispatch_cmd(cli_cmd, argc - optind, &args[optind]);
157
158 return 0;
159 }
160
161 static int list_trace_events(int argc, char *argv[])
162 {
163 struct trace_event_status *tes = NULL;
164 int i, sock;
165
166 sock = parse_and_connect_pid(argv[1]);
167
168 if (ustctl_get_tes(sock, &tes)) {
169 ERR("error while trying to list "
170 "trace_events for PID %s\n",
171 argv[1]);
172 return -1;
173 }
174 i = 0;
175 for (i = 0; tes[i].name; i++) {
176 printf("{PID: %s, trace_event: %s}\n",
177 argv[1],
178 tes[i].name);
179 }
180 ustctl_free_tes(tes);
181
182 return 0;
183 }
184
185 static int set_sock_path(int argc, char *argv[])
186 {
187 int sock;
188
189 sock = parse_and_connect_pid(argv[1]);
190
191 if (ustctl_set_sock_path(sock, argv[2])) {
192 ERR("error while trying to set sock path for PID %s\n", argv[1]);
193 return -1;
194 }
195
196 return 0;
197 }
198
199 static int get_sock_path(int argc, char *argv[])
200 {
201 int sock;
202 char *sock_path;
203
204 sock = parse_and_connect_pid(argv[1]);
205
206 if (ustctl_get_sock_path(sock, &sock_path)) {
207 ERR("error while trying to get sock path for PID %s\n", argv[1]);
208 return -1;
209 }
210 printf("The socket path is %s\n", sock_path);
211 free(sock_path);
212
213 return 0;
214 }
215
216 static int list_pids(int argc, char *argv[])
217 {
218 pid_t *pid_list;
219 int i;
220
221 pid_list = ustctl_get_online_pids();
222 if (!pid_list) {
223 return -1;
224 }
225
226 for (i = 0; pid_list[i]; i++) {
227 printf("%ld\n", (long)pid_list[i]);
228 }
229
230 free(pid_list);
231
232 return 0;
233 }
234
235 struct cli_cmd __cli_cmds general_cmds[] = {
236 {
237 .name = "list-trace-events",
238 .description = "List trace-events for a given pid",
239 .help_text = "list-trace-events <pid>\n"
240 "List the trace-events in a process\n",
241 .function = list_trace_events,
242 .desired_args = 1,
243 .desired_args_op = CLI_EQ,
244 },
245 {
246 .name = "set-sock-path",
247 .description = "Set the path to the consumer daemon socket",
248 .help_text = "set-sock-path <pid> <sock-path>\n"
249 "Set the path to the consumer daemon socket\n",
250 .function = set_sock_path,
251 .desired_args = 2,
252 .desired_args_op = CLI_EQ,
253 },
254 {
255 .name = "get-sock-path",
256 .description = "Get the path to the consumer daemon socket",
257 .help_text = "get-sock-path <pid>\n"
258 "Get the path to the consumer daemon socket\n",
259 .function = get_sock_path,
260 .desired_args = 1,
261 .desired_args_op = CLI_EQ,
262 },
263 {
264 .name = "list-pids",
265 .description = "List traceable pids",
266 .help_text = "list-pids\n"
267 "List the traceable pids for the current user\n",
268 .function = list_pids,
269 .desired_args = 0,
270 .desired_args_op = CLI_EQ,
271 },
272 };
This page took 0.033932 seconds and 4 git commands to generate.