From: Francis Deslauriers Date: Tue, 12 Nov 2019 22:55:25 +0000 (-0500) Subject: Fix: relayd: don't send streams if there is no metadata X-Git-Tag: v2.12.0-rc1~231 X-Git-Url: https://git.lttng.org./?a=commitdiff_plain;h=123ed7c22;p=lttng-tools.git Fix: relayd: don't send streams if there is no metadata Issue ===== When tracing short-live UST apps in per-pid mode, it happens that traces are closed before we can send all the streams to the viewer. This can place the viewer in an uncomfortable position where it is aware of data streams of a trace but can't get the metadata stream to decode the events. Solution ======== Only send the data streams if we have the metadata stream or if the metadata stream was already sent. This ensures that the viewer will either have all the {data,metadata} streams or none of them. Signed-off-by: Francis Deslauriers Signed-off-by: Jérémie Galarneau --- diff --git a/src/bin/lttng-relayd/ctf-trace.h b/src/bin/lttng-relayd/ctf-trace.h index 120549633..a448b19ce 100644 --- a/src/bin/lttng-relayd/ctf-trace.h +++ b/src/bin/lttng-relayd/ctf-trace.h @@ -57,6 +57,12 @@ struct ctf_trace { */ struct lttng_ht_node_str node; struct rcu_head rcu_node; /* For call_rcu teardown. */ + + /* + * True if the metadata stream of this trace was sent the viewer in the + * past. + */ + bool metadata_stream_sent_to_viewer; }; struct ctf_trace *ctf_trace_get_by_path_or_create(struct relay_session *session, diff --git a/src/bin/lttng-relayd/live.c b/src/bin/lttng-relayd/live.c index 3ca1797ed..6c1dbcd36 100644 --- a/src/bin/lttng-relayd/live.c +++ b/src/bin/lttng-relayd/live.c @@ -309,6 +309,7 @@ static int make_viewer_streams(struct relay_session *session, rcu_read_lock(); cds_lfht_for_each_entry(session->ctf_traces_ht->ht, &iter.iter, ctf_trace, node.node) { + bool trace_has_metadata_stream = false; struct relay_stream *stream; health_code_update(); @@ -317,6 +318,29 @@ static int make_viewer_streams(struct relay_session *session, continue; } + /* + * Iterate over all the streams of the trace to see if we have a + * metadata stream. + */ + cds_list_for_each_entry_rcu( + stream, &ctf_trace->stream_list, stream_node) + { + if (stream->is_metadata) { + trace_has_metadata_stream = true; + break; + } + } + + /* + * If there is no metadata stream in this trace at the moment + * and we never sent one to the viewer, skip the trace. We + * accept that the viewer will not see this trace at all. + */ + if (!trace_has_metadata_stream && + !ctf_trace->metadata_stream_sent_to_viewer) { + break; + } + cds_list_for_each_entry_rcu(stream, &ctf_trace->stream_list, stream_node) { struct relay_viewer_stream *vstream; @@ -331,6 +355,15 @@ static int make_viewer_streams(struct relay_session *session, } vstream = viewer_stream_get_by_id(stream->stream_handle); if (!vstream) { + /* + * Save that we sent the metadata stream to the + * viewer. So that we know what trace the viewer + * is aware of. + */ + if (stream->is_metadata) { + ctf_trace->metadata_stream_sent_to_viewer = + true; + } vstream = viewer_stream_create(stream, viewer_trace_chunk, seek_t); if (!vstream) {