cpp-common/bt2c/fmt.hpp: use `wise_enum::string_type` in `EnableIfIsWiseEnum` definition
[babeltrace.git] / src / plugins / ctf / lttng-live / metadata.cpp
CommitLineData
7cdc2bab 1/*
0235b0db 2 * SPDX-License-Identifier: MIT
7cdc2bab 3 *
0235b0db
MJ
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
7cdc2bab
MD
7 */
8
578e048b 9#include "compat/memstream.h"
15fcc425 10#include "cpp-common/bt2c/libc-up.hpp"
e66be7c3 11#include "cpp-common/bt2s/make-unique.hpp"
7cdc2bab 12
5656cea5
PP
13#include "../common/src/metadata/tsdl/ctf-meta-configure-ir-trace.hpp"
14#include "../common/src/metadata/tsdl/decoder.hpp"
15#include "lttng-live.hpp"
c802cacb 16#include "metadata.hpp"
7cdc2bab 17
4164020e 18#define TSDL_MAGIC 0x75d11d57
7cdc2bab 19
4164020e
SM
20struct packet_header
21{
22 uint32_t magic;
23 uint8_t uuid[16];
24 uint32_t checksum;
25 uint32_t content_size;
26 uint32_t packet_size;
27 uint8_t compression_scheme;
28 uint8_t encryption_scheme;
29 uint8_t checksum_scheme;
30 uint8_t major;
31 uint8_t minor;
32} __attribute__((__packed__));
14f28187 33
4164020e 34static bool stream_classes_all_have_default_clock_class(bt_trace_class *tc,
0f5c5d5c 35 const bt2c::Logger& logger)
7cdc2bab 36{
4164020e
SM
37 uint64_t i, sc_count;
38 const bt_clock_class *cc = NULL;
39 const bt_stream_class *sc;
4164020e
SM
40
41 sc_count = bt_trace_class_get_stream_class_count(tc);
42 for (i = 0; i < sc_count; i++) {
43 sc = bt_trace_class_borrow_stream_class_by_index_const(tc, i);
44
45 BT_ASSERT(sc);
46
47 cc = bt_stream_class_borrow_default_clock_class_const(sc);
48 if (!cc) {
0f5c5d5c
SM
49 BT_CPPLOGE_APPEND_CAUSE_SPEC(logger,
50 "Stream class doesn't have a default clock class: "
51 "sc-id={}, sc-name=\"{}\"",
52 bt_stream_class_get_id(sc), bt_stream_class_get_name(sc));
60323499 53 return false;
4164020e
SM
54 }
55 }
7cdc2bab 56
60323499 57 return true;
14f28187
FD
58}
59/*
60 * Iterate over the stream classes and returns the first clock class
61 * encountered. This is useful to create message iterator inactivity message as
62 * we don't need a particular clock class.
63 */
4164020e 64static const bt_clock_class *borrow_any_clock_class(bt_trace_class *tc)
14f28187 65{
4164020e
SM
66 uint64_t i, sc_count;
67 const bt_clock_class *cc = NULL;
68 const bt_stream_class *sc;
69
70 sc_count = bt_trace_class_get_stream_class_count(tc);
71 for (i = 0; i < sc_count; i++) {
72 sc = bt_trace_class_borrow_stream_class_by_index_const(tc, i);
73 BT_ASSERT_DBG(sc);
74
75 cc = bt_stream_class_borrow_default_clock_class_const(sc);
76 if (cc) {
60323499 77 return cc;
4164020e
SM
78 }
79 }
60323499
SM
80
81 bt_common_abort();
7cdc2bab
MD
82}
83
4164020e 84enum lttng_live_iterator_status lttng_live_metadata_update(struct lttng_live_trace *trace)
7cdc2bab 85{
4164020e 86 struct lttng_live_session *session = trace->session;
e66be7c3 87 struct lttng_live_metadata *metadata = trace->metadata.get();
15fcc425 88 std::vector<char> metadataBuf;
4164020e 89 bool keep_receiving;
15fcc425 90 bt2c::FileUP fp;
4164020e 91 enum ctf_metadata_decoder_status decoder_status;
4164020e
SM
92 enum lttng_live_get_one_metadata_status metadata_status;
93
0f5c5d5c
SM
94 BT_CPPLOGD_SPEC(metadata->logger, "Updating metadata for trace: session-id={}, trace-id={}",
95 session->id, trace->id);
4164020e
SM
96
97 /* No metadata stream yet. */
98 if (!metadata) {
86080481
FD
99 if (session->closed) {
100 /*
101 * The session is closed AND we never received any
102 * metadata this indicates that we will never receive
103 * any metadata.
104 */
60323499 105 return LTTNG_LIVE_ITERATOR_STATUS_END;
86080481 106 } else if (session->new_streams_needed) {
60323499 107 return LTTNG_LIVE_ITERATOR_STATUS_AGAIN;
4164020e
SM
108 } else {
109 session->new_streams_needed = true;
60323499 110 return LTTNG_LIVE_ITERATOR_STATUS_CONTINUE;
4164020e 111 }
4164020e
SM
112 }
113
114 if (trace->metadata_stream_state != LTTNG_LIVE_METADATA_STREAM_STATE_NEEDED) {
60323499 115 return LTTNG_LIVE_ITERATOR_STATUS_OK;
4164020e
SM
116 }
117
4164020e
SM
118 keep_receiving = true;
119 /* Grab all available metadata. */
120 while (keep_receiving) {
4164020e
SM
121 /*
122 * lttng_live_get_one_metadata_packet() asks the Relay Daemon
123 * for new metadata. If new metadata is received, the function
124 * writes it to the provided file handle and updates the
125 * reply_len output parameter. We call this function in loop
126 * until it returns _END meaning that no new metadata is
127 * available.
128 * We may receive a _CLOSED status if the metadata stream we
129 * are requesting is no longer available on the relay.
130 * If we receive an _ERROR status, it means there was a
131 * networking, allocating, or some other unrecoverable error.
132 */
15fcc425 133 metadata_status = lttng_live_get_one_metadata_packet(trace, metadataBuf);
4164020e
SM
134
135 switch (metadata_status) {
136 case LTTNG_LIVE_GET_ONE_METADATA_STATUS_OK:
4164020e
SM
137 break;
138 case LTTNG_LIVE_GET_ONE_METADATA_STATUS_END:
139 keep_receiving = false;
140 break;
141 case LTTNG_LIVE_GET_ONE_METADATA_STATUS_CLOSED:
0f5c5d5c
SM
142 BT_CPPLOGD_SPEC(
143 metadata->logger,
144 "Metadata stream was closed by the Relay, the trace is no longer active: "
145 "trace-id={}, metadata-stream-id={}",
146 trace->id, metadata->stream_id);
4164020e
SM
147 /*
148 * The stream was closed and we received everything
149 * there was to receive for this metadata stream.
150 * We go on with the decoding of what we received. So
151 * that data stream can be decoded.
152 */
153 keep_receiving = false;
154 trace->metadata_stream_state = LTTNG_LIVE_METADATA_STREAM_STATE_CLOSED;
155 break;
156 case LTTNG_LIVE_GET_ONE_METADATA_STATUS_ERROR:
0f5c5d5c
SM
157 BT_CPPLOGE_APPEND_CAUSE_SPEC(metadata->logger,
158 "Error getting one trace metadata packet: trace-id={}",
159 trace->id);
60323499 160 return LTTNG_LIVE_ITERATOR_STATUS_ERROR;
4164020e
SM
161 default:
162 bt_common_abort();
163 }
164 }
165
15fcc425 166 if (metadataBuf.empty()) {
4164020e 167 if (!trace->trace) {
60323499 168 return LTTNG_LIVE_ITERATOR_STATUS_AGAIN;
4164020e
SM
169 }
170
e7401568 171 /* The relay sent zero bytes of metadata. */
4164020e 172 trace->metadata_stream_state = LTTNG_LIVE_METADATA_STREAM_STATE_NOT_NEEDED;
60323499 173 return LTTNG_LIVE_ITERATOR_STATUS_OK;
4164020e
SM
174 }
175
176 /*
177 * Open a new reading file handle on the `metadata_buf` and pass it to
178 * the metadata decoder.
179 */
15fcc425 180 fp.reset(bt_fmemopen(metadataBuf.data(), metadataBuf.size(), "rb"));
4164020e
SM
181 if (!fp) {
182 if (errno == EINTR && lttng_live_graph_is_canceled(session->lttng_live_msg_iter)) {
183 session->lttng_live_msg_iter->was_interrupted = true;
60323499 184 return LTTNG_LIVE_ITERATOR_STATUS_AGAIN;
4164020e 185 } else {
0f5c5d5c
SM
186 BT_CPPLOGE_ERRNO_APPEND_CAUSE_SPEC(metadata->logger,
187 "Cannot memory-open metadata buffer", ".");
60323499 188 return LTTNG_LIVE_ITERATOR_STATUS_ERROR;
4164020e 189 }
4164020e
SM
190 }
191
192 /*
193 * The call to ctf_metadata_decoder_append_content() will append
194 * new metadata to our current trace class.
195 */
0f5c5d5c 196 BT_CPPLOGD_SPEC(metadata->logger, "Appending new metadata to the ctf_trace class");
15fcc425 197 decoder_status = ctf_metadata_decoder_append_content(metadata->decoder.get(), fp.get());
4164020e
SM
198 switch (decoder_status) {
199 case CTF_METADATA_DECODER_STATUS_OK:
200 if (!trace->trace_class) {
201 struct ctf_trace_class *tc =
1fa280c9 202 ctf_metadata_decoder_borrow_ctf_trace_class(metadata->decoder.get());
4164020e 203
a52f1f2e 204 trace->trace_class = ctf_metadata_decoder_get_ir_trace_class(metadata->decoder.get());
7916e7eb 205 trace->trace = trace->trace_class->instantiate();
4164020e 206 if (!trace->trace) {
0f5c5d5c 207 BT_CPPLOGE_APPEND_CAUSE_SPEC(metadata->logger, "Failed to create bt_trace");
60323499 208 return LTTNG_LIVE_ITERATOR_STATUS_ERROR;
4164020e 209 }
6954b97e
SM
210
211 ctf_trace_class_configure_ir_trace(tc, *trace->trace);
212
a52f1f2e 213 if (!stream_classes_all_have_default_clock_class(trace->trace_class->libObjPtr(),
0f5c5d5c 214 metadata->logger)) {
4164020e 215 /* Error logged in function. */
60323499 216 return LTTNG_LIVE_ITERATOR_STATUS_ERROR;
4164020e 217 }
a52f1f2e 218 trace->clock_class = borrow_any_clock_class(trace->trace_class->libObjPtr());
4164020e
SM
219 }
220
e7401568 221 /* The metadata was updated successfully. */
4164020e
SM
222 trace->metadata_stream_state = LTTNG_LIVE_METADATA_STREAM_STATE_NOT_NEEDED;
223
60323499 224 return LTTNG_LIVE_ITERATOR_STATUS_OK;
4164020e 225 default:
60323499 226 return LTTNG_LIVE_ITERATOR_STATUS_ERROR;
4164020e 227 }
7cdc2bab
MD
228}
229
4164020e 230int lttng_live_metadata_create_stream(struct lttng_live_session *session, uint64_t ctf_trace_id,
44bd6303 231 uint64_t stream_id)
7cdc2bab 232{
4164020e
SM
233 struct lttng_live_trace *trace;
234
0f5c5d5c 235 ctf_metadata_decoder_config cfg {session->logger};
4164020e 236 cfg.self_comp = session->self_comp;
4164020e
SM
237 cfg.create_trace_class = true;
238
e66be7c3 239 auto metadata = bt2s::make_unique<lttng_live_metadata>(session->logger);
4164020e
SM
240 metadata->stream_id = stream_id;
241
242 metadata->decoder = ctf_metadata_decoder_create(&cfg);
243 if (!metadata->decoder) {
0f5c5d5c 244 BT_CPPLOGE_APPEND_CAUSE_SPEC(session->logger, "Failed to create CTF metadata decoder");
e66be7c3 245 return -1;
4164020e 246 }
e66be7c3 247
4164020e
SM
248 trace = lttng_live_session_borrow_or_create_trace_by_id(session, ctf_trace_id);
249 if (!trace) {
0f5c5d5c 250 BT_CPPLOGE_APPEND_CAUSE_SPEC(session->logger, "Failed to borrow trace");
e66be7c3 251 return -1;
4164020e 252 }
4164020e 253
e66be7c3
SM
254 trace->metadata = std::move(metadata);
255 return 0;
7cdc2bab 256}
This page took 0.118581 seconds and 4 git commands to generate.