X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Fust-app.c;h=f44a30d1b13774c73c66d77c3e59d9a51bb7ba72;hb=a5a212809b470aafd9c7f4cacbebfb4652feb16b;hp=6e2659c1e08f385b99ee4b55fdba5e26953e11b2;hpb=fc4b93fa8aa36b19caad0f8dc4a6a3237fcc36bf;p=lttng-tools.git diff --git a/src/bin/lttng-sessiond/ust-app.c b/src/bin/lttng-sessiond/ust-app.c index 6e2659c1e..f44a30d1b 100644 --- a/src/bin/lttng-sessiond/ust-app.c +++ b/src/bin/lttng-sessiond/ust-app.c @@ -7,11 +7,14 @@ */ #define _LGPL_SOURCE +#include +#include #include #include #include #include #include +#include #include #include #include @@ -26,12 +29,13 @@ #include #include #include -#include -#include +#include +#include #include #include #include "buffer-registry.h" +#include "condition-internal.h" #include "fd-limit.h" #include "health-sessiond.h" #include "ust-app.h" @@ -44,6 +48,8 @@ #include "notification-thread-commands.h" #include "rotate.h" #include "event.h" +#include "event-notifier-error-accounting.h" + struct lttng_ht *ust_app_ht; struct lttng_ht *ust_app_ht_by_sock; @@ -999,16 +1005,23 @@ void delete_ust_app(struct ust_app *app) */ if (app->event_notifier_group.object) { enum lttng_error_code ret_code; + enum event_notifier_error_accounting_status status; + const int event_notifier_read_fd = lttng_pipe_get_readfd( app->event_notifier_group.event_pipe); ret_code = notification_thread_command_remove_tracer_event_source( - notification_thread_handle, + the_notification_thread_handle, event_notifier_read_fd); if (ret_code != LTTNG_OK) { ERR("Failed to remove application tracer event source from notification thread"); } + status = event_notifier_error_accounting_unregister_app(app); + if (status != EVENT_NOTIFIER_ERROR_ACCOUNTING_STATUS_OK) { + ERR("Error unregistering app from event notifier error accounting"); + } + ustctl_release_object(sock, app->event_notifier_group.object); free(app->event_notifier_group.object); } @@ -1253,11 +1266,16 @@ static struct ust_app_event_notifier_rule *alloc_ust_app_event_notifier_rule( condition = lttng_trigger_get_condition(trigger); assert(condition); - assert(lttng_condition_get_type(condition) == LTTNG_CONDITION_TYPE_EVENT_RULE_HIT); + assert(lttng_condition_get_type(condition) == + LTTNG_CONDITION_TYPE_EVENT_RULE_MATCHES); - assert(LTTNG_CONDITION_STATUS_OK == lttng_condition_event_rule_get_rule(condition, &event_rule)); + assert(LTTNG_CONDITION_STATUS_OK == + lttng_condition_event_rule_matches_get_rule( + condition, &event_rule)); assert(event_rule); + ua_event_notifier_rule->error_counter_index = + lttng_condition_event_rule_matches_get_error_counter_index(condition); /* Acquire the event notifier's reference to the trigger. */ lttng_trigger_get(trigger); @@ -1585,7 +1603,7 @@ error: static int set_ust_capture(struct ust_app *app, const struct lttng_bytecode *bytecode, unsigned int capture_seqnum, - struct lttng_ust_object_data *ust_object) + struct lttng_ust_abi_object_data *ust_object) { int ret; struct lttng_ust_abi_capture_bytecode *ust_bytecode = NULL; @@ -2000,7 +2018,6 @@ static int init_ust_event_notifier_from_event_rule( struct lttng_ust_abi_event_notifier *event_notifier) { enum lttng_event_rule_status status; - enum lttng_loglevel_type loglevel_type; enum lttng_ust_abi_loglevel_type ust_loglevel_type = LTTNG_UST_ABI_LOGLEVEL_ALL; int loglevel = -1, ret = 0; const char *pattern; @@ -2023,39 +2040,40 @@ static int init_ust_event_notifier_from_event_rule( loglevel = 0; ust_loglevel_type = LTTNG_UST_ABI_LOGLEVEL_ALL; } else { - status = lttng_event_rule_tracepoint_get_pattern( - rule, &pattern); - if (status != LTTNG_EVENT_RULE_STATUS_OK) { - /* At this point, this is a fatal error. */ - abort(); - } + const struct lttng_log_level_rule *log_level_rule; - status = lttng_event_rule_tracepoint_get_log_level_type( - rule, &loglevel_type); + status = lttng_event_rule_tracepoint_get_pattern(rule, &pattern); if (status != LTTNG_EVENT_RULE_STATUS_OK) { /* At this point, this is a fatal error. */ abort(); } - switch (loglevel_type) { - case LTTNG_EVENT_LOGLEVEL_ALL: + status = lttng_event_rule_tracepoint_get_log_level_rule( + rule, &log_level_rule); + if (status == LTTNG_EVENT_RULE_STATUS_UNSET) { ust_loglevel_type = LTTNG_UST_ABI_LOGLEVEL_ALL; - break; - case LTTNG_EVENT_LOGLEVEL_RANGE: - ust_loglevel_type = LTTNG_UST_ABI_LOGLEVEL_RANGE; - break; - case LTTNG_EVENT_LOGLEVEL_SINGLE: - ust_loglevel_type = LTTNG_UST_ABI_LOGLEVEL_SINGLE; - break; - default: - /* Unknown log level specification type. */ - abort(); - } + } else if (status == LTTNG_EVENT_RULE_STATUS_OK) { + enum lttng_log_level_rule_status llr_status; + + switch (lttng_log_level_rule_get_type(log_level_rule)) { + case LTTNG_LOG_LEVEL_RULE_TYPE_EXACTLY: + ust_loglevel_type = LTTNG_UST_ABI_LOGLEVEL_SINGLE; + llr_status = lttng_log_level_rule_exactly_get_level( + log_level_rule, &loglevel); + break; + case LTTNG_LOG_LEVEL_RULE_TYPE_AT_LEAST_AS_SEVERE_AS: + ust_loglevel_type = LTTNG_UST_ABI_LOGLEVEL_RANGE; + llr_status = lttng_log_level_rule_at_least_as_severe_as_get_level( + log_level_rule, &loglevel); + break; + default: + abort(); + } - if (loglevel_type != LTTNG_EVENT_LOGLEVEL_ALL) { - status = lttng_event_rule_tracepoint_get_log_level( - rule, &loglevel); - assert(status == LTTNG_EVENT_RULE_STATUS_OK); + assert(llr_status == LTTNG_LOG_LEVEL_RULE_STATUS_OK); + } else { + /* At this point this is a fatal error. */ + abort(); } } @@ -2095,15 +2113,19 @@ static int create_ust_event_notifier(struct ust_app *app, condition = lttng_trigger_get_const_condition( ua_event_notifier_rule->trigger); assert(condition); - assert(lttng_condition_get_type(condition) == LTTNG_CONDITION_TYPE_EVENT_RULE_HIT); + assert(lttng_condition_get_type(condition) == + LTTNG_CONDITION_TYPE_EVENT_RULE_MATCHES); - condition_status = lttng_condition_event_rule_get_rule(condition, &event_rule); + condition_status = lttng_condition_event_rule_matches_get_rule( + condition, &event_rule); assert(condition_status == LTTNG_CONDITION_STATUS_OK); + assert(event_rule); assert(lttng_event_rule_get_type(event_rule) == LTTNG_EVENT_RULE_TYPE_TRACEPOINT); init_ust_event_notifier_from_event_rule(event_rule, &event_notifier); event_notifier.event.token = ua_event_notifier_rule->token; + event_notifier.error_counter_index = ua_event_notifier_rule->error_counter_index; /* Create UST event notifier against the tracer. */ pthread_mutex_lock(&app->sock_lock); @@ -2158,13 +2180,13 @@ static int create_ust_event_notifier(struct ust_app *app, } /* Set the capture bytecodes. */ - cond_status = lttng_condition_event_rule_get_capture_descriptor_count( + cond_status = lttng_condition_event_rule_matches_get_capture_descriptor_count( condition, &capture_bytecode_count); assert(cond_status == LTTNG_CONDITION_STATUS_OK); for (i = 0; i < capture_bytecode_count; i++) { const struct lttng_bytecode *capture_bytecode = - lttng_condition_event_rule_get_capture_bytecode_at_index( + lttng_condition_event_rule_matches_get_capture_bytecode_at_index( condition, i); ret = set_ust_capture(app, capture_bytecode, i, @@ -2938,7 +2960,7 @@ static int do_consumer_create_channel(struct ltt_ust_session *usess, health_code_update(); /* - * Now get the channel from the consumer. This call wil populate the stream + * Now get the channel from the consumer. This call will populate the stream * list of that channel and set the ust objects. */ if (usess->consumer->enabled) { @@ -3011,12 +3033,12 @@ error: * * Return 0 on success or else a negative value. */ -static int duplicate_channel_object(struct buffer_reg_channel *reg_chan, +static int duplicate_channel_object(struct buffer_reg_channel *buf_reg_chan, struct ust_app_channel *ua_chan) { int ret; - assert(reg_chan); + assert(buf_reg_chan); assert(ua_chan); /* Need two fds for the channel. */ @@ -3027,10 +3049,10 @@ static int duplicate_channel_object(struct buffer_reg_channel *reg_chan, } /* Duplicate object for stream once the original is in the registry. */ - ret = ustctl_duplicate_ust_object_data(&ua_chan->obj, reg_chan->obj.ust); + ret = ustctl_duplicate_ust_object_data(&ua_chan->obj, buf_reg_chan->obj.ust); if (ret < 0) { ERR("Duplicate channel obj from %p to %p failed with ret: %d", - reg_chan->obj.ust, ua_chan->obj, ret); + buf_reg_chan->obj.ust, ua_chan->obj, ret); goto error; } ua_chan->handle = ua_chan->obj->handle; @@ -3049,14 +3071,14 @@ error_fd_get: * * Return 0 on success or else a negative value. */ -static int setup_buffer_reg_streams(struct buffer_reg_channel *reg_chan, +static int setup_buffer_reg_streams(struct buffer_reg_channel *buf_reg_chan, struct ust_app_channel *ua_chan, struct ust_app *app) { int ret = 0; struct ust_app_stream *stream, *stmp; - assert(reg_chan); + assert(buf_reg_chan); assert(ua_chan); DBG2("UST app setup buffer registry stream"); @@ -3076,7 +3098,7 @@ static int setup_buffer_reg_streams(struct buffer_reg_channel *reg_chan, */ reg_stream->obj.ust = stream->obj; stream->obj = NULL; - buffer_reg_stream_add(reg_stream, reg_chan); + buffer_reg_stream_add(reg_stream, buf_reg_chan); /* We don't need the streams anymore. */ cds_list_del(&stream->list); @@ -3099,7 +3121,7 @@ static int create_buffer_reg_channel(struct buffer_reg_session *reg_sess, struct ust_app_channel *ua_chan, struct buffer_reg_channel **regp) { int ret; - struct buffer_reg_channel *reg_chan = NULL; + struct buffer_reg_channel *buf_reg_chan = NULL; assert(reg_sess); assert(ua_chan); @@ -3107,14 +3129,14 @@ static int create_buffer_reg_channel(struct buffer_reg_session *reg_sess, DBG2("UST app creating buffer registry channel for %s", ua_chan->name); /* Create buffer registry channel. */ - ret = buffer_reg_channel_create(ua_chan->tracing_channel_id, ®_chan); + ret = buffer_reg_channel_create(ua_chan->tracing_channel_id, &buf_reg_chan); if (ret < 0) { goto error_create; } - assert(reg_chan); - reg_chan->consumer_key = ua_chan->key; - reg_chan->subbuf_size = ua_chan->attr.subbuf_size; - reg_chan->num_subbuf = ua_chan->attr.num_subbuf; + assert(buf_reg_chan); + buf_reg_chan->consumer_key = ua_chan->key; + buf_reg_chan->subbuf_size = ua_chan->attr.subbuf_size; + buf_reg_chan->num_subbuf = ua_chan->attr.num_subbuf; /* Create and add a channel registry to session. */ ret = ust_registry_channel_add(reg_sess->reg.ust, @@ -3122,17 +3144,17 @@ static int create_buffer_reg_channel(struct buffer_reg_session *reg_sess, if (ret < 0) { goto error; } - buffer_reg_channel_add(reg_sess, reg_chan); + buffer_reg_channel_add(reg_sess, buf_reg_chan); if (regp) { - *regp = reg_chan; + *regp = buf_reg_chan; } return 0; error: /* Safe because the registry channel object was not added to any HT. */ - buffer_reg_channel_destroy(reg_chan, LTTNG_DOMAIN_UST); + buffer_reg_channel_destroy(buf_reg_chan, LTTNG_DOMAIN_UST); error_create: return ret; } @@ -3144,32 +3166,32 @@ error_create: * Return 0 on success else a negative value. */ static int setup_buffer_reg_channel(struct buffer_reg_session *reg_sess, - struct ust_app_channel *ua_chan, struct buffer_reg_channel *reg_chan, + struct ust_app_channel *ua_chan, struct buffer_reg_channel *buf_reg_chan, struct ust_app *app) { int ret; assert(reg_sess); - assert(reg_chan); + assert(buf_reg_chan); assert(ua_chan); assert(ua_chan->obj); DBG2("UST app setup buffer registry channel for %s", ua_chan->name); /* Setup all streams for the registry. */ - ret = setup_buffer_reg_streams(reg_chan, ua_chan, app); + ret = setup_buffer_reg_streams(buf_reg_chan, ua_chan, app); if (ret < 0) { goto error; } - reg_chan->obj.ust = ua_chan->obj; + buf_reg_chan->obj.ust = ua_chan->obj; ua_chan->obj = NULL; return 0; error: - buffer_reg_channel_remove(reg_sess, reg_chan); - buffer_reg_channel_destroy(reg_chan, LTTNG_DOMAIN_UST); + buffer_reg_channel_remove(reg_sess, buf_reg_chan); + buffer_reg_channel_destroy(buf_reg_chan, LTTNG_DOMAIN_UST); return ret; } @@ -3178,21 +3200,21 @@ error: * * Return 0 on success else a negative value. */ -static int send_channel_uid_to_ust(struct buffer_reg_channel *reg_chan, +static int send_channel_uid_to_ust(struct buffer_reg_channel *buf_reg_chan, struct ust_app *app, struct ust_app_session *ua_sess, struct ust_app_channel *ua_chan) { int ret; struct buffer_reg_stream *reg_stream; - assert(reg_chan); + assert(buf_reg_chan); assert(app); assert(ua_sess); assert(ua_chan); DBG("UST app sending buffer registry channel to ust sock %d", app->sock); - ret = duplicate_channel_object(reg_chan, ua_chan); + ret = duplicate_channel_object(buf_reg_chan, ua_chan); if (ret < 0) { goto error; } @@ -3209,8 +3231,8 @@ static int send_channel_uid_to_ust(struct buffer_reg_channel *reg_chan, health_code_update(); /* Send all streams to application. */ - pthread_mutex_lock(®_chan->stream_list_lock); - cds_list_for_each_entry(reg_stream, ®_chan->streams, lnode) { + pthread_mutex_lock(&buf_reg_chan->stream_list_lock); + cds_list_for_each_entry(reg_stream, &buf_reg_chan->streams, lnode) { struct ust_app_stream stream; ret = duplicate_stream_object(reg_stream, &stream); @@ -3236,7 +3258,7 @@ static int send_channel_uid_to_ust(struct buffer_reg_channel *reg_chan, ua_chan->is_sent = 1; error_stream_unlock: - pthread_mutex_unlock(®_chan->stream_list_lock); + pthread_mutex_unlock(&buf_reg_chan->stream_list_lock); error: return ret; } @@ -3255,10 +3277,10 @@ static int create_channel_per_uid(struct ust_app *app, { int ret; struct buffer_reg_uid *reg_uid; - struct buffer_reg_channel *reg_chan; + struct buffer_reg_channel *buf_reg_chan; struct ltt_session *session = NULL; enum lttng_error_code notification_ret; - struct ust_registry_channel *chan_reg; + struct ust_registry_channel *ust_reg_chan; assert(app); assert(usess); @@ -3275,14 +3297,14 @@ static int create_channel_per_uid(struct ust_app *app, */ assert(reg_uid); - reg_chan = buffer_reg_channel_find(ua_chan->tracing_channel_id, + buf_reg_chan = buffer_reg_channel_find(ua_chan->tracing_channel_id, reg_uid); - if (reg_chan) { + if (buf_reg_chan) { goto send_channel; } /* Create the buffer registry channel object. */ - ret = create_buffer_reg_channel(reg_uid->registry, ua_chan, ®_chan); + ret = create_buffer_reg_channel(reg_uid->registry, ua_chan, &buf_reg_chan); if (ret < 0) { ERR("Error creating the UST channel \"%s\" registry instance", ua_chan->name); @@ -3311,8 +3333,8 @@ static int create_channel_per_uid(struct ust_app *app, */ ust_registry_channel_del_free(reg_uid->registry->reg.ust, ua_chan->tracing_channel_id, false); - buffer_reg_channel_remove(reg_uid->registry, reg_chan); - buffer_reg_channel_destroy(reg_chan, LTTNG_DOMAIN_UST); + buffer_reg_channel_remove(reg_uid->registry, buf_reg_chan); + buffer_reg_channel_destroy(buf_reg_chan, LTTNG_DOMAIN_UST); goto error; } @@ -3320,7 +3342,7 @@ static int create_channel_per_uid(struct ust_app *app, * Setup the streams and add it to the session registry. */ ret = setup_buffer_reg_channel(reg_uid->registry, - ua_chan, reg_chan, app); + ua_chan, buf_reg_chan, app); if (ret < 0) { ERR("Error setting up UST channel \"%s\"", ua_chan->name); goto error; @@ -3328,19 +3350,20 @@ static int create_channel_per_uid(struct ust_app *app, /* Notify the notification subsystem of the channel's creation. */ pthread_mutex_lock(®_uid->registry->reg.ust->lock); - chan_reg = ust_registry_channel_find(reg_uid->registry->reg.ust, + ust_reg_chan = ust_registry_channel_find(reg_uid->registry->reg.ust, ua_chan->tracing_channel_id); - assert(chan_reg); - chan_reg->consumer_key = ua_chan->key; - chan_reg = NULL; + assert(ust_reg_chan); + ust_reg_chan->consumer_key = ua_chan->key; + ust_reg_chan = NULL; pthread_mutex_unlock(®_uid->registry->reg.ust->lock); notification_ret = notification_thread_command_add_channel( - notification_thread_handle, session->name, - lttng_credentials_get_uid(&ua_sess->effective_credentials), - lttng_credentials_get_gid(&ua_sess->effective_credentials), - ua_chan->name, - ua_chan->key, LTTNG_DOMAIN_UST, + the_notification_thread_handle, session->name, + lttng_credentials_get_uid( + &ua_sess->effective_credentials), + lttng_credentials_get_gid( + &ua_sess->effective_credentials), + ua_chan->name, ua_chan->key, LTTNG_DOMAIN_UST, ua_chan->attr.subbuf_size * ua_chan->attr.num_subbuf); if (notification_ret != LTTNG_OK) { ret = - (int) notification_ret; @@ -3350,7 +3373,7 @@ static int create_channel_per_uid(struct ust_app *app, send_channel: /* Send buffers to the application. */ - ret = send_channel_uid_to_ust(reg_chan, app, ua_sess, ua_chan); + ret = send_channel_uid_to_ust(buf_reg_chan, app, ua_sess, ua_chan); if (ret < 0) { if (ret != -ENOTCONN) { ERR("Error sending channel to application"); @@ -3382,7 +3405,7 @@ static int create_channel_per_pid(struct ust_app *app, enum lttng_error_code cmd_ret; struct ltt_session *session = NULL; uint64_t chan_reg_key; - struct ust_registry_channel *chan_reg; + struct ust_registry_channel *ust_reg_chan; assert(app); assert(usess); @@ -3431,17 +3454,18 @@ static int create_channel_per_pid(struct ust_app *app, chan_reg_key = ua_chan->key; pthread_mutex_lock(®istry->lock); - chan_reg = ust_registry_channel_find(registry, chan_reg_key); - assert(chan_reg); - chan_reg->consumer_key = ua_chan->key; + ust_reg_chan = ust_registry_channel_find(registry, chan_reg_key); + assert(ust_reg_chan); + ust_reg_chan->consumer_key = ua_chan->key; pthread_mutex_unlock(®istry->lock); cmd_ret = notification_thread_command_add_channel( - notification_thread_handle, session->name, - lttng_credentials_get_uid(&ua_sess->effective_credentials), - lttng_credentials_get_gid(&ua_sess->effective_credentials), - ua_chan->name, - ua_chan->key, LTTNG_DOMAIN_UST, + the_notification_thread_handle, session->name, + lttng_credentials_get_uid( + &ua_sess->effective_credentials), + lttng_credentials_get_gid( + &ua_sess->effective_credentials), + ua_chan->name, ua_chan->key, LTTNG_DOMAIN_UST, ua_chan->attr.subbuf_size * ua_chan->attr.num_subbuf); if (cmd_ret != LTTNG_OK) { ret = - (int) cmd_ret; @@ -3672,12 +3696,12 @@ int create_ust_app_event_notifier_rule(struct lttng_trigger *trigger, DBG2("UST app create token event rule completed: app = '%s' (ppid: %d), token = %" PRIu64, app->name, app->ppid, lttng_trigger_get_tracer_token(trigger)); -end: - return ret; + goto end; error: /* The RCU read side lock is already being held by the caller. */ delete_ust_app_event_notifier_rule(-1, ua_event_notifier_rule, app); +end: return ret; } @@ -3834,9 +3858,11 @@ struct ust_app *ust_app_create(struct ust_register_msg *msg, int sock) DBG3("UST app creating application for socket %d", sock); if ((msg->bits_per_long == 64 && - (uatomic_read(&ust_consumerd64_fd) == -EINVAL)) - || (msg->bits_per_long == 32 && - (uatomic_read(&ust_consumerd32_fd) == -EINVAL))) { + (uatomic_read(&the_ust_consumerd64_fd) == + -EINVAL)) || + (msg->bits_per_long == 32 && + (uatomic_read(&the_ust_consumerd32_fd) == + -EINVAL))) { ERR("Registration failed: application \"%s\" (pid: %d) has " "%d-bit long, but no consumerd for this size is available.\n", msg->name, msg->pid, msg->bits_per_long); @@ -3992,6 +4018,7 @@ int ust_app_setup_event_notifier_group(struct ust_app *app) int event_pipe_write_fd; struct lttng_ust_abi_object_data *event_notifier_group = NULL; enum lttng_error_code lttng_ret; + enum event_notifier_error_accounting_status event_notifier_error_accounting_status; assert(app); @@ -4029,8 +4056,9 @@ int ust_app_setup_event_notifier_group(struct ust_app *app) lttng_fd_put(LTTNG_FD_APPS, 1); lttng_ret = notification_thread_command_add_tracer_event_source( - notification_thread_handle, - lttng_pipe_get_readfd(app->event_notifier_group.event_pipe), + the_notification_thread_handle, + lttng_pipe_get_readfd( + app->event_notifier_group.event_pipe), LTTNG_DOMAIN_UST); if (lttng_ret != LTTNG_OK) { ERR("Failed to add tracer event source to notification thread"); @@ -4040,11 +4068,37 @@ int ust_app_setup_event_notifier_group(struct ust_app *app) /* Assign handle only when the complete setup is valid. */ app->event_notifier_group.object = event_notifier_group; + + event_notifier_error_accounting_status = + event_notifier_error_accounting_register_app(app); + if (event_notifier_error_accounting_status != EVENT_NOTIFIER_ERROR_ACCOUNTING_STATUS_OK) { + if (event_notifier_error_accounting_status == EVENT_NOTIFIER_ERROR_ACCOUNTING_STATUS_APP_DEAD) { + DBG3("Failed to setup event notifier error accounting (application is dead): app socket fd = %d", + app->sock); + ret = 0; + goto error_accounting; + } + + ERR("Failed to setup event notifier error accounting for app"); + ret = -1; + goto error_accounting; + } + return ret; +error_accounting: + lttng_ret = notification_thread_command_remove_tracer_event_source( + the_notification_thread_handle, + lttng_pipe_get_readfd( + app->event_notifier_group.event_pipe)); + if (lttng_ret != LTTNG_OK) { + ERR("Failed to remove application tracer event source from notification thread"); + } + error: ustctl_release_object(app->sock, app->event_notifier_group.object); free(app->event_notifier_group.object); + app->event_notifier_group.object = NULL; return ret; } @@ -5190,7 +5244,7 @@ int ust_app_flush_session(struct ltt_ust_session *usess) /* Flush all per UID buffers associated to that session. */ cds_list_for_each_entry(reg, &usess->buffer_reg_uid_list, lnode) { struct ust_registry_session *ust_session_reg; - struct buffer_reg_channel *reg_chan; + struct buffer_reg_channel *buf_reg_chan; struct consumer_socket *socket; /* Get consumer socket to use to push the metadata.*/ @@ -5202,13 +5256,13 @@ int ust_app_flush_session(struct ltt_ust_session *usess) } cds_lfht_for_each_entry(reg->registry->channels->ht, &iter.iter, - reg_chan, node.node) { + buf_reg_chan, node.node) { /* * The following call will print error values so the return * code is of little importance because whatever happens, we * have to try them all. */ - (void) consumer_flush_channel(socket, reg_chan->consumer_key); + (void) consumer_flush_channel(socket, buf_reg_chan->consumer_key); } ust_session_reg = reg->registry->reg.ust; @@ -5337,7 +5391,7 @@ int ust_app_clear_quiescent_session(struct ltt_ust_session *usess) */ cds_list_for_each_entry(reg, &usess->buffer_reg_uid_list, lnode) { struct consumer_socket *socket; - struct buffer_reg_channel *reg_chan; + struct buffer_reg_channel *buf_reg_chan; /* Get associated consumer socket.*/ socket = consumer_find_socket_by_bitness( @@ -5351,7 +5405,7 @@ int ust_app_clear_quiescent_session(struct ltt_ust_session *usess) } cds_lfht_for_each_entry(reg->registry->channels->ht, - &iter.iter, reg_chan, node.node) { + &iter.iter, buf_reg_chan, node.node) { /* * The following call will print error values so * the return code is of little importance @@ -5359,7 +5413,7 @@ int ust_app_clear_quiescent_session(struct ltt_ust_session *usess) * all. */ (void) consumer_clear_quiescent_channel(socket, - reg_chan->consumer_key); + buf_reg_chan->consumer_key); } } break; @@ -5620,7 +5674,7 @@ void ust_app_synchronize_event_notifier_rules(struct ust_app *app) /* Get all triggers using uid 0 (root) */ ret_code = notification_thread_command_list_triggers( - notification_thread_handle, 0, &triggers); + the_notification_thread_handle, 0, &triggers); if (ret_code != LTTNG_OK) { ret = -1; goto end; @@ -5648,12 +5702,15 @@ void ust_app_synchronize_event_notifier_rules(struct ust_app *app) token = lttng_trigger_get_tracer_token(trigger); condition = lttng_trigger_get_condition(trigger); - if (lttng_condition_get_type(condition) != LTTNG_CONDITION_TYPE_EVENT_RULE_HIT) { + if (lttng_condition_get_type(condition) != + LTTNG_CONDITION_TYPE_EVENT_RULE_MATCHES) { /* Does not apply */ continue; } - condition_status = lttng_condition_event_rule_borrow_rule_mutable(condition, &event_rule); + condition_status = + lttng_condition_event_rule_matches_borrow_rule_mutable( + condition, &event_rule); assert(condition_status == LTTNG_CONDITION_STATUS_OK); if (lttng_event_rule_get_domain_type(event_rule) == LTTNG_DOMAIN_KERNEL) { @@ -5733,38 +5790,20 @@ end: } /* - * The caller must ensure that the application is compatible and is tracked - * by the process attribute trackers. + * RCU read lock must be held by the caller. */ static -void ust_app_synchronize(struct ltt_ust_session *usess, +void ust_app_synchronize_all_channels(struct ltt_ust_session *usess, + struct ust_app_session *ua_sess, struct ust_app *app) { int ret = 0; struct cds_lfht_iter uchan_iter; struct ltt_ust_channel *uchan; - struct ust_app_session *ua_sess = NULL; - - /* - * The application's configuration should only be synchronized for - * active sessions. - */ - assert(usess->active); - ret = find_or_create_ust_app_session(usess, app, &ua_sess, NULL); - if (ret < 0) { - /* Tracer is probably gone or ENOMEM. */ - goto error; - } + assert(usess); assert(ua_sess); - - pthread_mutex_lock(&ua_sess->lock); - if (ua_sess->deleted) { - pthread_mutex_unlock(&ua_sess->lock); - goto end; - } - - rcu_read_lock(); + assert(app); cds_lfht_for_each_entry(usess->domain_global.channels->ht, &uchan_iter, uchan, node.node) { @@ -5783,7 +5822,7 @@ void ust_app_synchronize(struct ltt_ust_session *usess, app, uchan, &ua_chan); if (ret) { /* Tracer is probably gone or ENOMEM. */ - goto error_unlock; + goto end; } if (!ua_chan) { @@ -5796,7 +5835,7 @@ void ust_app_synchronize(struct ltt_ust_session *usess, ret = ust_app_channel_synchronize_event(ua_chan, uevent, ua_sess, app); if (ret) { - goto error_unlock; + goto end; } } @@ -5805,10 +5844,47 @@ void ust_app_synchronize(struct ltt_ust_session *usess, enable_ust_app_channel(ua_sess, uchan, app) : disable_ust_app_channel(ua_sess, ua_chan, app); if (ret) { - goto error_unlock; + goto end; } } } +end: + return; +} + +/* + * The caller must ensure that the application is compatible and is tracked + * by the process attribute trackers. + */ +static +void ust_app_synchronize(struct ltt_ust_session *usess, + struct ust_app *app) +{ + int ret = 0; + struct ust_app_session *ua_sess = NULL; + + /* + * The application's configuration should only be synchronized for + * active sessions. + */ + assert(usess->active); + + ret = find_or_create_ust_app_session(usess, app, &ua_sess, NULL); + if (ret < 0) { + /* Tracer is probably gone or ENOMEM. */ + goto error; + } + assert(ua_sess); + + pthread_mutex_lock(&ua_sess->lock); + if (ua_sess->deleted) { + pthread_mutex_unlock(&ua_sess->lock); + goto end; + } + + rcu_read_lock(); + + ust_app_synchronize_all_channels(usess, ua_sess, app); /* * Create the metadata for the application. This returns gracefully if a @@ -6119,7 +6195,7 @@ static int reply_ust_register_channel(int sock, int cobjd, struct ust_app_channel *ua_chan; struct ust_app_session *ua_sess; struct ust_registry_session *registry; - struct ust_registry_channel *chan_reg; + struct ust_registry_channel *ust_reg_chan; rcu_read_lock(); @@ -6160,30 +6236,30 @@ static int reply_ust_register_channel(int sock, int cobjd, pthread_mutex_lock(®istry->lock); - chan_reg = ust_registry_channel_find(registry, chan_reg_key); - assert(chan_reg); + ust_reg_chan = ust_registry_channel_find(registry, chan_reg_key); + assert(ust_reg_chan); - if (!chan_reg->register_done) { + if (!ust_reg_chan->register_done) { /* * TODO: eventually use the registry event count for * this channel to better guess header type for per-pid * buffers. */ type = USTCTL_CHANNEL_HEADER_LARGE; - chan_reg->nr_ctx_fields = nr_fields; - chan_reg->ctx_fields = fields; + ust_reg_chan->nr_ctx_fields = nr_fields; + ust_reg_chan->ctx_fields = fields; fields = NULL; - chan_reg->header_type = type; + ust_reg_chan->header_type = type; } else { /* Get current already assigned values. */ - type = chan_reg->header_type; + type = ust_reg_chan->header_type; } /* Channel id is set during the object creation. */ - chan_id = chan_reg->chan_id; + chan_id = ust_reg_chan->chan_id; /* Append to metadata */ - if (!chan_reg->metadata_dumped) { - ret_code = ust_metadata_channel_statedump(registry, chan_reg); + if (!ust_reg_chan->metadata_dumped) { + ret_code = ust_metadata_channel_statedump(registry, ust_reg_chan); if (ret_code) { ERR("Error appending channel metadata (errno = %d)", ret_code); goto reply; @@ -6206,7 +6282,7 @@ reply: } /* This channel registry registration is completed. */ - chan_reg->register_done = 1; + ust_reg_chan->register_done = 1; error: pthread_mutex_unlock(®istry->lock); @@ -6648,7 +6724,7 @@ enum lttng_error_code ust_app_snapshot_record( struct buffer_reg_uid *reg; cds_list_for_each_entry(reg, &usess->buffer_reg_uid_list, lnode) { - struct buffer_reg_channel *reg_chan; + struct buffer_reg_channel *buf_reg_chan; struct consumer_socket *socket; char pathname[PATH_MAX]; size_t consumer_path_offset = 0; @@ -6685,9 +6761,9 @@ enum lttng_error_code ust_app_snapshot_record( } /* Add the UST default trace dir to path. */ cds_lfht_for_each_entry(reg->registry->channels->ht, &iter.iter, - reg_chan, node.node) { + buf_reg_chan, node.node) { status = consumer_snapshot_channel(socket, - reg_chan->consumer_key, + buf_reg_chan->consumer_key, output, 0, usess->uid, usess->gid, &trace_path[consumer_path_offset], wait, nb_packets_per_stream); @@ -6815,19 +6891,19 @@ uint64_t ust_app_get_size_one_more_packet_per_stream( struct buffer_reg_uid *reg; cds_list_for_each_entry(reg, &usess->buffer_reg_uid_list, lnode) { - struct buffer_reg_channel *reg_chan; + struct buffer_reg_channel *buf_reg_chan; rcu_read_lock(); cds_lfht_for_each_entry(reg->registry->channels->ht, &iter.iter, - reg_chan, node.node) { - if (cur_nr_packets >= reg_chan->num_subbuf) { + buf_reg_chan, node.node) { + if (cur_nr_packets >= buf_reg_chan->num_subbuf) { /* * Don't take channel into account if we * already grab all its packets. */ continue; } - tot_size += reg_chan->subbuf_size * reg_chan->stream_count; + tot_size += buf_reg_chan->subbuf_size * buf_reg_chan->stream_count; } rcu_read_unlock(); } @@ -7051,14 +7127,9 @@ enum lttng_error_code ust_app_rotate_session(struct ltt_session *session) struct buffer_reg_uid *reg; cds_list_for_each_entry(reg, &usess->buffer_reg_uid_list, lnode) { - struct buffer_reg_channel *reg_chan; + struct buffer_reg_channel *buf_reg_chan; struct consumer_socket *socket; - if (!reg->registry->reg.ust->metadata_key) { - /* Skip since no metadata is present */ - continue; - } - /* Get consumer socket to use to push the metadata.*/ socket = consumer_find_socket_by_bitness(reg->bits_per_long, usess->consumer); @@ -7069,9 +7140,9 @@ enum lttng_error_code ust_app_rotate_session(struct ltt_session *session) /* Rotate the data channels. */ cds_lfht_for_each_entry(reg->registry->channels->ht, &iter.iter, - reg_chan, node.node) { + buf_reg_chan, node.node) { ret = consumer_rotate_channel(socket, - reg_chan->consumer_key, + buf_reg_chan->consumer_key, usess->uid, usess->gid, usess->consumer, /* is_metadata_channel */ false); @@ -7081,6 +7152,19 @@ enum lttng_error_code ust_app_rotate_session(struct ltt_session *session) } } + /* + * The metadata channel might not be present. + * + * Consumer stream allocation can be done + * asynchronously and can fail on intermediary + * operations (i.e add context) and lead to data + * channels created with no metadata channel. + */ + if (!reg->registry->reg.ust->metadata_key) { + /* Skip since no metadata is present. */ + continue; + } + (void) push_metadata(reg->registry->reg.ust, usess->consumer); ret = consumer_rotate_channel(socket, @@ -7308,7 +7392,7 @@ enum lttng_error_code ust_app_clear_session(struct ltt_session *session) struct buffer_reg_uid *reg; cds_list_for_each_entry(reg, &usess->buffer_reg_uid_list, lnode) { - struct buffer_reg_channel *reg_chan; + struct buffer_reg_channel *buf_reg_chan; struct consumer_socket *socket; /* Get consumer socket to use to push the metadata.*/ @@ -7321,9 +7405,9 @@ enum lttng_error_code ust_app_clear_session(struct ltt_session *session) /* Clear the data channels. */ cds_lfht_for_each_entry(reg->registry->channels->ht, &iter.iter, - reg_chan, node.node) { + buf_reg_chan, node.node) { ret = consumer_clear_channel(socket, - reg_chan->consumer_key); + buf_reg_chan->consumer_key); if (ret < 0) { goto error; } @@ -7460,7 +7544,7 @@ enum lttng_error_code ust_app_open_packets(struct ltt_session *session) cds_list_for_each_entry ( reg, &usess->buffer_reg_uid_list, lnode) { - struct buffer_reg_channel *reg_chan; + struct buffer_reg_channel *buf_reg_chan; struct consumer_socket *socket; socket = consumer_find_socket_by_bitness( @@ -7471,11 +7555,11 @@ enum lttng_error_code ust_app_open_packets(struct ltt_session *session) } cds_lfht_for_each_entry(reg->registry->channels->ht, - &iter.iter, reg_chan, node.node) { + &iter.iter, buf_reg_chan, node.node) { const int open_ret = consumer_open_channel_packets( socket, - reg_chan->consumer_key); + buf_reg_chan->consumer_key); if (open_ret < 0) { ret = LTTNG_ERR_UNK;