X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Fust-app.c;h=17e33a1087dc837593520a2eeb3249267a5096f1;hb=822abc2fe108d5eec368de0f458e8d172a3e5d80;hp=e3995bdf612d0e82a2fea38e0c4008fd4795b8f2;hpb=fb83fe64f250bec7416f18891a8264450c61ead3;p=lttng-tools.git diff --git a/src/bin/lttng-sessiond/ust-app.c b/src/bin/lttng-sessiond/ust-app.c index e3995bdf6..17e33a108 100644 --- a/src/bin/lttng-sessiond/ust-app.c +++ b/src/bin/lttng-sessiond/ust-app.c @@ -376,6 +376,8 @@ void delete_ust_app_channel_rcu(struct rcu_head *head) * Extract the lost packet or discarded events counter when the channel is * being deleted and store the value in the parent channel so we can * access it from lttng list and at stop/destroy. + * + * The session list lock must be held by the caller. */ static void save_per_pid_lost_discarded_counters(struct ust_app_channel *ua_chan) @@ -390,12 +392,22 @@ void save_per_pid_lost_discarded_counters(struct ust_app_channel *ua_chan) rcu_read_lock(); session = session_find_by_id(ua_chan->session->tracing_id); - if (!session) { - ERR("Missing LTT session to get discarded events"); - goto end; - } - if (!session->ust_session) { - ERR("Missing UST session to get discarded events"); + if (!session || !session->ust_session) { + /* + * Not finding the session is not an error because there are + * multiple ways the channels can be torn down. + * + * 1) The session daemon can initiate the destruction of the + * ust app session after receiving a destroy command or + * during its shutdown/teardown. + * 2) The application, since we are in per-pid tracing, is + * unregistering and tearing down its ust app session. + * + * Both paths are protected by the session list lock which + * ensures that the accounting of lost packets and discarded + * events is done exactly once. The session is then unpublished + * from the session list, resulting in this condition. + */ goto end; } @@ -426,6 +438,8 @@ end: /* * Delete ust app channel safely. RCU read lock must be held before calling * this function. + * + * The session list lock must be held by the caller. */ static void delete_ust_app_channel(int sock, struct ust_app_channel *ua_chan, @@ -537,7 +551,7 @@ ssize_t ust_app_push_metadata(struct ust_registry_session *registry, char *metadata_str = NULL; size_t len, offset, new_metadata_len_sent; ssize_t ret_val; - uint64_t metadata_key; + uint64_t metadata_key, metadata_version; assert(registry); assert(socket); @@ -567,6 +581,7 @@ ssize_t ust_app_push_metadata(struct ust_registry_session *registry, offset = registry->metadata_len_sent; len = registry->metadata_len - registry->metadata_len_sent; new_metadata_len_sent = registry->metadata_len; + metadata_version = registry->metadata_version; if (len == 0) { DBG3("No metadata to push for metadata key %" PRIu64, registry->metadata_key); @@ -603,7 +618,7 @@ push_data: * different bidirectionnal communication sockets. */ ret = consumer_push_metadata(socket, metadata_key, - metadata_str, len, offset); + metadata_str, len, offset, metadata_version); pthread_mutex_lock(®istry->lock); if (ret < 0) { /* @@ -787,6 +802,8 @@ void delete_ust_app_session_rcu(struct rcu_head *head) /* * Delete ust app session safely. RCU read lock must be held before calling * this function. + * + * The session list lock must be held by the caller. */ static void delete_ust_app_session(int sock, struct ust_app_session *ua_sess, @@ -870,6 +887,11 @@ void delete_ust_app(struct ust_app *app) int ret, sock; struct ust_app_session *ua_sess, *tmp_ua_sess; + /* + * The session list lock must be held during this function to guarantee + * the existence of ua_sess. + */ + session_lock_list(); /* Delete ust app sessions info */ sock = app->sock; app->sock = -1; @@ -908,6 +930,7 @@ void delete_ust_app(struct ust_app *app) DBG2("UST app pid %d deleted", app->pid); free(app); + session_unlock_list(); } /* @@ -928,6 +951,8 @@ void delete_ust_app_rcu(struct rcu_head *head) /* * Delete the session from the application ht and delete the data structure by * freeing every object inside and releasing them. + * + * The session list lock must be held by the caller. */ static void destroy_app_session(struct ust_app *app, struct ust_app_session *ua_sess) @@ -2796,9 +2821,6 @@ static int send_channel_uid_to_ust(struct buffer_reg_channel *reg_chan, (void) release_ust_app_stream(-1, &stream, app); if (ret == -EPIPE || ret == -LTTNG_UST_ERR_EXITING) { ret = -ENOTCONN; /* Caused by app exiting. */ - goto error_stream_unlock; - } else if (ret < 0) { - goto error_stream_unlock; } goto error_stream_unlock; } @@ -5701,7 +5723,6 @@ int ust_app_snapshot_record(struct ltt_ust_session *usess, uint64_t nb_packets_per_stream) { int ret = 0; - unsigned int snapshot_done = 0; struct lttng_ht_iter iter; struct ust_app *app; char pathname[PATH_MAX]; @@ -5753,7 +5774,6 @@ int ust_app_snapshot_record(struct ltt_ust_session *usess, if (ret < 0) { goto error; } - snapshot_done = 1; } break; } @@ -5806,7 +5826,6 @@ int ust_app_snapshot_record(struct ltt_ust_session *usess, if (ret < 0) { goto error; } - snapshot_done = 1; } break; } @@ -5815,15 +5834,6 @@ int ust_app_snapshot_record(struct ltt_ust_session *usess, break; } - if (!snapshot_done) { - /* - * If no snapshot was made and we are not in the error path, this means - * that there are no buffers thus no (prior) application to snapshot - * data from so we have simply NO data. - */ - ret = -ENODATA; - } - error: rcu_read_unlock(); return ret; @@ -5920,9 +5930,11 @@ int ust_app_uid_get_channel_runtime_stats(uint64_t ust_session_id, if (overwrite) { ret = consumer_get_lost_packets(ust_session_id, consumer_chan_key, consumer, lost); + *discarded = 0; } else { ret = consumer_get_discarded_events(ust_session_id, consumer_chan_key, consumer, discarded); + *lost = 0; } end: @@ -5955,7 +5967,7 @@ int ust_app_pid_get_channel_runtime_stats(struct ltt_ust_session *usess, } /* Get channel */ - lttng_ht_lookup(ua_sess->channels, (void *)uchan->name, &uiter); + lttng_ht_lookup(ua_sess->channels, (void *) uchan->name, &uiter); ua_chan_node = lttng_ht_iter_get_node_str(&uiter); /* If the session is found for the app, the channel must be there */ assert(ua_chan_node); @@ -5965,13 +5977,14 @@ int ust_app_pid_get_channel_runtime_stats(struct ltt_ust_session *usess, if (overwrite) { ret = consumer_get_lost_packets(usess->id, ua_chan->key, consumer, lost); + *discarded = 0; goto end; } else { ret = consumer_get_discarded_events(usess->id, ua_chan->key, consumer, discarded); + *lost = 0; goto end; } - goto end; } end: