cli, plugins/ctf/fs-src: Make src.ctf.fs accept multiple root paths
authorSimon Marchi <simon.marchi@efficios.com>
Tue, 23 Apr 2019 16:03:29 +0000 (12:03 -0400)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Fri, 3 May 2019 22:19:39 +0000 (18:19 -0400)
A following patch will make it possible to process multiple traces that
share the same UUID as a single trace.  One requirement is to be able to
do this event when passing multiple arguments, like:

    babeltrace path1 path2 ...

With the current code, this instantiates two src.ctf.fs components, and
therefore makes it impossible to do this merging by UUID.

This patch therefore changes the design so that we only instantiate a
single src.ctf.fs component and pass an array with the paths.

We also need to make the trace-info query support receiving multiple
paths.  One reason is that in general, we want trace-info queries to
support the same parameters as the components.  A more pragmatic reason
is that it will need to do the same kind of UUID-merging anyway.  I
therefore made the trace-info query re-use more of the code used by the
component to locate and create the ctf_fs_trace list.  One difference
between the two usages is that in the case of the query, we don't want
to create IR streams or component ports.  I moved those outside of the
shared code path and made the component do that as a separate step.

One notable change in babeltrace.c is in set_stream_intersections.
We previously extracted the "path" parameter from the component creation
parameter, to make the query parameters.  Instead, we now directly pass
the component creation parameters to the query.  The idea is the same as
above, we want to pass the same parameters to the trace-info query as
what will be used to create the component, since it might alter how the
traces will be open, and therefore the results.

So in practice the changes boil down to:

- babeltrace-cfg-cli-args.c: Make it possible to serialize bt_value of
  type BT_VALUE_TYPE_ARRAY, so we can build the list of paths in a
  bt_value array, then serialize it to send it to "babeltrace run".
  Make it instantiate a single ctf component, this even simplifies the
  code a little bit.
- fs.c: Accept "paths" parameter with a list of paths, rather than
  "path" with a single path, iterate on that list to find traces and
  create trace objects just as before.  Separate creation or IR streams
  and component ports from the ctf_fs_trace creation.
- query.c: Re-use more of fs.c's functions to locate and create
  ctf_fs_trace objects.

There are no functional changes intended, except if you are the kind of
person to pass params by hand to the src.ctf.fs component.

Signed-off-by: Simon Marchi <simon.marchi@efficios.com>
cli/babeltrace-cfg-cli-args.c
cli/babeltrace.c
plugins/ctf/fs-src/fs.c
plugins/ctf/fs-src/fs.h
plugins/ctf/fs-src/query.c

index a125c6dbf6012713e95618cf416dffd9d7f4871f..159421650e5550f195f0520c3f73b374d217c6a7 100644 (file)
@@ -3131,17 +3131,6 @@ void finalize_implicit_component_args(struct implicit_component_args *args)
        bt_value_put_ref(args->extra_params);
 }
 
-static
-void destroy_implicit_component_args(void *args)
-{
-       if (!args) {
-               return;
-       }
-
-       finalize_implicit_component_args(args);
-       g_free(args);
-}
-
 static
 int init_implicit_component_args(struct implicit_component_args *args,
                const char *comp_arg, bool exists)
@@ -3207,22 +3196,12 @@ end:
        return g_string_free(ret, FALSE);
 }
 
-/*
- * Convert `value` to its equivalent representation as a command line parameter
- * value.
- */
-
 static
-gchar *bt_value_to_cli_param_value(bt_value *value)
+int bt_value_to_cli_param_value_append(const bt_value *value, GString *buf)
 {
-       GString *buf;
-       gchar *result = NULL;
+       BT_ASSERT(buf);
 
-       buf = g_string_new(NULL);
-       if (!buf) {
-               print_err_oom();
-               goto error;
-       }
+       int ret = -1;
 
        switch (bt_value_get_type(value)) {
        case BT_VALUE_TYPE_STRING:
@@ -3232,18 +3211,61 @@ gchar *bt_value_to_cli_param_value(bt_value *value)
 
                escaped_str_value = escape_string_value(str_value);
                if (!escaped_str_value) {
-                       goto error;
+                       goto end;
                }
 
-               g_string_printf(buf, "\"%s\"", escaped_str_value);
+               g_string_append_printf(buf, "\"%s\"", escaped_str_value);
 
                g_free(escaped_str_value);
                break;
        }
+       case BT_VALUE_TYPE_ARRAY: {
+               g_string_append_c(buf, '[');
+               uint64_t sz = bt_value_array_get_size(value);
+               for (uint64_t i = 0; i < sz; i++) {
+                       if (i > 0) {
+                               g_string_append_c(buf, ',');
+                       }
+                       const bt_value *item = bt_value_array_borrow_element_by_index_const(value, i);
+                       int ret = bt_value_to_cli_param_value_append(item, buf);
+                       if (ret) {
+                               goto end;
+                       }
+               }
+               g_string_append_c(buf, ']');
+               break;
+       }
        default:
                abort();
        }
 
+       ret = 0;
+
+end:
+       return ret;
+}
+
+/*
+ * Convert `value` to its equivalent representation as a command line parameter
+ * value.
+ */
+
+static
+gchar *bt_value_to_cli_param_value(bt_value *value)
+{
+       GString *buf;
+       gchar *result = NULL;
+
+       buf = g_string_new(NULL);
+       if (!buf) {
+               print_err_oom();
+               goto error;
+       }
+
+       if (bt_value_to_cli_param_value_append(value, buf)) {
+               goto error;
+       }
+
        result = g_string_free(buf, FALSE);
        buf = NULL;
 
@@ -3652,85 +3674,6 @@ end:
        return ret;
 }
 
