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