From 06be99464988953e390114337ccdd20622fb50d1 Mon Sep 17 00:00:00 2001 From: Philippe Proulx Date: Tue, 9 Jul 2019 19:40:45 -0400 Subject: [PATCH] ctf: refactor metadata decoder to always have an instance This patch changes the internal `ctf` plugin's metadata decoder API so that you need to create a decoder instance to read properties instead of calling ctf_metadata_decoder_packetized_file_stream_to_buf(). Now, you create a metadata decoder, you call ctf_metadata_decoder_append_content() (similar to what was called ctf_metadata_decoder_decode()), and then you can get the decoder's current properties: * ctf_metadata_decoder_get_ir_trace_class() * ctf_metadata_decoder_borrow_ctf_trace_class() * ctf_metadata_decoder_get_byte_order() * ctf_metadata_decoder_get_uuid() * ctf_metadata_decoder_get_text() The decoder's configuration contains two new flags: `create_trace_class`: Controls whether or not ctf_metadata_decoder_append_content() invokes the AST visitor to generate trace class objects. Trace classes are not needed, for example, for the `metadata-info` query. `keep_plain_text`: Controls whether or not the decoder accumulates the metadata stream's plain text when you call ctf_metadata_decoder_append_content(). This needs to be true to use ctf_metadata_decoder_get_text(). The goal of all this is to eventually add new metadata property getters which do not need to create trace classes or to keep the metadata plain text. Signed-off-by: Philippe Proulx Change-Id: If1095da91aee0f446d7f5efcec765e5abbb2b30a Reviewed-on: https://review.lttng.org/c/babeltrace/+/1842 CI-Build: Simon Marchi Reviewed-by: Simon Marchi Tested-by: jenkins --- src/plugins/ctf/common/metadata/decoder.c | 186 +++++++++++++++++----- src/plugins/ctf/common/metadata/decoder.h | 87 +++++++--- src/plugins/ctf/fs-src/metadata.c | 11 +- src/plugins/ctf/fs-src/query.c | 86 +++------- src/plugins/ctf/lttng-live/metadata.c | 8 +- 5 files changed, 242 insertions(+), 136 deletions(-) diff --git a/src/plugins/ctf/common/metadata/decoder.c b/src/plugins/ctf/common/metadata/decoder.c index a422ad43..17b2aa4b 100644 --- a/src/plugins/ctf/common/metadata/decoder.c +++ b/src/plugins/ctf/common/metadata/decoder.c @@ -40,11 +40,14 @@ extern int yydebug; struct ctf_metadata_decoder { + struct ctf_scanner *scanner; + GString *text; struct ctf_visitor_generate_ir *visitor; bt_uuid_t uuid; bool is_uuid_set; int bo; struct ctf_metadata_decoder_config config; + struct meta_log_config log_cfg; }; struct packet_header { @@ -61,26 +64,35 @@ struct packet_header { } __attribute__((__packed__)); BT_HIDDEN -bool ctf_metadata_decoder_is_packetized(FILE *fp, int *byte_order, - bt_logging_level log_level, bt_self_component *self_comp) +int ctf_metadata_decoder_packetized_file_stream_to_buf(FILE *fp, + char **buf, int byte_order, bool *is_uuid_set, + uint8_t *uuid, bt_logging_level log_level, + bt_self_component *self_comp); + +BT_HIDDEN +int ctf_metadata_decoder_is_packetized(FILE *fp, bool *is_packetized, + int *byte_order, bt_logging_level log_level, + bt_self_component *self_comp) { uint32_t magic; size_t len; int ret = 0; + *is_packetized = false; len = fread(&magic, sizeof(magic), 1, fp); if (len != 1) { BT_COMP_LOG_CUR_LVL(BT_LOG_INFO, log_level, self_comp, "Cannot read first metadata packet header: assuming the stream is not packetized."); + ret = -1; goto end; } if (byte_order) { if (magic == TSDL_MAGIC) { - ret = 1; + *is_packetized = true; *byte_order = BYTE_ORDER; } else if (magic == GUINT32_SWAP_LE_BE(TSDL_MAGIC)) { - ret = 1; + *is_packetized = true; *byte_order = BYTE_ORDER == BIG_ENDIAN ? LITTLE_ENDIAN : BIG_ENDIAN; } @@ -113,14 +125,29 @@ struct ctf_metadata_decoder *ctf_metadata_decoder_create( goto end; } + mdec->log_cfg.log_level = config->log_level; + mdec->log_cfg.self_comp = config->self_comp; + mdec->scanner = ctf_scanner_alloc(); + if (!mdec->scanner) { + BT_COMP_LOGE("Cannot allocate a metadata lexical scanner: " + "mdec-addr=%p", mdec); + goto error; + } + + mdec->text = g_string_new(NULL); + if (!mdec->text) { + BT_COMP_LOGE("Failed to allocate one GString: " + "mdec-addr=%p", mdec); + goto error; + } + + mdec->bo = -1; mdec->config = *config; mdec->visitor = ctf_visitor_generate_ir_create(config); if (!mdec->visitor) { BT_COMP_LOGE("Failed to create a CTF IR metadata AST visitor: " "mdec-addr=%p", mdec); - ctf_metadata_decoder_destroy(mdec); - mdec = NULL; - goto end; + goto error; } BT_COMP_LOGD("Creating CTF metadata decoder: " @@ -128,6 +155,11 @@ struct ctf_metadata_decoder *ctf_metadata_decoder_create( "clock-class-offset-ns=%" PRId64 ", addr=%p", config->clock_class_offset_s, config->clock_class_offset_ns, mdec); + goto end; + +error: + ctf_metadata_decoder_destroy(mdec); + mdec = NULL; end: return mdec; @@ -140,29 +172,40 @@ void ctf_metadata_decoder_destroy(struct ctf_metadata_decoder *mdec) return; } + if (mdec->scanner) { + ctf_scanner_free(mdec->scanner); + } + + if (mdec->text) { + g_string_free(mdec->text, TRUE); + } + BT_COMP_LOGD("Destroying CTF metadata decoder: addr=%p", mdec); ctf_visitor_generate_ir_destroy(mdec->visitor); g_free(mdec); } BT_HIDDEN -enum ctf_metadata_decoder_status ctf_metadata_decoder_decode( +enum ctf_metadata_decoder_status ctf_metadata_decoder_append_content( struct ctf_metadata_decoder *mdec, FILE *fp) { enum ctf_metadata_decoder_status status = CTF_METADATA_DECODER_STATUS_OK; int ret; - struct ctf_scanner *scanner = NULL; char *buf = NULL; bool close_fp = false; - struct meta_log_config log_cfg; + long start_pos = -1; + bool is_packetized; BT_ASSERT(mdec); - log_cfg.log_level = mdec->config.log_level; - log_cfg.self_comp = mdec->config.self_comp; + ret = ctf_metadata_decoder_is_packetized(fp, &is_packetized, &mdec->bo, + mdec->config.log_level, mdec->config.self_comp); + if (ret) { + status = CTF_METADATA_DECODER_STATUS_ERROR; + goto end; + } - if (ctf_metadata_decoder_is_packetized(fp, &mdec->bo, - mdec->config.log_level, mdec->config.self_comp)) { + if (is_packetized) { BT_COMP_LOGI("Metadata stream is packetized: mdec-addr=%p", mdec); ret = ctf_metadata_decoder_packetized_file_stream_to_buf(fp, &buf, mdec->bo, &mdec->is_uuid_set, @@ -232,17 +275,15 @@ enum ctf_metadata_decoder_status ctf_metadata_decoder_decode( yydebug = 1; } - /* Allocate a scanner and append the metadata text content */ - scanner = ctf_scanner_alloc(); - if (!scanner) { - BT_COMP_LOGE("Cannot allocate a metadata lexical scanner: " - "mdec-addr=%p", mdec); - status = CTF_METADATA_DECODER_STATUS_ERROR; - goto end; + /* Save the file's position: we'll seek back to append the plain text */ + BT_ASSERT(fp); + + if (mdec->config.keep_plain_text) { + start_pos = ftell(fp); } - BT_ASSERT(fp); - ret = ctf_scanner_append_ast(scanner, fp); + /* Append the metadata text content */ + ret = ctf_scanner_append_ast(mdec->scanner, fp); if (ret) { BT_COMP_LOGE("Cannot create the metadata AST out of the metadata text: " "mdec-addr=%p", mdec); @@ -250,7 +291,28 @@ enum ctf_metadata_decoder_status ctf_metadata_decoder_decode( goto end; } - ret = ctf_visitor_semantic_check(0, &scanner->ast->root, &log_cfg); + /* We know it's complete: append plain text */ + if (mdec->config.keep_plain_text) { + BT_ASSERT(start_pos != -1); + ret = fseek(fp, start_pos, SEEK_SET); + if (ret) { + BT_COMP_LOGE("Failed to seek file: ret=%d, mdec-addr=%p", + ret, mdec); + status = CTF_METADATA_DECODER_STATUS_ERROR; + goto end; + } + + ret = bt_common_append_file_content_to_g_string(mdec->text, fp); + if (ret) { + BT_COMP_LOGE("Failed to append to current plain text: " + "ret=%d, mdec-addr=%p", ret, mdec); + status = CTF_METADATA_DECODER_STATUS_ERROR; + goto end; + } + } + + ret = ctf_visitor_semantic_check(0, &mdec->scanner->ast->root, + &mdec->log_cfg); if (ret) { BT_COMP_LOGE("Validation of the metadata semantics failed: " "mdec-addr=%p", mdec); @@ -258,29 +320,27 @@ enum ctf_metadata_decoder_status ctf_metadata_decoder_decode( goto end; } - ret = ctf_visitor_generate_ir_visit_node(mdec->visitor, - &scanner->ast->root); - switch (ret) { - case 0: - /* Success */ - break; - case -EINCOMPLETE: - BT_COMP_LOGD("While visiting metadata AST: incomplete data: " - "mdec-addr=%p", mdec); - status = CTF_METADATA_DECODER_STATUS_INCOMPLETE; - goto end; - default: - BT_COMP_LOGE("Failed to visit AST node to create CTF IR objects: " - "mdec-addr=%p, ret=%d", mdec, ret); - status = CTF_METADATA_DECODER_STATUS_IR_VISITOR_ERROR; - goto end; + if (mdec->config.create_trace_class) { + ret = ctf_visitor_generate_ir_visit_node(mdec->visitor, + &mdec->scanner->ast->root); + switch (ret) { + case 0: + /* Success */ + break; + case -EINCOMPLETE: + BT_COMP_LOGD("While visiting metadata AST: incomplete data: " + "mdec-addr=%p", mdec); + status = CTF_METADATA_DECODER_STATUS_INCOMPLETE; + goto end; + default: + BT_COMP_LOGE("Failed to visit AST node to create CTF IR objects: " + "mdec-addr=%p, ret=%d", mdec, ret); + status = CTF_METADATA_DECODER_STATUS_IR_VISITOR_ERROR; + goto end; + } } end: - if (scanner) { - ctf_scanner_free(scanner); - } - yydebug = 0; if (fp && close_fp) { @@ -299,6 +359,8 @@ BT_HIDDEN bt_trace_class *ctf_metadata_decoder_get_ir_trace_class( struct ctf_metadata_decoder *mdec) { + BT_ASSERT(mdec); + BT_ASSERT(mdec->config.create_trace_class); return ctf_visitor_generate_ir_get_ir_trace_class(mdec->visitor); } @@ -306,5 +368,41 @@ BT_HIDDEN struct ctf_trace_class *ctf_metadata_decoder_borrow_ctf_trace_class( struct ctf_metadata_decoder *mdec) { + BT_ASSERT(mdec); + BT_ASSERT(mdec->config.create_trace_class); return ctf_visitor_generate_ir_borrow_ctf_trace_class(mdec->visitor); } + +BT_HIDDEN +const char *ctf_metadata_decoder_get_text(struct ctf_metadata_decoder *mdec) +{ + BT_ASSERT(mdec); + BT_ASSERT(mdec->config.keep_plain_text); + return mdec->text->str; +} + +BT_HIDDEN +int ctf_metadata_decoder_get_byte_order(struct ctf_metadata_decoder *mdec) +{ + BT_ASSERT(mdec); + return mdec->bo; +} + +BT_HIDDEN +int ctf_metadata_decoder_get_uuid(struct ctf_metadata_decoder *mdec, + bt_uuid_t uuid) +{ + int ret = 0; + + BT_ASSERT(mdec); + + if (!mdec->is_uuid_set) { + ret = -1; + goto end; + } + + bt_uuid_copy(uuid, mdec->uuid); + +end: + return ret; +} diff --git a/src/plugins/ctf/common/metadata/decoder.h b/src/plugins/ctf/common/metadata/decoder.h index 42e79bf2..f6754899 100644 --- a/src/plugins/ctf/common/metadata/decoder.h +++ b/src/plugins/ctf/common/metadata/decoder.h @@ -21,6 +21,9 @@ #include #include "common/macros.h" +#include "common/uuid.h" + +struct ctf_trace_class; /* A CTF metadata decoder object */ struct ctf_metadata_decoder; @@ -36,13 +39,24 @@ enum ctf_metadata_decoder_status { /* Decoding configuration */ struct ctf_metadata_decoder_config { + /* Active log level to use */ bt_logging_level log_level; - /* Weak */ + /* Component to use for logging (can be `NULL`); weak */ bt_self_component *self_comp; + /* Additional clock class offset to apply */ int64_t clock_class_offset_s; int64_t clock_class_offset_ns; + + /* True to create trace class objects */ + bool create_trace_class; + + /* + * True to keep the plain text when content is appended with + * ctf_metadata_decoder_append_content(). + */ + bool keep_plain_text; }; /* @@ -63,62 +77,89 @@ void ctf_metadata_decoder_destroy( struct ctf_metadata_decoder *metadata_decoder); /* - * Decodes a new chunk of CTF metadata. + * Appends content to the metadata decoder. * * This function reads the metadata from the current position of `fp` - * until the end of this file stream. If it finds new information (new - * event class, new stream class, or new clock class), it appends this - * information to the decoder's trace object (as returned by - * ctf_metadata_decoder_get_ir_trace_class()), or it creates this trace. + * until the end of this file stream. * * The metadata can be packetized or not. * - * The metadata chunk needs to be complete and scannable, that is, - * zero or more complete top-level blocks. If it's incomplete, this + * The metadata chunk needs to be complete and lexically scannable, that + * is, zero or more complete top-level blocks. If it's incomplete, this * function returns `CTF_METADATA_DECODER_STATUS_INCOMPLETE`. If this * function returns `CTF_METADATA_DECODER_STATUS_INCOMPLETE`, then you - * need to call it again with the same metadata and more to make it + * need to call it again with the _same_ metadata and more to make it * complete. For example: * * First call: event { name = hell * Second call: event { name = hello_world; ... }; * - * If the conversion from the metadata text to CTF IR objects fails, - * this function returns `CTF_METADATA_DECODER_STATUS_IR_VISITOR_ERROR`. - * * If everything goes as expected, this function returns * `CTF_METADATA_DECODER_STATUS_OK`. */ BT_HIDDEN -enum ctf_metadata_decoder_status ctf_metadata_decoder_decode( +enum ctf_metadata_decoder_status ctf_metadata_decoder_append_content( struct ctf_metadata_decoder *metadata_decoder, FILE *fp); +/* + * Returns the trace IR trace class of this metadata decoder (new + * reference). + * + * Returns `NULL` if there's none yet or if the metadata decoder is not + * configured to create trace classes. + */ BT_HIDDEN bt_trace_class *ctf_metadata_decoder_get_ir_trace_class( struct ctf_metadata_decoder *mdec); +/* + * Returns the CTF IR trace class of this metadata decoder. + * + * Returns `NULL` if there's none yet or if the metadata decoder is not + * configured to create trace classes. + */ BT_HIDDEN struct ctf_trace_class *ctf_metadata_decoder_borrow_ctf_trace_class( struct ctf_metadata_decoder *mdec); /* - * Checks whether or not a given metadata file stream is packetized, and - * if so, sets `*byte_order` to the byte order of the first packet. + * Checks whether or not a given metadata file stream `fp` is + * packetized, setting `is_packetized` accordingly on success. On + * success, also sets `*byte_order` to the byte order of the first + * packet. + * + * This function uses `log_level` and `self_comp` for logging purposes. + * `self_comp` can be `NULL` if not available. */ BT_HIDDEN -bool ctf_metadata_decoder_is_packetized(FILE *fp, int *byte_order, - bt_logging_level log_level, +int ctf_metadata_decoder_is_packetized(FILE *fp, bool *is_packetized, + int *byte_order, bt_logging_level log_level, bt_self_component *self_comp); /* - * Decodes a packetized metadata file stream to a NULL-terminated - * text buffer using the given byte order. + * Returns the byte order of the decoder's metadata stream as set by the + * last call to ctf_metadata_decoder_append_content(). + * + * Returns -1 if unknown (plain text content). */ BT_HIDDEN -int ctf_metadata_decoder_packetized_file_stream_to_buf(FILE *fp, - char **buf, int byte_order, bool *is_uuid_set, - uint8_t *uuid, bt_logging_level log_level, - bt_self_component *self_comp); +int ctf_metadata_decoder_get_byte_order(struct ctf_metadata_decoder *mdec); + +/* + * Returns the UUID of the decoder's metadata stream as set by the last + * call to ctf_metadata_decoder_append_content(). + * + * Returns -1 if unknown (plain text content). + */ +BT_HIDDEN +int ctf_metadata_decoder_get_uuid(struct ctf_metadata_decoder *mdec, + bt_uuid_t uuid); + +/* + * Returns the metadata decoder's current metadata text. + */ +BT_HIDDEN +const char *ctf_metadata_decoder_get_text(struct ctf_metadata_decoder *mdec); static inline bool ctf_metadata_decoder_is_packet_version_valid(unsigned int major, diff --git a/src/plugins/ctf/fs-src/metadata.c b/src/plugins/ctf/fs-src/metadata.c index 42e05324..41948b79 100644 --- a/src/plugins/ctf/fs-src/metadata.c +++ b/src/plugins/ctf/fs-src/metadata.c @@ -102,12 +102,13 @@ int ctf_fs_metadata_set_trace_class( .self_comp = self_comp, .clock_class_offset_s = config ? config->clock_class_offset_s : 0, .clock_class_offset_ns = config ? config->clock_class_offset_ns : 0, + .create_trace_class = true, }; bt_logging_level log_level = ctf_fs_trace->log_level; file = get_file(ctf_fs_trace->path->str, log_level, self_comp); if (!file) { - BT_COMP_LOGE("Cannot create metadata file object"); + BT_COMP_LOGE("Cannot create metadata file object."); ret = -1; goto end; } @@ -115,15 +116,15 @@ int ctf_fs_metadata_set_trace_class( ctf_fs_trace->metadata->decoder = ctf_metadata_decoder_create( &decoder_config); if (!ctf_fs_trace->metadata->decoder) { - BT_COMP_LOGE("Cannot create metadata decoder object"); + BT_COMP_LOGE("Cannot create metadata decoder object."); ret = -1; goto end; } - ret = ctf_metadata_decoder_decode(ctf_fs_trace->metadata->decoder, - file->fp); + ret = ctf_metadata_decoder_append_content( + ctf_fs_trace->metadata->decoder, file->fp); if (ret) { - BT_COMP_LOGE("Cannot decode metadata file"); + BT_COMP_LOGE("Cannot update metadata decoder's content."); goto end; } diff --git a/src/plugins/ctf/fs-src/query.c b/src/plugins/ctf/fs-src/query.c index e817165c..62a3f8b6 100644 --- a/src/plugins/ctf/fs-src/query.c +++ b/src/plugins/ctf/fs-src/query.c @@ -59,13 +59,14 @@ bt_component_class_query_method_status metadata_info_query( bt_self_component_class_source_as_self_component_class(self_comp_class_src); bt_value *result = NULL; const bt_value *path_value = NULL; - char *metadata_text = NULL; FILE *metadata_fp = NULL; - GString *g_metadata_text = NULL; int ret; int bo; const char *path; bool is_packetized; + struct ctf_metadata_decoder *decoder = NULL; + struct ctf_metadata_decoder_config decoder_cfg = { 0 }; + enum ctf_metadata_decoder_status decoder_status; result = bt_value_map_create(); if (!result) { @@ -107,69 +108,36 @@ bt_component_class_query_method_status metadata_info_query( goto error; } - is_packetized = ctf_metadata_decoder_is_packetized(metadata_fp, + ret = ctf_metadata_decoder_is_packetized(metadata_fp, &is_packetized, &bo, log_level, NULL); - - if (is_packetized) { - ret = ctf_metadata_decoder_packetized_file_stream_to_buf( - metadata_fp, &metadata_text, bo, NULL, NULL, - log_level, NULL); - if (ret) { - BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, - "Cannot decode packetized metadata file: path=\"%s\"", - path); - goto error; - } - } else { - long filesize; - - ret = fseek(metadata_fp, 0, SEEK_END); - if (ret) { - BT_COMP_CLASS_LOGE_APPEND_CAUSE_ERRNO(self_comp_class, - "Failed to seek to the end of the metadata file", - ": path=\"%s\"", path); - goto error; - } - filesize = ftell(metadata_fp); - if (filesize < 0) { - BT_COMP_CLASS_LOGE_APPEND_CAUSE_ERRNO(self_comp_class, - "Failed to get the current position in the metadata file", - ": path=\"%s\"", path); - goto error; - } - rewind(metadata_fp); - metadata_text = malloc(filesize + 1); - if (!metadata_text) { - BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, - "Cannot allocate buffer for metadata text."); - goto error; - } - - if (fread(metadata_text, filesize, 1, metadata_fp) != 1) { - BT_COMP_CLASS_LOGE_APPEND_CAUSE_ERRNO(self_comp_class, - "Cannot read metadata file", ": path=\"%s\"", - path); - goto error; - } - - metadata_text[filesize] = '\0'; + if (ret) { + BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, + "Cannot check whether or not the metadata stream is packetized: path=\"%s\".", + path); + goto error; } - g_metadata_text = g_string_new(NULL); - if (!g_metadata_text) { + decoder_cfg.log_level = log_level; + decoder_cfg.keep_plain_text = true; + decoder = ctf_metadata_decoder_create(&decoder_cfg); + if (!decoder) { + BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, + "Cannot create metadata decoder: path=\"%s\".", path); goto error; } - if (strncmp(metadata_text, METADATA_TEXT_SIG, - sizeof(METADATA_TEXT_SIG) - 1) != 0) { - g_string_assign(g_metadata_text, METADATA_TEXT_SIG); - g_string_append(g_metadata_text, " */\n\n"); + rewind(metadata_fp); + decoder_status = ctf_metadata_decoder_append_content(decoder, + metadata_fp); + if (decoder_status) { + BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, + "Cannot update metadata decoder's content: path=\"%s\".", + path); + goto error; } - g_string_append(g_metadata_text, metadata_text); - ret = bt_value_map_insert_string_entry(result, "text", - g_metadata_text->str); + ctf_metadata_decoder_get_text(decoder)); if (ret) { BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, "Cannot insert metadata text into query result."); @@ -195,11 +163,7 @@ error: } end: - free(metadata_text); - - if (g_metadata_text) { - g_string_free(g_metadata_text, TRUE); - } + ctf_metadata_decoder_destroy(decoder); if (metadata_fp) { fclose(metadata_fp); diff --git a/src/plugins/ctf/lttng-live/metadata.c b/src/plugins/ctf/lttng-live/metadata.c index db1dfd7d..61227141 100644 --- a/src/plugins/ctf/lttng-live/metadata.c +++ b/src/plugins/ctf/lttng-live/metadata.c @@ -217,10 +217,11 @@ enum lttng_live_iterator_status lttng_live_metadata_update( } /* - * The call to ctf_metadata_decoder_decode will append new metadata to - * our current trace class. + * The call to ctf_metadata_decoder_append_content() will append + * new metadata to our current trace class. */ - decoder_status = ctf_metadata_decoder_decode(metadata->decoder, fp); + decoder_status = ctf_metadata_decoder_append_content( + metadata->decoder, fp); switch (decoder_status) { case CTF_METADATA_DECODER_STATUS_OK: if (!trace->trace_class) { @@ -288,6 +289,7 @@ int lttng_live_metadata_create_stream(struct lttng_live_session *session, .self_comp = session->self_comp, .clock_class_offset_s = 0, .clock_class_offset_ns = 0, + .create_trace_class = true, }; metadata = g_new0(struct lttng_live_metadata, 1); -- 2.34.1