From: Philippe Proulx Date: Wed, 14 Jun 2017 15:15:00 +0000 (-0400) Subject: ctf: add metadata decoder config. and `strict-metadata` param in src.ctf.fs X-Git-Url: http://git.efficios.com/?p=babeltrace.git;a=commitdiff_plain;h=a2a545450763347fd1c1e5c089a296238e1cbc11 ctf: add metadata decoder config. and `strict-metadata` param in src.ctf.fs The common metadata decoder now accepts an optional configuration structure. The offset (seconds and nanoseconds) to apply to all the clock classes is found in there, as well as a new option which makes the decoder strict. In strict mode, the decoder does not allow the decoded metadata stream to be off semantically. For example, in strict mode, clock classes named `monotonic` are not forced to be absolute when it is detected that the stream was produced by an LTTng tracer. It's not expected that the strict mode be something that any user would want under normal conditions because the non-strict mode fixes errors made by known tracers to make things work for the other components of the graph. As such, there's no quick --strict option in the CLI's `convert` command: the user can instantiate its own source.ctf.fs component with --component for this and pass the options with --params: babeltrace -c src.ctf.fs --path ~/my-traces/trace -p strict-metadata=yes I'm also fixing the parameter names and types for the clock class offsets, both in the CLI and in source.ctf.fs, so that all the project's modules are in sync regarding this. The parameters are now `clock-class-offset-s` and `clock-class-offset-ns`, and with the `convert` command, they are set with resp. --clock-offset and --clock-offset-ns. They used to be passed to the `run` command as string values (using --key and --value), but now they are part of the component's --params option so that they are recognized as constant integer values (even if negative). Signed-off-by: Philippe Proulx Signed-off-by: Jérémie Galarneau --- diff --git a/cli/babeltrace-cfg-cli-args.c b/cli/babeltrace-cfg-cli-args.c index cd8fb189..541329ab 100644 --- a/cli/babeltrace-cfg-cli-args.c +++ b/cli/babeltrace-cfg-cli-args.c @@ -4093,7 +4093,8 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], break; case OPT_CLOCK_FORCE_CORRELATE: append_implicit_component_param( - &implicit_muxer_args, "assume-absolute-clock-classes", "yes"); + &implicit_muxer_args, + "assume-absolute-clock-classes", "yes"); break; case OPT_CLOCK_GMT: append_implicit_component_param( @@ -4102,8 +4103,9 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], break; case OPT_CLOCK_OFFSET: base_implicit_ctf_input_args.exists = true; - ret = append_implicit_component_extra_param( - &base_implicit_ctf_input_args, "clock-offset-cycles", arg); + append_implicit_component_param( + &implicit_muxer_args, + "clock-class-offset-s", arg); if (ret) { goto error; } @@ -4112,7 +4114,7 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], base_implicit_ctf_input_args.exists = true; ret = append_implicit_component_extra_param( &base_implicit_ctf_input_args, - "clock-offset-ns", arg); + "clock-class-offset-ns", arg); if (ret) { goto error; } diff --git a/plugins/ctf/common/metadata/ast.h b/plugins/ctf/common/metadata/ast.h index 737158cd..74bcde9f 100644 --- a/plugins/ctf/common/metadata/ast.h +++ b/plugins/ctf/common/metadata/ast.h @@ -24,6 +24,8 @@ #include #include +#include "decoder.h" + // the parameter name (of the reentrant 'yyparse' function) // data is a pointer to a 'SParserParam' structure //#define YYPARSE_PARAM scanner @@ -309,7 +311,8 @@ const char *node_type(struct ctf_node *node); BT_HIDDEN struct ctf_visitor_generate_ir *ctf_visitor_generate_ir_create( - int64_t clock_class_offset_ns, const char *name); + const struct ctf_metadata_decoder_config *config, + const char *name); void ctf_visitor_generate_ir_destroy(struct ctf_visitor_generate_ir *visitor); diff --git a/plugins/ctf/common/metadata/decoder.c b/plugins/ctf/common/metadata/decoder.c index 8837da77..aad6aa1e 100644 --- a/plugins/ctf/common/metadata/decoder.c +++ b/plugins/ctf/common/metadata/decoder.c @@ -41,6 +41,7 @@ struct ctf_metadata_decoder { uint8_t uuid[16]; bool is_uuid_set; int bo; + struct ctf_metadata_decoder_config config; }; struct packet_header { @@ -327,22 +328,35 @@ int ctf_metadata_decoder_packetized_file_stream_to_buf( BT_HIDDEN struct ctf_metadata_decoder *ctf_metadata_decoder_create( - int64_t clock_class_offset_ns, const char *name) + const struct ctf_metadata_decoder_config *config, + const char *name) { struct ctf_metadata_decoder *mdec = g_new0(struct ctf_metadata_decoder, 1); + struct ctf_metadata_decoder_config default_config = { + .clock_class_offset_s = 0, + .clock_class_offset_ns = 0, + .strict = false, + }; + + if (!config) { + config = &default_config; + } BT_LOGD("Creating CTF metadata decoder: " - "clock-class-offset-ns=%" PRId64 ", name=\"%s\"", - clock_class_offset_ns, name); + "clock-class-offset-s=%" PRId64 ", " + "clock-class-offset-ns=%" PRId64 ", " + "strict=%d, name=\"%s\"", + config->clock_class_offset_s, config->clock_class_offset_ns, + config->strict, name); if (!mdec) { BT_LOGE_STR("Failed to allocate one CTF metadata decoder."); goto end; } - mdec->visitor = ctf_visitor_generate_ir_create(clock_class_offset_ns, - name); + mdec->config = *config; + mdec->visitor = ctf_visitor_generate_ir_create(config, name); if (!mdec->visitor) { BT_LOGE("Failed to create a CTF IR metadata AST visitor: " "mdec-addr=%p", mdec); @@ -351,9 +365,12 @@ struct ctf_metadata_decoder *ctf_metadata_decoder_create( goto end; } - BT_LOGD("Created CTF metadata decoder: " - "clock-class-offset-ns=%" PRId64 ", name=\"%s\", addr=%p", - clock_class_offset_ns, name, mdec); + BT_LOGD("Creating CTF metadata decoder: " + "clock-class-offset-s=%" PRId64 ", " + "clock-class-offset-ns=%" PRId64 ", " + "strict=%d, name=\"%s\", addr=%p", + config->clock_class_offset_s, config->clock_class_offset_ns, + config->strict, name, mdec); end: return mdec; diff --git a/plugins/ctf/common/metadata/decoder.h b/plugins/ctf/common/metadata/decoder.h index 959bdd40..b7a95077 100644 --- a/plugins/ctf/common/metadata/decoder.h +++ b/plugins/ctf/common/metadata/decoder.h @@ -16,6 +16,7 @@ */ #include +#include struct bt_ctf_trace; @@ -31,16 +32,23 @@ enum ctf_metadata_decoder_status { CTF_METADATA_DECODER_STATUS_IR_VISITOR_ERROR = -4, }; +/* Decoding configuration */ +struct ctf_metadata_decoder_config { + int64_t clock_class_offset_s; + int64_t clock_class_offset_ns; + bool strict; +}; + /* - * Creates a CTF metadata decoder. `clock_class_offset_ns` is an - * offset to apply to the decoded clock classes's offsets. `name` is - * this decoder's trace's name. + * Creates a CTF metadata decoder. `name` is this decoder's trace's + * name. * * Returns `NULL` on error. */ BT_HIDDEN struct ctf_metadata_decoder *ctf_metadata_decoder_create( - int64_t clock_class_offset_ns, const char *name); + const struct ctf_metadata_decoder_config *config, + const char *name); /* * Destroys a CTF metadata decoder that you created with diff --git a/plugins/ctf/common/metadata/visitor-generate-ir.c b/plugins/ctf/common/metadata/visitor-generate-ir.c index 19a67896..0ebb0157 100644 --- a/plugins/ctf/common/metadata/visitor-generate-ir.c +++ b/plugins/ctf/common/metadata/visitor-generate-ir.c @@ -54,6 +54,7 @@ #include "scanner.h" #include "parser.h" #include "ast.h" +#include "decoder.h" /* Bit value (left shift) */ #define _BV(_val) (1 << (_val)) @@ -200,9 +201,6 @@ struct ctx { /* 1 if this is an LTTng trace */ bool is_lttng; - /* Offset (ns) to apply to clock classes on creation */ - int64_t clock_class_offset_ns; - /* Eventual name suffix of the trace to set */ char *trace_name_suffix; @@ -218,6 +216,9 @@ struct ctx { * int64_t -> struct bt_ctf_stream_class * */ GHashTable *stream_classes; + + /* Config passed by the user */ + struct ctf_metadata_decoder_config decoder_config; }; /* @@ -601,11 +602,14 @@ end: */ static struct ctx *ctx_create(struct bt_ctf_trace *trace, - int64_t clock_class_offset_ns, const char *trace_name_suffix) + const struct ctf_metadata_decoder_config *decoder_config, + const char *trace_name_suffix) { struct ctx *ctx = NULL; struct ctx_decl_scope *scope = NULL; + assert(decoder_config); + ctx = g_new0(struct ctx, 1); if (!ctx) { BT_LOGE_STR("Failed to allocate one visitor context."); @@ -638,7 +642,7 @@ struct ctx *ctx_create(struct bt_ctf_trace *trace, ctx->current_scope = scope; scope = NULL; ctx->trace_bo = BT_CTF_BYTE_ORDER_NATIVE; - ctx->clock_class_offset_ns = clock_class_offset_ns; + ctx->decoder_config = *decoder_config; return ctx; error: @@ -4348,12 +4352,14 @@ int visit_env(struct ctx *ctx, struct ctf_node *node) goto error; } - 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; + 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; + } } } @@ -4770,6 +4776,7 @@ int apply_clock_class_offset(struct ctx *ctx, struct bt_ctf_clock_class *clock) int ret; uint64_t freq; int64_t offset_cycles; + int64_t offset_to_apply; freq = bt_ctf_clock_class_get_frequency(clock); if (freq == -1ULL) { @@ -4785,7 +4792,10 @@ int apply_clock_class_offset(struct ctx *ctx, struct bt_ctf_clock_class *clock) goto end; } - offset_cycles += cycles_from_ns(freq, ctx->clock_class_offset_ns); + offset_to_apply = + ctx->decoder_config.clock_class_offset_s * 1000000000LL + + ctx->decoder_config.clock_class_offset_ns; + offset_cycles += cycles_from_ns(freq, offset_to_apply); ret = bt_ctf_clock_class_set_offset_cycles(clock, offset_cycles); end: @@ -5033,7 +5043,8 @@ end: BT_HIDDEN struct ctf_visitor_generate_ir *ctf_visitor_generate_ir_create( - int64_t clock_class_offset_ns, const char *name) + const struct ctf_metadata_decoder_config *decoder_config, + const char *name) { int ret; struct ctx *ctx = NULL; @@ -5053,7 +5064,7 @@ struct ctf_visitor_generate_ir *ctf_visitor_generate_ir_create( } /* Create visitor's context */ - ctx = ctx_create(trace, clock_class_offset_ns, name); + ctx = ctx_create(trace, decoder_config, name); if (!ctx) { BT_LOGE_STR("Cannot create visitor's context."); goto error; diff --git a/plugins/ctf/fs-src/fs.c b/plugins/ctf/fs-src/fs.c index f6a9f791..aa1d6b1f 100644 --- a/plugins/ctf/fs-src/fs.c +++ b/plugins/ctf/fs-src/fs.c @@ -898,7 +898,7 @@ end: BT_HIDDEN struct ctf_fs_trace *ctf_fs_trace_create(const char *path, const char *name, - struct metadata_overrides *overrides) + struct ctf_fs_metadata_config *metadata_config) { struct ctf_fs_trace *ctf_fs_trace; int ret; @@ -929,7 +929,7 @@ struct ctf_fs_trace *ctf_fs_trace_create(const char *path, const char *name, goto error; } - ret = ctf_fs_metadata_set_trace(ctf_fs_trace, overrides); + ret = ctf_fs_metadata_set_trace(ctf_fs_trace, metadata_config); if (ret) { goto error; } @@ -1149,10 +1149,6 @@ int create_ctf_fs_traces(struct ctf_fs_component *ctf_fs, GList *trace_names = NULL; GList *tp_node; GList *tn_node; - struct metadata_overrides metadata_overrides = { - .clock_offset_s = ctf_fs->options.clock_offset, - .clock_offset_ns = ctf_fs->options.clock_offset_ns, - }; norm_path = bt_common_normalize_path(path_param, NULL); if (!norm_path) { @@ -1185,7 +1181,7 @@ int create_ctf_fs_traces(struct ctf_fs_component *ctf_fs, GString *trace_name = tn_node->data; ctf_fs_trace = ctf_fs_trace_create(trace_path->str, - trace_name->str, &metadata_overrides); + trace_name->str, &ctf_fs->metadata_config); if (!ctf_fs_trace) { BT_LOGE("Cannot create trace for `%s`.", trace_path->str); @@ -1266,31 +1262,41 @@ struct ctf_fs_component *ctf_fs_create(struct bt_private_component *priv_comp, ret = bt_value_string_get(value, &path_param); assert(ret == 0); BT_PUT(value); - value = bt_value_map_get(params, "offset-s"); + value = bt_value_map_get(params, "clock-class-offset-s"); if (value) { - int64_t offset; + if (!bt_value_is_integer(value)) { + BT_LOGE("clock-class-offset-s should be an integer"); + goto error; + } + ret = bt_value_integer_get(value, + &ctf_fs->metadata_config.clock_class_offset_s); + assert(ret == 0); + BT_PUT(value); + } + value = bt_value_map_get(params, "clock-class-offset-ns"); + if (value) { if (!bt_value_is_integer(value)) { - BT_LOGE("offset-s should be an integer"); + BT_LOGE("clock-class-offset-ns should be an integer"); goto error; } - ret = bt_value_integer_get(value, &offset); + ret = bt_value_integer_get(value, + &ctf_fs->metadata_config.clock_class_offset_ns); assert(ret == 0); - ctf_fs->options.clock_offset = offset; BT_PUT(value); } - value = bt_value_map_get(params, "offset-ns"); + value = bt_value_map_get(params, "strict-metadata"); if (value) { - int64_t offset; + bt_bool strict; - if (!bt_value_is_integer(value)) { - BT_LOGE("offset-ns should be an integer"); + if (!bt_value_is_bool(value)) { + BT_LOGE("strict-metadata should be a boolean"); goto error; } - ret = bt_value_integer_get(value, &offset); + ret = bt_value_bool_get(value, &strict); assert(ret == 0); - ctf_fs->options.clock_offset_ns = offset; + ctf_fs->metadata_config.strict = !!strict; BT_PUT(value); } diff --git a/plugins/ctf/fs-src/fs.h b/plugins/ctf/fs-src/fs.h index c5c12fb4..13b0d07c 100644 --- a/plugins/ctf/fs-src/fs.h +++ b/plugins/ctf/fs-src/fs.h @@ -60,11 +60,6 @@ struct ctf_fs_metadata { int bo; }; -struct ctf_fs_component_options { - int64_t clock_offset; - int64_t clock_offset_ns; -}; - struct ctf_fs_component { /* Weak, guaranteed to exist */ struct bt_private_component *priv_comp; @@ -75,7 +70,7 @@ struct ctf_fs_component { /* Array of struct ctf_fs_trace *, owned by this */ GPtrArray *traces; - struct ctf_fs_component_options options; + struct ctf_fs_metadata_config metadata_config; }; struct ctf_fs_trace { @@ -143,7 +138,7 @@ struct bt_value *ctf_fs_query(struct bt_component_class *comp_class, BT_HIDDEN struct ctf_fs_trace *ctf_fs_trace_create(const char *path, const char *name, - struct metadata_overrides *overrides); + struct ctf_fs_metadata_config *config); BT_HIDDEN void ctf_fs_trace_destroy(struct ctf_fs_trace *trace); diff --git a/plugins/ctf/fs-src/metadata.c b/plugins/ctf/fs-src/metadata.c index 91465cb9..75e962f2 100644 --- a/plugins/ctf/fs-src/metadata.c +++ b/plugins/ctf/fs-src/metadata.c @@ -40,8 +40,6 @@ #define BT_LOG_TAG "PLUGIN-CTF-FS-METADATA-SRC" #include "logging.h" -#define NSEC_PER_SEC 1000000000LL - BT_HIDDEN FILE *ctf_fs_metadata_open_file(const char *trace_path) { @@ -99,12 +97,16 @@ end: } int ctf_fs_metadata_set_trace(struct ctf_fs_trace *ctf_fs_trace, - struct metadata_overrides *overrides) + struct ctf_fs_metadata_config *config) { int ret = 0; struct ctf_fs_file *file = NULL; struct ctf_metadata_decoder *metadata_decoder = NULL; - int64_t clock_offset_adjustment = 0; + 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); if (!file) { @@ -113,12 +115,7 @@ int ctf_fs_metadata_set_trace(struct ctf_fs_trace *ctf_fs_trace, goto end; } - if (overrides) { - clock_offset_adjustment = - overrides->clock_offset_s * NSEC_PER_SEC + - overrides->clock_offset_ns; - } - metadata_decoder = ctf_metadata_decoder_create(clock_offset_adjustment, + metadata_decoder = ctf_metadata_decoder_create(&decoder_config, ctf_fs_trace->name->str); if (!metadata_decoder) { BT_LOGE("Cannot create metadata decoder object"); diff --git a/plugins/ctf/fs-src/metadata.h b/plugins/ctf/fs-src/metadata.h index 112c681f..9c573433 100644 --- a/plugins/ctf/fs-src/metadata.h +++ b/plugins/ctf/fs-src/metadata.h @@ -33,9 +33,10 @@ struct ctf_fs_trace; struct ctf_fs_metadata; -struct metadata_overrides { - int64_t clock_offset_s; - int64_t clock_offset_ns; +struct ctf_fs_metadata_config { + int64_t clock_class_offset_s; + int64_t clock_class_offset_ns; + bool strict; }; BT_HIDDEN @@ -46,7 +47,7 @@ void ctf_fs_metadata_fini(struct ctf_fs_metadata *metadata); BT_HIDDEN int ctf_fs_metadata_set_trace(struct ctf_fs_trace *ctf_fs_trace, - struct metadata_overrides *overrides); + struct ctf_fs_metadata_config *config); BT_HIDDEN FILE *ctf_fs_metadata_open_file(const char *trace_path); diff --git a/plugins/ctf/lttng-live/metadata.c b/plugins/ctf/lttng-live/metadata.c index 1adc81c1..7fec74ad 100644 --- a/plugins/ctf/lttng-live/metadata.c +++ b/plugins/ctf/lttng-live/metadata.c @@ -248,7 +248,7 @@ int lttng_live_metadata_create_stream(struct lttng_live_session *session, if (!match) { goto error; } - metadata->decoder = ctf_metadata_decoder_create(0, + metadata->decoder = ctf_metadata_decoder_create(NULL, match); if (!metadata->decoder) { goto error;