.gitignore: add some missing files
[babeltrace.git] / src / plugins / ctf / lttng-live / metadata.cpp
1 /*
2 * SPDX-License-Identifier: MIT
3 *
4 * Copyright 2019 Francis Deslauriers <francis.deslauriers@efficios.com>
5 * Copyright 2016 Philippe Proulx <pproulx@efficios.com>
6 * Copyright 2010-2011 EfficiOS Inc. and Linux Foundation
7 */
8
9 #include "cpp-common/bt2s/make-unique.hpp"
10
11 #include "../common/src/metadata/tsdl/ctf-meta-configure-ir-trace.hpp"
12 #include "lttng-live.hpp"
13 #include "metadata.hpp"
14
15 #define TSDL_MAGIC 0x75d11d57
16
17 struct packet_header
18 {
19 uint32_t magic;
20 uint8_t uuid[16];
21 uint32_t checksum;
22 uint32_t content_size;
23 uint32_t packet_size;
24 uint8_t compression_scheme;
25 uint8_t encryption_scheme;
26 uint8_t checksum_scheme;
27 uint8_t major;
28 uint8_t minor;
29 } __attribute__((__packed__));
30
31 static bool stream_classes_all_have_default_clock_class(bt2::ConstTraceClass tc,
32 const bt2c::Logger& logger)
33 {
34 for (std::uint64_t i = 0; i < tc.length(); ++i) {
35 auto sc = tc[i];
36 auto cc = sc.defaultClockClass();
37
38 if (!cc) {
39 BT_CPPLOGE_APPEND_CAUSE_SPEC(logger,
40 "Stream class doesn't have a default clock class: "
41 "sc-id={}, sc-name=\"{}\"",
42 sc.id(), sc.name());
43 return false;
44 }
45 }
46
47 return true;
48 }
49 /*
50 * Iterate over the stream classes and returns the first clock class
51 * encountered. This is useful to create message iterator inactivity message as
52 * we don't need a particular clock class.
53 */
54 static bt2::ConstClockClass borrow_any_clock_class(bt2::ConstTraceClass tc)
55 {
56 return *tc[0].defaultClockClass();
57 }
58
59 enum lttng_live_iterator_status lttng_live_metadata_update(struct lttng_live_trace *trace)
60 {
61 struct lttng_live_session *session = trace->session;
62 struct lttng_live_metadata *metadata = trace->metadata.get();
63 bool keep_receiving;
64 enum lttng_live_get_one_metadata_status metadata_status;
65
66 BT_CPPLOGD_SPEC(metadata->logger, "Updating metadata for trace: session-id={}, trace-id={}",
67 session->id, trace->id);
68
69 /* No metadata stream yet. */
70 if (!metadata) {
71 if (session->closed) {
72 /*
73 * The session is closed AND we never received any
74 * metadata this indicates that we will never receive
75 * any metadata.
76 */
77 return LTTNG_LIVE_ITERATOR_STATUS_END;
78 } else if (session->new_streams_needed) {
79 return LTTNG_LIVE_ITERATOR_STATUS_AGAIN;
80 } else {
81 session->new_streams_needed = true;
82 return LTTNG_LIVE_ITERATOR_STATUS_CONTINUE;
83 }
84 }
85
86 if (trace->metadata_stream_state != LTTNG_LIVE_METADATA_STREAM_STATE_NEEDED) {
87 return LTTNG_LIVE_ITERATOR_STATUS_OK;
88 }
89
90 keep_receiving = true;
91 /* Grab all available metadata. */
92 std::vector<uint8_t> metadataBuf;
93 while (keep_receiving) {
94 /*
95 * lttng_live_get_one_metadata_packet() asks the Relay Daemon
96 * for new metadata. If new metadata is received, the function
97 * writes it to the provided file handle and updates the
98 * reply_len output parameter. We call this function in loop
99 * until it returns _END meaning that no new metadata is
100 * available.
101 * We may receive a _CLOSED status if the metadata stream we
102 * are requesting is no longer available on the relay.
103 * If we receive an _ERROR status, it means there was a
104 * networking, allocating, or some other unrecoverable error.
105 */
106 metadata_status = lttng_live_get_one_metadata_packet(trace, metadataBuf);
107
108 switch (metadata_status) {
109 case LTTNG_LIVE_GET_ONE_METADATA_STATUS_OK:
110 break;
111 case LTTNG_LIVE_GET_ONE_METADATA_STATUS_END:
112 keep_receiving = false;
113 break;
114 case LTTNG_LIVE_GET_ONE_METADATA_STATUS_CLOSED:
115 BT_CPPLOGD_SPEC(
116 metadata->logger,
117 "Metadata stream was closed by the Relay, the trace is no longer active: "
118 "trace-id={}, metadata-stream-id={}",
119 trace->id, metadata->stream_id);
120 /*
121 * The stream was closed and we received everything
122 * there was to receive for this metadata stream.
123 * We go on with the decoding of what we received. So
124 * that data stream can be decoded.
125 */
126 keep_receiving = false;
127 trace->metadata_stream_state = LTTNG_LIVE_METADATA_STREAM_STATE_CLOSED;
128 break;
129 case LTTNG_LIVE_GET_ONE_METADATA_STATUS_ERROR:
130 BT_CPPLOGE_APPEND_CAUSE_SPEC(metadata->logger,
131 "Error getting one trace metadata packet: trace-id={}",
132 trace->id);
133 return LTTNG_LIVE_ITERATOR_STATUS_ERROR;
134 default:
135 bt_common_abort();
136 }
137 }
138
139 if (metadataBuf.empty()) {
140 if (!trace->trace) {
141 return LTTNG_LIVE_ITERATOR_STATUS_AGAIN;
142 }
143
144 /* The relay sent zero bytes of metadata. */
145 trace->metadata_stream_state = LTTNG_LIVE_METADATA_STREAM_STATE_NOT_NEEDED;
146 return LTTNG_LIVE_ITERATOR_STATUS_OK;
147 }
148
149 /*
150 * The call to ctf_metadata_decoder_append_content() will append
151 * new metadata to our current trace class.
152 */
153 BT_CPPLOGD_SPEC(metadata->logger, "Appending new metadata to the ctf_trace class");
154 metadata->parseSection(metadataBuf);
155 if (!trace->trace) {
156 const ctf::src::TraceCls *ctfTraceCls = metadata->traceCls();
157 BT_ASSERT(ctfTraceCls);
158 bt2::OptionalBorrowedObject<bt2::TraceClass> irTraceCls = ctfTraceCls->libCls();
159
160 if (irTraceCls) {
161 trace->trace = irTraceCls->instantiate();
162
163 ctf_trace_class_configure_ir_trace(*ctfTraceCls, *trace->trace,
164 metadata->selfComp().graphMipVersion(),
165 metadata->logger);
166
167 if (!stream_classes_all_have_default_clock_class(trace->trace->cls(),
168 metadata->logger)) {
169 /* Error logged in function. */
170 return LTTNG_LIVE_ITERATOR_STATUS_ERROR;
171 }
172
173 trace->clock_class = borrow_any_clock_class(trace->trace->cls());
174 }
175 }
176
177 /* The metadata was updated successfully. */
178 trace->metadata_stream_state = LTTNG_LIVE_METADATA_STREAM_STATE_NOT_NEEDED;
179
180 return LTTNG_LIVE_ITERATOR_STATUS_OK;
181 }
182
183 int lttng_live_metadata_create_stream(struct lttng_live_session *session, uint64_t ctf_trace_id,
184 uint64_t stream_id)
185 {
186 auto metadata = bt2s::make_unique<lttng_live_metadata>(session->selfComp, session->logger);
187
188 metadata->stream_id = stream_id;
189
190 const auto trace = lttng_live_session_borrow_or_create_trace_by_id(session, ctf_trace_id);
191
192 if (!trace) {
193 BT_CPPLOGE_APPEND_CAUSE_SPEC(session->logger, "Failed to borrow trace");
194 return -1;
195 }
196
197 trace->metadata = std::move(metadata);
198 return 0;
199 }
This page took 0.037417 seconds and 5 git commands to generate.