From 7bf5af54b2e6cf5ed45f3416f96d837a120467ca Mon Sep 17 00:00:00 2001 From: Philippe Proulx Date: Thu, 15 Jun 2017 21:36:57 -0400 Subject: [PATCH] ctf: remove strict metadata mode, update automatic CC mapping behaviour MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Update the automatic mapping of specific fields to clock classes when no explicit mapping is found in the integer field type to follow this: | 0 CCs | 1 CC | 2+ CCs -------------------------------------------------------------------- FT is mapped | Unreachable | OK as is | OK as is FT is not mapped | Map to auto 1 GHz | Map to single CC | Error The (FT is not mapped, 0 CC) cell follows Babeltrace 1's behaviour: when a special timestamp field is found in the packet context (`timestamp_begin` or `timestamp_end`) or event header (`timestamp`) scope, when this timestamp field is not explicitly mapped to a clock class, and when there's no clock class at this point in the trace, then create an automatic, 1 GHz clock class and, in this case, name it `default`. Map the field to this implicit 1 GHz clock class. See section 8 ("Clocks") of CTF v1.8.2. Cell (FT is not mapped, 0 CC) is a fix for old versions of LTTng, and cell (FT is not mapped, 1 CC) is a fix for old versions of CTF writer. Cell (FT is not mapped, 2+ CCs) is an error because we wouldn't know which clock class to automatically map the field to. Signed-off-by: Philippe Proulx Signed-off-by: Jérémie Galarneau --- plugins/ctf/common/metadata/decoder.c | 10 +- plugins/ctf/common/metadata/decoder.h | 1 - .../ctf/common/metadata/visitor-generate-ir.c | 192 +++++++++++++----- plugins/ctf/fs-src/fs.c | 14 -- plugins/ctf/fs-src/metadata.c | 1 - plugins/ctf/fs-src/metadata.h | 1 - 6 files changed, 140 insertions(+), 79 deletions(-) diff --git a/plugins/ctf/common/metadata/decoder.c b/plugins/ctf/common/metadata/decoder.c index aad6aa1e..763b0508 100644 --- a/plugins/ctf/common/metadata/decoder.c +++ b/plugins/ctf/common/metadata/decoder.c @@ -336,7 +336,6 @@ struct ctf_metadata_decoder *ctf_metadata_decoder_create( struct ctf_metadata_decoder_config default_config = { .clock_class_offset_s = 0, .clock_class_offset_ns = 0, - .strict = false, }; if (!config) { @@ -345,10 +344,9 @@ struct ctf_metadata_decoder *ctf_metadata_decoder_create( BT_LOGD("Creating CTF metadata decoder: " "clock-class-offset-s=%" PRId64 ", " - "clock-class-offset-ns=%" PRId64 ", " - "strict=%d, name=\"%s\"", + "clock-class-offset-ns=%" PRId64 ", name=\"%s\"", config->clock_class_offset_s, config->clock_class_offset_ns, - config->strict, name); + name); if (!mdec) { BT_LOGE_STR("Failed to allocate one CTF metadata decoder."); @@ -368,9 +366,9 @@ struct ctf_metadata_decoder *ctf_metadata_decoder_create( BT_LOGD("Creating CTF metadata decoder: " "clock-class-offset-s=%" PRId64 ", " "clock-class-offset-ns=%" PRId64 ", " - "strict=%d, name=\"%s\", addr=%p", + "name=\"%s\", addr=%p", config->clock_class_offset_s, config->clock_class_offset_ns, - config->strict, name, mdec); + name, mdec); end: return mdec; diff --git a/plugins/ctf/common/metadata/decoder.h b/plugins/ctf/common/metadata/decoder.h index b7a95077..6ab0f30b 100644 --- a/plugins/ctf/common/metadata/decoder.h +++ b/plugins/ctf/common/metadata/decoder.h @@ -36,7 +36,6 @@ enum ctf_metadata_decoder_status { struct ctf_metadata_decoder_config { int64_t clock_class_offset_s; int64_t clock_class_offset_ns; - bool strict; }; /* diff --git a/plugins/ctf/common/metadata/visitor-generate-ir.c b/plugins/ctf/common/metadata/visitor-generate-ir.c index 56069e5c..b18b747b 100644 --- a/plugins/ctf/common/metadata/visitor-generate-ir.c +++ b/plugins/ctf/common/metadata/visitor-generate-ir.c @@ -3766,63 +3766,149 @@ end: } static -int auto_map_fields_to_trace_clock_class(struct ctx *ctx, - struct bt_ctf_field_type *packet_context_field_type, - const char **field_names) +int auto_map_field_to_trace_clock_class(struct ctx *ctx, + struct bt_ctf_field_type *ft) { - _BT_CTF_FIELD_TYPE_INIT(ft); - struct bt_ctf_clock_class *clock_class = NULL; + struct bt_ctf_clock_class *clock_class_to_map_to = NULL; struct bt_ctf_clock_class *mapped_clock_class = NULL; int ret = 0; - const char **field_name; + int64_t clock_class_count; + + if (!ft || !bt_ctf_field_type_is_integer(ft)) { + goto end; + } + + mapped_clock_class = + bt_ctf_field_type_integer_get_mapped_clock_class(ft); + if (mapped_clock_class) { + goto end; + } + + clock_class_count = bt_ctf_trace_get_clock_class_count(ctx->trace); + assert(clock_class_count >= 0); + + switch (clock_class_count) { + case 0: + /* + * No clock class exists in the trace at this + * point. Create an implicit one at 1 GHz, + * named `default`, and use this clock class. + */ + clock_class_to_map_to = bt_ctf_clock_class_create("default"); + if (!clock_class_to_map_to) { + BT_LOGE_STR("Cannot create a clock class."); + ret = -1; + goto end; + } + + ret = bt_ctf_clock_class_set_frequency(clock_class_to_map_to, + 1000000000); + assert(ret == 0); - if (ctx->decoder_config.strict) { + ret = bt_ctf_trace_add_clock_class(ctx->trace, + clock_class_to_map_to); + if (ret) { + BT_LOGE_STR("Cannot add clock class to trace."); + goto end; + } + break; + case 1: + /* + * Only one clock class exists in the trace at + * this point: use this one. + */ + clock_class_to_map_to = + bt_ctf_trace_get_clock_class_by_index(ctx->trace, 0); + assert(clock_class_to_map_to); + break; + default: + /* + * Timestamp field not mapped to a clock class + * and there's more than one clock class in the + * trace: this is an error. + */ + BT_LOGE_STR("Timestamp field found with no mapped clock class, " + "but there's more than one clock class in the trace at this point."); + ret = -1; goto end; } - if (!packet_context_field_type) { + assert(clock_class_to_map_to); + ret = bt_ctf_field_type_integer_set_mapped_clock_class(ft, + clock_class_to_map_to); + if (ret) { + BT_LOGE("Cannot map field type's field to trace's clock class: " + "clock-class-name=\"%s\", ret=%d", + bt_ctf_clock_class_get_name(clock_class_to_map_to), + ret); goto end; } - if (!bt_ctf_field_type_is_structure(packet_context_field_type)) { +end: + bt_put(clock_class_to_map_to); + bt_put(mapped_clock_class); + return ret; +} + +static +int auto_map_fields_to_trace_clock_class(struct ctx *ctx, + struct bt_ctf_field_type *root_ft, const char *field_name) +{ + int ret = 0; + int64_t i, count; + + if (!root_ft) { goto end; } - if (bt_ctf_trace_get_clock_class_count(ctx->trace) != 1) { + if (!bt_ctf_field_type_is_structure(root_ft) && + !bt_ctf_field_type_is_variant(root_ft)) { goto end; } - clock_class = bt_ctf_trace_get_clock_class_by_index(ctx->trace, 0); - assert(clock_class); + if (bt_ctf_field_type_is_structure(root_ft)) { + count = bt_ctf_field_type_structure_get_field_count(root_ft); + } else { + count = bt_ctf_field_type_variant_get_field_count(root_ft); + } - for (field_name = field_names; *field_name; field_name++) { - ft = bt_ctf_field_type_structure_get_field_type_by_name( - packet_context_field_type, *field_name); + assert(count >= 0); - if (ft && bt_ctf_field_type_is_integer(ft)) { - mapped_clock_class = - bt_ctf_field_type_integer_get_mapped_clock_class(ft); + for (i = 0; i < count; i++) { + _BT_CTF_FIELD_TYPE_INIT(ft); + const char *name; - if (!mapped_clock_class) { - ret = bt_ctf_field_type_integer_set_mapped_clock_class( - ft, clock_class); - if (ret) { - BT_LOGE("Cannot map field type's field to trace's clock class: " - "field-name=\"%s\", ret=%d", - *field_name, ret); - goto end; - } + if (bt_ctf_field_type_is_structure(root_ft)) { + ret = bt_ctf_field_type_structure_get_field_by_index( + root_ft, &name, &ft, i); + } else if (bt_ctf_field_type_is_variant(root_ft)) { + ret = bt_ctf_field_type_variant_get_field_by_index( + root_ft, &name, &ft, i); + } + + assert(ret == 0); + + if (strcmp(name, field_name) == 0) { + ret = auto_map_field_to_trace_clock_class(ctx, ft); + if (ret) { + BT_LOGE("Cannot automatically map field to trace's clock class: " + "field-name=\"%s\"", field_name); + bt_put(ft); + goto end; } } - BT_PUT(mapped_clock_class); - BT_PUT(ft); + ret = auto_map_fields_to_trace_clock_class(ctx, ft, field_name); + bt_put(ft); + if (ret) { + BT_LOGE("Cannot automatically map structure or variant field type's fields to trace's clock class: " + "field-name=\"%s\", root-field-name=\"%s\"", + field_name, name); + goto end; + } } end: - bt_put(mapped_clock_class); - bt_put(clock_class); - bt_put(ft); return ret; } @@ -3903,12 +3989,6 @@ int visit_stream_decl_entry(struct ctx *ctx, struct ctf_node *node, _SET(set, _STREAM_ID_SET); } else if (!strcmp(left, "event.header")) { - const char *field_names[] = { - "timestamp", - "ts", - NULL, - }; - if (_IS_SET(set, _STREAM_EVENT_HEADER_SET)) { _BT_LOGE_NODE(node, "Duplicate `event.header` entry in stream class."); @@ -3929,10 +4009,10 @@ int visit_stream_decl_entry(struct ctx *ctx, struct ctf_node *node, assert(decl); ret = auto_map_fields_to_trace_clock_class(ctx, - decl, field_names); + decl, "timestamp"); if (ret) { _BT_LOGE_NODE(node, - "Cannot automatically map specific event header field type fields to trace's clock class."); + "Cannot automatically map specific event header field type fields named `timestamp` to trace's clock class."); goto error; } @@ -3978,12 +4058,6 @@ int visit_stream_decl_entry(struct ctx *ctx, struct ctf_node *node, _SET(set, _STREAM_EVENT_CONTEXT_SET); } else if (!strcmp(left, "packet.context")) { - const char *field_names[] = { - "timestamp_begin", - "timestamp_end", - NULL, - }; - if (_IS_SET(set, _STREAM_PACKET_CONTEXT_SET)) { _BT_LOGE_NODE(node, "Duplicate `packet.context` entry in stream class."); @@ -4004,10 +4078,18 @@ int visit_stream_decl_entry(struct ctx *ctx, struct ctf_node *node, assert(decl); ret = auto_map_fields_to_trace_clock_class(ctx, - decl, field_names); + decl, "timestamp_begin"); + if (ret) { + _BT_LOGE_NODE(node, + "Cannot automatically map specific packet context field type fields named `timestamp_begin` to trace's clock class."); + goto error; + } + + ret = auto_map_fields_to_trace_clock_class(ctx, + decl, "timestamp_end"); if (ret) { _BT_LOGE_NODE(node, - "Cannot automatically map specific packet context field type fields to trace's clock class."); + "Cannot automatically map specific packet context field type fields named `timestamp_end` to trace's clock class."); goto error; } @@ -4443,14 +4525,12 @@ int visit_env(struct ctx *ctx, struct ctf_node *node) goto error; } - if (!ctx->decoder_config.strict) { - if (strcmp(left, "tracer_name") == 0) { - if (strncmp(right, "lttng", 5) == 0) { - BT_LOGI("Non-strict mode: detected LTTng trace from `%s` environment value: " - "tracer-name=\"%s\"", - left, right); - ctx->is_lttng = 1; - } + if (strcmp(left, "tracer_name") == 0) { + if (strncmp(right, "lttng", 5) == 0) { + BT_LOGI("Detected LTTng trace from `%s` environment value: " + "tracer-name=\"%s\"", + left, right); + ctx->is_lttng = 1; } } diff --git a/plugins/ctf/fs-src/fs.c b/plugins/ctf/fs-src/fs.c index aa1d6b1f..07aa8cf3 100644 --- a/plugins/ctf/fs-src/fs.c +++ b/plugins/ctf/fs-src/fs.c @@ -1286,20 +1286,6 @@ struct ctf_fs_component *ctf_fs_create(struct bt_private_component *priv_comp, BT_PUT(value); } - value = bt_value_map_get(params, "strict-metadata"); - if (value) { - bt_bool strict; - - if (!bt_value_is_bool(value)) { - BT_LOGE("strict-metadata should be a boolean"); - goto error; - } - ret = bt_value_bool_get(value, &strict); - assert(ret == 0); - ctf_fs->metadata_config.strict = !!strict; - BT_PUT(value); - } - ctf_fs->port_data = g_ptr_array_new_with_free_func(port_data_destroy); if (!ctf_fs->port_data) { goto error; diff --git a/plugins/ctf/fs-src/metadata.c b/plugins/ctf/fs-src/metadata.c index 75e962f2..18ecb0c5 100644 --- a/plugins/ctf/fs-src/metadata.c +++ b/plugins/ctf/fs-src/metadata.c @@ -105,7 +105,6 @@ int ctf_fs_metadata_set_trace(struct ctf_fs_trace *ctf_fs_trace, struct ctf_metadata_decoder_config decoder_config = { .clock_class_offset_s = config->clock_class_offset_s, .clock_class_offset_ns = config->clock_class_offset_ns, - .strict = config->strict, }; file = get_file(ctf_fs_trace->path->str); diff --git a/plugins/ctf/fs-src/metadata.h b/plugins/ctf/fs-src/metadata.h index 9c573433..d77ca6a4 100644 --- a/plugins/ctf/fs-src/metadata.h +++ b/plugins/ctf/fs-src/metadata.h @@ -36,7 +36,6 @@ struct ctf_fs_metadata; struct ctf_fs_metadata_config { int64_t clock_class_offset_s; int64_t clock_class_offset_ns; - bool strict; }; BT_HIDDEN -- 2.34.1