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