From cd80958d00fddabced5fbd60641978516a01e29e Mon Sep 17 00:00:00 2001 From: David Goulet Date: Fri, 12 Aug 2011 14:12:55 -0400 Subject: [PATCH] Change lttng API to use a lttng_handle Introduce the lttng_handle structure that is now used by the API containing the session name and lttng domain. This removes multiple static variables of the library and makes it safe for multithread tool to use the library. Signed-off-by: David Goulet --- include/lttng/lttng.h | 68 ++--- liblttngctl/lttngctl.c | 403 ++++++++++++++++++++---------- lttng/commands/add_context.c | 39 ++- lttng/commands/calibrate.c | 12 +- lttng/commands/destroy.c | 11 +- lttng/commands/disable_channels.c | 36 ++- lttng/commands/disable_events.c | 34 ++- lttng/commands/enable_channels.c | 32 ++- lttng/commands/enable_events.c | 43 ++-- lttng/commands/list.c | 52 ++-- lttng/commands/start.c | 12 +- lttng/commands/stop.c | 17 +- lttng/utils.c | 32 +-- 13 files changed, 520 insertions(+), 271 deletions(-) diff --git a/include/lttng/lttng.h b/include/lttng/lttng.h index c08580ac2..3f96a24b6 100644 --- a/include/lttng/lttng.h +++ b/include/lttng/lttng.h @@ -188,6 +188,14 @@ struct lttng_session { char path[PATH_MAX]; }; +/* + * Handle used as a context for commands. + */ +struct lttng_handle { + char session_name[NAME_MAX]; + struct lttng_domain domain; +}; + /* * Public LTTng control API * @@ -202,8 +210,19 @@ struct lttng_session { */ /* - * Session daemon control + * Create an handle used as a context for every request made to the library. + * + * This handle contains the session name and lttng domain on which the command + * will be executed on. + */ +extern struct lttng_handle *lttng_create_handle(const char *session_name, + struct lttng_domain *domain); + +/* + * Destroy an handle. This will simply free(3) the data pointer returned by + * lttng_create_handle() and rendering it unsuable. */ +extern void lttng_destroy_handle(struct lttng_handle *handle); /* * Create tracing session using a name and a path where trace will be written. @@ -216,7 +235,7 @@ extern int lttng_create_session(const char *name, const char *path); * The session will not be useable anymore, tracing will stopped for all * registered trace and tracing buffers will be flushed. */ -extern int lttng_destroy_session(const char *name); +extern int lttng_destroy_session(struct lttng_handle *handle); /* * List all tracing sessions. @@ -230,7 +249,7 @@ extern int lttng_list_sessions(struct lttng_session **sessions); * * Return the size of the "lttng_domain" array. Caller must free(3). */ -extern int lttng_list_domains(const char *session_name, +extern int lttng_list_domains(struct lttng_handle *handle, struct lttng_domain **domains); /* @@ -238,24 +257,23 @@ extern int lttng_list_domains(const char *session_name, * * Return the size of the "lttng_channel" array. Caller must free(3). */ -extern int lttng_list_channels(struct lttng_domain *domain, - const char *session_name, struct lttng_channel **channels); +extern int lttng_list_channels(struct lttng_handle *handle, + struct lttng_channel **channels); /* * List event(s) of a session channel. * * Return the size of the "lttng_event" array. Caller must free(3). */ -extern int lttng_list_events(struct lttng_domain *domain, - const char *session_name, const char *channel_name, - struct lttng_event **events); +extern int lttng_list_events(struct lttng_handle *handle, + const char *channel_name, struct lttng_event **events); /* - * List available tracepoints of domain. + * List available tracepoints of a specific lttng domain. * * Return the size of the "lttng_event" array. Caller must free(3). */ -extern int lttng_list_tracepoints(struct lttng_domain *domain, +extern int lttng_list_tracepoints(struct lttng_handle *handle, struct lttng_event **events); /* @@ -268,15 +286,6 @@ extern int lttng_session_daemon_alive(void); */ extern int lttng_set_tracing_group(const char *name); -/* - * Set the session name of the *current* flow of execution. - * - * This is a VERY important things to do before doing any tracing actions. If - * it's not done, you'll get an error saying that the session is not found. - * It avoids the use of a session name on every API call. - */ -extern void lttng_set_session_name(const char *name); - /* * Return a human readable error message of a lttng-tools error code. * @@ -287,12 +296,12 @@ extern const char *lttng_get_readable_code(int code); /* * Start tracing for *all* registered trace (kernel and user-space). */ -extern int lttng_start_tracing(const char *session_name); +extern int lttng_start_tracing(struct lttng_handle *handle); /* * Stop tracing for *all* registered trace (kernel and user-space). */ -extern int lttng_stop_tracing(const char *session_name); +extern int lttng_stop_tracing(struct lttng_handle *handle); /* * Add context to event for a specific channel. @@ -301,8 +310,7 @@ extern int lttng_stop_tracing(const char *session_name); * If channel_name is NULL, a lookup of the event's channel is done. * If both are NULL, the context is applied on all events of all channels. */ - -extern int lttng_add_context(struct lttng_domain *domain, +extern int lttng_add_context(struct lttng_handle *handle, struct lttng_event_context *ctx, const char *event_name, const char *channel_name); @@ -314,15 +322,15 @@ extern int lttng_add_context(struct lttng_domain *domain, * * If channel_name is NULL, the default channel is used (channel0). */ -extern int lttng_enable_event(struct lttng_domain *domain, struct lttng_event *ev, - const char *channel_name); +extern int lttng_enable_event(struct lttng_handle *handle, + struct lttng_event *ev, const char *channel_name); /* * Create or enable a kernel channel. * * If name is NULL, the default channel is enabled (channel0). */ -extern int lttng_enable_channel(struct lttng_domain *domain, +extern int lttng_enable_channel(struct lttng_handle *handle, struct lttng_channel *chan); /* @@ -330,21 +338,21 @@ extern int lttng_enable_channel(struct lttng_domain *domain, * * If channel_name is NULL, the default channel is used (channel0). */ -extern int lttng_disable_event(struct lttng_domain *domain, const char *name, - const char *channel_name); +extern int lttng_disable_event(struct lttng_handle *handle, + const char *name, const char *channel_name); /* * Disable kernel channel. * * If channel_name is NULL, the default channel is disabled (channel0). */ -extern int lttng_disable_channel(struct lttng_domain *domain, +extern int lttng_disable_channel(struct lttng_handle *handle, const char *name); /* * Calibrate LTTng overhead. */ -extern int lttng_calibrate(struct lttng_domain *domain, +extern int lttng_calibrate(struct lttng_handle *handle, struct lttng_calibrate *calibrate); #endif /* _LTTNG_H */ diff --git a/liblttngctl/lttngctl.c b/liblttngctl/lttngctl.c index b266797bd..14055ed48 100644 --- a/liblttngctl/lttngctl.c +++ b/liblttngctl/lttngctl.c @@ -38,10 +38,6 @@ static int sessiond_socket; static char sessiond_sock_path[PATH_MAX]; -/* Communication structure to ltt-sessiond */ -static struct lttcomm_session_msg lsm; -static struct lttcomm_lttng_msg llm; - /* Variables */ static char *tracing_group; static int connected; @@ -51,22 +47,45 @@ static int connected; */ static void copy_string(char *dst, const char *src, size_t len) { - if (src && dst) { + if (src) { strncpy(dst, src, len); /* Enforce the NULL terminated byte */ dst[len - 1] = '\0'; + } else if (dst) { + dst[0] = '\0'; } } /* - * send_data_sessiond + * Copy domain to lttcomm_session_msg domain. * - * Send lttcomm_session_msg to the session daemon. + * If domain is unknown, default domain will be the kernel. + */ +static void copy_lttng_domain(struct lttng_domain *dst, struct lttng_domain *src) +{ + if (src && dst) { + switch (src->type) { + case LTTNG_DOMAIN_KERNEL: + case LTTNG_DOMAIN_UST: + case LTTNG_DOMAIN_UST_EXEC_NAME: + case LTTNG_DOMAIN_UST_PID: + case LTTNG_DOMAIN_UST_PID_FOLLOW_CHILDREN: + memcpy(dst, src, sizeof(struct lttng_domain)); + break; + default: + dst->type = LTTNG_DOMAIN_KERNEL; + break; + } + } +} + +/* + * Send lttcomm_session_msg to the session daemon. * - * On success, return 0 - * On error, return error code + * On success, return 0 + * On error, return error code */ -static int send_data_sessiond(void) +static int send_session_msg(struct lttcomm_session_msg *lsm) { int ret; @@ -75,19 +94,18 @@ static int send_data_sessiond(void) goto end; } - ret = lttcomm_send_unix_sock(sessiond_socket, &lsm, sizeof(lsm)); + ret = lttcomm_send_unix_sock(sessiond_socket, lsm, + sizeof(struct lttcomm_session_msg)); end: return ret; } /* - * recv_data_sessiond - * - * Receive data from the sessiond socket. + * Receive data from the sessiond socket. * - * On success, return 0 - * On error, return recv() error code + * On success, return 0 + * On error, return recv() error code */ static int recv_data_sessiond(void *buf, size_t len) { @@ -167,13 +185,14 @@ static int set_session_daemon_path(void) ret = check_tracing_group(tracing_group); if (ret < 0 && getuid() != 0) { if (snprintf(sessiond_sock_path, PATH_MAX, - DEFAULT_HOME_CLIENT_UNIX_SOCK, - getenv("HOME")) < 0) { + DEFAULT_HOME_CLIENT_UNIX_SOCK, + getenv("HOME")) < 0) { return -ENOMEM; } } else { - copy_string(sessiond_sock_path, DEFAULT_GLOBAL_CLIENT_UNIX_SOCK, - PATH_MAX); + copy_string(sessiond_sock_path, + DEFAULT_GLOBAL_CLIENT_UNIX_SOCK, + PATH_MAX); } return 0; @@ -222,35 +241,24 @@ static int disconnect_sessiond(void) } /* - * Reset the session message structure. - */ -static void reset_session_msg(void) -{ - memset(&lsm, 0, sizeof(struct lttcomm_session_msg)); -} - -/* - * ask_sessiond - * - * Ask the session daemon a specific command and put the data into buf. + * Ask the session daemon a specific command and put the data into buf. * - * Return size of data (only payload, not header). + * Return size of data (only payload, not header). */ -static int ask_sessiond(enum lttcomm_sessiond_command lct, void **buf) +static int ask_sessiond(struct lttcomm_session_msg *lsm, void **buf) { int ret; size_t size; void *data = NULL; + struct lttcomm_lttng_msg llm; ret = connect_sessiond(); if (ret < 0) { goto end; } - lsm.cmd_type = lct; - /* Send command to session daemon */ - ret = send_data_sessiond(); + ret = send_session_msg(lsm); if (ret < 0) { goto end; } @@ -287,144 +295,230 @@ static int ask_sessiond(enum lttcomm_sessiond_command lct, void **buf) end: disconnect_sessiond(); - reset_session_msg(); return ret; } /* - * Copy domain to lttcomm_session_msg domain. If unknown domain, default domain - * will be the kernel. + * Create lttng handle and return pointer. */ -static void copy_lttng_domain(struct lttng_domain *dom) +struct lttng_handle *lttng_create_handle(const char *session_name, + struct lttng_domain *domain) { - if (dom) { - switch (dom->type) { - case LTTNG_DOMAIN_KERNEL: - case LTTNG_DOMAIN_UST: - case LTTNG_DOMAIN_UST_EXEC_NAME: - case LTTNG_DOMAIN_UST_PID: - case LTTNG_DOMAIN_UST_PID_FOLLOW_CHILDREN: - memcpy(&lsm.domain, dom, sizeof(struct lttng_domain)); - break; - default: - lsm.domain.type = LTTNG_DOMAIN_KERNEL; - break; - } + struct lttng_handle *handle; + + handle = malloc(sizeof(struct lttng_handle)); + if (handle == NULL) { + perror("malloc handle"); + goto end; + } + + /* Copy session name */ + copy_string(handle->session_name, session_name, + sizeof(handle->session_name)); + + /* Copy lttng domain */ + copy_lttng_domain(&handle->domain, domain); + +end: + return handle; +} + +/* + * Destroy handle by free(3) the pointer. + */ +void lttng_destroy_handle(struct lttng_handle *handle) +{ + if (handle) { + free(handle); } } /* * Start tracing for all trace of the session. */ -int lttng_start_tracing(const char *session_name) +int lttng_start_tracing(struct lttng_handle *handle) { - copy_string(lsm.session.name, session_name, NAME_MAX); - return ask_sessiond(LTTNG_START_TRACE, NULL); + struct lttcomm_session_msg lsm; + + if (!handle) { + return -1; + } + + lsm.cmd_type = LTTNG_START_TRACE; + copy_string(lsm.session.name, handle->session_name, + sizeof(lsm.session.name)); + + return ask_sessiond(&lsm, NULL); } /* * Stop tracing for all trace of the session. */ -int lttng_stop_tracing(const char *session_name) +int lttng_stop_tracing(struct lttng_handle *handle) { - copy_string(lsm.session.name, session_name, NAME_MAX); - return ask_sessiond(LTTNG_STOP_TRACE, NULL); + struct lttcomm_session_msg lsm; + + lsm.cmd_type = LTTNG_STOP_TRACE; + copy_string(lsm.session.name, handle->session_name, + sizeof(lsm.session.name)); + + return ask_sessiond(&lsm, NULL); } /* - * lttng_add_context + * Add context to event or/and channel. */ -int lttng_add_context(struct lttng_domain *domain, +int lttng_add_context(struct lttng_handle *handle, struct lttng_event_context *ctx, const char *event_name, const char *channel_name) { - copy_string(lsm.u.context.channel_name, channel_name, NAME_MAX); - copy_string(lsm.u.context.event_name, event_name, NAME_MAX); - copy_lttng_domain(domain); + struct lttcomm_session_msg lsm; + + if (!handle) { + return -1; + } + + lsm.cmd_type = LTTNG_ADD_CONTEXT; + + /* Copy channel name */ + copy_string(lsm.u.context.channel_name, channel_name, + sizeof(lsm.u.context.channel_name)); + /* Copy event name */ + copy_string(lsm.u.context.event_name, event_name, + sizeof(lsm.u.context.event_name)); + + copy_lttng_domain(&lsm.domain, &handle->domain); if (ctx) { memcpy(&lsm.u.context.ctx, ctx, sizeof(struct lttng_event_context)); } - return ask_sessiond(LTTNG_ADD_CONTEXT, NULL); + copy_string(lsm.session.name, handle->session_name, + sizeof(lsm.session.name)); + + return ask_sessiond(&lsm, NULL); } /* - * lttng_enable_event + * Enable event */ -int lttng_enable_event(struct lttng_domain *domain, +int lttng_enable_event(struct lttng_handle *handle, struct lttng_event *ev, const char *channel_name) { - int ret; + struct lttcomm_session_msg lsm; + + if (!handle) { + return -1; + } if (channel_name == NULL) { - copy_string(lsm.u.enable.channel_name, DEFAULT_CHANNEL_NAME, NAME_MAX); + copy_string(lsm.u.enable.channel_name, DEFAULT_CHANNEL_NAME, + sizeof(lsm.u.enable.channel_name)); } else { - copy_string(lsm.u.enable.channel_name, channel_name, NAME_MAX); + copy_string(lsm.u.enable.channel_name, channel_name, + sizeof(lsm.u.enable.channel_name)); } - copy_lttng_domain(domain); + copy_lttng_domain(&lsm.domain, &handle->domain); - if (ev == NULL) { - ret = ask_sessiond(LTTNG_ENABLE_ALL_EVENT, NULL); + if (ev) { + lsm.cmd_type = LTTNG_ENABLE_EVENT; + memcpy(&lsm.u.enable.event, ev, sizeof(lsm.u.enable.event)); } else { - memcpy(&lsm.u.enable.event, ev, sizeof(struct lttng_event)); - ret = ask_sessiond(LTTNG_ENABLE_EVENT, NULL); + lsm.cmd_type = LTTNG_ENABLE_ALL_EVENT; } - return ret; + copy_string(lsm.session.name, handle->session_name, + sizeof(lsm.session.name)); + + return ask_sessiond(&lsm, NULL); } /* * Disable event of a channel and domain. */ -int lttng_disable_event(struct lttng_domain *domain, const char *name, +int lttng_disable_event(struct lttng_handle *handle, const char *name, const char *channel_name) { - int ret = -1; + struct lttcomm_session_msg lsm; - if (channel_name == NULL) { - copy_string(lsm.u.disable.channel_name, DEFAULT_CHANNEL_NAME, NAME_MAX); + if (!handle) { + return -1; + } + + if (channel_name) { + copy_string(lsm.u.disable.channel_name, channel_name, + sizeof(lsm.u.disable.channel_name)); } else { - copy_string(lsm.u.disable.channel_name, channel_name, NAME_MAX); + copy_string(lsm.u.disable.channel_name, DEFAULT_CHANNEL_NAME, + sizeof(lsm.u.disable.channel_name)); } - copy_lttng_domain(domain); + copy_lttng_domain(&lsm.domain, &handle->domain); if (name == NULL) { - ret = ask_sessiond(LTTNG_DISABLE_ALL_EVENT, NULL); + copy_string(lsm.u.disable.name, name, sizeof(lsm.u.disable.name)); + lsm.cmd_type = LTTNG_DISABLE_EVENT; } else { - copy_string(lsm.u.disable.name, name, NAME_MAX); - ret = ask_sessiond(LTTNG_DISABLE_EVENT, NULL); + lsm.cmd_type = LTTNG_DISABLE_ALL_EVENT; } - return ret; + copy_string(lsm.session.name, handle->session_name, + sizeof(lsm.session.name)); + + return ask_sessiond(&lsm, NULL); } /* * Enable channel per domain */ -int lttng_enable_channel(struct lttng_domain *domain, +int lttng_enable_channel(struct lttng_handle *handle, struct lttng_channel *chan) { + struct lttcomm_session_msg lsm; + + if (!handle) { + return -1; + } + if (chan) { - memcpy(&lsm.u.channel.chan, chan, sizeof(struct lttng_channel)); + memcpy(&lsm.u.channel.chan, chan, sizeof(lsm.u.channel.chan)); } - copy_lttng_domain(domain); + lsm.cmd_type = LTTNG_ENABLE_CHANNEL; + + copy_lttng_domain(&lsm.domain, &handle->domain); - return ask_sessiond(LTTNG_ENABLE_CHANNEL, NULL); + copy_string(lsm.session.name, handle->session_name, + sizeof(lsm.session.name)); + + return ask_sessiond(&lsm, NULL); } /* * All tracing will be stopped for registered events of the channel. */ -int lttng_disable_channel(struct lttng_domain *domain, const char *name) +int lttng_disable_channel(struct lttng_handle *handle, const char *name) { - copy_string(lsm.u.disable.channel_name, name, NAME_MAX); - copy_lttng_domain(domain); + struct lttcomm_session_msg lsm; + + if (!handle) { + return -1; + } + + if (name) { + copy_string(lsm.u.disable.channel_name, name, + sizeof(lsm.u.disable.channel_name)); + } + + lsm.cmd_type = LTTNG_DISABLE_CHANNEL; - return ask_sessiond(LTTNG_DISABLE_CHANNEL, NULL); + copy_lttng_domain(&lsm.domain, &handle->domain); + + copy_string(lsm.session.name, handle->session_name, + sizeof(lsm.session.name)); + + return ask_sessiond(&lsm, NULL); } /* @@ -433,14 +527,20 @@ int lttng_disable_channel(struct lttng_domain *domain, const char *name) * Return the size (bytes) of the list and set the events array. * On error, return negative value. */ -int lttng_list_tracepoints(struct lttng_domain *domain, +int lttng_list_tracepoints(struct lttng_handle *handle, struct lttng_event **events) { int ret; + struct lttcomm_session_msg lsm; + + if (!handle) { + return -1; + } - copy_lttng_domain(domain); + lsm.cmd_type = LTTNG_LIST_TRACEPOINTS; + copy_lttng_domain(&lsm.domain, &handle->domain); - ret = ask_sessiond(LTTNG_LIST_TRACEPOINTS, (void **) events); + ret = ask_sessiond(&lsm, (void **) events); if (ret < 0) { return ret; } @@ -465,18 +565,31 @@ const char *lttng_get_readable_code(int code) */ int lttng_create_session(const char *name, const char *path) { - copy_string(lsm.session.name, name, NAME_MAX); - copy_string(lsm.session.path, path, PATH_MAX); - return ask_sessiond(LTTNG_CREATE_SESSION, NULL); + struct lttcomm_session_msg lsm; + + lsm.cmd_type = LTTNG_CREATE_SESSION; + copy_string(lsm.session.name, name, sizeof(lsm.session.name)); + copy_string(lsm.session.path, path, sizeof(lsm.session.path)); + + return ask_sessiond(&lsm, NULL); } /* * Destroy session using name. */ -int lttng_destroy_session(const char *name) +int lttng_destroy_session(struct lttng_handle *handle) { - copy_string(lsm.session.name, name, NAME_MAX); - return ask_sessiond(LTTNG_DESTROY_SESSION, NULL); + struct lttcomm_session_msg lsm; + + if (!handle) { + return -1; + } + + lsm.cmd_type = LTTNG_DESTROY_SESSION; + copy_string(lsm.session.name, handle->session_name, + sizeof(lsm.session.name)); + + return ask_sessiond(&lsm, NULL); } /* @@ -488,8 +601,10 @@ int lttng_destroy_session(const char *name) int lttng_list_sessions(struct lttng_session **sessions) { int ret; + struct lttcomm_session_msg lsm; - ret = ask_sessiond(LTTNG_LIST_SESSIONS, (void**) sessions); + lsm.cmd_type = LTTNG_LIST_SESSIONS; + ret = ask_sessiond(&lsm, (void**) sessions); if (ret < 0) { return ret; } @@ -500,12 +615,22 @@ int lttng_list_sessions(struct lttng_session **sessions) /* * List domain of a session. */ -int lttng_list_domains(const char *session_name, struct lttng_domain **domains) +int lttng_list_domains(struct lttng_handle *handle, + struct lttng_domain **domains) { int ret; + struct lttcomm_session_msg lsm; + + if (!handle) { + return -1; + } - copy_string(lsm.session.name, session_name, NAME_MAX); - ret = ask_sessiond(LTTNG_LIST_DOMAINS, (void**) domains); + lsm.cmd_type = LTTNG_LIST_DOMAINS; + + copy_string(lsm.session.name, handle->session_name, + sizeof(lsm.session.name)); + + ret = ask_sessiond(&lsm, (void**) domains); if (ret < 0) { return ret; } @@ -516,15 +641,23 @@ int lttng_list_domains(const char *session_name, struct lttng_domain **domains) /* * List channels of a session */ -int lttng_list_channels(struct lttng_domain *domain, - const char *session_name, struct lttng_channel **channels) +int lttng_list_channels(struct lttng_handle *handle, + struct lttng_channel **channels) { int ret; + struct lttcomm_session_msg lsm; + + if (!handle) { + return -1; + } + + lsm.cmd_type = LTTNG_LIST_CHANNELS; + copy_string(lsm.session.name, handle->session_name, + sizeof(lsm.session.name)); - copy_string(lsm.session.name, session_name, NAME_MAX); - copy_lttng_domain(domain); + copy_lttng_domain(&lsm.domain, &handle->domain); - ret = ask_sessiond(LTTNG_LIST_CHANNELS, (void**) channels); + ret = ask_sessiond(&lsm, (void**) channels); if (ret < 0) { return ret; } @@ -535,17 +668,25 @@ int lttng_list_channels(struct lttng_domain *domain, /* * List events of a session channel. */ -int lttng_list_events(struct lttng_domain *domain, - const char *session_name, const char *channel_name, - struct lttng_event **events) +int lttng_list_events(struct lttng_handle *handle, + const char *channel_name, struct lttng_event **events) { int ret; + struct lttcomm_session_msg lsm; - copy_string(lsm.session.name, session_name, NAME_MAX); - copy_string(lsm.u.list.channel_name, channel_name, NAME_MAX); - copy_lttng_domain(domain); + if (!handle) { + return -1; + } + + lsm.cmd_type = LTTNG_LIST_EVENTS; + copy_string(lsm.session.name, handle->session_name, + sizeof(lsm.session.name)); + copy_string(lsm.u.list.channel_name, channel_name, + sizeof(lsm.u.list.channel_name)); + + copy_lttng_domain(&lsm.domain, &handle->domain); - ret = ask_sessiond(LTTNG_LIST_EVENTS, (void**) events); + ret = ask_sessiond(&lsm, (void**) events); if (ret < 0) { return ret; } @@ -553,14 +694,6 @@ int lttng_list_events(struct lttng_domain *domain, return ret / sizeof(struct lttng_event); } -/* - * Set session name for the current lsm. - */ -void lttng_set_session_name(const char *name) -{ - copy_string(lsm.session.name, name, NAME_MAX); -} - /* * lttng_set_tracing_group * @@ -579,17 +712,21 @@ int lttng_set_tracing_group(const char *name) /* * lttng_calibrate */ -int lttng_calibrate(struct lttng_domain *domain, +int lttng_calibrate(struct lttng_handle *handle, struct lttng_calibrate *calibrate) { - int ret; + struct lttcomm_session_msg lsm; - copy_lttng_domain(domain); + if (!handle) { + return -1; + } - memcpy(&lsm.u.calibrate, calibrate, sizeof(struct lttng_calibrate)); - ret = ask_sessiond(LTTNG_CALIBRATE, NULL); + lsm.cmd_type = LTTNG_CALIBRATE; + copy_lttng_domain(&lsm.domain, &handle->domain); - return ret; + memcpy(&lsm.u.calibrate, calibrate, sizeof(lsm.u.calibrate)); + + return ask_sessiond(&lsm, NULL); } /* diff --git a/lttng/commands/add_context.c b/lttng/commands/add_context.c index eb88f2465..619f7c9ac 100644 --- a/lttng/commands/add_context.c +++ b/lttng/commands/add_context.c @@ -47,6 +47,8 @@ enum { OPT_TYPE, }; +static struct lttng_handle *handle; + /* * Taken from the LTTng ABI */ @@ -341,7 +343,7 @@ end: /* * Add context to channel or event. */ -static int add_context(void) +static int add_context(char *session_name) { int ret = CMD_SUCCESS; struct lttng_event_context context; @@ -349,13 +351,18 @@ static int add_context(void) struct ctx_type *type; char *ptr; + if (opt_kernel) { + dom.type = LTTNG_DOMAIN_KERNEL; + } + + handle = lttng_create_handle(session_name, &dom); + if (handle == NULL) { + ret = -1; + goto error; + } + /* Iterate over all context type given */ cds_list_for_each_entry(type, &ctx_type_list.head, list) { - /* Set session name for the current command */ - if (set_session_name(opt_session_name) < 0) { - ret = CMD_ERROR; - goto error; - } context.ctx = type->opt->ctx_type; if (context.ctx == LTTNG_EVENT_CONTEXT_PERF_COUNTER) { @@ -371,11 +378,8 @@ static int add_context(void) } } if (opt_kernel) { - /* Create kernel domain */ - dom.type = LTTNG_DOMAIN_KERNEL; - DBG("Adding kernel context"); - ret = lttng_add_context(&dom, &context, opt_event_name, + ret = lttng_add_context(handle, &context, opt_event_name, opt_channel_name); if (ret < 0) { fprintf(stderr, "%s: ", type->opt->symbol); @@ -399,6 +403,8 @@ static int add_context(void) } error: + lttng_destroy_handle(handle); + return ret; } @@ -411,6 +417,7 @@ int cmd_add_context(int argc, const char **argv) char *tmp; static poptContext pc; struct ctx_type *type, *tmptype; + char *session_name = NULL; if (argc < 2) { usage(stderr); @@ -461,7 +468,17 @@ int cmd_add_context(int argc, const char **argv) } } - ret = add_context(); + if (!opt_session_name) { + session_name = get_session_name(); + if (session_name == NULL) { + ret = -1; + goto end; + } + } else { + session_name = opt_session_name; + } + + ret = add_context(session_name); /* Cleanup allocated memory */ cds_list_for_each_entry_safe(type, tmptype, &ctx_type_list.head, list) { diff --git a/lttng/commands/calibrate.c b/lttng/commands/calibrate.c index 76227e27e..b4d0fe045 100644 --- a/lttng/commands/calibrate.c +++ b/lttng/commands/calibrate.c @@ -49,6 +49,8 @@ enum { OPT_FUNCTION_ENTRY, }; +static struct lttng_handle *handle; + static struct poptOption long_options[] = { /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */ {"help", 'h', POPT_ARG_NONE, 0, OPT_HELP, 0, 0}, @@ -105,6 +107,12 @@ static int calibrate_lttng(void) dom.type = LTTNG_DOMAIN_KERNEL; } + handle = lttng_create_handle(NULL, &dom); + if (handle == NULL) { + ret = -1; + goto end; + } + /* Kernel tracer action */ if (opt_kernel) { switch (opt_event_type) { @@ -117,7 +125,7 @@ static int calibrate_lttng(void) case LTTNG_EVENT_FUNCTION: DBG("Calibrating kernel functions"); calibrate.type = LTTNG_CALIBRATE_FUNCTION; - ret = lttng_calibrate(&dom, &calibrate); + ret = lttng_calibrate(handle, &calibrate); break; case LTTNG_EVENT_FUNCTION_ENTRY: DBG("Calibrating kernel function entry"); @@ -140,6 +148,8 @@ static int calibrate_lttng(void) goto end; } end: + lttng_destroy_handle(handle); + return ret; } diff --git a/lttng/commands/destroy.c b/lttng/commands/destroy.c index 516f8ab95..3b02a53ee 100644 --- a/lttng/commands/destroy.c +++ b/lttng/commands/destroy.c @@ -30,6 +30,7 @@ #include "../utils.h" static char *opt_session_name; +static struct lttng_handle *handle; enum { OPT_HELP = 1, @@ -76,7 +77,13 @@ static int destroy_session() session_name = opt_session_name; } - ret = lttng_destroy_session(session_name); + handle = lttng_create_handle(session_name, NULL); + if (handle == NULL) { + ret = -1; + goto error; + } + + ret = lttng_destroy_session(handle); if (ret < 0) { goto free_name; } @@ -101,6 +108,8 @@ free_name: free(session_name); } error: + lttng_destroy_handle(handle); + return ret; } diff --git a/lttng/commands/disable_channels.c b/lttng/commands/disable_channels.c index 92cd2a58e..9a816e3ef 100644 --- a/lttng/commands/disable_channels.c +++ b/lttng/commands/disable_channels.c @@ -41,6 +41,8 @@ enum { OPT_USERSPACE, }; +static struct lttng_handle *handle; + static struct poptOption long_options[] = { /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */ {"help", 'h', POPT_ARG_NONE, 0, OPT_HELP, 0, 0}, @@ -69,32 +71,31 @@ static void usage(FILE *ofp) } /* - * disable_channels - * - * Disabling channel using the lttng API. + * Disabling channel using the lttng API. */ -static int disable_channels(void) +static int disable_channels(char *session_name) { int ret = CMD_SUCCESS; char *channel_name; struct lttng_domain dom; - if (set_session_name(opt_session_name) < 0) { - ret = CMD_ERROR; - goto error; - } - if (opt_kernel) { dom.type = LTTNG_DOMAIN_KERNEL; } + handle = lttng_create_handle(session_name, &dom); + if (handle == NULL) { + ret = -1; + goto error; + } + /* Strip channel list */ channel_name = strtok(opt_channels, ","); while (channel_name != NULL) { /* Kernel tracer action */ if (opt_kernel) { DBG("Disabling kernel channel %s", channel_name); - ret = lttng_disable_channel(&dom, channel_name); + ret = lttng_disable_channel(handle, channel_name); if (ret < 0) { goto error; } else { @@ -119,6 +120,8 @@ static int disable_channels(void) } error: + lttng_destroy_handle(handle); + return ret; } @@ -131,6 +134,7 @@ int cmd_disable_channels(int argc, const char **argv) { int opt, ret; static poptContext pc; + char *session_name = NULL; pc = poptGetContext(NULL, argc, argv, long_options, 0); poptReadDefaultConfig(pc, 0); @@ -159,7 +163,17 @@ int cmd_disable_channels(int argc, const char **argv) goto end; } - ret = disable_channels(); + if (!opt_session_name) { + session_name = get_session_name(); + if (session_name == NULL) { + ret = -1; + goto end; + } + } else { + session_name = opt_session_name; + } + + ret = disable_channels(session_name); end: return ret; diff --git a/lttng/commands/disable_events.c b/lttng/commands/disable_events.c index 60e77bdcf..b4d5ecb04 100644 --- a/lttng/commands/disable_events.c +++ b/lttng/commands/disable_events.c @@ -44,6 +44,8 @@ enum { OPT_USERSPACE, }; +static struct lttng_handle *handle; + static struct poptOption long_options[] = { /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */ {"help", 'h', POPT_ARG_NONE, 0, OPT_HELP, 0, 0}, @@ -80,18 +82,13 @@ static void usage(FILE *ofp) * * Disabling event using the lttng API. */ -static int disable_events(void) +static int disable_events(char *session_name) { int err, ret = CMD_SUCCESS; char *event_name, *channel_name = NULL; struct lttng_event ev; struct lttng_domain dom; - if (set_session_name(opt_session_name) < 0) { - ret = CMD_ERROR; - goto error; - } - if (opt_channel_name == NULL) { err = asprintf(&channel_name, DEFAULT_CHANNEL_NAME); if (err < 0) { @@ -106,9 +103,15 @@ static int disable_events(void) dom.type = LTTNG_DOMAIN_KERNEL; } + handle = lttng_create_handle(session_name, &dom); + if (handle == NULL) { + ret = -1; + goto error; + } + if (opt_disable_all) { if (opt_kernel) { - ret = lttng_disable_event(&dom, NULL, channel_name); + ret = lttng_disable_event(handle, NULL, channel_name); goto error; } @@ -126,7 +129,7 @@ static int disable_events(void) /* Copy name and type of the event */ strncpy(ev.name, event_name, LTTNG_SYMBOL_NAME_LEN); ev.name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0'; - ret = lttng_disable_event(&dom, event_name, channel_name); + ret = lttng_disable_event(handle, event_name, channel_name); if (ret < 0) { MSG("Unable to disable event %s for channel %s", event_name, channel_name); @@ -156,6 +159,8 @@ error: if (opt_channel_name == NULL) { free(channel_name); } + lttng_destroy_handle(handle); + return ret; } @@ -168,6 +173,7 @@ int cmd_disable_events(int argc, const char **argv) { int opt, ret; static poptContext pc; + char *session_name = NULL; pc = poptGetContext(NULL, argc, argv, long_options, 0); poptReadDefaultConfig(pc, 0); @@ -197,7 +203,17 @@ int cmd_disable_events(int argc, const char **argv) goto end; } - ret = disable_events(); + if (!opt_session_name) { + session_name = get_session_name(); + if (session_name == NULL) { + ret = -1; + goto end; + } + } else { + session_name = opt_session_name; + } + + ret = disable_events(session_name); end: return ret; diff --git a/lttng/commands/enable_channels.c b/lttng/commands/enable_channels.c index 1bdf60667..e49559e4f 100644 --- a/lttng/commands/enable_channels.c +++ b/lttng/commands/enable_channels.c @@ -50,6 +50,8 @@ enum { OPT_USERSPACE, }; +static struct lttng_handle *handle; + static struct poptOption long_options[] = { /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */ {"help", 'h', POPT_ARG_NONE, 0, OPT_HELP, 0, 0}, @@ -96,21 +98,22 @@ static void usage(FILE *ofp) * * Adding channel using the lttng API. */ -static int enable_channel(void) +static int enable_channel(char *session_name) { int ret = CMD_SUCCESS; char *channel_name; struct lttng_domain dom; - if (set_session_name(opt_session_name) < 0) { - ret = CMD_ERROR; - goto error; - } - if (opt_kernel) { dom.type = LTTNG_DOMAIN_KERNEL; } + handle = lttng_create_handle(session_name, &dom); + if (handle == NULL) { + ret = -1; + goto error; + } + /* Strip event list */ channel_name = strtok(opt_channels, ","); while (channel_name != NULL) { @@ -122,7 +125,7 @@ static int enable_channel(void) strncpy(chan.name, channel_name, NAME_MAX); chan.name[NAME_MAX - 1] = '\0'; - ret = lttng_enable_channel(&dom, &chan); + ret = lttng_enable_channel(handle, &chan); if (ret < 0) { goto error; } else { @@ -147,6 +150,8 @@ static int enable_channel(void) } error: + lttng_destroy_handle(handle); + return ret; } @@ -172,6 +177,7 @@ int cmd_enable_channels(int argc, const char **argv) { int opt, ret; static poptContext pc; + char *session_name = NULL; init_channel_config(); @@ -227,7 +233,17 @@ int cmd_enable_channels(int argc, const char **argv) goto end; } - ret = enable_channel(); + if (!opt_session_name) { + session_name = get_session_name(); + if (session_name == NULL) { + ret = -1; + goto end; + } + } else { + session_name = opt_session_name; + } + + ret = enable_channel(session_name); end: return ret; diff --git a/lttng/commands/enable_events.c b/lttng/commands/enable_events.c index 5b844e493..f6bca6e94 100644 --- a/lttng/commands/enable_events.c +++ b/lttng/commands/enable_events.c @@ -55,6 +55,8 @@ enum { OPT_FUNCTION_ENTRY, }; +static struct lttng_handle *handle; + static struct poptOption long_options[] = { /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */ {"help", 'h', POPT_ARG_NONE, 0, OPT_HELP, 0, 0}, @@ -179,7 +181,7 @@ end: * * Enabling event using the lttng API. */ -static int enable_events(void) +static int enable_events(char *session_name) { int err, ret = CMD_SUCCESS; char *event_name, *channel_name = NULL; @@ -201,14 +203,15 @@ static int enable_events(void) dom.type = LTTNG_DOMAIN_KERNEL; } - if (opt_enable_all) { - if (set_session_name(opt_session_name) < 0) { - ret = CMD_ERROR; - goto error; - } + handle = lttng_create_handle(session_name, &dom); + if (handle == NULL) { + ret = -1; + goto error; + } + if (opt_enable_all) { if (opt_kernel) { - ret = lttng_enable_event(&dom, NULL, channel_name); + ret = lttng_enable_event(handle, NULL, channel_name); if (ret == 0) { MSG("All kernel events are enabled in channel %s", channel_name); } @@ -221,11 +224,6 @@ static int enable_events(void) /* Strip event list */ event_name = strtok(opt_event_list, ","); while (event_name != NULL) { - if (set_session_name(opt_session_name) < 0) { - ret = CMD_ERROR; - goto error; - } - /* Kernel tracer action */ if (opt_kernel) { DBG("Enabling kernel event %s for channel %s", @@ -265,7 +263,7 @@ static int enable_events(void) goto error; } - ret = lttng_enable_event(&dom, &ev, channel_name); + ret = lttng_enable_event(handle, &ev, channel_name); if (ret == 0) { MSG("Kernel event %s created in channel %s", event_name, channel_name); } @@ -291,6 +289,8 @@ error: if (opt_channel_name == NULL) { free(channel_name); } + lttng_destroy_handle(handle); + return ret; } @@ -303,6 +303,7 @@ int cmd_enable_events(int argc, const char **argv) { int opt, ret; static poptContext pc; + char *session_name = NULL; pc = poptGetContext(NULL, argc, argv, long_options, 0); poptReadDefaultConfig(pc, 0); @@ -353,8 +354,22 @@ int cmd_enable_events(int argc, const char **argv) goto end; } - ret = enable_events(); + if (!opt_session_name) { + session_name = get_session_name(); + if (session_name == NULL) { + ret = -1; + goto end; + } + } else { + session_name = opt_session_name; + } + + ret = enable_events(session_name); end: + if (opt_session_name == NULL) { + free(session_name); + } + return ret; } diff --git a/lttng/commands/list.c b/lttng/commands/list.c index 445bd5fa8..f0c8c880f 100644 --- a/lttng/commands/list.c +++ b/lttng/commands/list.c @@ -39,6 +39,8 @@ enum { OPT_HELP = 1, }; +static struct lttng_handle *handle; + static struct poptOption long_options[] = { /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */ {"help", 'h', POPT_ARG_NONE, 0, OPT_HELP, 0, 0}, @@ -113,13 +115,10 @@ static int list_kernel_events(void) { int i, size; struct lttng_event *event_list; - struct lttng_domain dom; DBG("Getting all tracing events"); - dom.type = LTTNG_DOMAIN_KERNEL; - - size = lttng_list_tracepoints(&dom, &event_list); + size = lttng_list_tracepoints(handle, &event_list); if (size < 0) { ERR("Unable to list kernel events"); return size; @@ -139,13 +138,12 @@ static int list_kernel_events(void) /* * List events of channel of session and domain. */ -static int list_events(struct lttng_domain *dom, - const char *session_name, const char *channel_name) +static int list_events(const char *channel_name) { int ret, count, i; struct lttng_event *events = NULL; - count = lttng_list_events(dom, session_name, channel_name, &events); + count = lttng_list_events(handle, channel_name, &events); if (count < 0) { ret = count; goto error; @@ -222,8 +220,7 @@ static void print_channel(struct lttng_channel *channel) * * If channel_name is NULL, all channels are listed. */ -static int list_channels(struct lttng_domain *dom, - const char *session_name, const char *channel_name) +static int list_channels(const char *channel_name) { int count, i, ret = CMD_SUCCESS; unsigned int chan_found = 0; @@ -231,7 +228,7 @@ static int list_channels(struct lttng_domain *dom, DBG("Listing channel(s) (%s)", channel_name); - count = lttng_list_channels(dom, session_name, &channels); + count = lttng_list_channels(handle, &channels); if (count < 0) { ret = count; goto error; @@ -255,7 +252,7 @@ static int list_channels(struct lttng_domain *dom, print_channel(&channels[i]); /* Listing events per channel */ - ret = list_events(dom, session_name, channels[i].name); + ret = list_events(channels[i].name); if (ret < 0) { MSG("%s", lttng_get_readable_code(ret)); } @@ -307,6 +304,7 @@ static int list_sessions(const char *session_name) MSG("%sTrace path: %s\n", indent4, sessions[i].path); break; } + continue; } MSG(" %d) %s (%s)", i + 1, sessions[i].name, sessions[i].path); @@ -335,14 +333,14 @@ error: /* * List available domain(s) for a session. */ -static int list_domains(const char *session_name) +static int list_domains(void) { int i, count, ret = CMD_SUCCESS; struct lttng_domain *domains = NULL; MSG("Domains:\n-------------"); - count = lttng_list_domains(session_name, &domains); + count = lttng_list_domains(handle, &domains); if (count < 0) { ret = count; goto error; @@ -406,6 +404,15 @@ int cmd_list(int argc, const char **argv) session_name = poptGetArg(pc); DBG("Session name: %s", session_name); + if (opt_kernel) { + domain.type = LTTNG_DOMAIN_KERNEL; + } + + handle = lttng_create_handle(session_name, &domain); + if (handle == NULL) { + goto end; + } + if (session_name == NULL) { if (opt_kernel) { ret = list_kernel_events(); @@ -427,14 +434,13 @@ int cmd_list(int argc, const char **argv) /* Domain listing */ if (opt_domain) { - ret = list_domains(session_name); + ret = list_domains(); goto end; } if (opt_kernel) { - domain.type = LTTNG_DOMAIN_KERNEL; /* Channel listing */ - ret = list_channels(&domain, session_name, opt_channel); + ret = list_channels(opt_channel); if (ret < 0) { goto end; } @@ -442,7 +448,7 @@ int cmd_list(int argc, const char **argv) /* TODO: Userspace domain */ } else { /* We want all domain(s) */ - ret = lttng_list_domains(session_name, &domains); + ret = lttng_list_domains(handle, &domains); if (ret < 0) { goto end; } @@ -457,7 +463,15 @@ int cmd_list(int argc, const char **argv) break; } - ret = list_channels(&domains[i], session_name, opt_channel); + /* Clean handle before creating a new one */ + lttng_destroy_handle(handle); + + handle = lttng_create_handle(session_name, &domains[i]); + if (handle == NULL) { + goto end; + } + + ret = list_channels(opt_channel); if (ret < 0) { goto end; } @@ -469,5 +483,7 @@ end: if (domains) { free(domains); } + lttng_destroy_handle(handle); + return ret; } diff --git a/lttng/commands/start.c b/lttng/commands/start.c index 2eacc462f..312e94ed2 100644 --- a/lttng/commands/start.c +++ b/lttng/commands/start.c @@ -35,6 +35,8 @@ enum { OPT_HELP = 1, }; +static struct lttng_handle *handle; + static struct poptOption long_options[] = { /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */ {"help", 'h', POPT_ARG_NONE, 0, OPT_HELP, 0, 0}, @@ -75,9 +77,15 @@ static int start_tracing(void) session_name = opt_session_name; } + handle = lttng_create_handle(session_name, NULL); + if (handle == NULL) { + ret = -1; + goto error; + } + DBG("Starting tracing for session %s", session_name); - ret = lttng_start_tracing(session_name); + ret = lttng_start_tracing(handle); if (ret < 0) { goto free_name; } @@ -89,6 +97,8 @@ free_name: free(session_name); } error: + lttng_destroy_handle(handle); + return ret; } diff --git a/lttng/commands/stop.c b/lttng/commands/stop.c index 87862b4b9..b40a63881 100644 --- a/lttng/commands/stop.c +++ b/lttng/commands/stop.c @@ -35,6 +35,8 @@ enum { OPT_HELP = 1, }; +static struct lttng_handle *handle; + static struct poptOption long_options[] = { /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */ {"help", 'h', POPT_ARG_NONE, 0, OPT_HELP, 0, 0}, @@ -56,9 +58,7 @@ static void usage(FILE *ofp) } /* - * stop_tracing - * - * Start tracing for all trace of the session. + * Start tracing for all trace of the session. */ static int stop_tracing(void) { @@ -75,7 +75,13 @@ static int stop_tracing(void) session_name = opt_session_name; } - ret = lttng_stop_tracing(session_name); + handle = lttng_create_handle(session_name, NULL); + if (handle == NULL) { + ret = -1; + goto error; + } + + ret = lttng_stop_tracing(handle); if (ret < 0) { goto free_name; } @@ -86,7 +92,10 @@ free_name: if (opt_session_name == NULL) { free(session_name); } + error: + lttng_destroy_handle(handle); + return ret; } diff --git a/lttng/utils.c b/lttng/utils.c index ee0e297b1..db7fd38fe 100644 --- a/lttng/utils.c +++ b/lttng/utils.c @@ -21,6 +21,7 @@ #include #include "conf.h" +#include "lttngerr.h" /* * get_session_name @@ -45,35 +46,6 @@ char *get_session_name(void) } error: + DBG("Session name found: %s", session_name); return session_name; } - -/* - * set_session_name - * - * Get session name and set it for the lttng control lib. - */ -int set_session_name(char *name) -{ - int ret; - char *session_name; - - if (!name) { - session_name = get_session_name(); - if (session_name == NULL) { - ret = -1; - goto error; - } - } else { - session_name = name; - } - - lttng_set_session_name(session_name); - if (!name) - free(session_name); - - ret = 0; - -error: - return ret; -} -- 2.34.1