X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=src%2Fcli%2Fbabeltrace2-cfg-cli-args.c;h=a16fbfceaa4b6d2cff737bddd1eee9ba374c7b4d;hb=5084732e40a7925d22f741e4ed08f19d36078fbe;hp=6214a594ff30a189318c43a8f7be3efcde29218f;hpb=9f90145146cee221f46087a8dd250c1c0f14c9c0;p=babeltrace.git diff --git a/src/cli/babeltrace2-cfg-cli-args.c b/src/cli/babeltrace2-cfg-cli-args.c index 6214a594..a16fbfce 100644 --- a/src/cli/babeltrace2-cfg-cli-args.c +++ b/src/cli/babeltrace2-cfg-cli-args.c @@ -41,6 +41,8 @@ #include "babeltrace2-cfg-cli-args.h" #include "babeltrace2-cfg-cli-args-connect.h" #include "babeltrace2-cfg-cli-params-arg.h" +#include "babeltrace2-plugins.h" +#include "babeltrace2-cfg-src-auto-disc.h" #include "common/version.h" static const int cli_default_log_level = BT_LOG_WARNING; @@ -504,7 +506,7 @@ void destroy_glist_of_gstring(GList *list) return; } - for (at = list; at != NULL; at = g_list_next(at)) { + for (at = list; at; at = g_list_next(at)) { g_string_free(at->data, TRUE); } @@ -2517,8 +2519,13 @@ end: struct implicit_component_args { bool exists; + + /* The component class name (e.g. src.ctf.fs). */ GString *comp_arg; + + /* The component instance name. */ GString *name_arg; + GString *params_arg; bt_value *extra_params; }; @@ -2639,6 +2646,8 @@ end: return ret; } +/* Free the fields of a `struct implicit_component_args`. */ + static void finalize_implicit_component_args(struct implicit_component_args *args) { @@ -2659,6 +2668,17 @@ void finalize_implicit_component_args(struct implicit_component_args *args) bt_value_put_ref(args->extra_params); } +/* Destroy a dynamically-allocated `struct implicit_component_args`. */ + +static +void destroy_implicit_component_args(struct implicit_component_args *args) +{ + finalize_implicit_component_args(args); + g_free(args); +} + +/* Initialize the fields of an already allocated `struct implicit_component_args`. */ + static int init_implicit_component_args(struct implicit_component_args *args, const char *comp_arg, bool exists) @@ -2683,6 +2703,31 @@ end: return ret; } +/* Dynamically allocate and initialize a `struct implicit_component_args`. */ + +static +struct implicit_component_args *create_implicit_component_args( + const char *comp_arg) +{ + struct implicit_component_args *args; + int status; + + args = g_new(struct implicit_component_args, 1); + if (!args) { + BT_CLI_LOGE_APPEND_CAUSE_OOM(); + goto end; + } + + status = init_implicit_component_args(args, comp_arg, true); + if (status != 0) { + g_free(args); + args = NULL; + } + +end: + return args; +} + static void append_implicit_component_param(struct implicit_component_args *args, const char *key, const char *value) @@ -2693,6 +2738,33 @@ void append_implicit_component_param(struct implicit_component_args *args, append_param_arg(args->params_arg, key, value); } +/* + * Append the given parameter (`key=value`) to all component specifications + * in `implicit_comp_args` (an array of `struct implicit_component_args *`) + * which match `comp_arg`. + * + * Return the number of matching components. + */ + +static +int append_multiple_implicit_components_param(GPtrArray *implicit_comp_args, + const char *comp_arg, const char *key, const char *value) +{ + int i; + int n = 0; + + for (i = 0; i < implicit_comp_args->len; i++) { + struct implicit_component_args *args = implicit_comp_args->pdata[i]; + + if (strcmp(args->comp_arg->str, comp_arg) == 0) { + append_implicit_component_param(args, key, value); + n++; + } + } + + return n; +} + /* Escape value to make it suitable to use as a string parameter value. */ static gchar *escape_string_value(const char *value) @@ -3090,7 +3162,7 @@ int convert_auto_connect(bt_value *run_args, BT_ASSERT(sink_names); /* Connect all sources to the first filter */ - for (source_at = source_names; source_at != NULL; source_at = g_list_next(source_at)) { + for (source_at = source_names; source_at; source_at = g_list_next(source_at)) { GString *source_name = source_at->data; GString *filter_name = filter_at->data; @@ -3105,7 +3177,7 @@ int convert_auto_connect(bt_value *run_args, filter_at = g_list_next(filter_at); /* Connect remaining filters */ - for (; filter_at != NULL; filter_prev = filter_at, filter_at = g_list_next(filter_at)) { + for (; filter_at; filter_prev = filter_at, filter_at = g_list_next(filter_at)) { GString *filter_name = filter_at->data; GString *filter_prev_name = filter_prev->data; @@ -3117,7 +3189,7 @@ int convert_auto_connect(bt_value *run_args, } /* Connect last filter to all sinks */ - for (sink_at = sink_names; sink_at != NULL; sink_at = g_list_next(sink_at)) { + for (sink_at = sink_names; sink_at; sink_at = g_list_next(sink_at)) { GString *filter_name = filter_prev->data; GString *sink_name = sink_at->data; @@ -3208,6 +3280,55 @@ end: return ret; } +/* + * Create `struct implicit_component_args` structures for each of the source + * components we identified. Add them to `component_args`. + */ + +static +void create_implicit_component_args_from_auto_discovered_sources( + const struct auto_source_discovery *auto_disc, GPtrArray *component_args) +{ + gchar *cc_name = NULL; + struct implicit_component_args *comp = NULL; + int status; + guint i, len; + + len = auto_disc->results->len; + + for (i = 0; i < len; i++) { + struct auto_source_discovery_result *res = + g_ptr_array_index(auto_disc->results, i); + + g_free(cc_name); + cc_name = g_strdup_printf("source.%s.%s", res->plugin_name, res->source_cc_name); + if (!cc_name) { + BT_CLI_LOGE_APPEND_CAUSE_OOM(); + goto end; + } + + comp = create_implicit_component_args(cc_name); + if (!comp) { + goto end; + } + + status = append_parameter_to_args(comp->extra_params, "inputs", res->inputs); + if (status != 0) { + goto end; + } + + g_ptr_array_add(component_args, comp); + comp = NULL; + } + +end: + g_free(cc_name); + + if (comp) { + destroy_implicit_component_args(comp); + } +} + /* * Creates a Babeltrace config object from the arguments of a convert * command. @@ -3243,7 +3364,6 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], GList *filter_names = NULL; GList *sink_names = NULL; bt_value *leftovers = NULL; - struct implicit_component_args implicit_ctf_input_args = { 0 }; struct implicit_component_args implicit_ctf_output_args = { 0 }; struct implicit_component_args implicit_lttng_live_args = { 0 }; struct implicit_component_args implicit_dummy_args = { 0 }; @@ -3256,6 +3376,24 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], size_t i; struct bt_common_lttng_live_url_parts lttng_live_url_parts = { 0 }; char *output = NULL; + struct auto_source_discovery auto_disc = { NULL }; + GString *auto_disc_comp_name = NULL; + + /* + * Array of `struct implicit_component_args *` created for the sources + * we have auto-discovered. + */ + GPtrArray *discovered_source_args = NULL; + + /* + * If set, restrict automatic source discovery to this component class + * of this plugin. + */ + const char *auto_source_discovery_restrict_plugin_name = NULL; + const char *auto_source_discovery_restrict_component_class_name = NULL; + + gchar *ctf_fs_source_clock_class_offset_arg = NULL; + gchar *ctf_fs_source_clock_class_offset_ns_arg = NULL; (void) bt_value_copy(initial_plugin_paths, &plugin_paths); @@ -3267,11 +3405,6 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], goto end; } - if (init_implicit_component_args(&implicit_ctf_input_args, - "source.ctf.fs", false)) { - goto error; - } - if (init_implicit_component_args(&implicit_ctf_output_args, "sink.ctf.fs", false)) { goto error; @@ -3342,6 +3475,23 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], goto error; } + if (auto_source_discovery_init(&auto_disc) != 0) { + goto error; + } + + discovered_source_args = + g_ptr_array_new_with_free_func((GDestroyNotify) destroy_implicit_component_args); + if (!discovered_source_args) { + BT_CLI_LOGE_APPEND_CAUSE_OOM(); + goto error; + } + + auto_disc_comp_name = g_string_new(NULL); + if (!auto_disc_comp_name) { + BT_CLI_LOGE_APPEND_CAUSE_OOM(); + goto error; + } + /* * First pass: collect all arguments which need to be passed * as is to the run command. This pass can also add --name @@ -3727,16 +3877,28 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], implicit_text_args.exists = true; break; case OPT_CLOCK_OFFSET: - implicit_ctf_input_args.exists = true; - append_implicit_component_param( - &implicit_ctf_input_args, - "clock-class-offset-s", arg); + if (ctf_fs_source_clock_class_offset_arg) { + BT_CLI_LOGE_APPEND_CAUSE("Duplicate --clock-offset option\n"); + goto error; + } + + ctf_fs_source_clock_class_offset_arg = g_strdup(arg); + if (!ctf_fs_source_clock_class_offset_arg) { + BT_CLI_LOGE_APPEND_CAUSE_OOM(); + goto error; + } break; case OPT_CLOCK_OFFSET_NS: - implicit_ctf_input_args.exists = true; - append_implicit_component_param( - &implicit_ctf_input_args, - "clock-class-offset-ns", arg); + if (ctf_fs_source_clock_class_offset_ns_arg) { + BT_CLI_LOGE_APPEND_CAUSE("Duplicate --clock-offset-ns option\n"); + goto error; + } + + ctf_fs_source_clock_class_offset_ns_arg = g_strdup(arg); + if (!ctf_fs_source_clock_class_offset_ns_arg) { + BT_CLI_LOGE_APPEND_CAUSE_OOM(); + goto error; + } break; case OPT_CLOCK_SECONDS: append_implicit_component_param( @@ -3826,8 +3988,11 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], got_input_format_opt = true; if (strcmp(arg, "ctf") == 0) { - implicit_ctf_input_args.exists = true; + auto_source_discovery_restrict_plugin_name = "ctf"; + auto_source_discovery_restrict_component_class_name = "fs"; } else if (strcmp(arg, "lttng-live") == 0) { + auto_source_discovery_restrict_plugin_name = "ctf"; + auto_source_discovery_restrict_component_class_name = "lttng-live"; implicit_lttng_live_args.exists = true; } else { BT_CLI_LOGE_APPEND_CAUSE("Unknown legacy input format:\n %s", @@ -4086,42 +4251,55 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], goto error; } } else { - /* - * Create one source.ctf.fs component, pass it an array - * with the leftovers. - * Note that it still has to be named later. - */ - implicit_ctf_input_args.exists = true; - ret = append_parameter_to_args(implicit_ctf_input_args.extra_params, - "paths", leftovers); - if (ret) { + int status; + + status = auto_discover_source_components(plugin_paths, leftovers, + auto_source_discovery_restrict_plugin_name, + auto_source_discovery_restrict_component_class_name, + *default_log_level >= 0 ? *default_log_level : cli_default_log_level, + &auto_disc); + + if (status != 0) { goto error; } + + create_implicit_component_args_from_auto_discovered_sources( + &auto_disc, discovered_source_args); } } - /* - * Ensure mutual exclusion between implicit `source.ctf.fs` and - * `source.ctf.lttng-live` components. - */ - if (implicit_ctf_input_args.exists && implicit_lttng_live_args.exists) { - BT_CLI_LOGE_APPEND_CAUSE("Cannot create both implicit `%s` and `%s` components.", - implicit_ctf_input_args.comp_arg->str, - implicit_lttng_live_args.comp_arg->str); - goto error; + /* If --clock-offset was given, apply it to any src.ctf.fs component. */ + if (ctf_fs_source_clock_class_offset_arg) { + int n; + + n = append_multiple_implicit_components_param( + discovered_source_args, "source.ctf.fs", "clock-class-offset-s", + ctf_fs_source_clock_class_offset_arg); + + if (n == 0) { + BT_CLI_LOGE_APPEND_CAUSE("--clock-offset specified, but no source.ctf.fs component instantiated."); + goto error; + } } - /* - * If the implicit `source.ctf.fs` or `source.ctf.lttng-live` - * components exists, make sure there's at least one leftover - * (which is the path or URL). - */ - if (implicit_ctf_input_args.exists && bt_value_array_is_empty(leftovers)) { - BT_CLI_LOGE_APPEND_CAUSE("Missing path for implicit `%s` component.", - implicit_ctf_input_args.comp_arg->str); - goto error; + /* If --clock-offset-ns was given, apply it to any src.ctf.fs component. */ + if (ctf_fs_source_clock_class_offset_ns_arg) { + int n; + + n = append_multiple_implicit_components_param( + discovered_source_args, "source.ctf.fs", "clock-class-offset-ns", + ctf_fs_source_clock_class_offset_ns_arg); + + if (n == 0) { + BT_CLI_LOGE_APPEND_CAUSE("--clock-offset-ns specified, but no source.ctf.fs component instantiated."); + goto error; + } } + /* + * If the implicit `source.ctf.lttng-live` component exists, make sure + * there's at least one leftover (which is the URL). + */ if (implicit_lttng_live_args.exists && bt_value_array_is_empty(leftovers)) { BT_CLI_LOGE_APPEND_CAUSE("Missing URL for implicit `%s` component.", implicit_lttng_live_args.comp_arg->str); @@ -4129,10 +4307,26 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], } /* Assign names to implicit components */ - ret = assign_name_to_implicit_component(&implicit_ctf_input_args, - "source-ctf-fs", all_names, &source_names, true); - if (ret) { - goto error; + for (i = 0; i < discovered_source_args->len; i++) { + struct implicit_component_args *args; + int j; + + args = discovered_source_args->pdata[i]; + + g_string_printf(auto_disc_comp_name, "auto-disc-%s", args->comp_arg->str); + + /* Give it a name like `auto-disc-src-ctf-fs`. */ + for (j = 0; j < auto_disc_comp_name->len; j++) { + if (auto_disc_comp_name->str[j] == '.') { + auto_disc_comp_name->str[j] = '-'; + } + } + + ret = assign_name_to_implicit_component(args, + auto_disc_comp_name->str, all_names, &source_names, true); + if (ret) { + goto error; + } } ret = assign_name_to_implicit_component(&implicit_lttng_live_args, @@ -4218,9 +4412,14 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], * Append the equivalent run arguments for the implicit * components. */ - ret = append_run_args_for_implicit_component(&implicit_ctf_input_args, run_args); - if (ret) { - goto error; + for (i = 0; i < discovered_source_args->len; i++) { + struct implicit_component_args *args = + discovered_source_args->pdata[i]; + + ret = append_run_args_for_implicit_component(args, run_args); + if (ret) { + goto error; + } } ret = append_run_args_for_implicit_component(&implicit_lttng_live_args, @@ -4379,7 +4578,6 @@ end: destroy_glist_of_gstring(filter_names); destroy_glist_of_gstring(sink_names); bt_value_put_ref(leftovers); - finalize_implicit_component_args(&implicit_ctf_input_args); finalize_implicit_component_args(&implicit_ctf_output_args); finalize_implicit_component_args(&implicit_lttng_live_args); finalize_implicit_component_args(&implicit_dummy_args); @@ -4389,6 +4587,19 @@ end: finalize_implicit_component_args(&implicit_trimmer_args); bt_value_put_ref(plugin_paths); bt_common_destroy_lttng_live_url_parts(<tng_live_url_parts); + auto_source_discovery_fini(&auto_disc); + + if (discovered_source_args) { + g_ptr_array_free(discovered_source_args, TRUE); + } + + g_free(ctf_fs_source_clock_class_offset_arg); + g_free(ctf_fs_source_clock_class_offset_ns_arg); + + if (auto_disc_comp_name) { + g_string_free(auto_disc_comp_name, TRUE); + } + return cfg; }