From 96243366860d20e371efed0500070cdbc4a01ec7 Mon Sep 17 00:00:00 2001 From: David Goulet Date: Wed, 4 May 2011 16:37:26 -0400 Subject: [PATCH] Add support for auto session creation Support for auto session creation when no session (-s) is specified. The session is created with the name being the current date and time. For all commands that do not needs a session, no auto session is created and for thoses who needs -s also. Improve shorten uuid management all around the lttng client code. Fix uuid usage in lttng_session data structure and a small fix in the liblttngctl for the set_current_uuid fct. Fix session name regex of the tests. Signed-off-by: David Goulet --- include/lttng/lttng.h | 9 +- liblttngctl/liblttngctl.c | 4 +- ltt-sessiond/session.c | 2 +- lttng/lttng.c | 201 +++++++++++++++++++++++--------------- lttng/lttng.h | 5 +- lttng/options.c | 21 +++- tests/ltt-sessiond/run.sh | 2 +- 7 files changed, 150 insertions(+), 94 deletions(-) diff --git a/include/lttng/lttng.h b/include/lttng/lttng.h index 71c5e8208..e88e22b07 100644 --- a/include/lttng/lttng.h +++ b/include/lttng/lttng.h @@ -31,9 +31,10 @@ */ #define LTTNG_SESSIOND_PATH_ENV "LTTNG_SESSIOND_PATH" -/* From libuuid - */ +/* UUID string length (including \0) */ #define UUID_STR_LEN 37 +/* UUID short string version length (including \0) */ +#define UUID_SHORT_STR_LEN 9 /* Trace type for lttng_trace. */ @@ -45,7 +46,7 @@ enum lttng_trace_type { */ struct lttng_session { char name[NAME_MAX]; - char uuid[UUID_STR_LEN]; + uuid_t uuid; }; /* Simple trace representation. @@ -66,7 +67,7 @@ extern const char *lttng_get_readable_code(int code); extern int lttng_ust_list_apps(pid_t **pids); extern int lttng_list_sessions(struct lttng_session **sessions); extern int lttng_list_traces(uuid_t *uuid, struct lttng_trace **traces); -extern void lttng_set_current_session_uuid(char *uuid); +extern void lttng_set_current_session_uuid(uuid_t *uuid); extern int lttng_ust_create_trace(pid_t pid); extern int lttng_ust_start_trace(pid_t pid); extern int lttng_ust_stop_trace(pid_t pid); diff --git a/liblttngctl/liblttngctl.c b/liblttngctl/liblttngctl.c index adff646e1..1793bc53a 100644 --- a/liblttngctl/liblttngctl.c +++ b/liblttngctl/liblttngctl.c @@ -375,9 +375,9 @@ int lttng_disconnect_sessiond(void) * * Set the session uuid for current lsm. */ -void lttng_set_current_session_uuid(char *uuid) +void lttng_set_current_session_uuid(uuid_t *uuid) { - uuid_parse(uuid, lsm.session_id); + uuid_copy(lsm.session_id, *uuid); } /* diff --git a/ltt-sessiond/session.c b/ltt-sessiond/session.c index 6e19b372e..93f03e4c5 100644 --- a/ltt-sessiond/session.c +++ b/ltt-sessiond/session.c @@ -237,7 +237,7 @@ void get_lttng_session(struct lttng_session *lt) */ cds_list_for_each_entry(iter, <t_session_list.head, list) { /* Copy name and uuid */ - uuid_unparse(iter->uuid, lsess.uuid); + uuid_copy(lsess.uuid, iter->uuid); strncpy(lsess.name, iter->name, sizeof(lsess.name)); lsess.name[sizeof(lsess.name) - 1] = '\0'; memcpy(<[i], &lsess, sizeof(lsess)); diff --git a/lttng/lttng.c b/lttng/lttng.c index 3c3747de1..4c74d21fe 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 char short_str_uuid[UUID_SHORT_STR_LEN]; +static char long_str_uuid[UUID_STR_LEN]; +static uuid_t current_uuid; /* Prototypes */ static int process_client_opt(void); @@ -45,12 +48,13 @@ 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 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); +static void shorten_uuid(char *long_u, char *short_u); /* * start_client @@ -62,7 +66,8 @@ 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(); @@ -78,37 +83,42 @@ static int process_client_opt(void) } } - if (opt_list_traces) { - ret = process_opt_list_traces(); + if (opt_destroy_session) { + ret = lttng_destroy_session(¤t_uuid); if (ret < 0) { goto end; } + MSG("Session %s destroyed.", opt_session_uuid); } - if (opt_create_session != NULL) { - ret = process_opt_create_session(); - if (ret < 0) { - goto end; + 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; + } } - } - if (opt_destroy_session != NULL) { - uuid_parse(opt_destroy_session, uuid); - ret = lttng_destroy_session(&uuid); + DBG("Set session uuid to %s", long_str_uuid); + ret = set_session_uuid(); if (ret < 0) { - goto end; + ERR("Session UUID %s not found", opt_session_uuid); + goto error; } } - 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; @@ -153,16 +163,72 @@ error: } /* - * process_opt_session_uuid + * 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) +{ + int count, i, short_len; + char *tok; + struct lttng_session *sessions; + + 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'; + } + + /* 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; + } + } + } + + if (opt_session_name != NULL) { + session_name = strndup(opt_session_name, NAME_MAX); + } +} + +/* + * shorten_uuid + * + * Small function to shorten the 37 bytes long uuid_t + * string representation to 8 characters. + */ +static void shorten_uuid(char *long_u, char *short_u) +{ + memcpy(short_u, long_u, 8); + short_u[UUID_SHORT_STR_LEN - 1] = '\0'; +} + +/* + * set_session_uuid * * Set current session uuid to the current flow of - * command(s) using the already shorten uuid. + * command(s) using the already shorten uuid or + * current full uuid. */ -static int process_opt_session_uuid(void) +static int set_session_uuid(void) { int ret, count, i; + char str_uuid[37]; 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 +236,16 @@ 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); + uuid_unparse(sessions[i].uuid, str_uuid); + if (strncmp(str_uuid, short_str_uuid, 8) == 0) { + lttng_set_current_session_uuid(&sessions[i].uuid); break; } } free(sessions); +end: return 0; error: @@ -192,11 +260,9 @@ 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); if (ret < 0) { goto error; } @@ -236,53 +302,33 @@ 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) { + time(&rawtime); + timeinfo = localtime(&rawtime); + strftime(name, sizeof(name), "%Y%m%d-%H%M%S", timeinfo); + session_name = strndup(name, sizeof(name)); + } - ret = lttng_create_session(opt_create_session, &session_id); + ret = lttng_create_session(session_name, &session_id); 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 created:"); - MSG(" %s (%s)", opt_create_session, str_uuid); + MSG("Session UUID created: %s.%s", session_name, short_str_uuid); 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 * @@ -293,6 +339,7 @@ static int process_opt_list_sessions(void) { int ret, count, i; char tmp_short_uuid[9]; + char str_uuid[37]; struct lttng_session *sess; count = lttng_list_sessions(&sess); @@ -304,7 +351,8 @@ 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); + 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); } @@ -397,30 +445,21 @@ end: */ static int validate_options(void) { - int ret; - /* 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."); 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 ."); - goto error; - } + } else if (opt_session_uuid && opt_create_session) { + ERR("Please don't use -s and -c together. Useless action."); + goto error; + } else if (opt_list_traces && opt_session_uuid == NULL) { + ERR("Can't use -t without -s, --session option."); + goto error; } return 0; @@ -586,6 +625,10 @@ static void sighandler(int sig) void clean_exit(int code) { DBG("Clean exit"); + if (session_name) { + free(session_name); + } + exit(code); } diff --git a/lttng/lttng.h b/lttng/lttng.h index 1cc7981f5..537ab74d9 100644 --- a/lttng/lttng.h +++ b/lttng/lttng.h @@ -28,9 +28,10 @@ extern int opt_verbose; extern int opt_quiet; extern char *opt_tracing_group; extern char *opt_session_uuid; -extern char *opt_create_session; extern char *opt_sessiond_path; -extern char *opt_destroy_session; +extern char *opt_session_name; +extern int opt_destroy_session; +extern int opt_create_session; extern int opt_list_apps; extern int opt_no_sessiond; extern int opt_list_session; diff --git a/lttng/options.c b/lttng/options.c index b4630c3d7..57cb9b795 100644 --- a/lttng/options.c +++ b/lttng/options.c @@ -24,9 +24,10 @@ /* Option variables */ char *opt_tracing_group; char *opt_session_uuid; -char *opt_create_session; char *opt_sessiond_path; -char *opt_destroy_session; +char *opt_session_name; +int opt_create_session; +int opt_destroy_session; int opt_trace_kernel = 0; int opt_quiet = 0; int opt_verbose = 0; @@ -41,14 +42,16 @@ pid_t opt_trace_pid = 0; enum { OPT_HELP = 42, + OPT_CREATE_SESSION, + OPT_DESTROY_SESSION, }; static struct poptOption long_options[] = { /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */ - {"create-session", 'c', POPT_ARG_STRING, &opt_create_session, 0, 0, 0}, + {"create-session", 'c', POPT_ARG_STRING, 0, OPT_CREATE_SESSION, 0, 0}, {"create-trace", 'C', POPT_ARG_VAL, &opt_create_trace, 1, 0, 0}, - {"destroy-session", 'd', POPT_ARG_STRING, &opt_destroy_session, 0, 0, 0}, - {"group", 0, POPT_ARG_STRING, &opt_tracing_group, 0, 0}, + {"destroy-session", 'd', POPT_ARG_STRING, 0, OPT_DESTROY_SESSION, 0, 0}, + {"group", 0, POPT_ARG_STRING, &opt_tracing_group, 0, 0, 0}, {"help", 'h', POPT_ARG_NONE, 0, OPT_HELP, 0, 0}, {"kernel", 0, POPT_ARG_VAL, &opt_trace_kernel, 1, 0, 0}, {"list-apps", 'L', POPT_ARG_VAL, &opt_list_apps, 1, 0, 0}, @@ -129,6 +132,14 @@ int parse_args(int argc, const char **argv) usage(stderr); clean_exit(EXIT_SUCCESS); break; + case OPT_CREATE_SESSION: + opt_create_session = 1; + opt_session_name = poptGetOptArg(pc); + break; + case OPT_DESTROY_SESSION: + opt_destroy_session = 1; + opt_session_uuid = poptGetOptArg(pc); + break; default: usage(stderr); clean_exit(EXIT_FAILURE); diff --git a/tests/ltt-sessiond/run.sh b/tests/ltt-sessiond/run.sh index b378285ed..0f89d8b35 100755 --- a/tests/ltt-sessiond/run.sh +++ b/tests/ltt-sessiond/run.sh @@ -25,7 +25,7 @@ SESSIOND_BIN="$PWD/../../ltt-sessiond/ltt-sessiond" LTTNG_BIN="$PWD/../../lttng/lttng" #SESSIOND_ARGS="-c $SESSIOND_CLIENT_SOCK_PATH -a $SESSIOND_APPS_SOCK_PATH" SESSIOND_ARGS="" -SESSION_ID_REGEX="[[:alnum:]]{8}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{12}" +SESSION_ID_REGEX=".[[:alnum:]]{8}" function clean_exit() { -- 2.34.1