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)
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:
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;
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.
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 };
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;
}
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();
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
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:
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 {
/* 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;
}
/* 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;
}
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(
}
/* 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",
}
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(
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;
}
* 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;
}
* 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,
* 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,
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);
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;
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: "
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);
return ret;
}
-static
+BT_HIDDEN
void ctf_fs_destroy(struct ctf_fs_component *ctf_fs)
{
if (!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) {
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
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);
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:
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)
return ret;
}
-BT_HIDDEN
+static
int ctf_fs_find_traces(GList **trace_paths, const char *start_path)
{
int ret;
return ret;
}
-BT_HIDDEN
+static
GList *ctf_fs_create_trace_names(GList *trace_paths, const char *base_path) {
GList *trace_names = NULL;
GList *node;
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)
{
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;
}
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(
* 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) {
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;
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,
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 */
}
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,
.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++) {
end:
bt_value_put_ref(file_groups);
- ctf_fs_trace_destroy(trace);
return ret;
}
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);
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;
}
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) {
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;
}
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;