-static
-struct implicit_component_args *create_implicit_component_args(void)
-{
-       struct implicit_component_args *impl_args =
-               g_new0(struct implicit_component_args, 1);
-
-       if (!impl_args) {
-               goto end;
-       }
-
-       if (init_implicit_component_args(impl_args, NULL, true)) {
-               destroy_implicit_component_args(impl_args);
-               impl_args = NULL;
-               goto end;
-       }
-
-end:
-       return impl_args;
-}
-
-static
-int fill_implicit_ctf_inputs_args(GPtrArray *implicit_ctf_inputs_args,
-               struct implicit_component_args *base_implicit_ctf_input_args,
-               GList *leftovers)
-{
-       int ret = 0;
-       GList *leftover;
-       bt_value_status status;
-
-       for (leftover = leftovers; leftover != NULL;
-                       leftover = g_list_next(leftover)) {
-               GString *gs_leftover = leftover->data;
-               struct implicit_component_args *impl_args =
-                       create_implicit_component_args();
-
-               if (!impl_args) {
-                       print_err_oom();
-                       goto error;
-               }
-
-               impl_args->exists = true;
-               g_string_assign(impl_args->comp_arg,
-                       base_implicit_ctf_input_args->comp_arg->str);
-               g_string_assign(impl_args->params_arg,
-                       base_implicit_ctf_input_args->params_arg->str);
-
-               /*
-                * We need our own copy of the extra parameters because
-                * this is where the unique path goes.
-                */
-               BT_VALUE_PUT_REF_AND_RESET(impl_args->extra_params);
-               status = bt_value_copy(base_implicit_ctf_input_args->extra_params,
-                       &impl_args->extra_params);
-               if (status != BT_VALUE_STATUS_OK) {
-                       print_err_oom();
-                       destroy_implicit_component_args(impl_args);
-                       goto error;
-               }
-
-               /* Append unique path parameter */
-               ret = append_implicit_component_extra_param(impl_args,
-                       "path", gs_leftover->str);
-               if (ret) {
-                       destroy_implicit_component_args(impl_args);
-                       goto error;
-               }
-
-               g_ptr_array_add(implicit_ctf_inputs_args, impl_args);
-       }
-
-       goto end;
-
-error:
-       ret = -1;
-
-end:
-       return ret;
-}
-
 /*
  * Creates a Babeltrace config object from the arguments of a convert
  * command.
@@ -3765,9 +3708,8 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[],
        GList *source_names = NULL;
        GList *filter_names = NULL;
        GList *sink_names = NULL;
-       GList *leftovers = NULL;
-       GPtrArray *implicit_ctf_inputs_args = NULL;
-       struct implicit_component_args base_implicit_ctf_input_args = { 0 };
+       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 };
@@ -3791,7 +3733,7 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[],
                goto end;
        }
 
-       if (init_implicit_component_args(&base_implicit_ctf_input_args,
+       if (init_implicit_component_args(&implicit_ctf_input_args,
                        "source.ctf.fs", false)) {
                goto error;
        }
@@ -3831,13 +3773,6 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[],
                goto error;
        }
 
-       implicit_ctf_inputs_args = g_ptr_array_new_with_free_func(
-               (GDestroyNotify) destroy_implicit_component_args);
-       if (!implicit_ctf_inputs_args) {
-               print_err_oom();
-               goto error;
-       }
-
        all_names = bt_value_map_create();
        if (!all_names) {
                print_err_oom();
@@ -3867,6 +3802,12 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[],
                goto error;
        }
 
+       leftovers = bt_value_array_create();
+       if (!leftovers) {
+               print_err_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
@@ -4233,15 +4174,15 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[],
                        implicit_text_args.exists = true;
                        break;
                case OPT_CLOCK_OFFSET:
-                       base_implicit_ctf_input_args.exists = true;
+                       implicit_ctf_input_args.exists = true;
                        append_implicit_component_param(
-                                       &base_implicit_ctf_input_args,
+                                       &implicit_ctf_input_args,
                                        "clock-class-offset-s", arg);
                        break;
                case OPT_CLOCK_OFFSET_NS:
-                       base_implicit_ctf_input_args.exists = true;
+                       implicit_ctf_input_args.exists = true;
                        append_implicit_component_param(
-                                       &base_implicit_ctf_input_args,
+                                       &implicit_ctf_input_args,
                                        "clock-class-offset-ns", arg);
                        break;
                case OPT_CLOCK_SECONDS:
@@ -4332,7 +4273,7 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[],
                        got_input_format_opt = true;
 
                        if (strcmp(arg, "ctf") == 0) {
-                               base_implicit_ctf_input_args.exists = true;
+                               implicit_ctf_input_args.exists = true;
                        } else if (strcmp(arg, "lttng-live") == 0) {
                                implicit_lttng_live_args.exists = true;
                        } else {
@@ -4441,16 +4382,8 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[],
 
        /* Consume and keep leftover arguments */
        while ((leftover = poptGetArg(pc))) {
-               GString *gs_leftover = g_string_new(leftover);
-
-               if (!gs_leftover) {
-                       print_err_oom();
-                       goto error;
-               }
-
-               leftovers = g_list_append(leftovers, gs_leftover);
-               if (!leftovers) {
-                       g_string_free(gs_leftover, TRUE);
+               bt_value_status status = bt_value_array_append_string_element(leftovers, leftover);
+               if (status != BT_VALUE_STATUS_OK) {
                        print_err_oom();
                        goto error;
                }
@@ -4458,14 +4391,14 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[],
 
        /* Print CTF metadata or print LTTng live sessions */
        if (print_ctf_metadata) {
-               GString *gs_leftover;
+               const bt_value *bt_val_leftover;
 
-               if (g_list_length(leftovers) == 0) {
+               if (bt_value_array_is_empty(leftovers)) {
                        printf_err("--output-format=ctf-metadata specified without a path\n");
                        goto error;
                }
 
-               if (g_list_length(leftovers) > 1) {
+               if (bt_value_array_get_size(leftovers) > 1) {
                        printf_err("Too many paths specified for --output-format=ctf-metadata\n");
                        goto error;
                }
@@ -4475,9 +4408,9 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[],
                        goto error;
                }
 
-               gs_leftover = leftovers->data;
+               bt_val_leftover = bt_value_array_borrow_element_by_index_const(leftovers, 0);
                g_string_assign(cfg->cmd_data.print_ctf_metadata.path,
-                       gs_leftover->str);
+                               bt_value_string_get(bt_val_leftover));
 
                if (output) {
                        g_string_assign(
@@ -4543,18 +4476,18 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[],
        }
 
        /* Decide where the leftover argument(s) go */
-       if (g_list_length(leftovers) > 0) {
+       if (bt_value_array_get_size(leftovers) > 0) {
                if (implicit_lttng_live_args.exists) {
-                       GString *gs_leftover;
+                       const bt_value *bt_val_leftover;
 
-                       if (g_list_length(leftovers) > 1) {
+                       if (bt_value_array_get_size(leftovers) > 1) {
                                printf_err("Too many URLs specified for --output-format=lttng-live\n");
                                goto error;
                        }
 
-                       gs_leftover = leftovers->data;
+                       bt_val_leftover = bt_value_array_borrow_element_by_index_const(leftovers, 0);
                        lttng_live_url_parts =
-                               bt_common_parse_lttng_live_url(gs_leftover->str,
+                               bt_common_parse_lttng_live_url(bt_value_string_get(bt_val_leftover),
                                        error_buf, sizeof(error_buf));
                        if (!lttng_live_url_parts.proto) {
                                printf_err("Invalid LTTng live URL format: %s\n",
@@ -4571,7 +4504,7 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[],
                                }
 
                                g_string_assign(cfg->cmd_data.print_lttng_live_sessions.url,
-                                       gs_leftover->str);
+                                       bt_value_string_get(bt_val_leftover));
 
                                if (output) {
                                        g_string_assign(
@@ -4584,20 +4517,19 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[],
 
                        ret = append_implicit_component_extra_param(
                                &implicit_lttng_live_args, "url",
-                               gs_leftover->str);
+                               bt_value_string_get(bt_val_leftover));
                        if (ret) {
                                goto error;
                        }
                } else {
                        /*
-                        * Append one implicit component argument set
-                        * for each leftover (souce.ctf.fs paths). Copy
-                        * the base implicit component arguments.
-                        * Note that they still have to be named later.
+                        * Create one source.ctf.fs component, pass it an array
+                        * with the leftovers.
+                        * Note that it still has to be named later.
                         */
-                       ret = fill_implicit_ctf_inputs_args(
-                               implicit_ctf_inputs_args,
-                               &base_implicit_ctf_input_args, leftovers);
+                       implicit_ctf_input_args.exists = true;
+                       ret = append_parameter_to_args(implicit_ctf_input_args.extra_params,
+                                       "paths", leftovers);
                        if (ret) {
                                goto error;
                        }
@@ -4608,10 +4540,9 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[],
         * Ensure mutual exclusion between implicit `source.ctf.fs` and
         * `source.ctf.lttng-live` components.
         */
-       if (base_implicit_ctf_input_args.exists &&
-                       implicit_lttng_live_args.exists) {
+       if (implicit_ctf_input_args.exists && implicit_lttng_live_args.exists) {
                printf_err("Cannot create both implicit `%s` and `%s` components\n",
-                       base_implicit_ctf_input_args.comp_arg->str,
+                       implicit_ctf_input_args.comp_arg->str,
                        implicit_lttng_live_args.comp_arg->str);
                goto error;
        }
@@ -4621,29 +4552,23 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[],
         * components exists, make sure there's at least one leftover
         * (which is the path or URL).
         */
-       if (base_implicit_ctf_input_args.exists &&
-                       g_list_length(leftovers) == 0) {
+       if (implicit_ctf_input_args.exists && bt_value_array_is_empty(leftovers)) {
                printf_err("Missing path for implicit `%s` component\n",
-                       base_implicit_ctf_input_args.comp_arg->str);
+                       implicit_ctf_input_args.comp_arg->str);
                goto error;
        }
 
-       if (implicit_lttng_live_args.exists && g_list_length(leftovers) == 0) {
+       if (implicit_lttng_live_args.exists && bt_value_array_is_empty(leftovers)) {
                printf_err("Missing URL for implicit `%s` component\n",
                        implicit_lttng_live_args.comp_arg->str);
                goto error;
        }
 
        /* Assign names to implicit components */
-       for (i = 0; i < implicit_ctf_inputs_args->len; i++) {
-               struct implicit_component_args *impl_args =
-                       g_ptr_array_index(implicit_ctf_inputs_args, i);
-
-               ret = assign_name_to_implicit_component(impl_args,
-                       "source-ctf-fs", all_names, &source_names, true);
-               if (ret) {
-                       goto error;
-               }
+       ret = assign_name_to_implicit_component(&implicit_ctf_input_args,
+               "source-ctf-fs", all_names, &source_names, true);
+       if (ret) {
+               goto error;
        }
 
        ret = assign_name_to_implicit_component(&implicit_lttng_live_args,
@@ -4729,15 +4654,9 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[],
         * Append the equivalent run arguments for the implicit
         * components.
         */
-       for (i = 0; i < implicit_ctf_inputs_args->len; i++) {
-               struct implicit_component_args *impl_args =
-                       g_ptr_array_index(implicit_ctf_inputs_args, i);
-
-               ret = append_run_args_for_implicit_component(impl_args,
-                       run_args);
-               if (ret) {
-                       goto error;
-               }
+       ret = append_run_args_for_implicit_component(&implicit_ctf_input_args, run_args);
+       if (ret) {
+               goto error;
        }
 
        ret = append_run_args_for_implicit_component(&implicit_lttng_live_args,
@@ -4874,17 +4793,13 @@ end:
                g_string_free(cur_name_prefix, TRUE);
        }
 
-       if (implicit_ctf_inputs_args) {
-               g_ptr_array_free(implicit_ctf_inputs_args, TRUE);
-       }
-
        bt_value_put_ref(run_args);
        bt_value_put_ref(all_names);
        destroy_glist_of_gstring(source_names);
        destroy_glist_of_gstring(filter_names);
        destroy_glist_of_gstring(sink_names);
-       destroy_glist_of_gstring(leftovers);
-       finalize_implicit_component_args(&base_implicit_ctf_input_args);
+       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);
index 436c488e1b612bdf71f7fac576352a13a98e7ee6..a0de86f770139881ca8599f97a6312ff704b079a 100644 (file)
@@ -2149,10 +2149,7 @@ int set_stream_intersections(struct cmd_run_ctx *ctx,
        int ret = 0;
        uint64_t trace_idx;
        int64_t trace_count;
-       bt_value_status value_status;
        const char *path = NULL;
-       const bt_value *component_path_value = NULL;
-       bt_value *query_params = NULL;
        const bt_value *query_result = NULL;
        const bt_value *trace_info = NULL;
        const bt_value *intersection_range = NULL;
@@ -2168,33 +2165,8 @@ int set_stream_intersections(struct cmd_run_ctx *ctx,
        const bt_component_class *comp_cls =
                bt_component_class_source_as_component_class_const(src_comp_cls);
 
-       component_path_value = bt_value_map_borrow_entry_value(cfg_comp->params,
-                                                              "path");
-       if (component_path_value && !bt_value_is_string(component_path_value)) {
-               BT_LOGD("Cannot get path parameter: component-name=%s",
-                       cfg_comp->instance_name->str);
-               ret = -1;
-               goto error;
-       }
-
-       path = bt_value_string_get(component_path_value);
-       query_params = bt_value_map_create();
-       if (!query_params) {
-               BT_LOGE_STR("Cannot create query parameters.");
-               ret = -1;
-               goto error;
-       }
-
-       value_status = bt_value_map_insert_string_entry(query_params, "path",
-               path);
-       if (value_status != BT_VALUE_STATUS_OK) {
-               BT_LOGE_STR("Cannot insert path parameter in query parameter map.");
-               ret = -1;
-               goto error;
-       }
-
        ret = query(comp_cls, "trace-info",
-               query_params, &query_result,
+               cfg_comp->params, &query_result,
                &fail_reason);
        if (ret) {
                BT_LOGD("Component class does not support the `trace-info` query: %s: "
@@ -2372,7 +2344,6 @@ error:
                path ? path : "(unknown)",
                bt_common_color_reset());
 end:
-       bt_value_put_ref(query_params);
        bt_value_put_ref(query_result);
        g_free(port_id);
        g_free(trace_range);
index e20a2ec7412d0e584889cc69e23547b9bf279d14..801fc883d6cf829ddd7c12893e9bc20e4d798bf6 100644 (file)
@@ -291,7 +291,7 @@ end:
        return ret;
 }
 
-static
+BT_HIDDEN
 void ctf_fs_destroy(struct ctf_fs_component *ctf_fs)
 {
        if (!ctf_fs) {
@@ -309,7 +309,22 @@ void ctf_fs_destroy(struct ctf_fs_component *ctf_fs)
        g_free(ctf_fs);
 }
 
-BT_HIDDEN
+static
+void port_data_destroy(struct ctf_fs_port_data *port_data)
+{
+       if (!port_data) {
+               return;
+       }
+
+       g_free(port_data);
+}
+
+static
+void port_data_destroy_notifier(void *data) {
+       port_data_destroy(data);
+}
+
+static
 void ctf_fs_trace_destroy(struct ctf_fs_trace *ctf_fs_trace)
 {
        if (!ctf_fs_trace) {
@@ -345,21 +360,42 @@ void ctf_fs_trace_destroy_notifier(void *data)
        ctf_fs_trace_destroy(trace);
 }
 
-void ctf_fs_finalize(bt_self_component_source *component)
+struct ctf_fs_component *ctf_fs_component_create(void)
 {
-       ctf_fs_destroy(bt_self_component_get_data(
-               bt_self_component_source_as_self_component(component)));
-}
+       struct ctf_fs_component *ctf_fs;
 
-static
-void port_data_destroy(void *data) {
-       struct ctf_fs_port_data *port_data = data;
+       ctf_fs = g_new0(struct ctf_fs_component, 1);
+       if (!ctf_fs) {
+               goto error;
+       }
 
-       if (!port_data) {
-               return;
+       ctf_fs->port_data =
+               g_ptr_array_new_with_free_func(port_data_destroy_notifier);
+       if (!ctf_fs->port_data) {
+               goto error;
        }
 
-       g_free(port_data);
+       ctf_fs->traces =
+               g_ptr_array_new_with_free_func(ctf_fs_trace_destroy_notifier);
+       if (!ctf_fs->traces) {
+               goto error;
+       }
+
+       goto end;
+
+error:
+       if (ctf_fs) {
+               ctf_fs_destroy(ctf_fs);
+       }
+
+end:
+       return ctf_fs;
+}
+
+void ctf_fs_finalize(bt_self_component_source *component)
+{
+       ctf_fs_destroy(bt_self_component_get_data(
+               bt_self_component_source_as_self_component(component)));
 }
 
 static
@@ -764,7 +800,6 @@ int create_ds_file_groups(struct ctf_fs_trace *ctf_fs_trace)
        const char *basename;
        GError *error = NULL;
        GDir *dir = NULL;
-       size_t i;
 
        /* Check each file in the path directory, except specific ones */
        dir = g_dir_open(ctf_fs_trace->path->str, 0, &error);
@@ -835,68 +870,6 @@ int create_ds_file_groups(struct ctf_fs_trace *ctf_fs_trace)
                ctf_fs_file_destroy(file);
        }
 
-       if (!ctf_fs_trace->trace) {
-               goto end;
-       }
-
-       /*
-        * At this point, DS file groupes are created, but their
-        * associated stream objects do not exist yet. This is because
-        * we need to name the created stream object with the data
-        * stream file's path. We have everything we need here to do
-        * this.
-        */
-       for (i = 0; i < ctf_fs_trace->ds_file_groups->len; i++) {
-               struct ctf_fs_ds_file_group *ds_file_group =
-                       g_ptr_array_index(ctf_fs_trace->ds_file_groups, i);
-               GString *name = get_stream_instance_unique_name(ds_file_group);
-
-               if (!name) {
-                       goto error;
-               }
-
-               if (ds_file_group->sc->ir_sc) {
-                       BT_ASSERT(ctf_fs_trace->trace);
-
-                       if (ds_file_group->stream_id == UINT64_C(-1)) {
-                               /* No stream ID: use 0 */
-                               ds_file_group->stream = bt_stream_create_with_id(
-                                       ds_file_group->sc->ir_sc,
-                                       ctf_fs_trace->trace,
-                                       ctf_fs_trace->next_stream_id);
-                               ctf_fs_trace->next_stream_id++;
-                       } else {
-                               /* Specific stream ID */
-                               ds_file_group->stream = bt_stream_create_with_id(
-                                       ds_file_group->sc->ir_sc,
-                                       ctf_fs_trace->trace,
-                                       (uint64_t) ds_file_group->stream_id);
-                       }
-               } else {
-                       ds_file_group->stream = NULL;
-               }
-
-               if (!ds_file_group->stream) {
-                       BT_LOGE("Cannot create stream for DS file group: "
-                               "addr=%p, stream-name=\"%s\"",
-                               ds_file_group, name->str);
-                       g_string_free(name, TRUE);
-                       goto error;
-               }
-
-               ret = bt_stream_set_name(ds_file_group->stream,
-                       name->str);
-               if (ret) {
-                       BT_LOGE("Cannot set stream's name: "
-                               "addr=%p, stream-name=\"%s\"",
-                               ds_file_group->stream, name->str);
-                       g_string_free(name, TRUE);
-                       goto error;
-               }
-
-               g_string_free(name, TRUE);
-       }
-
        goto end;
 
 error:
@@ -963,7 +936,7 @@ end:
        return ret;
 }
 
-BT_HIDDEN
+static
 struct ctf_fs_trace *ctf_fs_trace_create(bt_self_component_source *self_comp,
                const char *path, const char *name,
                struct ctf_fs_metadata_config *metadata_config)
@@ -1089,7 +1062,7 @@ end:
        return ret;
 }
 
-BT_HIDDEN
+static
 int ctf_fs_find_traces(GList **trace_paths, const char *start_path)
 {
        int ret;
@@ -1160,7 +1133,7 @@ end:
        return ret;
 }
 
-BT_HIDDEN
+static
 GList *ctf_fs_create_trace_names(GList *trace_paths, const char *base_path) {
        GList *trace_names = NULL;
        GList *node;
@@ -1213,8 +1186,10 @@ GList *ctf_fs_create_trace_names(GList *trace_paths, const char *base_path) {
        return trace_names;
 }
 
+/* Helper for ctf_fs_component_create_ctf_fs_traces, to handle a single path/root. */
+
 static
-int create_ctf_fs_traces(bt_self_component_source *self_comp,
+int ctf_fs_component_create_ctf_fs_traces_one_root(bt_self_component_source *self_comp,
                struct ctf_fs_component *ctf_fs,
                const char *path_param)
 {
@@ -1265,11 +1240,6 @@ int create_ctf_fs_traces(bt_self_component_source *self_comp,
                        goto error;
                }
 
-               ret = create_ports_for_trace(ctf_fs, ctf_fs_trace);
-               if (ret) {
-                       goto error;
-               }
-
                g_ptr_array_add(ctf_fs->traces, ctf_fs_trace);
                ctf_fs_trace = NULL;
        }
@@ -1308,18 +1278,158 @@ end:
        return ret;
 }
 
+int ctf_fs_component_create_ctf_fs_traces(bt_self_component_source *self_comp,
+               struct ctf_fs_component *ctf_fs,
+               const bt_value *paths_value)
+{
+       int ret = 0;
+       uint64_t i;
+
+       for (i = 0; i < bt_value_array_get_size(paths_value); i++) {
+               const bt_value *path_value = bt_value_array_borrow_element_by_index_const(paths_value, i);
+               const char *path = bt_value_string_get(path_value);
+
+               ret = ctf_fs_component_create_ctf_fs_traces_one_root(self_comp, ctf_fs, path);
+               if (ret) {
+                       goto end;
+               }
+       }
+
+end:
+       return ret;
+}
+
+/* Create the IR stream objects for ctf_fs_trace. */
+
+static
+int create_streams_for_trace(struct ctf_fs_trace *ctf_fs_trace)
+{
+       int ret;
+       GString *name = NULL;
+       guint i;
+
+       for (i = 0; i < ctf_fs_trace->ds_file_groups->len; i++) {
+               struct ctf_fs_ds_file_group *ds_file_group =
+                       g_ptr_array_index(ctf_fs_trace->ds_file_groups, i);
+               name = get_stream_instance_unique_name(ds_file_group);
+
+               if (!name) {
+                       goto error;
+               }
+
+               if (ds_file_group->sc->ir_sc) {
+                       BT_ASSERT(ctf_fs_trace->trace);
+
+                       if (ds_file_group->stream_id == UINT64_C(-1)) {
+                               /* No stream ID: use 0 */
+                               ds_file_group->stream = bt_stream_create_with_id(
+                                       ds_file_group->sc->ir_sc,
+                                       ctf_fs_trace->trace,
+                                       ctf_fs_trace->next_stream_id);
+                               ctf_fs_trace->next_stream_id++;
+                       } else {
+                               /* Specific stream ID */
+                               ds_file_group->stream = bt_stream_create_with_id(
+                                       ds_file_group->sc->ir_sc,
+                                       ctf_fs_trace->trace,
+                                       (uint64_t) ds_file_group->stream_id);
+                       }
+               } else {
+                       ds_file_group->stream = NULL;
+               }
+
+               if (!ds_file_group->stream) {
+                       BT_LOGE("Cannot create stream for DS file group: "
+                               "addr=%p, stream-name=\"%s\"",
+                               ds_file_group, name->str);
+                       goto error;
+               }
+
+               ret = bt_stream_set_name(ds_file_group->stream,
+                       name->str);
+               if (ret) {
+                       BT_LOGE("Cannot set stream's name: "
+                               "addr=%p, stream-name=\"%s\"",
+                               ds_file_group->stream, name->str);
+                       goto error;
+               }
+
+               g_string_free(name, TRUE);
+               name = NULL;
+       }
+
+       ret = 0;
+       goto end;
+
+error:
+       ret = -1;
+
+end:
+
+       if (name) {
+               g_string_free(name, TRUE);
+       }
+       return ret;
+}
+
+bool validate_paths_parameter(const bt_value *paths)
+{
+       bool ret;
+       bt_value_type type;
+       uint64_t i;
+
+       if (!paths) {
+               BT_LOGE("missing \"paths\" parameter");
+               goto error;
+       }
+
+       type = bt_value_get_type(paths);
+       if (type != BT_VALUE_TYPE_ARRAY) {
+               BT_LOGE("`paths` parameter: expecting array value: type=%s",
+                       bt_common_value_type_string(type));
+               goto error;
+       }
+
+       for (i = 0; i < bt_value_array_get_size(paths); i++) {
+               const bt_value *elem;
+
+               elem = bt_value_array_borrow_element_by_index_const(paths, i);
+               type = bt_value_get_type(elem);
+               if (type != BT_VALUE_TYPE_STRING) {
+                       BT_LOGE("`paths` parameter: expecting string value: index=%" PRIu64 ", type=%s",
+                               i, bt_common_value_type_string(type));
+                       goto error;
+               }
+       }
+
+       ret = true;
+       goto end;
+
+error:
+       ret = false;
+
+end:
+       return ret;
+}
+
 static
 struct ctf_fs_component *ctf_fs_create(
                bt_self_component_source *self_comp,
                const bt_value *params)
 {
-       struct ctf_fs_component *ctf_fs;
+       struct ctf_fs_component *ctf_fs = NULL;
        const bt_value *value = NULL;
-       const char *path_param;
+       guint i;
+       const bt_value *paths_value;
 
-       ctf_fs = g_new0(struct ctf_fs_component, 1);
+       paths_value = bt_value_map_borrow_entry_value_const(params, "paths");
+       if (!validate_paths_parameter(paths_value)) {
+               goto error;
+       }
+
+       ctf_fs = ctf_fs_component_create();
        if (!ctf_fs) {
-               goto end;
+               goto error;
        }
 
        bt_self_component_set_data(
@@ -1332,12 +1442,7 @@ struct ctf_fs_component *ctf_fs_create(
         * private component should also exist.
         */
        ctf_fs->self_comp = self_comp;
-       value = bt_value_map_borrow_entry_value_const(params, "path");
-       if (value && !bt_value_is_string(value)) {
-               goto error;
-       }
 
-       path_param = bt_value_string_get(value);
        value = bt_value_map_borrow_entry_value_const(params,
                "clock-class-offset-s");
        if (value) {
@@ -1358,19 +1463,20 @@ struct ctf_fs_component *ctf_fs_create(
                ctf_fs->metadata_config.clock_class_offset_ns = bt_value_integer_get(value);
        }
 
-       ctf_fs->port_data = g_ptr_array_new_with_free_func(port_data_destroy);
-       if (!ctf_fs->port_data) {
+       if (ctf_fs_component_create_ctf_fs_traces(self_comp, ctf_fs, paths_value)) {
                goto error;
        }
 
-       ctf_fs->traces = g_ptr_array_new_with_free_func(
-                       ctf_fs_trace_destroy_notifier);
-       if (!ctf_fs->traces) {
-               goto error;
-       }
+       for (i = 0; i < ctf_fs->traces->len; i++) {
+               struct ctf_fs_trace *trace = g_ptr_array_index(ctf_fs->traces, i);
 
-       if (create_ctf_fs_traces(self_comp, ctf_fs, path_param)) {
-               goto error;
+               if (create_streams_for_trace(trace)) {
+                       goto error;
+               }
+
+               if (create_ports_for_trace(ctf_fs, trace)) {
+                       goto error;
+               }
        }
 
        goto end;
index e254aeb4416345b224dd0b31fec4e40df4b6610e..1ee4a6821e91bef0da3ca5f3c2fad15b11bd6f1b 100644 (file)
@@ -164,20 +164,6 @@ bt_query_status ctf_fs_query(
                const char *object, const bt_value *params,
                const bt_value **result);
 
-BT_HIDDEN
-struct ctf_fs_trace *ctf_fs_trace_create(bt_self_component_source *self_comp,
-               const char *path, const char *name,
-               struct ctf_fs_metadata_config *config);
-
-BT_HIDDEN
-void ctf_fs_trace_destroy(struct ctf_fs_trace *trace);
-
-BT_HIDDEN
-int ctf_fs_find_traces(GList **trace_paths, const char *start_path);
-
-BT_HIDDEN
-GList *ctf_fs_create_trace_names(GList *trace_paths, const char *base_path);
-
 BT_HIDDEN
 bt_self_message_iterator_status ctf_fs_iterator_init(
                bt_self_message_iterator *self_msg_iter,
@@ -197,4 +183,31 @@ BT_HIDDEN
 bt_self_message_iterator_status ctf_fs_iterator_seek_beginning(
                bt_self_message_iterator *message_iterator);
 
+/* Create and initialize a new, empty ctf_fs_component. */
+
+BT_HIDDEN
+struct ctf_fs_component *ctf_fs_component_create(void);
+
+/*
+ * Search recursively under all paths in `paths_value` (an array of strings),
+ * for CTF traces. For each CTF trace found, create a ctf_fs_trace in
+ * `ctf_fs` representing that trace.
+ */
+
+BT_HIDDEN
+int ctf_fs_component_create_ctf_fs_traces(bt_self_component_source *self_comp,
+               struct ctf_fs_component *ctf_fs,
+               const bt_value *paths_value);
+
+/* Free `ctf_fs` and everything it owns. */
+
+BT_HIDDEN
+void ctf_fs_destroy(struct ctf_fs_component *ctf_fs);
+
+/* Validate the "paths" parameter passed to this component.  It must be
+   present, and it must be an array of strings. */
+
+BT_HIDDEN
+bool validate_paths_parameter(const bt_value *paths);
+
 #endif /* BABELTRACE_PLUGIN_CTF_FS_H */
index 0e2fb991b088eb57215bf306e9b2e94b163a33ba..0235cf6bccf40a983d29b06bf62b79186c9f670a 100644 (file)
@@ -327,14 +327,12 @@ end:
 }
 
 static
-int populate_trace_info(const char *trace_path, const char *trace_name,
-               bt_value *trace_info)
+int populate_trace_info(const struct ctf_fs_trace *trace, bt_value *trace_info)
 {
        int ret = 0;
        size_t group_idx;
-       struct ctf_fs_trace *trace = NULL;
        bt_value_status status;
-       bt_value *file_groups;
+       bt_value *file_groups = NULL;
        struct range trace_range = {
                .begin_ns = INT64_MAX,
                .end_ns = 0,
@@ -346,38 +344,31 @@ int populate_trace_info(const char *trace_path, const char *trace_name,
                .set = false,
        };
 
+       BT_ASSERT(trace->ds_file_groups);
+       /* Add trace range info only if it contains streams. */
+       if (trace->ds_file_groups->len == 0) {
+               ret = -1;
+               goto end;
+       }
+
        file_groups = bt_value_array_create();
        if (!file_groups) {
                goto end;
        }
 
        status = bt_value_map_insert_string_entry(trace_info, "name",
-               trace_name);
+               trace->name->str);
        if (status != BT_VALUE_STATUS_OK) {
                ret = -1;
                goto end;
        }
        status = bt_value_map_insert_string_entry(trace_info, "path",
-                       trace_path);
+               trace->path->str);
        if (status != BT_VALUE_STATUS_OK) {
                ret = -1;
                goto end;
        }
 
-       trace = ctf_fs_trace_create(NULL, trace_path, trace_name, NULL);
-       if (!trace) {
-               BT_LOGE("Failed to create fs trace at \'%s\'", trace_path);
-               ret = -1;
-               goto end;
-       }
-
-       BT_ASSERT(trace->ds_file_groups);
-       /* Add trace range info only if it contains streams. */
-       if (trace->ds_file_groups->len == 0) {
-               ret = -1;
-               goto end;
-       }
-
        /* Find range of all stream groups, and of the trace. */
        for (group_idx = 0; group_idx < trace->ds_file_groups->len;
                        group_idx++) {
@@ -443,7 +434,6 @@ int populate_trace_info(const char *trace_path, const char *trace_name,
 
 end:
        bt_value_put_ref(file_groups);
-       ctf_fs_trace_destroy(trace);
        return ret;
 }
 
@@ -453,16 +443,12 @@ bt_query_status trace_info_query(
                const bt_value *params,
                const bt_value **user_result)
 {
+       struct ctf_fs_component *ctf_fs = NULL;
        bt_query_status status = BT_QUERY_STATUS_OK;
        bt_value *result = NULL;
-       const bt_value *path_value = NULL;
+       const bt_value *paths_value = NULL;
        int ret = 0;
-       const char *path = NULL;
-       GList *trace_paths = NULL;
-       GList *trace_names = NULL;
-       GList *tp_node = NULL;
-       GList *tn_node = NULL;
-       GString *normalized_path = NULL;
+       guint i;
 
        BT_ASSERT(params);
 
@@ -472,25 +458,17 @@ bt_query_status trace_info_query(
                goto error;
        }
 
-       path_value = bt_value_map_borrow_entry_value_const(params, "path");
-       path = bt_value_string_get(path_value);
-
-       normalized_path = bt_common_normalize_path(path, NULL);
-       if (!normalized_path) {
-               BT_LOGE("Failed to normalize path: `%s`.", path);
+       paths_value = bt_value_map_borrow_entry_value_const(params, "paths");
+       if (!validate_paths_parameter(paths_value)) {
                goto error;
        }
-       BT_ASSERT(path);
 
-       ret = ctf_fs_find_traces(&trace_paths, normalized_path->str);
-       if (ret) {
+       ctf_fs = ctf_fs_component_create();
+       if (!ctf_fs) {
                goto error;
        }
 
-       trace_names = ctf_fs_create_trace_names(trace_paths,
-               normalized_path->str);
-       if (!trace_names) {
-               BT_LOGE("Cannot create trace names from trace paths.");
+       if (ctf_fs_component_create_ctf_fs_traces(NULL, ctf_fs, paths_value)) {
                goto error;
        }
 
@@ -500,14 +478,13 @@ bt_query_status trace_info_query(
                goto error;
        }
 
-       /* Iterates over both trace paths and names simultaneously. */
-       for (tp_node = trace_paths, tn_node = trace_names; tp_node;
-                       tp_node = g_list_next(tp_node),
-                       tn_node = g_list_next(tn_node)) {
-               GString *trace_path = tp_node->data;
-               GString *trace_name = tn_node->data;
-               bt_value_status status;
+       for (i = 0; i < ctf_fs->traces->len; i++) {
+               struct ctf_fs_trace *trace;
                bt_value *trace_info;
+               bt_value_status status;
+
+               trace = g_ptr_array_index(ctf_fs->traces, i);
+               BT_ASSERT(trace);
 
                trace_info = bt_value_map_create();
                if (!trace_info) {
@@ -515,8 +492,7 @@ bt_query_status trace_info_query(
                        goto error;
                }
 
-               ret = populate_trace_info(trace_path->str, trace_name->str,
-                       trace_info);
+               ret = populate_trace_info(trace, trace_info);
                if (ret) {
                        bt_value_put_ref(trace_info);
                        goto error;
@@ -540,24 +516,9 @@ error:
        }
 
 end:
-       if (normalized_path) {
-               g_string_free(normalized_path, TRUE);
-       }
-       if (trace_paths) {
-               for (tp_node = trace_paths; tp_node; tp_node = g_list_next(tp_node)) {
-                       if (tp_node->data) {
-                               g_string_free(tp_node->data, TRUE);
-                       }
-               }
-               g_list_free(trace_paths);
-       }
-       if (trace_names) {
-               for (tn_node = trace_names; tn_node; tn_node = g_list_next(tn_node)) {
-                       if (tn_node->data) {
-                               g_string_free(tn_node->data, TRUE);
-                       }
-               }
-               g_list_free(trace_names);
+       if (ctf_fs) {
+               ctf_fs_destroy(ctf_fs);
+               ctf_fs = NULL;
        }
 
        *user_result = result;
This page took 0.045826 seconds and 4 git commands to generate.