X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=lttng%2Flttng.c;h=10ce2ddfc08539bb121c2a0aa8b3bfe017a93f20;hp=f6cad42434e2f718a1a8077a4823866998a7acfd;hb=894be886aae0f1a1f49e63723511fcb15e816e7e;hpb=ad874cce2adeaadea08fcc76300ff43e091febca diff --git a/lttng/lttng.c b/lttng/lttng.c index f6cad4243..10ce2ddfc 100644 --- a/lttng/lttng.c +++ b/lttng/lttng.c @@ -30,13 +30,17 @@ #include #include -#include +#include #include "lttng.h" #include "lttngerr.h" /* Variables */ static char *progname; +static char *session_name; +static uuid_t current_uuid; +static int auto_session; +static int auto_trace; /* Prototypes */ static int process_client_opt(void); @@ -44,10 +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_kernel_create_trace(void); +static int process_opt_kernel_event(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); /* * start_client @@ -59,19 +67,15 @@ static char *get_cmdline_by_pid(pid_t pid); static int process_client_opt(void) { int ret; - uuid_t uuid; - /* Connect to the session daemon */ - ret = lttng_connect_sessiond(); - if (ret < 0) { - goto end; - } + set_opt_session_info(); if (opt_list_apps) { ret = process_opt_list_apps(); if (ret < 0) { goto end; } + goto error; } if (opt_list_session) { @@ -79,51 +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(); + ret = set_session_uuid(); + if (ret < 0) { + ERR("Session %s not found", opt_session_name); + goto error; + } + + if (opt_destroy_session) { + ret = lttng_destroy_session(¤t_uuid); if (ret < 0) { goto end; } + MSG("Session %s destroyed.", opt_session_name); } - if (opt_destroy_session != NULL) { - uuid_parse(opt_destroy_session, uuid); - ret = lttng_destroy_session(&uuid); + if (opt_list_traces) { + ret = process_opt_list_traces(); if (ret < 0) { goto end; } } - if (opt_session_uuid != NULL) { - DBG("Set session uuid to %s", opt_session_uuid); - lttng_set_current_session_uuid(opt_session_uuid); - } + /* + * 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) { @@ -145,6 +170,102 @@ static int process_client_opt(void) end: ERR("%s", lttng_get_readable_code(ret)); +error: /* fall through */ + return ret; +} + +/* + * process_kernel_create_trace + * + * Create a kernel trace. + */ +static int process_kernel_create_trace(void) +{ + return 0; +} + +/* + * process_kernel_event + * + * Enable kernel event from the command line list given. + */ +static int process_opt_kernel_event(void) +{ + 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; + goto error; + } + + for (i = 0; i < count; i++) { + 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: return ret; } @@ -156,15 +277,20 @@ end: 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) { @@ -198,18 +324,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; - ret = lttng_create_session(opt_create_session, &session_id); + /* 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(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; @@ -224,21 +357,22 @@ error: static int process_opt_list_sessions(void) { int ret, count, i; - 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; goto error; } - MSG("Available sessions [Name (uuid)]:"); + MSG("Available sessions (UUIDs):"); for (i = 0; i < count; i++) { - MSG("\tName: %s (uuid: %s)", sess[i].name, sess[i].uuid); + MSG(" %d) %s", i+1, sessions[i].name); } - free(sess); - MSG("\nTo select a session, use --session UUID."); + free(sessions); + MSG("\nTo select a session, use -s, --session UUID."); return 0; @@ -318,30 +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) { + /* 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; + /* 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: @@ -361,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(); @@ -399,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) { @@ -414,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; @@ -498,15 +666,17 @@ static void sighandler(int sig) return; } + /* * clean_exit */ void clean_exit(int code) { DBG("Clean exit"); - if (lttng_disconnect_sessiond() < 0) { - ERR("Session daemon disconnect failed."); + if (session_name) { + free(session_name); } + exit(code); }