From: compudj Date: Mon, 18 Jul 2005 22:29:06 +0000 (+0000) Subject: lttctl ok X-Git-Tag: v0.12.20~2520 X-Git-Url: https://git.lttng.org./?a=commitdiff_plain;h=5adba60f59d60999ea41b075c121301165308bff;p=lttv.git lttctl ok git-svn-id: http://ltt.polymtl.ca/svn@969 04897980-b3bd-0310-b5e0-8ef037075253 --- diff --git a/ltt/branches/poly/lttctl/Makefile.am b/ltt/branches/poly/lttctl/Makefile.am index 5fe870d0..7530c9db 100644 --- a/ltt/branches/poly/lttctl/Makefile.am +++ b/ltt/branches/poly/lttctl/Makefile.am @@ -4,6 +4,6 @@ bin_PROGRAMS = lttctl lttctl_SOURCES = \ lttctl.c - -lttctl_LIBADD = libltt.la +lttctl_DEPENDENCIES = ../libltt/libltt.la +lttctl_LDADD = $(lttctl_DEPENDENCIES) diff --git a/ltt/branches/poly/lttctl/lttctl.c b/ltt/branches/poly/lttctl/lttctl.c index cb0c2550..1eeb1b12 100644 --- a/ltt/branches/poly/lttctl/lttctl.c +++ b/ltt/branches/poly/lttctl/lttctl.c @@ -8,6 +8,292 @@ * Mathieu Desnoyers */ -#include +#include +#include +#include +#include +#include +#include +#include +enum trace_ctl_op { + CTL_OP_CREATE, + CTL_OP_DESTROY, + CTL_OP_START, + CTL_OP_STOP, + CTL_OP_DAEMON, + CTL_OP_NONE +}; +static char *trace_name = NULL; +static char *mode_name = NULL; +static enum trace_mode mode = LTT_TRACE_NORMAL; +static enum trace_ctl_op op = CTL_OP_NONE; +static char *channel_root = NULL; +static char *trace_root = NULL; + +void handler(int signo) +{ + printf("signal %d received\n", signo); +} + + +/* Args : + * + */ +void show_arguments(void) +{ + printf("Please use the following arguments :\n"); + printf("\n"); + printf("-n name Name of the trace.\n"); + printf("-c mode Create trace channels in mode normal or flight recorder.\n"); + printf(" Mode values : normal (default) or flight.\n"); + printf("-r Destroy trace channels.\n"); + printf("-s Start tracing.\n"); + //printf(" Note : will automatically create a normal trace if " + // "none exists.\n"); + printf("-q Stop tracing.\n"); + printf("-d Create trace, spawn a lttd daemon, start tracing.\n"); + printf(" (optionnaly, you can set LTT_DAEMON env. var.)\n"); + printf("-t Trace root path. (ex. /root/traces/example_trace)\n"); + printf("-l LTT channels root path. (ex. /mnt/relayfs/ltt)\n"); + printf("\n"); +} + + +/* parse_arguments + * + * Parses the command line arguments. + * + * Returns 1 if the arguments were correct, but doesn't ask for program + * continuation. Returns -1 if the arguments are incorrect, or 0 if OK. + */ +int parse_arguments(int argc, char **argv) +{ + int ret = 0; + int argn = 1; + + if(argc == 2) { + if(strcmp(argv[1], "-h") == 0) { + return 1; + } + } + + while(argn < argc) { + + switch(argv[argn][0]) { + case '-': + switch(argv[argn][1]) { + case 'n': + if(argn+1 < argc) { + trace_name = argv[argn+1]; + argn++; + } else { + printf("Specify a trace name after -n.\n", argv[argn]); + printf("\n"); + ret = -1; + } + + break; + case 'c': + op = CTL_OP_CREATE; + if(argn+1 < argc) { + mode_name = argv[argn+1]; + argn++; + if(strcmp(mode_name, "normal") == 0) + mode = LTT_TRACE_NORMAL; + else if(strcmp(mode_name, "flight") == 0) + mode = LTT_TRACE_FLIGHT; + else { + printf("Invalid mode '%s'.\n", argv[argn]); + printf("\n"); + ret = -1; + } + } else { + printf("Specify a mode after -c.\n", argv[argn]); + printf("\n"); + ret = -1; + } + break; + case 'r': + op = CTL_OP_DESTROY; + break; + case 's': + op = CTL_OP_START; + break; + case 'q': + op = CTL_OP_STOP; + break; + case 'd': + op = CTL_OP_DAEMON; + break; + case 't': + if(argn+1 < argc) { + trace_root = argv[argn+1]; + argn++; + } else { + printf("Specify a trace root path after -t.\n", argv[argn]); + printf("\n"); + ret = -1; + } + break; + case 'l': + if(argn+1 < argc) { + channel_root = argv[argn+1]; + argn++; + } else { + printf("Specify a channel root path after -l.\n", argv[argn]); + printf("\n"); + ret = -1; + } + break; + default: + printf("Invalid argument '%s'.\n", argv[argn]); + printf("\n"); + ret = -1; + } + break; + default: + printf("Invalid argument '%s'.\n", argv[argn]); + printf("\n"); + ret = -1; + } + argn++; + } + + if(trace_name == NULL) { + printf("Please specify a trace name.\n"); + printf("\n"); + ret = -1; + } + + if(op == CTL_OP_NONE) { + printf("Please specify an operation.\n"); + printf("\n"); + ret = -1; + } + + if(op == CTL_OP_DAEMON) { + if(trace_root == NULL) { + printf("Please specify -t trace_root_path with the -d option.\n"); + printf("\n"); + ret = -1; + } + if(channel_root == NULL) { + printf("Please specify -l ltt_root_path with the -d option.\n"); + printf("\n"); + ret = -1; + } + } + + return ret; +} + +void show_info(void) +{ + printf("Linux Trace Toolkit Trace Control\n"); + printf("\n"); + printf("Controlling trace : %s\n", trace_name); + printf("\n"); +} + +int lttctl_daemon(struct lttctl_handle *handle, char *trace_name) +{ + char channel_path[PATH_MAX] = ""; + pid_t pid; + int ret; + char *lttd_path = getenv("LTT_DAEMON"); + struct sigaction act; + + if(lttd_path == NULL) lttd_path = "lttd"; + + strcat(channel_path, channel_root); + strcat(channel_path, "/"); + strcat(channel_path, trace_name); + + + ret = lttctl_create_trace(handle, trace_name, mode); + if(ret != 0) goto create_error; + + act.sa_handler = handler; + sigemptyset(&(act.sa_mask)); + sigaddset(&(act.sa_mask), SIGIO); + sigaction(SIGIO, &act, NULL); + + pid = fork(); + + if(pid > 0) { + //sleep(1); + /* parent */ + pause(); + + /* Now the trace is created, go on and create the supplementary files... */ + printf("Creating supplementary trace files\n"); + + } else if(pid == 0) { + /* child */ + int ret = + execlp(lttd_path, lttd_path, "-t", trace_root, "-c", channel_path, "-s", NULL); + if(ret) { + perror("Error in executing the lttd daemon"); + exit(-1); + } + } else { + /* error */ + perror("Error in forking for lttd daemon"); + + } + + ret = lttctl_start(handle, trace_name); + if(ret != 0) goto start_error; + + return 0; + + /* error handling */ +start_error: + ret |= lttctl_destroy_trace(handle, trace_name); +create_error: + return ret; +} + +int main(int argc, char ** argv) +{ + int ret; + struct lttctl_handle *handle; + + ret = parse_arguments(argc, argv); + + if(ret != 0) show_arguments(); + if(ret < 0) return EINVAL; + if(ret > 0) return 0; + + show_info(); + + handle = lttctl_create_handle(); + + if(handle == NULL) return -1; + + switch(op) { + case CTL_OP_CREATE: + ret = lttctl_create_trace(handle, trace_name, mode); + break; + case CTL_OP_DESTROY: + ret = lttctl_destroy_trace(handle, trace_name); + break; + case CTL_OP_START: + ret = lttctl_start(handle, trace_name); + break; + case CTL_OP_STOP: + ret = lttctl_stop(handle, trace_name); + break; + case CTL_OP_DAEMON: + ret = lttctl_daemon(handle, trace_name); + break; + case CTL_OP_NONE: + break; + } + + ret |= lttctl_destroy_handle(handle); + + return ret; +}