X-Git-Url: http://git.efficios.com/?p=lttng-tools.git;a=blobdiff_plain;f=lttng%2Flttng.c;h=b523960c33063be98e5bdf35fc9359fcdf76835f;hp=ab7f67ec52c296245d697d4a663488318acc22f0;hb=d686b40f66ea5df5ac0b9405991bbc33348b0a88;hpb=5e16da05d15eb413f28dea441e1bc49809cddc9b diff --git a/lttng/lttng.c b/lttng/lttng.c index ab7f67ec5..b523960c3 100644 --- a/lttng/lttng.c +++ b/lttng/lttng.c @@ -32,29 +32,32 @@ #include -#include "lttng.h" #include "lttngerr.h" +#include "options.h" /* Variables */ static char *progname; static char *session_name; -static char short_str_uuid[UUID_SHORT_STR_LEN]; -static char long_str_uuid[UUID_STR_LEN]; static uuid_t current_uuid; +static int auto_session; +static int auto_trace; /* Prototypes */ static int process_client_opt(void); 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_kernel_list_events(void); static int process_opt_create_session(void); +static int process_kernel_create_trace(void); +static int process_opt_kernel_event(void); +static int process_kernel_start_trace(void); static int set_session_uuid(void); static void sighandler(int sig); 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); -static void shorten_uuid(char *long_u, char *short_u); /* * start_client @@ -74,6 +77,7 @@ static int process_client_opt(void) if (ret < 0) { goto end; } + goto error; } if (opt_list_session) { @@ -81,32 +85,42 @@ static int process_client_opt(void) if (ret < 0) { goto end; } + goto error; } - if (opt_destroy_session) { - ret = lttng_destroy_session(¤t_uuid); + if (opt_list_events) { + if (opt_trace_kernel) { + ret = process_opt_kernel_list_events(); + if (ret < 0) { + goto end; + } + } else if (opt_trace_pid != 0) { + // TODO + } + goto error; + } + + /* 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; } - MSG("Session %s destroyed.", opt_session_uuid); } - if (!opt_list_session && !opt_list_apps) { - if (uuid_is_null(current_uuid)) { - /* If no session uuid, create session */ - DBG("No session specified. Creating session."); - 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; + } - DBG("Set session uuid to %s", long_str_uuid); - ret = set_session_uuid(); + if (opt_destroy_session) { + ret = lttng_destroy_session(¤t_uuid); if (ret < 0) { - ERR("Session UUID %s not found", opt_session_uuid); - goto error; + goto end; } + MSG("Session %s destroyed.", opt_session_name); } if (opt_list_traces) { @@ -119,23 +133,51 @@ static int process_client_opt(void) /* * Action on traces (kernel or/and userspace). */ + if (opt_trace_kernel) { - ERR("Not implemented yet"); - ret = -ENOSYS; - 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 || opt_enable_all_event) { + ret = process_opt_kernel_event(); + if (ret < 0) { + goto end; + } + } + + if (auto_trace || opt_start_trace) { + DBG("Starting kernel tracing"); + ret = process_kernel_start_trace(); + if (ret < 0) { + goto end; + } + } + + if (opt_stop_trace) { + DBG("Stopping kernel tracing"); + ret = lttng_kernel_stop_tracing(); + if (ret < 0) { + goto end; + } + } } 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) { @@ -162,65 +204,159 @@ error: /* fall through */ } /* - * set_opt_session_info + * process_kernel_start_trace * - * Setup session_name, current_uuid, short_str_uuid and - * long_str_uuid using the command line options. + * Start a kernel trace. */ -static void set_opt_session_info(void) +static int process_kernel_start_trace(void) { - int count, i, short_len; - char *tok; - struct lttng_session *sessions; + int ret; - if (opt_session_uuid != NULL) { - short_len = sizeof(short_str_uuid) - 1; - /* Shorten uuid */ - tok = strchr(opt_session_uuid, '.'); - if (strlen(tok + 1) == short_len) { - memcpy(short_str_uuid, tok + 1, short_len); - short_str_uuid[short_len] = '\0'; - } + ret = lttng_kernel_create_stream(); + if (ret < 0) { + goto error; + } - /* Get long real uuid_t from session daemon */ - count = lttng_list_sessions(&sessions); - for (i = 0; i < count; i++) { - uuid_unparse(sessions[i].uuid, long_str_uuid); - if (strncmp(long_str_uuid, short_str_uuid, 8) == 0) { - uuid_copy(current_uuid, sessions[i].uuid); - break; - } + ret = lttng_kernel_start_tracing(); + if (ret < 0) { + goto error; + } + + MSG("Kernel tracing started"); + + return 0; + +error: + return ret; +} + +/* + * process_kernel_create_trace + * + * Create a kernel trace. + */ +static int process_kernel_create_trace(void) +{ + int ret; + + /* Setup kernel session */ + ret = lttng_kernel_create_session(); + if (ret < 0) { + goto error; + } + + /* Create an empty channel (with no event) */ + ret = lttng_kernel_create_channel(); + if (ret < 0) { + goto error; + } + + /* Opening metadata for session */ + ret = lttng_kernel_open_metadata(); + if (ret < 0) { + goto error; + } + + return 0; + +error: + return ret; +} + +/* + * process_opt_kernel_list_events + * + * Ask for all trace events in the kernel and pretty print them. + */ +static int process_opt_kernel_list_events(void) +{ + int ret, pos, size; + char *event_list, *event, *ptr; + + DBG("Getting all tracing events"); + + ret = lttng_kernel_list_events(&event_list); + if (ret < 0) { + ERR("Unable to list events."); + return ret; + } + + MSG("Kernel tracepoints:\n-------------"); + + ptr = event_list; + while ((size = sscanf(ptr, "event { name = %m[^;]; };%n\n", &event, &pos)) == 1) { + MSG(" - %s", event); + /* Move pointer to the next line */ + ptr += pos + 1; + free(event); + } + + free(event_list); + + return 0; +} + +/* + * process_opt_kernel_event + * + * Enable kernel event from the command line list given. + */ +static int process_opt_kernel_event(void) +{ + int ret; + char *event_name; + + if (opt_enable_all_event) { + ret = lttng_kernel_enable_event(NULL); + if (ret < 0) { + ERR("%s", lttng_get_readable_code(ret)); + } else { + MSG("All kernel event enabled"); } + + goto end; } - if (opt_session_name != NULL) { - session_name = strndup(opt_session_name, NAME_MAX); + 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, ","); } + +end: + return 0; } /* - * shorten_uuid + * set_opt_session_info * - * Small function to shorten the 37 bytes long uuid_t - * string representation to 8 characters. + * Setup session_name, current_uuid, short_str_uuid and + * long_str_uuid using the command line options. */ -static void shorten_uuid(char *long_u, char *short_u) +static void set_opt_session_info(void) { - memcpy(short_u, long_u, 8); - short_u[UUID_SHORT_STR_LEN - 1] = '\0'; + 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 already shorten uuid or - * current full 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; - char str_uuid[37]; + int ret, count, i, found = 0; struct lttng_session *sessions; if (!uuid_is_null(current_uuid)) { @@ -235,16 +371,22 @@ static int set_session_uuid(void) } for (i = 0; i < count; i++) { - uuid_unparse(sessions[i].uuid, str_uuid); - if (strncmp(str_uuid, short_str_uuid, 8) == 0) { + 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: @@ -262,10 +404,17 @@ static int process_opt_list_traces(void) struct lttng_trace *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) { @@ -299,30 +448,25 @@ 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 creation */ - if (opt_create_session == 0) { + /* Auto session name creation */ + if (opt_session_name == NULL) { time(&rawtime); timeinfo = localtime(&rawtime); - strftime(name, sizeof(name), "%Y%m%d-%H%M%S", timeinfo); + 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(session_name, &session_id); + ret = lttng_create_session(session_name); if (ret < 0) { goto error; } - uuid_unparse(session_id, str_uuid); - uuid_copy(current_uuid, session_id); - shorten_uuid(str_uuid, short_str_uuid); - - MSG("Session UUID created: %s.%s", session_name, short_str_uuid); + MSG("Session created: %s", session_name); error: return ret; @@ -337,11 +481,9 @@ error: static int process_opt_list_sessions(void) { int ret, count, i; - char tmp_short_uuid[9]; - char str_uuid[37]; - 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; @@ -350,12 +492,10 @@ static int process_opt_list_sessions(void) MSG("Available sessions (UUIDs):"); for (i = 0; i < count; i++) { - uuid_unparse(sess[i].uuid, str_uuid); - shorten_uuid(str_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; @@ -436,31 +576,73 @@ 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) { + /* 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; /* 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."); - goto error; - } else if (opt_session_uuid && opt_create_session) { - ERR("Please don't use -s and -c together. Useless action."); + } 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; - } else if (opt_list_traces && opt_session_uuid == NULL) { + /* 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; + } else if (opt_stop_trace && opt_session_name == NULL) { + ERR("Please specify a session to stop tracing"); + goto error; + } + + /* If start trace, auto start tracing */ + if (opt_start_trace || opt_event_list != NULL || opt_enable_all_event) { + 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: @@ -519,8 +701,8 @@ static int check_ltt_sessiond(void) int ret; char *pathname = NULL, *alloc_pathname = NULL; - ret = lttng_check_session_daemon(); - if (ret < 0) { + ret = lttng_session_daemon_alive(); + if (ret == 0) { /* not alive */ /* Try command line option path */ if (opt_sessiond_path != NULL) { ret = access(opt_sessiond_path, F_OK | X_OK);