Fix: relayd: don't send streams if there is no metadata
authorFrancis Deslauriers <francis.deslauriers@efficios.com>
Tue, 12 Nov 2019 22:55:25 +0000 (17:55 -0500)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Fri, 22 Nov 2019 23:14:30 +0000 (18:14 -0500)
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 <francis.deslauriers@efficios.com>
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
src/bin/lttng-relayd/ctf-trace.h
src/bin/lttng-relayd/live.c

index 120549633c082fa9a6b00313787322f826be1863..a448b19cefa0cbc923aeea3e8e94630fed11c1d6 100644 (file)
@@ -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,
index 3ca1797ed9b07b12468840f0bcd963709f72a92b..6c1dbcd36763f5c7309ab4e5b08d12c1fd528860 100644 (file)
@@ -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) {
This page took 0.029244 seconds and 5 git commands to generate.