ctf: remove strict metadata mode, update automatic CC mapping behaviour
authorPhilippe Proulx <eeppeliteloop@gmail.com>
Fri, 16 Jun 2017 01:36:57 +0000 (21:36 -0400)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Fri, 16 Jun 2017 19:57:36 +0000 (15:57 -0400)
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 <eeppeliteloop@gmail.com>
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
plugins/ctf/common/metadata/decoder.c
plugins/ctf/common/metadata/decoder.h
plugins/ctf/common/metadata/visitor-generate-ir.c
plugins/ctf/fs-src/fs.c
plugins/ctf/fs-src/metadata.c
plugins/ctf/fs-src/metadata.h

index aad6aa1e571c2bd54bbe1d2087d630d8e6742d30..763b0508a80742e69998a2705ffac20ece98ba2c 100644 (file)
@@ -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;
index b7a9507752894d5866e8bcc5e2db7f254a565678..6ab0f30b4208aa4fe7f6a0b499130fd063f7195d 100644 (file)
@@ -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;
 };
 
 /*
index 56069e5cd6d6d26c9a236ec1325598c21c0d9598..b18b747b989f7f6789f06598c74f971df83de6e1 100644 (file)
@@ -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;
                                }
                        }
 
index aa1d6b1f40481809764fdaf9d38c1f483f49bbde..07aa8cf36f9d724b0ab02dcc3b903533c501b4f4 100644 (file)
@@ -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;
index 75e962f2d0bb586c61ab86a505da4deb0762846e..18ecb0c598d1dc926280b3a2e565038226203263 100644 (file)
@@ -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);
index 9c573433cbcdebaf9d99b237bf1ab7819ab25da8..d77ca6a4099d5fd9d637c1372a88dc09ff2b7efb 100644 (file)
@@ -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
This page took 0.032482 seconds and 4 git commands to generate.