X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Fcmd.c;h=800859b8e55437919af0eba63d3278652eba1bed;hp=058dbae4d894955480526b631e5b76b212765dd5;hb=d31d3e8cf774b98a8ed46b8c7f6273364360f246;hpb=f5ac4bd72b128dc3e6e5d41d3f76755e6215a02d diff --git a/src/bin/lttng-sessiond/cmd.c b/src/bin/lttng-sessiond/cmd.c index 058dbae4d..800859b8e 100644 --- a/src/bin/lttng-sessiond/cmd.c +++ b/src/bin/lttng-sessiond/cmd.c @@ -1,5 +1,6 @@ /* * Copyright (C) 2012 - David Goulet + * Copyright (C) 2016 - Jérémie Galarneau * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License, version 2 only, as @@ -15,10 +16,8 @@ * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#define _GNU_SOURCE #define _LGPL_SOURCE #include -#include #include #include #include @@ -28,6 +27,7 @@ #include #include #include +#include #include "channel.h" #include "consumer.h" @@ -198,19 +198,48 @@ static void list_lttng_channels(enum lttng_domain_type domain, } } +static void increment_extended_len(const char *filter_expression, + size_t *extended_len) +{ + *extended_len += sizeof(struct lttcomm_event_extended_header); + + if (filter_expression) { + *extended_len += strlen(filter_expression) + 1; + } +} + +static void append_extended_info(const char *filter_expression, + void **extended_at) +{ + struct lttcomm_event_extended_header extended_header; + size_t filter_len = 0; + + if (filter_expression) { + filter_len = strlen(filter_expression) + 1; + } + + extended_header.filter_len = filter_len; + memcpy(*extended_at, &extended_header, sizeof(extended_header)); + *extended_at += sizeof(extended_header); + memcpy(*extended_at, filter_expression, filter_len); + *extended_at += filter_len; +} + /* * Create a list of agent domain events. * * Return number of events in list on success or else a negative value. */ static int list_lttng_agent_events(struct agent *agt, - struct lttng_event **events) + struct lttng_event **events, size_t *total_size) { int i = 0, ret = 0; unsigned int nb_event = 0; struct agent_event *event; struct lttng_event *tmp_events; struct lttng_ht_iter iter; + size_t extended_len = 0; + void *extended_at; assert(agt); assert(events); @@ -222,16 +251,34 @@ static int list_lttng_agent_events(struct agent *agt, rcu_read_unlock(); if (nb_event == 0) { ret = nb_event; + *total_size = 0; goto error; } - tmp_events = zmalloc(nb_event * sizeof(*tmp_events)); + /* Compute required extended infos size */ + extended_len = nb_event * sizeof(struct lttcomm_event_extended_header); + + /* + * This is only valid because the commands which add events are + * processed in the same thread as the listing. + */ + rcu_read_lock(); + cds_lfht_for_each_entry(agt->events->ht, &iter.iter, event, node.node) { + increment_extended_len(event->filter_expression, &extended_len); + } + rcu_read_unlock(); + + *total_size = nb_event * sizeof(*tmp_events) + extended_len; + tmp_events = zmalloc(*total_size); if (!tmp_events) { PERROR("zmalloc agent events session"); ret = -LTTNG_ERR_FATAL; goto error; } + extended_at = ((uint8_t *) tmp_events) + + nb_event * sizeof(struct lttng_event); + rcu_read_lock(); cds_lfht_for_each_entry(agt->events->ht, &iter.iter, event, node.node) { strncpy(tmp_events[i].name, event->name, sizeof(tmp_events[i].name)); @@ -240,6 +287,9 @@ static int list_lttng_agent_events(struct agent *agt, tmp_events[i].loglevel = event->loglevel_value; tmp_events[i].loglevel_type = event->loglevel_type; i++; + + /* Append extended info */ + append_extended_info(event->filter_expression, &extended_at); } rcu_read_unlock(); @@ -255,7 +305,8 @@ error: * Create a list of ust global domain events. */ static int list_lttng_ust_global_events(char *channel_name, - struct ltt_ust_domain_global *ust_global, struct lttng_event **events) + struct ltt_ust_domain_global *ust_global, + struct lttng_event **events, size_t *total_size) { int i = 0, ret = 0; unsigned int nb_event = 0; @@ -264,6 +315,8 @@ static int list_lttng_ust_global_events(char *channel_name, struct ltt_ust_channel *uchan; struct ltt_ust_event *uevent; struct lttng_event *tmp; + size_t extended_len = 0; + void *extended_at; DBG("Listing UST global events for channel %s", channel_name); @@ -273,7 +326,7 @@ static int list_lttng_ust_global_events(char *channel_name, node = lttng_ht_iter_get_node_str(&iter); if (node == NULL) { ret = LTTNG_ERR_UST_CHAN_NOT_FOUND; - goto error; + goto end; } uchan = caa_container_of(&node->node, struct ltt_ust_channel, node.node); @@ -281,21 +334,41 @@ static int list_lttng_ust_global_events(char *channel_name, nb_event = lttng_ht_get_count(uchan->events); if (nb_event == 0) { ret = nb_event; - goto error; + *total_size = 0; + goto end; } DBG3("Listing UST global %d events", nb_event); - tmp = zmalloc(nb_event * sizeof(struct lttng_event)); + /* Compute required extended infos size */ + cds_lfht_for_each_entry(uchan->events->ht, &iter.iter, uevent, node.node) { + if (uevent->internal) { + nb_event--; + continue; + } + + increment_extended_len(uevent->filter_expression, + &extended_len); + } + if (nb_event == 0) { + /* All events are internal, skip. */ + ret = 0; + *total_size = 0; + goto end; + } + + *total_size = nb_event * sizeof(struct lttng_event) + extended_len; + tmp = zmalloc(*total_size); if (tmp == NULL) { ret = LTTNG_ERR_FATAL; goto error; } + extended_at = ((uint8_t *) tmp) + nb_event * sizeof(struct lttng_event); + cds_lfht_for_each_entry(uchan->events->ht, &iter.iter, uevent, node.node) { if (uevent->internal) { /* This event should remain hidden from clients */ - nb_event--; continue; } strncpy(tmp[i].name, uevent->attr.name, LTTNG_SYMBOL_NAME_LEN); @@ -333,12 +406,14 @@ static int list_lttng_ust_global_events(char *channel_name, tmp[i].exclusion = 1; } i++; + + /* Append extended info */ + append_extended_info(uevent->filter_expression, &extended_at); } ret = nb_event; *events = tmp; - -error: +end: rcu_read_unlock(); return ret; } @@ -347,12 +422,15 @@ error: * Fill lttng_event array of all kernel events in the channel. */ static int list_lttng_kernel_events(char *channel_name, - struct ltt_kernel_session *kernel_session, struct lttng_event **events) + struct ltt_kernel_session *kernel_session, + struct lttng_event **events, size_t *total_size) { int i = 0, ret; unsigned int nb_event; struct ltt_kernel_event *event; struct ltt_kernel_channel *kchan; + size_t extended_len = 0; + void *extended_at; kchan = trace_kernel_get_channel_by_name(channel_name, kernel_session); if (kchan == NULL) { @@ -365,16 +443,26 @@ static int list_lttng_kernel_events(char *channel_name, DBG("Listing events for channel %s", kchan->channel->name); if (nb_event == 0) { + *total_size = 0; *events = NULL; goto syscall; } - *events = zmalloc(nb_event * sizeof(struct lttng_event)); + /* Compute required extended infos size */ + cds_list_for_each_entry(event, &kchan->events_list.head, list) { + increment_extended_len(event->filter_expression, &extended_len); + } + + *total_size = nb_event * sizeof(struct lttng_event) + extended_len; + *events = zmalloc(*total_size); if (*events == NULL) { ret = LTTNG_ERR_FATAL; goto error; } + extended_at = ((uint8_t *) events) + + nb_event * sizeof(struct lttng_event); + /* Kernel channels */ cds_list_for_each_entry(event, &kchan->events_list.head , list) { strncpy((*events)[i].name, event->event->name, LTTNG_SYMBOL_NAME_LEN); @@ -413,6 +501,9 @@ static int list_lttng_kernel_events(char *channel_name, break; } i++; + + /* Append extended info */ + append_extended_info(event->filter_expression, &extended_at); } syscall: @@ -1048,7 +1139,7 @@ int cmd_enable_channel(struct ltt_session *session, assert(attr); assert(domain); - len = strnlen(attr->name, sizeof(attr->name)); + len = lttng_strnlen(attr->name, sizeof(attr->name)); /* Validate channel name */ if (attr->name[0] == '.' || @@ -1225,28 +1316,18 @@ int cmd_disable_event(struct ltt_session *session, switch (event->type) { case LTTNG_EVENT_ALL: - ret = event_kernel_disable_event_all(kchan); - if (ret != LTTNG_OK) { - goto error_unlock; - } - break; - case LTTNG_EVENT_TRACEPOINT: /* fall-through */ + case LTTNG_EVENT_TRACEPOINT: case LTTNG_EVENT_SYSCALL: - if (!strcmp(event_name, "*")) { - ret = event_kernel_disable_event_type(kchan, - event->type); + case LTTNG_EVENT_PROBE: + case LTTNG_EVENT_FUNCTION: + case LTTNG_EVENT_FUNCTION_ENTRY:/* fall-through */ + if (event_name[0] == '\0') { + ret = event_kernel_disable_event(kchan, + NULL, event->type); } else { ret = event_kernel_disable_event(kchan, - event_name); - } - if (ret != LTTNG_OK) { - goto error_unlock; + event_name, event->type); } - break; - case LTTNG_EVENT_PROBE: - case LTTNG_EVENT_FUNCTION: - case LTTNG_EVENT_FUNCTION_ENTRY: - ret = event_kernel_disable_event(kchan, event_name); if (ret != LTTNG_OK) { goto error_unlock; } @@ -1273,7 +1354,7 @@ int cmd_disable_event(struct ltt_session *session, /* * If a non-default channel has been created in the - * session, explicitely require that -c chan_name needs + * session, explicitly require that -c chan_name needs * to be provided. */ if (usess->has_non_default_channel && channel_name[0] == '\0') { @@ -1290,7 +1371,16 @@ int cmd_disable_event(struct ltt_session *session, switch (event->type) { case LTTNG_EVENT_ALL: - ret = event_ust_disable_tracepoint(usess, uchan, event_name); + /* + * An empty event name means that everything + * should be disabled. + */ + if (event->name[0] == '\0') { + ret = event_ust_disable_all_tracepoints(usess, uchan); + } else { + ret = event_ust_disable_tracepoint(usess, uchan, + event_name); + } if (ret != LTTNG_OK) { goto error_unlock; } @@ -1326,8 +1416,11 @@ int cmd_disable_event(struct ltt_session *session, ret = -LTTNG_ERR_UST_EVENT_NOT_FOUND; goto error_unlock; } - /* The wild card * means that everything should be disabled. */ - if (strncmp(event->name, "*", 1) == 0 && strlen(event->name) == 1) { + /* + * An empty event name means that everything + * should be disabled. + */ + if (event->name[0] == '\0') { ret = event_agent_disable_all(usess, agt); } else { ret = event_agent_disable(usess, agt, event_name); @@ -1358,6 +1451,12 @@ int cmd_add_context(struct ltt_session *session, enum lttng_domain_type domain, char *channel_name, struct lttng_event_context *ctx, int kwpipe) { int ret, chan_kern_created = 0, chan_ust_created = 0; + char *app_ctx_provider_name = NULL, *app_ctx_name = NULL; + + if (ctx->ctx == LTTNG_EVENT_CONTEXT_APP_CONTEXT) { + app_ctx_provider_name = ctx->u.app_ctx.provider_name; + app_ctx_name = ctx->u.app_ctx.ctx_name; + } switch (domain) { case LTTNG_DOMAIN_KERNEL: @@ -1377,6 +1476,29 @@ int cmd_add_context(struct ltt_session *session, enum lttng_domain_type domain, goto error; } break; + case LTTNG_DOMAIN_JUL: + case LTTNG_DOMAIN_LOG4J: + { + /* + * Validate channel name. + * If no channel name is given and the domain is JUL or LOG4J, + * set it to the appropriate domain-specific channel name. If + * a name is provided but does not match the expexted channel + * name, return an error. + */ + if (domain == LTTNG_DOMAIN_JUL && *channel_name && + strcmp(channel_name, + DEFAULT_JUL_CHANNEL_NAME)) { + ret = LTTNG_ERR_UST_CHAN_NOT_FOUND; + goto error; + } else if (domain == LTTNG_DOMAIN_LOG4J && *channel_name && + strcmp(channel_name, + DEFAULT_LOG4J_CHANNEL_NAME)) { + ret = LTTNG_ERR_UST_CHAN_NOT_FOUND; + goto error; + } + /* break is _not_ missing here. */ + } case LTTNG_DOMAIN_UST: { struct ltt_ust_session *usess = session->ust_session; @@ -1404,6 +1526,10 @@ int cmd_add_context(struct ltt_session *session, enum lttng_domain_type domain, } ret = context_ust_add(usess, domain, ctx, channel_name); + free(app_ctx_provider_name); + free(app_ctx_name); + app_ctx_name = NULL; + app_ctx_provider_name = NULL; if (ret != LTTNG_OK) { goto error; } @@ -1414,7 +1540,8 @@ int cmd_add_context(struct ltt_session *session, enum lttng_domain_type domain, goto error; } - return LTTNG_OK; + ret = LTTNG_OK; + goto end; error: if (chan_kern_created) { @@ -1438,6 +1565,9 @@ error: uchan); trace_ust_destroy_channel(uchan); } +end: + free(app_ctx_provider_name); + free(app_ctx_name); return ret; } @@ -1633,9 +1763,10 @@ static int _cmd_enable_event(struct ltt_session *session, event->type = LTTNG_EVENT_SYSCALL; /* Hack */ ret = event_kernel_enable_event(kchan, event, filter_expression_a, filter_a); + /* We have passed ownership */ + filter_expression_a = NULL; + filter_a = NULL; if (ret != LTTNG_OK) { - free(filter_expression_a); - free(filter_a); goto error; } break; @@ -1751,7 +1882,9 @@ static int _cmd_enable_event(struct ltt_session *session, filter_expression = NULL; filter = NULL; exclusion = NULL; - if (ret != LTTNG_OK) { + if (ret == LTTNG_ERR_UST_EVENT_ENABLED) { + goto already_enabled; + } else if (ret != LTTNG_OK) { goto error; } break; @@ -1849,7 +1982,9 @@ static int _cmd_enable_event(struct ltt_session *session, filter_copy, NULL, wpipe); } - if (ret != LTTNG_OK && ret != LTTNG_ERR_UST_EVENT_ENABLED) { + if (ret == LTTNG_ERR_UST_EVENT_ENABLED) { + goto already_enabled; + } else if (ret != LTTNG_OK) { goto error; } @@ -1876,6 +2011,7 @@ static int _cmd_enable_event(struct ltt_session *session, ret = LTTNG_OK; +already_enabled: error: free(filter_expression); free(filter); @@ -2726,7 +2862,7 @@ error: */ ssize_t cmd_list_events(enum lttng_domain_type domain, struct ltt_session *session, char *channel_name, - struct lttng_event **events) + struct lttng_event **events, size_t *total_size) { int ret = 0; ssize_t nb_event = 0; @@ -2735,14 +2871,16 @@ ssize_t cmd_list_events(enum lttng_domain_type domain, case LTTNG_DOMAIN_KERNEL: if (session->kernel_session != NULL) { nb_event = list_lttng_kernel_events(channel_name, - session->kernel_session, events); + session->kernel_session, events, + total_size); } break; case LTTNG_DOMAIN_UST: { if (session->ust_session != NULL) { nb_event = list_lttng_ust_global_events(channel_name, - &session->ust_session->domain_global, events); + &session->ust_session->domain_global, events, + total_size); } break; } @@ -2756,7 +2894,12 @@ ssize_t cmd_list_events(enum lttng_domain_type domain, rcu_read_lock(); cds_lfht_for_each_entry(session->ust_session->agents->ht, &iter.iter, agt, node.node) { - nb_event = list_lttng_agent_events(agt, events); + if (agt->domain == domain) { + nb_event = list_lttng_agent_events( + agt, events, + total_size); + break; + } } rcu_read_unlock(); }