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