X-Git-Url: http://git.efficios.com/?p=babeltrace.git;a=blobdiff_plain;f=src%2Fplugins%2Fctf%2Ffs-src%2Ffs.c;h=42956c22bf9fb38ed40299727c815f429175bcd0;hp=0f28a09a8e6376f1792285f5822e56bd7537e382;hb=0235b0db7de5bcacdb3650c92461f2ce5eb2143d;hpb=4829c3e2f7137d73c75baff615bce560268ebba4 diff --git a/src/plugins/ctf/fs-src/fs.c b/src/plugins/ctf/fs-src/fs.c index 0f28a09a..42956c22 100644 --- a/src/plugins/ctf/fs-src/fs.c +++ b/src/plugins/ctf/fs-src/fs.c @@ -1,28 +1,10 @@ /* - * fs.c - * - * Babeltrace CTF file system Reader Component + * SPDX-License-Identifier: MIT * * Copyright 2015-2017 Philippe Proulx * Copyright 2016 Jérémie Galarneau * - * 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 @@ -54,39 +36,6 @@ struct tracer_info { int64_t patch; }; -static -int msg_iter_data_set_current_ds_file(struct ctf_fs_msg_iter_data *msg_iter_data) -{ - struct ctf_fs_ds_file_info *ds_file_info; - int ret = 0; - - BT_ASSERT(msg_iter_data->ds_file_info_index < - msg_iter_data->ds_file_group->ds_file_infos->len); - ds_file_info = g_ptr_array_index( - msg_iter_data->ds_file_group->ds_file_infos, - msg_iter_data->ds_file_info_index); - - /* Destroy the previous ds file. */ - ctf_fs_ds_file_destroy(msg_iter_data->ds_file); - - /* Create the new ds file. */ - msg_iter_data->ds_file = ctf_fs_ds_file_create( - msg_iter_data->ds_file_group->ctf_fs_trace, - msg_iter_data->self_msg_iter, - msg_iter_data->ds_file_group->stream, - ds_file_info->path->str, - msg_iter_data->log_level); - if (!msg_iter_data->ds_file) { - ret = -1; - } - - /* Tell the ctf message iterator to iterate on the new ds file. */ - ctf_msg_iter_set_medops_data(msg_iter_data->msg_iter, - msg_iter_data->ds_file); - - return ret; -} - static void ctf_fs_msg_iter_data_destroy( struct ctf_fs_msg_iter_data *msg_iter_data) @@ -95,102 +44,74 @@ void ctf_fs_msg_iter_data_destroy( return; } - ctf_fs_ds_file_destroy(msg_iter_data->ds_file); - if (msg_iter_data->msg_iter) { ctf_msg_iter_destroy(msg_iter_data->msg_iter); } - g_free(msg_iter_data); -} + if (msg_iter_data->msg_iter_medops_data) { + ctf_fs_ds_group_medops_data_destroy( + msg_iter_data->msg_iter_medops_data); + } -static -void set_msg_iter_emits_stream_beginning_end_messages( - struct ctf_fs_msg_iter_data *msg_iter_data) -{ - ctf_msg_iter_set_emit_stream_beginning_message( - msg_iter_data->msg_iter, - msg_iter_data->ds_file_info_index == 0); - ctf_msg_iter_set_emit_stream_end_message( - msg_iter_data->msg_iter, - msg_iter_data->ds_file_info_index == - msg_iter_data->ds_file_group->ds_file_infos->len - 1); + g_free(msg_iter_data); } 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_ASSERT_DBG(msg_iter_data->ds_file); + 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; - while (true) { - enum ctf_msg_iter_status msg_iter_status; - int ret; - - msg_iter_status = ctf_msg_iter_get_next_message( - msg_iter_data->msg_iter, out_msg); - - 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; - goto end; + msg_iter_status = ctf_msg_iter_get_next_message( + msg_iter_data->msg_iter, out_msg); - case CTF_MSG_ITER_STATUS_EOF: - if (msg_iter_data->ds_file_info_index == - msg_iter_data->ds_file_group->ds_file_infos->len - 1) { - /* End of all group's stream files */ - status = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_NEXT_METHOD_STATUS_END; - goto end; - } + switch (msg_iter_status) { + case CTF_MSG_ITER_STATUS_OK: + /* Cool, message has been written to *out_msg. */ + status = BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_OK; + break; - msg_iter_data->ds_file_info_index++; - ctf_msg_iter_reset_for_next_stream_file( - msg_iter_data->msg_iter); - set_msg_iter_emits_stream_beginning_end_messages( - msg_iter_data); + case CTF_MSG_ITER_STATUS_EOF: + status = BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_END; + break; - /* - * Open and start reading the next stream file - * within our stream file group. - */ - ret = msg_iter_data_set_current_ds_file(msg_iter_data); - if (ret) { - status = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_NEXT_METHOD_STATUS_ERROR; - goto end; - } + case CTF_MSG_ITER_STATUS_AGAIN: + /* + * Should not make it this far as this is + * medium-specific; there is nothing for the user to do + * and it should have been handled upstream. + */ + bt_common_abort(); - /* Continue the loop to get the next message. */ - break; + 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_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_ERROR; + break; - case CTF_MSG_ITER_STATUS_AGAIN: - /* - * Should not make it this far as this is - * medium-specific; there is nothing for the user to do - * and it should have been handled upstream. - */ - bt_common_abort(); + 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_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_MEMORY_ERROR; + break; - default: - status = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_NEXT_METHOD_STATUS_ERROR; - goto end; - } + default: + bt_common_abort(); } -end: return status; } 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; @@ -208,19 +129,19 @@ bt_component_class_message_iterator_next_method_status ctf_fs_iterator_next( 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 @@ -239,46 +160,26 @@ bt_component_class_message_iterator_next_method_status ctf_fs_iterator_next( } *count = i; - status = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_NEXT_METHOD_STATUS_OK; + status = BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_OK; } end: return status; } -static -int ctf_fs_iterator_reset(struct ctf_fs_msg_iter_data *msg_iter_data) -{ - int ret; - - msg_iter_data->ds_file_info_index = 0; - ret = msg_iter_data_set_current_ds_file(msg_iter_data); - if (ret) { - goto end; - } - - ctf_msg_iter_reset(msg_iter_data->msg_iter); - set_msg_iter_emits_stream_beginning_end_messages(msg_iter_data); - -end: - return ret; -} - 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 = bt_self_message_iterator_get_data(it); - bt_component_class_message_iterator_seek_beginning_method_status status = - BT_COMPONENT_CLASS_MESSAGE_ITERATOR_SEEK_BEGINNING_METHOD_STATUS_OK; BT_ASSERT(msg_iter_data); - if (ctf_fs_iterator_reset(msg_iter_data)) { - status = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_SEEK_BEGINNING_METHOD_STATUS_ERROR; - } - return status; + 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_MESSAGE_ITERATOR_CLASS_SEEK_BEGINNING_METHOD_STATUS_OK; } BT_HIDDEN @@ -289,19 +190,18 @@ void ctf_fs_iterator_finalize(bt_self_message_iterator *it) } 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 ret = - BT_COMPONENT_CLASS_MESSAGE_ITERATOR_INITIALIZE_METHOD_STATUS_OK; + bt_message_iterator_class_initialize_method_status status; bt_logging_level log_level; + enum ctf_msg_iter_medium_status medium_status; bt_self_component *self_comp = - bt_self_component_source_as_self_component(self_comp_src); + 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( @@ -310,27 +210,39 @@ bt_component_class_message_iterator_initialize_method_status ctf_fs_iterator_ini log_level = port_data->ctf_fs->log_level; msg_iter_data = g_new0(struct ctf_fs_msg_iter_data, 1); if (!msg_iter_data) { - ret = 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->log_level = log_level; msg_iter_data->self_comp = self_comp; msg_iter_data->self_msg_iter = self_msg_iter; + msg_iter_data->ds_file_group = port_data->ds_file_group; + + medium_status = ctf_fs_ds_group_medops_data_create( + msg_iter_data->ds_file_group, self_msg_iter, log_level, + &msg_iter_data->msg_iter_medops_data); + BT_ASSERT( + medium_status == CTF_MSG_ITER_MEDIUM_STATUS_OK || + medium_status == CTF_MSG_ITER_MEDIUM_STATUS_ERROR || + medium_status == CTF_MSG_ITER_MEDIUM_STATUS_MEMORY_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; + goto error; + } + msg_iter_data->msg_iter = ctf_msg_iter_create( - port_data->ds_file_group->ctf_fs_trace->metadata->tc, + msg_iter_data->ds_file_group->ctf_fs_trace->metadata->tc, bt_common_get_page_size(msg_iter_data->log_level) * 8, - ctf_fs_ds_file_medops, NULL, msg_iter_data->log_level, + ctf_fs_ds_group_medops, + msg_iter_data->msg_iter_medops_data, + msg_iter_data->log_level, self_comp, self_msg_iter); if (!msg_iter_data->msg_iter) { BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Cannot create a CTF message iterator."); - ret = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_INITIALIZE_METHOD_STATUS_MEMORY_ERROR; - goto error; - } - - msg_iter_data->ds_file_group = port_data->ds_file_group; - if (ctf_fs_iterator_reset(msg_iter_data)) { - ret = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_INITIALIZE_METHOD_STATUS_ERROR; + status = BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_MEMORY_ERROR; goto error; } @@ -345,10 +257,9 @@ bt_component_class_message_iterator_initialize_method_status ctf_fs_iterator_ini bt_self_message_iterator_set_data(self_msg_iter, msg_iter_data); - if (ret != BT_COMPONENT_CLASS_MESSAGE_ITERATOR_INITIALIZE_METHOD_STATUS_OK) { - goto error; - } msg_iter_data = NULL; + + status = BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_OK; goto end; error: @@ -356,7 +267,7 @@ error: end: ctf_fs_msg_iter_data_destroy(msg_iter_data); - return ret; + return status; } static @@ -624,12 +535,7 @@ void ctf_fs_ds_file_group_destroy(struct ctf_fs_ds_file_group *ds_file_group) g_ptr_array_free(ds_file_group->ds_file_infos, TRUE); } - if (ds_file_group->index) { - if (ds_file_group->index->entries) { - g_ptr_array_free(ds_file_group->index->entries, TRUE); - } - g_free(ds_file_group->index); - } + ctf_fs_ds_index_destroy(ds_file_group->index); bt_stream_put_ref(ds_file_group->stream); g_free(ds_file_group); @@ -756,7 +662,7 @@ void ds_index_insert_ds_index_entry_sorted( 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++) { @@ -839,6 +745,8 @@ int add_ds_file_to_ds_file_group(struct ctf_fs_trace *ctf_fs_trace, 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, @@ -883,7 +791,7 @@ int add_ds_file_to_ds_file_group(struct ctf_fs_trace *ctf_fs_trace, 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. */ @@ -2118,6 +2026,15 @@ gint compare_ds_file_groups_by_first_path(gconstpointer a, gconstpointer b) 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, @@ -2128,6 +2045,7 @@ int ctf_fs_component_create_ctf_fs_trace( int ret = 0; uint64_t i; bt_logging_level log_level = ctf_fs->log_level; + GPtrArray *paths = NULL; GPtrArray *traces; const char *trace_name; @@ -2141,15 +2059,43 @@ int ctf_fs_component_create_ctf_fs_trace( 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; } @@ -2233,7 +2179,14 @@ error: 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; }