From: Philippe Proulx Date: Fri, 16 Jun 2017 01:36:57 +0000 (-0400) Subject: ctf: remove strict metadata mode, update automatic CC mapping behaviour X-Git-Url: http://git.efficios.com/?p=babeltrace.git;a=commitdiff_plain;h=7bf5af54b2e6cf5ed45f3416f96d837a120467ca ctf: remove strict metadata mode, update automatic CC mapping behaviour 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 --- 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