X-Git-Url: http://git.efficios.com/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Fcmd.c;h=803a88090c95d28a733f7e04614238c830980055;hp=5e146931e5e31d848d99232068c9c4c8b59aca5a;hb=d40f035921a2d3be652d31bdcc250db521f96209;hpb=b0880ae543e5a637f05aeda604e958efb523a224 diff --git a/src/bin/lttng-sessiond/cmd.c b/src/bin/lttng-sessiond/cmd.c index 5e146931e..803a88090 100644 --- a/src/bin/lttng-sessiond/cmd.c +++ b/src/bin/lttng-sessiond/cmd.c @@ -34,7 +34,9 @@ #include #include #include +#include #include +#include #include "channel.h" #include "consumer.h" @@ -61,7 +63,6 @@ static pthread_mutex_t relayd_net_seq_idx_lock = PTHREAD_MUTEX_INITIALIZER; static uint64_t relayd_net_seq_idx; -static int validate_event_name(const char *); static int validate_ust_event_name(const char *); static int cmd_enable_event_internal(struct ltt_session *session, struct lttng_domain *domain, @@ -166,14 +167,14 @@ static int get_kernel_runtime_stats(struct ltt_session *session, goto end; } - ret = consumer_get_discarded_events(session->id, kchan->fd, + ret = consumer_get_discarded_events(session->id, kchan->key, session->kernel_session->consumer, discarded_events); if (ret < 0) { goto end; } - ret = consumer_get_lost_packets(session->id, kchan->fd, + ret = consumer_get_lost_packets(session->id, kchan->key, session->kernel_session->consumer, lost_packets); if (ret < 0) { @@ -243,11 +244,11 @@ end: /* * Fill lttng_channel array of all channels. */ -static void list_lttng_channels(enum lttng_domain_type domain, +static ssize_t list_lttng_channels(enum lttng_domain_type domain, struct ltt_session *session, struct lttng_channel *channels, - struct lttcomm_channel_extended *chan_exts) + struct lttng_channel_extended *chan_exts) { - int i = 0, ret; + int i = 0, ret = 0; struct ltt_kernel_channel *kchan; DBG("Listing channels for session %s", session->name); @@ -259,6 +260,10 @@ static void list_lttng_channels(enum lttng_domain_type domain, cds_list_for_each_entry(kchan, &session->kernel_session->channel_list.head, list) { uint64_t discarded_events, lost_packets; + struct lttng_channel_extended *extended; + + extended = (struct lttng_channel_extended *) + kchan->channel->attr.extended.ptr; ret = get_kernel_runtime_stats(session, kchan, &discarded_events, &lost_packets); @@ -271,6 +276,9 @@ static void list_lttng_channels(enum lttng_domain_type domain, chan_exts[i].discarded_events = discarded_events; chan_exts[i].lost_packets = lost_packets; + chan_exts[i].monitor_timer_interval = + extended->monitor_timer_interval; + chan_exts[i].blocking_timeout = 0; i++; } } @@ -316,6 +324,11 @@ static void list_lttng_channels(enum lttng_domain_type domain, break; } + chan_exts[i].monitor_timer_interval = + uchan->monitor_timer_interval; + chan_exts[i].blocking_timeout = + uchan->attr.u.s.blocking_timeout; + ret = get_ust_runtime_stats(session, uchan, &discarded_events, &lost_packets); if (ret < 0) { @@ -333,7 +346,11 @@ static void list_lttng_channels(enum lttng_domain_type domain, } end: - return; + if (ret < 0) { + return -LTTNG_ERR_FATAL; + } else { + return LTTNG_OK; + } } static void increment_extended_len(const char *filter_expression, @@ -767,17 +784,17 @@ static int add_uri_to_consumer(struct consumer_output *consumer, break; case LTTNG_DST_PATH: DBG2("Setting trace directory path from URI to %s", uri->dst.path); - memset(consumer->dst.trace_path, 0, - sizeof(consumer->dst.trace_path)); + memset(consumer->dst.session_root_path, 0, + sizeof(consumer->dst.session_root_path)); /* Explicit length checks for strcpy and strcat. */ if (strlen(uri->dst.path) + strlen(default_trace_dir) - >= sizeof(consumer->dst.trace_path)) { + >= sizeof(consumer->dst.session_root_path)) { ret = LTTNG_ERR_FATAL; goto error; } - strcpy(consumer->dst.trace_path, uri->dst.path); + strcpy(consumer->dst.session_root_path, uri->dst.path); /* Append default trace dir */ - strcat(consumer->dst.trace_path, default_trace_dir); + strcat(consumer->dst.session_root_path, default_trace_dir); /* Flag consumer as local. */ consumer->type = CONSUMER_DST_LOCAL; break; @@ -860,8 +877,11 @@ static int create_connect_relayd(struct lttng_uri *uri, /* Check relayd version */ ret = relayd_version_check(rsock); - if (ret < 0) { - ret = LTTNG_ERR_RELAYD_VERSION_FAIL; + if (ret == LTTNG_ERR_RELAYD_VERSION_FAIL) { + goto close_sock; + } else if (ret < 0) { + ERR("Unable to reach lttng-relayd"); + ret = LTTNG_ERR_RELAYD_CONNECT_FAIL; goto close_sock; } consumer->relay_major_version = rsock->major; @@ -890,6 +910,8 @@ error: /* * Connect to the relayd using URI and send the socket to the right consumer. + * + * The consumer socket lock must be held by the caller. */ static int send_consumer_relayd_socket(enum lttng_domain_type domain, unsigned int session_id, struct lttng_uri *relayd_uri, @@ -903,7 +925,7 @@ static int send_consumer_relayd_socket(enum lttng_domain_type domain, /* Connect to relayd and make version check if uri is the control. */ ret = create_connect_relayd(relayd_uri, &rsock, consumer); if (ret != LTTNG_OK) { - goto error; + goto relayd_comm_error; } assert(rsock); @@ -943,10 +965,6 @@ static int send_consumer_relayd_socket(enum lttng_domain_type domain, */ close_sock: - (void) relayd_close(rsock); - free(rsock); - -error: if (ret != LTTNG_OK) { /* * The consumer output for this session should not be used anymore @@ -955,6 +973,10 @@ error: */ consumer->enabled = 0; } + (void) relayd_close(rsock); + free(rsock); + +relayd_comm_error: return ret; } @@ -962,6 +984,8 @@ error: * Send both relayd sockets to a specific consumer and domain. This is a * helper function to facilitate sending the information to the consumer for a * session. + * + * The consumer socket lock must be held by the caller. */ static int send_consumer_relayd_sockets(enum lttng_domain_type domain, unsigned int session_id, struct consumer_output *consumer, @@ -1341,6 +1365,30 @@ int cmd_enable_channel(struct ltt_session *session, attr->attr.switch_timer_interval = 0; } + /* Check for feature support */ + switch (domain->type) { + case LTTNG_DOMAIN_KERNEL: + { + if (kernel_supports_ring_buffer_snapshot_sample_positions(kernel_tracer_fd) != 1) { + /* Sampling position of buffer is not supported */ + WARN("Kernel tracer does not support buffer monitoring. " + "Setting the monitor interval timer to 0 " + "(disabled) for channel '%s' of session '%s'", + attr-> name, session->name); + lttng_channel_set_monitor_timer_interval(attr, 0); + } + break; + } + case LTTNG_DOMAIN_UST: + case LTTNG_DOMAIN_JUL: + case LTTNG_DOMAIN_LOG4J: + case LTTNG_DOMAIN_PYTHON: + break; + default: + ret = LTTNG_ERR_UNKNOWN_DOMAIN; + goto error; + } + switch (domain->type) { case LTTNG_DOMAIN_KERNEL: { @@ -1436,10 +1484,6 @@ int cmd_disable_event(struct ltt_session *session, DBG("Disable event command for event \'%s\'", event->name); event_name = event->name; - if (validate_event_name(event_name)) { - ret = LTTNG_ERR_INVALID_EVENT_NAME; - goto error; - } /* Error out on unhandled search criteria */ if (event->loglevel_type || event->loglevel != -1 || event->enabled @@ -1613,6 +1657,16 @@ int cmd_add_context(struct ltt_session *session, enum lttng_domain_type domain, int ret, chan_kern_created = 0, chan_ust_created = 0; char *app_ctx_provider_name = NULL, *app_ctx_name = NULL; + /* + * Don't try to add a context if the session has been started at + * some point in time before. The tracer does not allow it and would + * result in a corrupted trace. + */ + if (session->has_been_started) { + ret = LTTNG_ERR_TRACE_ALREADY_STARTED; + goto end; + } + 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; @@ -1681,7 +1735,7 @@ int cmd_add_context(struct ltt_session *session, enum lttng_domain_type domain, free(attr); goto error; } - free(attr); + channel_attr_destroy(attr); chan_ust_created = 1; } @@ -1731,43 +1785,6 @@ end: return ret; } -static int validate_event_name(const char *name) -{ - int ret = 0; - const char *c = name; - const char *event_name_end = c + LTTNG_SYMBOL_NAME_LEN; - bool null_terminated = false; - - /* - * Make sure that unescaped wildcards are only used as the last - * character of the event name. - */ - while (c < event_name_end) { - switch (*c) { - case '\0': - null_terminated = true; - goto end; - case '\\': - c++; - break; - case '*': - if ((c + 1) < event_name_end && *(c + 1)) { - /* Wildcard is not the last character */ - ret = LTTNG_ERR_INVALID_EVENT_NAME; - goto end; - } - default: - break; - } - c++; - } -end: - if (!ret && !null_terminated) { - ret = LTTNG_ERR_INVALID_EVENT_NAME; - } - return ret; -} - static inline bool name_starts_with(const char *name, const char *prefix) { const size_t max_cmp_len = min(strlen(prefix), LTTNG_SYMBOL_NAME_LEN); @@ -1813,7 +1830,7 @@ static int _cmd_enable_event(struct ltt_session *session, struct lttng_event_exclusion *exclusion, int wpipe, bool internal_event) { - int ret, channel_created = 0; + int ret = 0, channel_created = 0; struct lttng_channel *attr = NULL; assert(session); @@ -1823,15 +1840,24 @@ static int _cmd_enable_event(struct ltt_session *session, /* If we have a filter, we must have its filter expression */ assert(!(!!filter_expression ^ !!filter)); - DBG("Enable event command for event \'%s\'", event->name); + /* Normalize event name as a globbing pattern */ + strutils_normalize_star_glob_pattern(event->name); - rcu_read_lock(); + /* Normalize exclusion names as globbing patterns */ + if (exclusion) { + size_t i; - ret = validate_event_name(event->name); - if (ret) { - goto error; + for (i = 0; i < exclusion->count; i++) { + char *name = LTTNG_EVENT_EXCLUSION_NAME_AT(exclusion, i); + + strutils_normalize_star_glob_pattern(name); + } } + DBG("Enable event command for event \'%s\'", event->name); + + rcu_read_lock(); + switch (domain->type) { case LTTNG_DOMAIN_KERNEL: { @@ -2179,7 +2205,7 @@ error: free(filter_expression); free(filter); free(exclusion); - free(attr); + channel_attr_destroy(attr); rcu_read_unlock(); return ret; } @@ -2948,8 +2974,8 @@ ssize_t cmd_list_channels(enum lttng_domain_type domain, if (nb_chan > 0) { const size_t channel_size = sizeof(struct lttng_channel) + - sizeof(struct lttcomm_channel_extended); - struct lttcomm_channel_extended *channel_exts; + sizeof(struct lttng_channel_extended); + struct lttng_channel_extended *channel_exts; payload_size = nb_chan * channel_size; *channels = zmalloc(payload_size); @@ -2960,7 +2986,12 @@ ssize_t cmd_list_channels(enum lttng_domain_type domain, channel_exts = ((void *) *channels) + (nb_chan * sizeof(struct lttng_channel)); - list_lttng_channels(domain, session, *channels, channel_exts); + ret = list_lttng_channels(domain, session, *channels, channel_exts); + if (ret != LTTNG_OK) { + free(*channels); + *channels = NULL; + goto end; + } } else { *channels = NULL; } @@ -3068,7 +3099,7 @@ void cmd_list_lttng_sessions(struct lttng_session *sessions, uid_t uid, sizeof(sessions[i].path), session); } else { ret = snprintf(sessions[i].path, sizeof(sessions[i].path), "%s", - session->consumer->dst.trace_path); + session->consumer->dst.session_root_path); } if (ret < 0) { PERROR("snprintf session path"); @@ -3305,7 +3336,7 @@ ssize_t cmd_snapshot_list_outputs(struct ltt_session *session, } if (output->consumer->type == CONSUMER_DST_LOCAL) { if (lttng_strncpy(list[idx].ctrl_url, - output->consumer->dst.trace_path, + output->consumer->dst.session_root_path, sizeof(list[idx].ctrl_url))) { ret = -LTTNG_ERR_INVALID; goto error; @@ -3536,7 +3567,6 @@ int cmd_regenerate_statedump(struct ltt_session *session) ret = LTTNG_ERR_SESSION_NOT_STARTED; goto end; } - ret = 0; if (session->kernel_session) { ret = kernctl_session_regenerate_statedump( @@ -3611,7 +3641,10 @@ int cmd_register_trigger(struct command_ctx *cmd_ctx, int sock, ret = notification_thread_command_register_trigger(notification_thread, trigger); + /* Ownership of trigger was transferred. */ + trigger = NULL; end: + lttng_trigger_destroy(trigger); lttng_dynamic_buffer_reset(&trigger_buffer); return ret; } @@ -3654,6 +3687,7 @@ int cmd_unregister_trigger(struct command_ctx *cmd_ctx, int sock, ret = notification_thread_command_unregister_trigger(notification_thread, trigger); end: + lttng_trigger_destroy(trigger); lttng_dynamic_buffer_reset(&trigger_buffer); return ret; } @@ -3689,10 +3723,12 @@ static int set_relayd_for_snapshot(struct consumer_output *consumer, rcu_read_lock(); cds_lfht_for_each_entry(snap_output->consumer->socks->ht, &iter.iter, socket, node.node) { + pthread_mutex_lock(socket->lock); ret = send_consumer_relayd_sockets(0, session->id, snap_output->consumer, socket, session->name, session->hostname, session->live_timer); + pthread_mutex_unlock(socket->lock); if (ret != LTTNG_OK) { rcu_read_unlock(); goto error;