X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=lttng%2Flttng.c;h=10ce2ddfc08539bb121c2a0aa8b3bfe017a93f20;hp=3c3747de1f002a971ab64794f4a6f8ffe68a8036;hb=894be886aae0f1a1f49e63723511fcb15e816e7e;hpb=7442b2ba0c15bf9c950b96a19e948243c2b57683 diff --git a/lttng/lttng.c b/lttng/lttng.c index 3c3747de1..10ce2ddfc 100644 --- a/lttng/lttng.c +++ b/lttng/lttng.c @@ -37,7 +37,10 @@ /* Variables */ static char *progname; -static char short_uuid[9]; +static char *session_name; +static uuid_t current_uuid; +static int auto_session; +static int auto_trace; /* Prototypes */ static int process_client_opt(void); @@ -45,12 +48,14 @@ static int process_opt_list_apps(void); static int process_opt_list_sessions(void); static int process_opt_list_traces(void); static int process_opt_create_session(void); -static int process_opt_session_uuid(void); +static int process_kernel_create_trace(void); +static int process_opt_kernel_event(void); +static int set_session_uuid(void); static void sighandler(int sig); -static void shorten_uuid(char *in, char *out); static int set_signal_handler(void); static int validate_options(void); static char *get_cmdline_by_pid(pid_t pid); +static void set_opt_session_info(void); /* * start_client @@ -62,13 +67,15 @@ static char *get_cmdline_by_pid(pid_t pid); static int process_client_opt(void) { int ret; - uuid_t uuid; + + set_opt_session_info(); if (opt_list_apps) { ret = process_opt_list_apps(); if (ret < 0) { goto end; } + goto error; } if (opt_list_session) { @@ -76,55 +83,72 @@ static int process_client_opt(void) if (ret < 0) { goto end; } + goto error; } - if (opt_list_traces) { - ret = process_opt_list_traces(); + /* Session creation or auto session set on */ + if (auto_session || opt_create_session) { + DBG("Creating a new session"); + ret = process_opt_create_session(); if (ret < 0) { goto end; } } - if (opt_create_session != NULL) { - ret = process_opt_create_session(); - if (ret < 0) { - goto end; - } + ret = set_session_uuid(); + if (ret < 0) { + ERR("Session %s not found", opt_session_name); + goto error; } - if (opt_destroy_session != NULL) { - uuid_parse(opt_destroy_session, uuid); - ret = lttng_destroy_session(&uuid); + if (opt_destroy_session) { + ret = lttng_destroy_session(¤t_uuid); if (ret < 0) { goto end; } + MSG("Session %s destroyed.", opt_session_name); } - if (opt_session_uuid != NULL) { - DBG("Set session uuid to %s", short_uuid); - ret = process_opt_session_uuid(); + if (opt_list_traces) { + ret = process_opt_list_traces(); if (ret < 0) { - ERR("Session UUID %s not found", opt_session_uuid); - goto error; + goto end; } } + /* + * Action on traces (kernel or/and userspace). + */ + if (opt_trace_kernel) { - ERR("Not implemented yet"); - goto end; + if (auto_trace || opt_create_trace) { + DBG("Creating a kernel trace"); + ret = process_kernel_create_trace(); + if (ret < 0) { + goto end; + } + } + + if (opt_event_list != NULL) { + ret = process_opt_kernel_event(); + } else { + // Enable all events + } + + goto error; } if (opt_trace_pid != 0) { - if (opt_create_trace) { + if (auto_trace || opt_create_trace) { DBG("Create a userspace trace for pid %d", opt_trace_pid); ret = lttng_ust_create_trace(opt_trace_pid); if (ret < 0) { goto end; } - MSG("Trace created successfully!\nUse --start to start tracing."); + MSG("Trace created successfully!"); } - if (opt_start_trace) { + if (auto_trace || opt_start_trace) { DBG("Start trace for pid %d", opt_trace_pid); ret = lttng_ust_start_trace(opt_trace_pid); if (ret < 0) { @@ -146,23 +170,76 @@ static int process_client_opt(void) end: ERR("%s", lttng_get_readable_code(ret)); +error: /* fall through */ return ret; +} -error: - return ret; +/* + * process_kernel_create_trace + * + * Create a kernel trace. + */ +static int process_kernel_create_trace(void) +{ + return 0; } /* - * process_opt_session_uuid + * process_kernel_event * - * Set current session uuid to the current flow of - * command(s) using the already shorten uuid. + * Enable kernel event from the command line list given. */ -static int process_opt_session_uuid(void) +static int process_opt_kernel_event(void) { - int ret, count, i; + int ret; + char *event_name; + + event_name = strtok(opt_event_list, ","); + while (event_name != NULL) { + DBG("Enabling kernel event %s", event_name); + ret = lttng_kernel_enable_event(event_name); + if (ret < 0) { + ERR("%s %s", lttng_get_readable_code(ret), event_name); + } else { + MSG("Kernel event %s enabled.", event_name); + } + /* Next event */ + event_name = strtok(NULL, ","); + } + + return 0; +} + +/* + * set_opt_session_info + * + * Setup session_name, current_uuid, short_str_uuid and + * long_str_uuid using the command line options. + */ +static void set_opt_session_info(void) +{ + if (opt_session_name != NULL) { + session_name = strndup(opt_session_name, NAME_MAX); + DBG("Session name set to %s", session_name); + } +} + +/* + * set_session_uuid + * + * Set current session uuid to the current flow of command(s) using the + * session_name. + */ +static int set_session_uuid(void) +{ + int ret, count, i, found = 0; struct lttng_session *sessions; + if (!uuid_is_null(current_uuid)) { + lttng_set_current_session_uuid(¤t_uuid); + goto end; + } + count = lttng_list_sessions(&sessions); if (count < 0) { ret = count; @@ -170,14 +247,22 @@ static int process_opt_session_uuid(void) } for (i = 0; i < count; i++) { - if (strncmp(sessions[i].uuid, short_uuid, 8) == 0) { - lttng_set_current_session_uuid(sessions[i].uuid); + if (strncmp(sessions[i].name, session_name, NAME_MAX) == 0) { + lttng_set_current_session_uuid(&sessions[i].uuid); + uuid_copy(current_uuid, sessions[i].uuid); + found = 1; break; } } free(sessions); + if (!found) { + return -1; + } + +end: + DBG("Session UUID set"); return 0; error: @@ -192,15 +277,20 @@ error: static int process_opt_list_traces(void) { int ret, i; - uuid_t uuid; struct lttng_trace *traces; - uuid_parse(opt_session_uuid, uuid); - ret = lttng_list_traces(&uuid, &traces); + ret = lttng_list_traces(¤t_uuid, &traces); + DBG("Number of traces to list %d", ret); if (ret < 0) { goto error; } + /* No traces */ + if (ret == 0) { + MSG("No traces found."); + goto error; + } + MSG("Userspace traces:"); for (i = 0; i < ret; i++) { if (traces[i].type == USERSPACE) { @@ -234,55 +324,30 @@ error: static int process_opt_create_session(void) { int ret; - uuid_t session_id; - char str_uuid[37]; + char name[NAME_MAX]; + time_t rawtime; + struct tm *timeinfo; + + /* Auto session name creation */ + if (opt_session_name == NULL) { + time(&rawtime); + timeinfo = localtime(&rawtime); + strftime(name, sizeof(name), "auto-%Y%m%d-%H%M%S", timeinfo); + session_name = strndup(name, sizeof(name)); + DBG("Auto session name set to %s", session_name); + } - ret = lttng_create_session(opt_create_session, &session_id); + ret = lttng_create_session(session_name); if (ret < 0) { goto error; } - uuid_unparse(session_id, str_uuid); - - MSG("Session created:"); - MSG(" %s (%s)", opt_create_session, str_uuid); + MSG("Session created: %s", session_name); error: return ret; } -/* - * extract_short_uuid - * - * Extract shorten uuid and copy it to out. - * Shorten uuid format : '.' - */ -static int extract_short_uuid(char *in, char *out) -{ - char *tok; - - tok = strchr(in, '.'); - if (strlen(tok+1) == 8) { - memcpy(out, tok+1, 8); - out[9] = '\0'; - return 0; - } - - return -1; -} - -/* - * shorten_uuid - * - * Small function to shorten the 37 bytes long uuid_t - * string representation to 8 characters. - */ -static void shorten_uuid(char *in, char *out) -{ - memcpy(out, in, 8); - out[8] = '\0'; -} - /* * process_opt_list_sessions * @@ -292,10 +357,9 @@ static void shorten_uuid(char *in, char *out) static int process_opt_list_sessions(void) { int ret, count, i; - char tmp_short_uuid[9]; - struct lttng_session *sess; + struct lttng_session *sessions; - count = lttng_list_sessions(&sess); + count = lttng_list_sessions(&sessions); DBG("Session count %d", count); if (count < 0) { ret = count; @@ -304,11 +368,10 @@ static int process_opt_list_sessions(void) MSG("Available sessions (UUIDs):"); for (i = 0; i < count; i++) { - shorten_uuid(sess[i].uuid, tmp_short_uuid); - MSG(" %d) %s.%s", i+1, sess[i].name, tmp_short_uuid); + MSG(" %d) %s", i+1, sessions[i].name); } - free(sess); + free(sessions); MSG("\nTo select a session, use -s, --session UUID."); return 0; @@ -389,40 +452,70 @@ end: /* * validate_options * - * Make sure that all options passed to the command line - * are compatible with each others. + * Make sure that all options passed to the command line are compatible with + * each others. * * On error, return -1 * On success, return 0 */ static int validate_options(void) { - int ret; - + /* If listing options, jump validation */ + if (opt_list_apps || opt_list_session) { + goto end; + } /* Conflicting command */ if (opt_start_trace && opt_stop_trace) { ERR("Can't use --start and --stop together."); goto error; - /* Must have a session UUID for trace action. */ - } else if ((opt_session_uuid == NULL) && - (opt_create_trace || opt_start_trace || opt_stop_trace || opt_list_traces)) { - ERR("You need to specify a session UUID.\nPlease use --session UUID to do so."); - goto error; /* If no PID specified and trace_kernel is off */ - } else if ((opt_trace_pid == 0 && opt_trace_kernel == 0) && - (opt_create_trace || opt_start_trace || opt_stop_trace)) { - ERR("Please specify a PID using -p, --pid PID."); + } else if ((opt_trace_pid == 0 && !opt_trace_kernel) && + (opt_create_trace || opt_start_trace || opt_stop_trace || opt_destroy_trace)) { + ERR("Please specify for which tracer (-k or -p PID)."); goto error; - } - - if (opt_session_uuid != NULL) { - ret = extract_short_uuid(opt_session_uuid, short_uuid); - if (ret < 0) { - ERR("Session UUID not valid. Must be ."); + /* List traces, we need a session name */ + } else if (opt_list_traces && opt_session_name == NULL) { + ERR("Can't use -t without -s, --session option."); + goto error; + /* Can't set event for both kernel and userspace at the same time */ + } else if (opt_event_list != NULL && (opt_trace_kernel && opt_trace_pid)) { + ERR("Please don't use --event for both kernel and userspace.\nOne at a time to enable events."); + goto error; + /* Don't need a trace name for kernel tracig */ + } else if (opt_trace_name != NULL && opt_trace_kernel) { + ERR("For action on a kernel trace, please don't specify a trace name."); + goto error; + } else if (opt_destroy_trace && opt_session_name == NULL) { + ERR("Please specify a session in order to destroy a trace"); + goto error; + } else if (opt_create_trace || opt_destroy_trace) { + /* Both kernel and user-space are denied for these options */ + if (opt_trace_pid != 0 && opt_trace_kernel) { + ERR("Kernel and user-space trace creation and destruction can't be used together."); + goto error; + /* Need a trace name for user-space tracing */ + } else if (opt_trace_name == NULL && opt_trace_pid != 0) { + ERR("Please specify a trace name for user-space tracing"); goto error; } + } else if (opt_stop_trace && opt_trace_pid != 0 && opt_trace_name == NULL) { + ERR("Please specify a trace name for user-space tracing"); + goto error; + } + + /* If start trace, auto start tracing */ + if (opt_start_trace) { + DBG("Requesting auto tracing"); + auto_trace = 1; + } + + /* If no session, auto create one */ + if (opt_session_name == NULL) { + DBG("Requesting an auto session creation"); + auto_session = 1; } +end: return 0; error: @@ -442,20 +535,19 @@ static int spawn_sessiond(char *pathname) MSG("Spawning session daemon"); pid = fork(); if (pid == 0) { - /* Spawn session daemon and tell + /* + * Spawn session daemon and tell * it to signal us when ready. */ - ret = execlp(pathname, "ltt-sessiond", "--sig-parent", "--quiet", NULL); - if (ret < 0) { - if (errno == ENOENT) { - ERR("No session daemon found. Use --sessiond-path."); - } else { - perror("execlp"); - } - kill(getppid(), SIGTERM); - exit(EXIT_FAILURE); + execlp(pathname, "ltt-sessiond", "--sig-parent", "--quiet", NULL); + /* execlp only returns if error happened */ + if (errno == ENOENT) { + ERR("No session daemon found. Use --sessiond-path."); + } else { + perror("execlp"); } - exit(EXIT_SUCCESS); + kill(getppid(), SIGTERM); /* unpause parent */ + exit(EXIT_FAILURE); } else if (pid > 0) { /* Wait for ltt-sessiond to start */ pause(); @@ -480,7 +572,7 @@ end: static int check_ltt_sessiond(void) { int ret; - char *pathname = NULL; + char *pathname = NULL, *alloc_pathname = NULL; ret = lttng_check_session_daemon(); if (ret < 0) { @@ -495,24 +587,19 @@ static int check_ltt_sessiond(void) } else { /* Try LTTNG_SESSIOND_PATH env variable */ pathname = getenv(LTTNG_SESSIOND_PATH_ENV); - if (pathname != NULL) { - /* strdup here in order to make the free() - * not fail later on. - */ - pathname = strdup(pathname); - } } /* Let's rock and roll */ if (pathname == NULL) { - ret = asprintf(&pathname, "ltt-sessiond"); + ret = asprintf(&alloc_pathname, "ltt-sessiond"); if (ret < 0) { goto end; } + pathname = alloc_pathname; } ret = spawn_sessiond(pathname); - free(pathname); + free(alloc_pathname); if (ret < 0) { ERR("Problem occurs when starting %s", pathname); goto end; @@ -586,6 +673,10 @@ static void sighandler(int sig) void clean_exit(int code) { DBG("Clean exit"); + if (session_name) { + free(session_name); + } + exit(code); }