From: David Goulet Date: Fri, 31 Oct 2014 17:23:29 +0000 (-0400) Subject: Fix: UST consumer sync all available metadata X-Git-Tag: v2.7.0-rc1~239 X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=commitdiff_plain;h=e5ca40eeb602ab82458d902b0ba4de87204d23b3 Fix: UST consumer sync all available metadata In live mode, the sync metadata function was only working on one single metadata stream of a given session ID. However, we can have multiple metadata stream for the same session ID thus failing to send the data in live mode correctly for the other streams. This fixes it by simply iterating over all metadata stream for a session ID and syncing them all. Signed-off-by: David Goulet --- diff --git a/src/common/consumer-stream.c b/src/common/consumer-stream.c index a9e4deef5..8fe02e74e 100644 --- a/src/common/consumer-stream.c +++ b/src/common/consumer-stream.c @@ -391,45 +391,20 @@ error: } /* - * Synchronize the metadata using a given session ID. A successful acquisition - * of a metadata stream will trigger a request to the session daemon and a - * snapshot so the metadata thread can consume it. + * Actually do the metadata sync using the given metadata stream. * - * This function call is a rendez-vous point between the metadata thread and - * the data thread. - * - * Return 0 on success or else a negative value. + * Return 0 on success else a negative value. ENODATA can be returned also + * indicating that there is no metadata available for that stream. */ -int consumer_stream_sync_metadata(struct lttng_consumer_local_data *ctx, - uint64_t session_id) +static int do_sync_metadata(struct lttng_consumer_stream *metadata, + struct lttng_consumer_local_data *ctx) { int ret; - struct lttng_consumer_stream *metadata = NULL, *stream = NULL; - struct lttng_ht_iter iter; - struct lttng_ht *ht; + assert(metadata); + assert(metadata->metadata_flag); assert(ctx); - /* Ease our life a bit. */ - ht = consumer_data.stream_list_ht; - - rcu_read_lock(); - - /* Search the metadata associated with the session id of the given stream. */ - - cds_lfht_for_each_entry_duplicate(ht->ht, - ht->hash_fct(&session_id, lttng_ht_seed), ht->match_fct, - &session_id, &iter.iter, stream, node_session_id.node) { - if (stream->metadata_flag) { - metadata = stream; - break; - } - } - if (!metadata) { - ret = 0; - goto end_unlock_rcu; - } - /* * In UST, since we have to write the metadata from the cache packet * by packet, we might need to start this procedure multiple times @@ -515,12 +490,61 @@ int consumer_stream_sync_metadata(struct lttng_consumer_local_data *ctx, pthread_mutex_unlock(&metadata->metadata_rdv_lock); } while (ret == EAGAIN); - ret = 0; - goto end_unlock_rcu; + /* Success */ + return 0; end_unlock_mutex: pthread_mutex_unlock(&metadata->lock); -end_unlock_rcu: + return ret; +} + +/* + * Synchronize the metadata using a given session ID. A successful acquisition + * of a metadata stream will trigger a request to the session daemon and a + * snapshot so the metadata thread can consume it. + * + * This function call is a rendez-vous point between the metadata thread and + * the data thread. + * + * Return 0 on success or else a negative value. + */ +int consumer_stream_sync_metadata(struct lttng_consumer_local_data *ctx, + uint64_t session_id) +{ + int ret; + struct lttng_consumer_stream *stream = NULL; + struct lttng_ht_iter iter; + struct lttng_ht *ht; + + assert(ctx); + + /* Ease our life a bit. */ + ht = consumer_data.stream_list_ht; + + rcu_read_lock(); + + /* Search the metadata associated with the session id of the given stream. */ + + cds_lfht_for_each_entry_duplicate(ht->ht, + ht->hash_fct(&session_id, lttng_ht_seed), ht->match_fct, + &session_id, &iter.iter, stream, node_session_id.node) { + if (!stream->metadata_flag) { + continue; + } + + ret = do_sync_metadata(stream, ctx); + if (ret < 0) { + goto end; + } + } + + /* + * Force return code to 0 (success) since ret might be ENODATA for instance + * which is not an error but rather that we should come back. + */ + ret = 0; + +end: rcu_read_unlock(); return ret; }