/*
- * fs.c
- *
- * Babeltrace CTF file system Reader Component
+ * SPDX-License-Identifier: MIT
*
* Copyright 2015-2017 Philippe Proulx <pproulx@efficios.com>
* Copyright 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com>
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Babeltrace CTF file system Reader Component
*/
#define BT_COMP_LOG_SELF_COMP self_comp
}
static
-bt_component_class_message_iterator_next_method_status ctf_fs_iterator_next_one(
+bt_message_iterator_class_next_method_status ctf_fs_iterator_next_one(
struct ctf_fs_msg_iter_data *msg_iter_data,
const bt_message **out_msg)
{
- bt_component_class_message_iterator_next_method_status status;
+ bt_message_iterator_class_next_method_status status;
enum ctf_msg_iter_status msg_iter_status;
bt_logging_level log_level = msg_iter_data->log_level;
switch (msg_iter_status) {
case CTF_MSG_ITER_STATUS_OK:
/* Cool, message has been written to *out_msg. */
- status = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_NEXT_METHOD_STATUS_OK;
+ status = BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_OK;
break;
case CTF_MSG_ITER_STATUS_EOF:
- status = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_NEXT_METHOD_STATUS_END;
+ status = BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_END;
break;
case CTF_MSG_ITER_STATUS_AGAIN:
case CTF_MSG_ITER_MEDIUM_STATUS_ERROR:
BT_MSG_ITER_LOGE_APPEND_CAUSE(msg_iter_data->self_msg_iter,
"Failed to get next message from CTF message iterator.");
- status = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_NEXT_METHOD_STATUS_ERROR;
+ status = BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_ERROR;
break;
case CTF_MSG_ITER_MEDIUM_STATUS_MEMORY_ERROR:
BT_MSG_ITER_LOGE_APPEND_CAUSE(msg_iter_data->self_msg_iter,
"Failed to get next message from CTF message iterator.");
- status = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_NEXT_METHOD_STATUS_MEMORY_ERROR;
+ status = BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_MEMORY_ERROR;
break;
default:
}
BT_HIDDEN
-bt_component_class_message_iterator_next_method_status ctf_fs_iterator_next(
+bt_message_iterator_class_next_method_status ctf_fs_iterator_next(
bt_self_message_iterator *iterator,
bt_message_array_const msgs, uint64_t capacity,
uint64_t *count)
{
- bt_component_class_message_iterator_next_method_status status;
+ bt_message_iterator_class_next_method_status status;
struct ctf_fs_msg_iter_data *msg_iter_data =
bt_self_message_iterator_get_data(iterator);
uint64_t i = 0;
do {
status = ctf_fs_iterator_next_one(msg_iter_data, &msgs[i]);
- if (status == BT_COMPONENT_CLASS_MESSAGE_ITERATOR_NEXT_METHOD_STATUS_OK) {
+ if (status == BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_OK) {
i++;
}
} while (i < capacity &&
- status == BT_COMPONENT_CLASS_MESSAGE_ITERATOR_NEXT_METHOD_STATUS_OK);
+ status == BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_OK);
if (i > 0) {
/*
* Even if ctf_fs_iterator_next_one() returned something
- * else than BT_COMPONENT_CLASS_MESSAGE_ITERATOR_NEXT_METHOD_STATUS_OK, we
+ * else than BT_MESSAGE_ITERATOR_NEXT_METHOD_STATUS_OK, we
* accumulated message objects in the output
* message array, so we need to return
- * BT_COMPONENT_CLASS_MESSAGE_ITERATOR_NEXT_METHOD_STATUS_OK so that they are
+ * BT_MESSAGE_ITERATOR_NEXT_METHOD_STATUS_OK so that they are
* transfered to downstream. This other status occurs
* again the next time muxer_msg_iter_do_next() is
* called, possibly without any accumulated
}
*count = i;
- status = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_NEXT_METHOD_STATUS_OK;
+ status = BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_OK;
}
end:
}
BT_HIDDEN
-bt_component_class_message_iterator_seek_beginning_method_status
+bt_message_iterator_class_seek_beginning_method_status
ctf_fs_iterator_seek_beginning(bt_self_message_iterator *it)
{
struct ctf_fs_msg_iter_data *msg_iter_data =
ctf_msg_iter_reset(msg_iter_data->msg_iter);
ctf_fs_ds_group_medops_data_reset(msg_iter_data->msg_iter_medops_data);
- return BT_COMPONENT_CLASS_MESSAGE_ITERATOR_SEEK_BEGINNING_METHOD_STATUS_OK;
+ return BT_MESSAGE_ITERATOR_CLASS_SEEK_BEGINNING_METHOD_STATUS_OK;
}
BT_HIDDEN
bt_self_message_iterator_get_data(it));
}
+static
+bt_message_iterator_class_initialize_method_status
+ctf_msg_iter_medium_status_to_msg_iter_initialize_status
+ (enum ctf_msg_iter_medium_status status)
+{
+ switch (status) {
+ case CTF_MSG_ITER_MEDIUM_STATUS_EOF:
+ case CTF_MSG_ITER_MEDIUM_STATUS_AGAIN:
+ case CTF_MSG_ITER_MEDIUM_STATUS_ERROR:
+ return BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_ERROR;
+ case CTF_MSG_ITER_MEDIUM_STATUS_MEMORY_ERROR:
+ return BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_MEMORY_ERROR;
+ case CTF_MSG_ITER_MEDIUM_STATUS_OK:
+ return BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_OK;
+ }
+
+ bt_common_abort();
+}
+
BT_HIDDEN
-bt_component_class_message_iterator_initialize_method_status ctf_fs_iterator_init(
+bt_message_iterator_class_initialize_method_status ctf_fs_iterator_init(
bt_self_message_iterator *self_msg_iter,
bt_self_message_iterator_configuration *config,
- bt_self_component_source *self_comp_src,
bt_self_component_port_output *self_port)
{
struct ctf_fs_port_data *port_data;
struct ctf_fs_msg_iter_data *msg_iter_data = NULL;
- bt_component_class_message_iterator_initialize_method_status status;
+ bt_message_iterator_class_initialize_method_status status;
bt_logging_level log_level;
- bt_self_component *self_comp =
- bt_self_component_source_as_self_component(self_comp_src);
enum ctf_msg_iter_medium_status medium_status;
+ bt_self_component *self_comp =
+ bt_self_message_iterator_borrow_component(self_msg_iter);
port_data = bt_self_component_port_get_data(
bt_self_component_port_output_as_self_component_port(
log_level = port_data->ctf_fs->log_level;
msg_iter_data = g_new0(struct ctf_fs_msg_iter_data, 1);
if (!msg_iter_data) {
- status = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_INITIALIZE_METHOD_STATUS_MEMORY_ERROR;
+ status = BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_MEMORY_ERROR;
goto error;
}
if (medium_status != CTF_MSG_ITER_MEDIUM_STATUS_OK) {
BT_MSG_ITER_LOGE_APPEND_CAUSE(self_msg_iter,
"Failed to create ctf_fs_ds_group_medops");
- status = (int) medium_status;
+ status = ctf_msg_iter_medium_status_to_msg_iter_initialize_status(medium_status);
goto error;
}
self_comp, self_msg_iter);
if (!msg_iter_data->msg_iter) {
BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Cannot create a CTF message iterator.");
- status = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_INITIALIZE_METHOD_STATUS_MEMORY_ERROR;
+ status = BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_MEMORY_ERROR;
goto error;
}
msg_iter_data);
msg_iter_data = NULL;
- status = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_INITIALIZE_METHOD_STATUS_OK;
+ status = BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_OK;
goto end;
error:
struct ctf_fs_ds_index_entry *entry)
{
guint i;
- struct ctf_fs_ds_index_entry *other_entry;
+ struct ctf_fs_ds_index_entry *other_entry = NULL;
/* Find the spot where to insert this index entry. */
for (i = 0; i < index->entries->len; i++) {
goto error;
}
+ ctf_msg_iter_set_dry_run(msg_iter, true);
+
ret = ctf_msg_iter_get_packet_properties(msg_iter, &props);
if (ret) {
BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, self_comp_class,
if (begin_ns == -1) {
/*
- * No beggining timestamp to sort the stream files
+ * No beginning timestamp to sort the stream files
* within a stream file group, so consider that this
* file must be the only one within its group.
*/
first_ds_file_info_b->path->str);
}
+static
+gint compare_strings(gconstpointer p_a, gconstpointer p_b)
+{
+ const char *a = *((const char **) p_a);
+ const char *b = *((const char **) p_b);
+
+ return strcmp(a, b);
+}
+
int ctf_fs_component_create_ctf_fs_trace(
struct ctf_fs_component *ctf_fs,
const bt_value *paths_value,
int ret = 0;
uint64_t i;
bt_logging_level log_level = ctf_fs->log_level;
+ GPtrArray *paths = NULL;
GPtrArray *traces;
const char *trace_name;
goto error;
}
+ paths = g_ptr_array_new_with_free_func(g_free);
+ if (!paths) {
+ BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, self_comp_class,
+ "Failed to allocate a GPtrArray.");
+ goto error;
+ }
+
trace_name = trace_name_value ? bt_value_string_get(trace_name_value) : NULL;
- /* Start by creating a separate ctf_fs_trace object for each path. */
+ /*
+ * Create a sorted array of the paths, to make the execution of this
+ * component deterministic.
+ */
for (i = 0; i < bt_value_array_get_length(paths_value); i++) {
- const bt_value *path_value = bt_value_array_borrow_element_by_index_const(paths_value, i);
+ const bt_value *path_value =
+ bt_value_array_borrow_element_by_index_const(paths_value, i);
const char *input = bt_value_string_get(path_value);
+ gchar *input_copy;
+
+ input_copy = g_strdup(input);
+ if (!input_copy) {
+ BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, self_comp_class,
+ "Failed to copy a string.");
+ goto error;
+ }
+
+ g_ptr_array_add(paths, input_copy);
+ }
+
+ g_ptr_array_sort(paths, compare_strings);
+
+ /* Create a separate ctf_fs_trace object for each path. */
+ for (i = 0; i < paths->len; i++) {
+ const char *path = g_ptr_array_index(paths, i);
ret = ctf_fs_component_create_ctf_fs_trace_one_path(ctf_fs,
- input, trace_name, traces, self_comp, self_comp_class);
+ path, trace_name, traces, self_comp, self_comp_class);
if (ret) {
goto end;
}
ret = -1;
end:
- g_ptr_array_free(traces, TRUE);
+ if (traces) {
+ g_ptr_array_free(traces, TRUE);
+ }
+
+ if (paths) {
+ g_ptr_array_free(paths, TRUE);
+ }
+
return ret;
}