X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Fust-app.c;h=65d27bbe923f094d0b4a5c7974b9cc37900c2c61;hb=e1ac6bb9dd3fc4f03a2c102b8233900e2822f875;hp=d297cf0a30cb68f34b123576aacd6893edd9b5a7;hpb=3177a074b69835f56bef5787c2265d79248a3f8f;p=lttng-tools.git diff --git a/src/bin/lttng-sessiond/ust-app.c b/src/bin/lttng-sessiond/ust-app.c index d297cf0a3..65d27bbe9 100644 --- a/src/bin/lttng-sessiond/ust-app.c +++ b/src/bin/lttng-sessiond/ust-app.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include @@ -38,13 +37,18 @@ #include "health-sessiond.h" #include "ust-app.h" #include "ust-consumer.h" -#include "ust-ctl.h" +#include "lttng-ust-ctl.h" +#include "lttng-ust-error.h" #include "utils.h" #include "session.h" #include "lttng-sessiond.h" #include "notification-thread-commands.h" #include "rotate.h" +struct lttng_ht *ust_app_ht; +struct lttng_ht *ust_app_ht_by_sock; +struct lttng_ht *ust_app_ht_by_notify_sock; + static int ust_app_flush_app_session(struct ust_app *app, struct ust_app_session *ua_sess); @@ -741,6 +745,10 @@ error: * nullified. The session lock MUST be held unless the application is * in the destroy path. * + * Do not hold the registry lock while communicating with the consumerd, because + * doing so causes inter-process deadlocks between consumerd and sessiond with + * the metadata request notification. + * * Return 0 on success else a negative value. */ static int close_metadata(struct ust_registry_session *registry, @@ -748,6 +756,8 @@ static int close_metadata(struct ust_registry_session *registry, { int ret; struct consumer_socket *socket; + uint64_t metadata_key; + bool registry_was_already_closed; assert(registry); assert(consumer); @@ -755,8 +765,19 @@ static int close_metadata(struct ust_registry_session *registry, rcu_read_lock(); pthread_mutex_lock(®istry->lock); + metadata_key = registry->metadata_key; + registry_was_already_closed = registry->metadata_closed; + if (metadata_key != 0) { + /* + * Metadata closed. Even on error this means that the consumer + * is not responding or not found so either way a second close + * should NOT be emit for this registry. + */ + registry->metadata_closed = 1; + } + pthread_mutex_unlock(®istry->lock); - if (!registry->metadata_key || registry->metadata_closed) { + if (metadata_key == 0 || registry_was_already_closed) { ret = 0; goto end; } @@ -766,23 +787,15 @@ static int close_metadata(struct ust_registry_session *registry, consumer); if (!socket) { ret = -1; - goto error; + goto end; } - ret = consumer_close_metadata(socket, registry->metadata_key); + ret = consumer_close_metadata(socket, metadata_key); if (ret < 0) { - goto error; + goto end; } -error: - /* - * Metadata closed. Even on error this means that the consumer is not - * responding or not found so either way a second close should NOT be emit - * for this registry. - */ - registry->metadata_closed = 1; end: - pthread_mutex_unlock(®istry->lock); rcu_read_unlock(); return ret; } @@ -1100,7 +1113,7 @@ struct ust_app_event *alloc_ust_app_event(char *name, /* Init most of the default value by allocating and zeroing */ ua_event = zmalloc(sizeof(struct ust_app_event)); if (ua_event == NULL) { - PERROR("malloc"); + PERROR("Failed to allocate ust_app_event structure"); goto error; } @@ -2485,7 +2498,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) { @@ -3133,7 +3146,7 @@ int create_ust_app_event(struct ust_app_session *ua_sess, ua_event = alloc_ust_app_event(uevent->attr.name, &uevent->attr); if (ua_event == NULL) { - /* Only malloc can failed so something is really wrong */ + /* Only failure mode of alloc_ust_app_event(). */ ret = -ENOMEM; goto end; } @@ -4109,11 +4122,14 @@ int ust_app_channel_create(struct ltt_ust_session *usess, ret = ust_app_channel_allocate(ua_sess, uchan, LTTNG_UST_CHAN_PER_CPU, usess, &ua_chan); - if (ret == 0) { - ret = ust_app_channel_send(app, usess, - ua_sess, ua_chan); - } else { - goto end; + if (ret < 0) { + goto error; + } + + ret = ust_app_channel_send(app, usess, + ua_sess, ua_chan); + if (ret) { + goto error; } /* Add contexts. */ @@ -4121,10 +4137,12 @@ int ust_app_channel_create(struct ltt_ust_session *usess, ret = create_ust_app_channel_context(ua_chan, &uctx->ctx, app); if (ret) { - goto end; + goto error; } } } + +error: if (ret < 0) { switch (ret) { case -ENOTCONN: @@ -4140,7 +4158,7 @@ int ust_app_channel_create(struct ltt_ust_session *usess, break; } } -end: + if (ret == 0 && _ua_chan) { /* * Only return the application's channel on success. Note @@ -4212,7 +4230,7 @@ int ust_app_create_channel_glb(struct ltt_ust_session *usess, if (session_was_created) { destroy_app_session(app, ua_sess); } - goto error_rcu_unlock; + /* Continue to the next application. */ } } @@ -4412,15 +4430,6 @@ int ust_app_start_trace(struct ltt_ust_session *usess, struct ust_app *app) goto skip_setup; } - /* - * Create the metadata for the application. This returns gracefully if a - * metadata was already set for the session. - */ - ret = create_ust_app_metadata(ua_sess, app, usess->consumer); - if (ret < 0) { - goto error_unlock; - } - health_code_update(); skip_setup: @@ -5086,6 +5095,7 @@ void ust_app_synchronize(struct ltt_ust_session *usess, } rcu_read_lock(); + cds_lfht_for_each_entry(usess->domain_global.channels->ht, &uchan_iter, uchan, node.node) { struct ust_app_channel *ua_chan; @@ -5129,6 +5139,21 @@ void ust_app_synchronize(struct ltt_ust_session *usess, } } } + + /* + * Create the metadata for the application. This returns gracefully if a + * metadata was already set for the session. + * + * The metadata channel must be created after the data channels as the + * consumer daemon assumes this ordering. When interacting with a relay + * daemon, the consumer will use this assumption to send the + * "STREAMS_SENT" message to the relay daemon. + */ + ret = create_ust_app_metadata(ua_sess, app, usess->consumer); + if (ret < 0) { + goto error_unlock; + } + rcu_read_unlock(); end: @@ -6338,6 +6363,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, @@ -6477,6 +6515,17 @@ enum lttng_error_code ust_app_create_channel_subdirectories( { struct ust_app *app; + /* + * Create the toplevel ust/ directory in case no apps are running. + */ + chunk_status = lttng_trace_chunk_create_subdirectory( + usess->current_trace_chunk, + DEFAULT_UST_TRACE_DIR); + if (chunk_status != LTTNG_TRACE_CHUNK_STATUS_OK) { + ret = LTTNG_ERR_CREATE_DIR_FAIL; + goto error; + } + cds_lfht_for_each_entry(ust_app_ht->ht, &iter.iter, app, pid_n.node) { struct ust_app_session *ua_sess;