err val handling
[lttv.git] / ltt / branches / poly / lttctl / lttctl.c
CommitLineData
2cdb6fcb 1/* lttctl
2 *
3 * Linux Trace Toolkit Control
4 *
5 * Small program that controls LTT through libltt.
6 *
7 * Copyright 2005 -
8 * Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
9 */
10
4e4d11b3 11#ifdef HAVE_CONFIG_H
12#include <config.h>
13#endif
14
5adba60f 15#include <libltt/libltt.h>
16#include <errno.h>
17#include <stdio.h>
18#include <stdlib.h>
19#include <sys/types.h>
20#include <unistd.h>
21#include <signal.h>
2cdb6fcb 22
5adba60f 23enum trace_ctl_op {
24 CTL_OP_CREATE,
25 CTL_OP_DESTROY,
26 CTL_OP_START,
27 CTL_OP_STOP,
28 CTL_OP_DAEMON,
29 CTL_OP_NONE
30};
2cdb6fcb 31
5adba60f 32static char *trace_name = NULL;
33static char *mode_name = NULL;
988614ed 34static unsigned subbuf_size = 0;
35static unsigned n_subbufs = 0;
5adba60f 36static enum trace_mode mode = LTT_TRACE_NORMAL;
37static enum trace_ctl_op op = CTL_OP_NONE;
38static char *channel_root = NULL;
39static char *trace_root = NULL;
40
ada84671 41static int sigio_received = 0;
42
5adba60f 43void handler(int signo)
44{
45 printf("signal %d received\n", signo);
ada84671 46 sigio_received = 1;
5adba60f 47}
48
49
50/* Args :
51 *
52 */
53void show_arguments(void)
54{
55 printf("Please use the following arguments :\n");
56 printf("\n");
57 printf("-n name Name of the trace.\n");
58 printf("-c mode Create trace channels in mode normal or flight recorder.\n");
59 printf(" Mode values : normal (default) or flight.\n");
60 printf("-r Destroy trace channels.\n");
61 printf("-s Start tracing.\n");
62 //printf(" Note : will automatically create a normal trace if "
63 // "none exists.\n");
64 printf("-q Stop tracing.\n");
65 printf("-d Create trace, spawn a lttd daemon, start tracing.\n");
66 printf(" (optionnaly, you can set LTT_DAEMON env. var.)\n");
67 printf("-t Trace root path. (ex. /root/traces/example_trace)\n");
68 printf("-l LTT channels root path. (ex. /mnt/relayfs/ltt)\n");
4085af66 69 printf("-z Size of the subbuffers (will be rounded to next page size)\n");
988614ed 70 printf("-x Number of subbuffers\n");
5adba60f 71 printf("\n");
72}
73
74
75/* parse_arguments
76 *
77 * Parses the command line arguments.
78 *
79 * Returns 1 if the arguments were correct, but doesn't ask for program
80 * continuation. Returns -1 if the arguments are incorrect, or 0 if OK.
81 */
82int parse_arguments(int argc, char **argv)
83{
84 int ret = 0;
85 int argn = 1;
86
87 if(argc == 2) {
88 if(strcmp(argv[1], "-h") == 0) {
89 return 1;
90 }
91 }
92
93 while(argn < argc) {
94
95 switch(argv[argn][0]) {
96 case '-':
97 switch(argv[argn][1]) {
98 case 'n':
99 if(argn+1 < argc) {
100 trace_name = argv[argn+1];
101 argn++;
102 } else {
103 printf("Specify a trace name after -n.\n", argv[argn]);
104 printf("\n");
105 ret = -1;
106 }
107
108 break;
109 case 'c':
110 op = CTL_OP_CREATE;
111 if(argn+1 < argc) {
112 mode_name = argv[argn+1];
113 argn++;
114 if(strcmp(mode_name, "normal") == 0)
115 mode = LTT_TRACE_NORMAL;
116 else if(strcmp(mode_name, "flight") == 0)
117 mode = LTT_TRACE_FLIGHT;
118 else {
119 printf("Invalid mode '%s'.\n", argv[argn]);
120 printf("\n");
121 ret = -1;
122 }
123 } else {
988614ed 124 printf("Specify a mode after -c.\n");
5adba60f 125 printf("\n");
126 ret = -1;
127 }
128 break;
129 case 'r':
130 op = CTL_OP_DESTROY;
131 break;
132 case 's':
133 op = CTL_OP_START;
134 break;
135 case 'q':
136 op = CTL_OP_STOP;
137 break;
988614ed 138 case 'z':
139 if(argn+1 < argc) {
140 subbuf_size = (unsigned)atoi(argv[argn+1]);
141 argn++;
142 } else {
143 printf("Specify a number of subbuffers after -z.\n");
144 printf("\n");
145 ret = -1;
146 }
147 break;
148 case 'x':
149 if(argn+1 < argc) {
150 n_subbufs = (unsigned)atoi(argv[argn+1]);
151 argn++;
152 } else {
153 printf("Specify a subbuffer size after -x.\n");
154 printf("\n");
155 ret = -1;
156 }
157 break;
5adba60f 158 case 'd':
159 op = CTL_OP_DAEMON;
160 break;
161 case 't':
162 if(argn+1 < argc) {
163 trace_root = argv[argn+1];
164 argn++;
165 } else {
988614ed 166 printf("Specify a trace root path after -t.\n");
5adba60f 167 printf("\n");
168 ret = -1;
169 }
170 break;
171 case 'l':
172 if(argn+1 < argc) {
173 channel_root = argv[argn+1];
174 argn++;
175 } else {
988614ed 176 printf("Specify a channel root path after -l.\n");
5adba60f 177 printf("\n");
178 ret = -1;
179 }
180 break;
181 default:
182 printf("Invalid argument '%s'.\n", argv[argn]);
183 printf("\n");
184 ret = -1;
185 }
186 break;
187 default:
188 printf("Invalid argument '%s'.\n", argv[argn]);
189 printf("\n");
190 ret = -1;
191 }
192 argn++;
193 }
194
195 if(trace_name == NULL) {
196 printf("Please specify a trace name.\n");
197 printf("\n");
198 ret = -1;
199 }
200
201 if(op == CTL_OP_NONE) {
202 printf("Please specify an operation.\n");
203 printf("\n");
204 ret = -1;
205 }
206
207 if(op == CTL_OP_DAEMON) {
208 if(trace_root == NULL) {
209 printf("Please specify -t trace_root_path with the -d option.\n");
210 printf("\n");
211 ret = -1;
212 }
213 if(channel_root == NULL) {
214 printf("Please specify -l ltt_root_path with the -d option.\n");
215 printf("\n");
216 ret = -1;
217 }
218 }
219
220 return ret;
221}
222
223void show_info(void)
224{
225 printf("Linux Trace Toolkit Trace Control\n");
226 printf("\n");
227 printf("Controlling trace : %s\n", trace_name);
228 printf("\n");
229}
230
231int lttctl_daemon(struct lttctl_handle *handle, char *trace_name)
232{
233 char channel_path[PATH_MAX] = "";
234 pid_t pid;
235 int ret;
236 char *lttd_path = getenv("LTT_DAEMON");
237 struct sigaction act;
238
239 if(lttd_path == NULL) lttd_path = "lttd";
240
241 strcat(channel_path, channel_root);
242 strcat(channel_path, "/");
243 strcat(channel_path, trace_name);
244
245
988614ed 246 ret = lttctl_create_trace(handle, trace_name, mode, subbuf_size, n_subbufs);
5adba60f 247 if(ret != 0) goto create_error;
248
249 act.sa_handler = handler;
250 sigemptyset(&(act.sa_mask));
251 sigaddset(&(act.sa_mask), SIGIO);
252 sigaction(SIGIO, &act, NULL);
253
ada84671 254 sigio_received = 0;
255
5adba60f 256 pid = fork();
257
258 if(pid > 0) {
5adba60f 259 /* parent */
ada84671 260 while(!sigio_received) pause();
5adba60f 261
262 /* Now the trace is created, go on and create the supplementary files... */
263 printf("Creating supplementary trace files\n");
264
265 } else if(pid == 0) {
266 /* child */
267 int ret =
268 execlp(lttd_path, lttd_path, "-t", trace_root, "-c", channel_path, "-s", NULL);
269 if(ret) {
270 perror("Error in executing the lttd daemon");
271 exit(-1);
272 }
273 } else {
274 /* error */
275 perror("Error in forking for lttd daemon");
276
277 }
278
279 ret = lttctl_start(handle, trace_name);
280 if(ret != 0) goto start_error;
281
282 return 0;
283
284 /* error handling */
285start_error:
286 ret |= lttctl_destroy_trace(handle, trace_name);
287create_error:
288 return ret;
289}
290
291int main(int argc, char ** argv)
292{
293 int ret;
294 struct lttctl_handle *handle;
295
296 ret = parse_arguments(argc, argv);
297
298 if(ret != 0) show_arguments();
299 if(ret < 0) return EINVAL;
300 if(ret > 0) return 0;
301
302 show_info();
303
304 handle = lttctl_create_handle();
305
306 if(handle == NULL) return -1;
307
308 switch(op) {
309 case CTL_OP_CREATE:
988614ed 310 ret = lttctl_create_trace(handle, trace_name, mode, subbuf_size,
311 n_subbufs);
5adba60f 312 case CTL_OP_DESTROY:
313 ret = lttctl_destroy_trace(handle, trace_name);
314 break;
315 case CTL_OP_START:
316 ret = lttctl_start(handle, trace_name);
317 break;
318 case CTL_OP_STOP:
319 ret = lttctl_stop(handle, trace_name);
320 break;
321 case CTL_OP_DAEMON:
322 ret = lttctl_daemon(handle, trace_name);
323 break;
324 case CTL_OP_NONE:
325 break;
326 }
327
328 ret |= lttctl_destroy_handle(handle);
329
330 return ret;
331}
This page took 0.036005 seconds and 4 git commands to generate.