X-Git-Url: http://git.lttng.org./?a=blobdiff_plain;f=ltt%2Fbranches%2Fpoly%2Flttctl%2Flttctl.c;h=105aacb61efb627cdb6a957e6f9cec0b30a73559;hb=2312de30ce2be53f81c4eaaa772ffff21511b509;hp=f56faa421ae6e517214770d96d5fce220aa3b75a;hpb=bd55296ce63a1f771bd747a14c1a79907a671938;p=lttv.git diff --git a/ltt/branches/poly/lttctl/lttctl.c b/ltt/branches/poly/lttctl/lttctl.c index f56faa42..105aacb6 100644 --- a/ltt/branches/poly/lttctl/lttctl.c +++ b/ltt/branches/poly/lttctl/lttctl.c @@ -12,11 +12,12 @@ #include #endif -#include +#include #include #include #include #include +#include #include #include #include @@ -24,11 +25,13 @@ #include /* Buffer for file copy : 4k seems optimal. */ -#define BUF_SIZE 4194304 +#define BUF_SIZE 4096 enum trace_ctl_op { + CTL_OP_CREATE_START, CTL_OP_CREATE, CTL_OP_DESTROY, + CTL_OP_STOP_DESTROY, CTL_OP_START, CTL_OP_STOP, CTL_OP_DAEMON, @@ -40,17 +43,18 @@ static char *trace_name = NULL; static char *mode_name = NULL; static unsigned subbuf_size = 0; static unsigned n_subbufs = 0; +static unsigned append_trace = 0; 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; -static int sigio_received = 0; +static int sigchld_received = 0; -void handler(int signo) +void sigchld_handler(int signo) { printf("signal %d received\n", signo); - sigio_received = 1; + sigchld_received = 1; } @@ -62,9 +66,12 @@ 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("-b Create trace channels and start tracing (no daemon).\n"); + printf("-c Create trace channels.\n"); + printf("-m mode Normal or flight recorder mode.\n"); printf(" Mode values : normal (default) or flight.\n"); printf("-r Destroy trace channels.\n"); + printf("-R Stop tracing and destroy trace channels.\n"); printf("-s Start tracing.\n"); //printf(" Note : will automatically create a normal trace if " // "none exists.\n"); @@ -77,6 +84,7 @@ void show_arguments(void) printf("-z Size of the subbuffers (will be rounded to next page size)\n"); printf("-x Number of subbuffers\n"); printf("-e Get XML facilities description\n"); + printf("-a Append to trace\n"); printf("\n"); } @@ -85,8 +93,8 @@ void show_arguments(void) * * 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. + * Returns -1 if the arguments were correct, but doesn't ask for program + * continuation. Returns EINVAL if the arguments are incorrect, or 0 if OK. */ int parse_arguments(int argc, char **argv) { @@ -95,7 +103,7 @@ int parse_arguments(int argc, char **argv) if(argc == 2) { if(strcmp(argv[1], "-h") == 0) { - return 1; + return -1; } } @@ -109,14 +117,18 @@ int parse_arguments(int argc, char **argv) trace_name = argv[argn+1]; argn++; } else { - printf("Specify a trace name after -n.\n", argv[argn]); + printf("Specify a trace name after -n.\n"); printf("\n"); - ret = -1; + ret = EINVAL; } break; + case 'b': + op = CTL_OP_CREATE_START; case 'c': op = CTL_OP_CREATE; + break; + case 'm': if(argn+1 < argc) { mode_name = argv[argn+1]; argn++; @@ -127,17 +139,20 @@ int parse_arguments(int argc, char **argv) else { printf("Invalid mode '%s'.\n", argv[argn]); printf("\n"); - ret = -1; + ret = EINVAL; } } else { - printf("Specify a mode after -c.\n"); + printf("Specify a mode after -m.\n"); printf("\n"); - ret = -1; + ret = EINVAL; } break; case 'r': op = CTL_OP_DESTROY; break; + case 'R': + op = CTL_OP_STOP_DESTROY; + break; case 's': op = CTL_OP_START; break; @@ -151,7 +166,7 @@ int parse_arguments(int argc, char **argv) } else { printf("Specify a number of subbuffers after -z.\n"); printf("\n"); - ret = -1; + ret = EINVAL; } break; case 'x': @@ -161,7 +176,7 @@ int parse_arguments(int argc, char **argv) } else { printf("Specify a subbuffer size after -x.\n"); printf("\n"); - ret = -1; + ret = EINVAL; } break; case 'd': @@ -177,7 +192,7 @@ int parse_arguments(int argc, char **argv) } else { printf("Specify a trace root path after -t.\n"); printf("\n"); - ret = -1; + ret = EINVAL; } break; case 'l': @@ -187,19 +202,22 @@ int parse_arguments(int argc, char **argv) } else { printf("Specify a channel root path after -l.\n"); printf("\n"); - ret = -1; + ret = EINVAL; } break; + case 'a': + append_trace = 1; + break; default: printf("Invalid argument '%s'.\n", argv[argn]); printf("\n"); - ret = -1; + ret = EINVAL; } break; default: printf("Invalid argument '%s'.\n", argv[argn]); printf("\n"); - ret = -1; + ret = EINVAL; } argn++; } @@ -207,25 +225,25 @@ int parse_arguments(int argc, char **argv) if(op != CTL_OP_DESCRIPTION && trace_name == NULL) { printf("Please specify a trace name.\n"); printf("\n"); - ret = -1; + ret = EINVAL; } if(op == CTL_OP_NONE) { printf("Please specify an operation.\n"); printf("\n"); - ret = -1; + ret = EINVAL; } 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; + ret = EINVAL; } if(channel_root == NULL) { printf("Please specify -l ltt_root_path with the -d option.\n"); printf("\n"); - ret = -1; + ret = EINVAL; } } @@ -233,7 +251,7 @@ int parse_arguments(int argc, char **argv) if(trace_root == NULL) { printf("Please specify -t trace_root_path with the -e option.\n"); printf("\n"); - ret = -1; + ret = EINVAL; } } @@ -260,10 +278,11 @@ int create_eventdefs(void) struct dirent *entry; char *facilities_path = getenv("LTT_FACILITIES"); if(facilities_path == NULL) facilities_path = - "/usr/share/LinuxTraceToolkitViewer/facilities"; + PACKAGE_DATA_DIR "/" PACKAGE "/facilities"; ret = mkdir(trace_root, S_IRWXU|S_IRWXG|S_IRWXO); if(ret == -1 && errno != EEXIST) { + ret = errno; perror("Cannot create trace_root directory"); printf("trace_root is %s\n", trace_root); goto error; @@ -275,7 +294,8 @@ int create_eventdefs(void) strncat(eventdefs_path, "/eventdefs/", PATH_MAX - trace_root_len); size_t eventdefs_path_len = strlen(eventdefs_path); ret = mkdir(eventdefs_path, S_IRWXU|S_IRWXG|S_IRWXO); - if(ret == -1 && errno != EEXIST) { + if(ret == -1 && (!append_trace || errno != EEXIST)) { + ret = errno; perror("Cannot create eventdefs directory"); goto error; } @@ -283,6 +303,12 @@ int create_eventdefs(void) DIR *facilities_dir = opendir(facilities_path); + if(facilities_dir == NULL) { + perror("Cannot open facilities directory"); + ret = EEXIST; + goto error; + } + while((entry = readdir(facilities_dir)) != NULL) { if(entry->d_name[0] == '.') continue; @@ -301,6 +327,7 @@ int create_eventdefs(void) strncat(facilities_file, entry->d_name, PATH_MAX - facilities_dir_len-1); FILE *src = fopen(facilities_file, "r"); if(!src) { + ret = errno; perror("Cannot open eventdefs file for reading"); goto close_dest; } @@ -309,11 +336,13 @@ int create_eventdefs(void) size_t read_size, write_size; read_size = fread(read_buf, sizeof(char), BUF_SIZE, src); if(ferror(src)) { + ret = errno; perror("Cannot read eventdefs file"); goto close_src; } write_size = fwrite(read_buf, sizeof(char), read_size, dest); if(ferror(dest)) { + ret = errno; perror("Cannot write eventdefs file"); goto close_src; } @@ -330,7 +359,7 @@ close_dest: closedir(facilities_dir); - error: +error: return ret; } @@ -344,7 +373,8 @@ int lttctl_daemon(struct lttctl_handle *handle, char *trace_name) char *lttd_path = getenv("LTT_DAEMON"); struct sigaction act; - if(lttd_path == NULL) lttd_path = "lttd"; + if(lttd_path == NULL) lttd_path = + PACKAGE_BIN_DIR "/lttd"; strcat(channel_path, channel_root); strcat(channel_path, "/"); @@ -354,37 +384,45 @@ int lttctl_daemon(struct lttctl_handle *handle, char *trace_name) ret = lttctl_create_trace(handle, trace_name, mode, subbuf_size, n_subbufs); if(ret != 0) goto create_error; - act.sa_handler = handler; + act.sa_handler = sigchld_handler; sigemptyset(&(act.sa_mask)); - sigaddset(&(act.sa_mask), SIGIO); - sigaction(SIGIO, &act, NULL); - - sigio_received = 0; + sigaddset(&(act.sa_mask), SIGCHLD); + sigaction(SIGCHLD, &act, NULL); pid = fork(); if(pid > 0) { + int status; /* parent */ - while(!sigio_received) pause(); + while(!(sigchld_received)) pause(); + + waitpid(pid, &status, 0); + ret = 0; + if(WIFEXITED(status)) + ret = WEXITSTATUS(status); + if(ret) goto start_error; - /* Now the trace is created, go on and create the supplementary files... */ - printf("Creating supplementary trace files\n"); ret = create_eventdefs(); if(ret) goto start_error; } else if(pid == 0) { /* child */ - int ret = - execlp(lttd_path, lttd_path, "-t", trace_root, "-c", channel_path, "-s", NULL); + int ret; + if(append_trace) + ret = execlp(lttd_path, lttd_path, "-t", trace_root, "-c", + channel_path, "-d", "-a", NULL); + else + ret = execlp(lttd_path, lttd_path, "-t", trace_root, "-c", + channel_path, "-d", NULL); if(ret) { + ret = errno; perror("Error in executing the lttd daemon"); - exit(-1); + exit(ret); } } else { /* error */ perror("Error in forking for lttd daemon"); - } ret = lttctl_start(handle, trace_name); @@ -394,6 +432,7 @@ int lttctl_daemon(struct lttctl_handle *handle, char *trace_name) /* error handling */ start_error: + printf("Trace start error\n"); ret |= lttctl_destroy_trace(handle, trace_name); create_error: return ret; @@ -407,8 +446,8 @@ int main(int argc, char ** argv) ret = parse_arguments(argc, argv); if(ret != 0) show_arguments(); - if(ret < 0) return EINVAL; - if(ret > 0) return 0; + if(ret == EINVAL) return EINVAL; + if(ret == -1) return 0; show_info(); @@ -417,12 +456,24 @@ int main(int argc, char ** argv) if(handle == NULL) return -1; switch(op) { + case CTL_OP_CREATE_START: + ret = lttctl_create_trace(handle, trace_name, mode, subbuf_size, + n_subbufs); + if(!ret) + ret = lttctl_start(handle, trace_name); + break; case CTL_OP_CREATE: ret = lttctl_create_trace(handle, trace_name, mode, subbuf_size, n_subbufs); + break; case CTL_OP_DESTROY: ret = lttctl_destroy_trace(handle, trace_name); break; + case CTL_OP_STOP_DESTROY: + ret = lttctl_stop(handle, trace_name); + if(!ret) + ret = lttctl_destroy_trace(handle, trace_name); + break; case CTL_OP_START: ret = lttctl_start(handle, trace_name); break;