3 * Linux Trace Toolkit Control
5 * Small program that controls LTT through libltt.
8 * Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
15 #include <libltt/libltt.h>
19 #include <sys/types.h>
26 /* Buffer for file copy : 4k seems optimal. */
27 #define BUF_SIZE 4194304
38 static char *trace_name
= NULL
;
39 static char *mode_name
= NULL
;
40 static unsigned subbuf_size
= 0;
41 static unsigned n_subbufs
= 0;
42 static enum trace_mode mode
= LTT_TRACE_NORMAL
;
43 static enum trace_ctl_op op
= CTL_OP_NONE
;
44 static char *channel_root
= NULL
;
45 static char *trace_root
= NULL
;
47 static int sigio_received
= 0;
49 void handler(int signo
)
51 printf("signal %d received\n", signo
);
59 void show_arguments(void)
61 printf("Please use the following arguments :\n");
63 printf("-n name Name of the trace.\n");
64 printf("-c mode Create trace channels in mode normal or flight recorder.\n");
65 printf(" Mode values : normal (default) or flight.\n");
66 printf("-r Destroy trace channels.\n");
67 printf("-s Start tracing.\n");
68 //printf(" Note : will automatically create a normal trace if "
70 printf("-q Stop tracing.\n");
71 printf("-d Create trace, spawn a lttd daemon, start tracing.\n");
72 printf(" (optionnaly, you can set LTT_DAEMON\n");
73 printf(" and the LTT_FACILITIES env. vars.)\n");
74 printf("-t Trace root path. (ex. /root/traces/example_trace)\n");
75 printf("-l LTT channels root path. (ex. /mnt/relayfs/ltt)\n");
76 printf("-z Size of the subbuffers (will be rounded to next page size)\n");
77 printf("-x Number of subbuffers\n");
84 * Parses the command line arguments.
86 * Returns 1 if the arguments were correct, but doesn't ask for program
87 * continuation. Returns -1 if the arguments are incorrect, or 0 if OK.
89 int parse_arguments(int argc
, char **argv
)
95 if(strcmp(argv
[1], "-h") == 0) {
102 switch(argv
[argn
][0]) {
104 switch(argv
[argn
][1]) {
107 trace_name
= argv
[argn
+1];
110 printf("Specify a trace name after -n.\n", argv
[argn
]);
119 mode_name
= argv
[argn
+1];
121 if(strcmp(mode_name
, "normal") == 0)
122 mode
= LTT_TRACE_NORMAL
;
123 else if(strcmp(mode_name
, "flight") == 0)
124 mode
= LTT_TRACE_FLIGHT
;
126 printf("Invalid mode '%s'.\n", argv
[argn
]);
131 printf("Specify a mode after -c.\n");
147 subbuf_size
= (unsigned)atoi(argv
[argn
+1]);
150 printf("Specify a number of subbuffers after -z.\n");
157 n_subbufs
= (unsigned)atoi(argv
[argn
+1]);
160 printf("Specify a subbuffer size after -x.\n");
170 trace_root
= argv
[argn
+1];
173 printf("Specify a trace root path after -t.\n");
180 channel_root
= argv
[argn
+1];
183 printf("Specify a channel root path after -l.\n");
189 printf("Invalid argument '%s'.\n", argv
[argn
]);
195 printf("Invalid argument '%s'.\n", argv
[argn
]);
202 if(trace_name
== NULL
) {
203 printf("Please specify a trace name.\n");
208 if(op
== CTL_OP_NONE
) {
209 printf("Please specify an operation.\n");
214 if(op
== CTL_OP_DAEMON
) {
215 if(trace_root
== NULL
) {
216 printf("Please specify -t trace_root_path with the -d option.\n");
220 if(channel_root
== NULL
) {
221 printf("Please specify -l ltt_root_path with the -d option.\n");
232 printf("Linux Trace Toolkit Trace Control\n");
234 printf("Controlling trace : %s\n", trace_name
);
238 int lttctl_daemon(struct lttctl_handle
*handle
, char *trace_name
)
240 char channel_path
[PATH_MAX
] = "";
243 char *lttd_path
= getenv("LTT_DAEMON");
244 char *facilities_path
= getenv("LTT_FACILITIES");
245 struct sigaction act
;
246 char eventdefs_path
[PATH_MAX
];
247 char eventdefs_file
[PATH_MAX
];
248 char facilities_file
[PATH_MAX
];
249 char read_buf
[BUF_SIZE
];
250 struct dirent
*entry
;
252 if(lttd_path
== NULL
) lttd_path
= "lttd";
253 if(facilities_path
== NULL
) facilities_path
=
254 "/usr/share/LinuxTraceToolkitViewer/facilities";
256 strcat(channel_path
, channel_root
);
257 strcat(channel_path
, "/");
258 strcat(channel_path
, trace_name
);
261 ret
= lttctl_create_trace(handle
, trace_name
, mode
, subbuf_size
, n_subbufs
);
262 if(ret
!= 0) goto create_error
;
264 act
.sa_handler
= handler
;
265 sigemptyset(&(act
.sa_mask
));
266 sigaddset(&(act
.sa_mask
), SIGIO
);
267 sigaction(SIGIO
, &act
, NULL
);
275 while(!sigio_received
) pause();
277 /* Now the trace is created, go on and create the supplementary files... */
279 printf("Creating supplementary trace files\n");
280 size_t trace_root_len
= strlen(trace_root
);
281 strncpy(eventdefs_path
, trace_root
, PATH_MAX
);
282 strncat(eventdefs_path
, "/eventdefs/", PATH_MAX
- trace_root_len
);
283 size_t eventdefs_path_len
= strlen(eventdefs_path
);
284 ret
= mkdir(eventdefs_path
, S_IRWXU
|S_IRWXG
|S_IRWXO
);
286 perror("Cannot create eventdefs directory");
291 DIR *facilities_dir
= opendir(facilities_path
);
293 while((entry
= readdir(facilities_dir
)) != NULL
) {
294 if(entry
->d_name
[0] == '.') continue;
296 printf("Appending facility file %s\n", entry
->d_name
);
297 strncpy(eventdefs_file
, eventdefs_path
, PATH_MAX
);
298 strncat(eventdefs_file
, entry
->d_name
, PATH_MAX
- eventdefs_path_len
);
299 /* Append to the file */
300 FILE *dest
= fopen(eventdefs_file
, "a");
302 perror("Cannot create eventdefs file");
305 strncpy(facilities_file
, facilities_path
, PATH_MAX
);
306 size_t facilities_dir_len
= strlen(facilities_path
);
307 strncat(facilities_file
, "/", PATH_MAX
- facilities_dir_len
);
308 strncat(facilities_file
, entry
->d_name
, PATH_MAX
- facilities_dir_len
-1);
309 FILE *src
= fopen(facilities_file
, "r");
311 perror("Cannot open eventdefs file for reading");
316 size_t read_size
, write_size
;
317 read_size
= fread(read_buf
, sizeof(char), BUF_SIZE
, src
);
319 perror("Cannot read eventdefs file");
322 write_size
= fwrite(read_buf
, sizeof(char), read_size
, dest
);
324 perror("Cannot write eventdefs file");
329 /* Add spacing between facilities */
330 fwrite("\n", 1, 1, dest
);
338 closedir(facilities_dir
);
340 } else if(pid
== 0) {
343 execlp(lttd_path
, lttd_path
, "-t", trace_root
, "-c", channel_path
, "-s", NULL
);
345 perror("Error in executing the lttd daemon");
350 perror("Error in forking for lttd daemon");
354 ret
= lttctl_start(handle
, trace_name
);
355 if(ret
!= 0) goto start_error
;
361 ret
|= lttctl_destroy_trace(handle
, trace_name
);
366 int main(int argc
, char ** argv
)
369 struct lttctl_handle
*handle
;
371 ret
= parse_arguments(argc
, argv
);
373 if(ret
!= 0) show_arguments();
374 if(ret
< 0) return EINVAL
;
375 if(ret
> 0) return 0;
379 handle
= lttctl_create_handle();
381 if(handle
== NULL
) return -1;
385 ret
= lttctl_create_trace(handle
, trace_name
, mode
, subbuf_size
,
388 ret
= lttctl_destroy_trace(handle
, trace_name
);
391 ret
= lttctl_start(handle
, trace_name
);
394 ret
= lttctl_stop(handle
, trace_name
);
397 ret
= lttctl_daemon(handle
, trace_name
);
403 ret
|= lttctl_destroy_handle(handle
);
This page took 0.037564 seconds and 5 git commands to generate.