X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=src%2Fplugins%2Fctf%2Ffs-src%2Fquery.c;h=adc8f4d12fc9280f81d439c69bcb3f3134d2241d;hb=516bf0a77e025cfccce2fa400b757e94dc0bf1d8;hp=e817165c4e6c4a12285f6e5a30726ab05896262c;hpb=760b266cd90c1769b869d43ebba5f24f7b3c40e0;p=babeltrace.git diff --git a/src/plugins/ctf/fs-src/query.c b/src/plugins/ctf/fs-src/query.c index e817165c..adc8f4d1 100644 --- a/src/plugins/ctf/fs-src/query.c +++ b/src/plugins/ctf/fs-src/query.c @@ -1,27 +1,9 @@ /* - * query.c - * - * Babeltrace CTF file system Reader Component queries + * SPDX-License-Identifier: MIT * * Copyright 2017 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 queries */ #define BT_LOG_OUTPUT_LEVEL log_level @@ -30,6 +12,11 @@ #include "query.h" #include +#include +#include +#include +#include +#include #include "common/assert.h" #include "metadata.h" #include "../common/metadata/decoder.h" @@ -59,13 +46,14 @@ bt_component_class_query_method_status metadata_info_query( bt_self_component_class_source_as_self_component_class(self_comp_class_src); bt_value *result = NULL; const bt_value *path_value = NULL; - char *metadata_text = NULL; FILE *metadata_fp = NULL; - GString *g_metadata_text = NULL; int ret; int bo; const char *path; bool is_packetized; + struct ctf_metadata_decoder *decoder = NULL; + struct ctf_metadata_decoder_config decoder_cfg = { 0 }; + enum ctf_metadata_decoder_status decoder_status; result = bt_value_map_create(); if (!result) { @@ -107,69 +95,37 @@ bt_component_class_query_method_status metadata_info_query( goto error; } - is_packetized = ctf_metadata_decoder_is_packetized(metadata_fp, + ret = ctf_metadata_decoder_is_packetized(metadata_fp, &is_packetized, &bo, log_level, NULL); - - if (is_packetized) { - ret = ctf_metadata_decoder_packetized_file_stream_to_buf( - metadata_fp, &metadata_text, bo, NULL, NULL, - log_level, NULL); - if (ret) { - BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, - "Cannot decode packetized metadata file: path=\"%s\"", - path); - goto error; - } - } else { - long filesize; - - ret = fseek(metadata_fp, 0, SEEK_END); - if (ret) { - BT_COMP_CLASS_LOGE_APPEND_CAUSE_ERRNO(self_comp_class, - "Failed to seek to the end of the metadata file", - ": path=\"%s\"", path); - goto error; - } - filesize = ftell(metadata_fp); - if (filesize < 0) { - BT_COMP_CLASS_LOGE_APPEND_CAUSE_ERRNO(self_comp_class, - "Failed to get the current position in the metadata file", - ": path=\"%s\"", path); - goto error; - } - rewind(metadata_fp); - metadata_text = malloc(filesize + 1); - if (!metadata_text) { - BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, - "Cannot allocate buffer for metadata text."); - goto error; - } - - if (fread(metadata_text, filesize, 1, metadata_fp) != 1) { - BT_COMP_CLASS_LOGE_APPEND_CAUSE_ERRNO(self_comp_class, - "Cannot read metadata file", ": path=\"%s\"", - path); - goto error; - } - - metadata_text[filesize] = '\0'; + if (ret) { + BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, + "Cannot check whether or not the metadata stream is packetized: path=\"%s\".", + path); + goto error; } - g_metadata_text = g_string_new(NULL); - if (!g_metadata_text) { + decoder_cfg.log_level = log_level; + decoder_cfg.self_comp_class = self_comp_class; + decoder_cfg.keep_plain_text = true; + decoder = ctf_metadata_decoder_create(&decoder_cfg); + if (!decoder) { + BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, + "Cannot create metadata decoder: path=\"%s\".", path); goto error; } - if (strncmp(metadata_text, METADATA_TEXT_SIG, - sizeof(METADATA_TEXT_SIG) - 1) != 0) { - g_string_assign(g_metadata_text, METADATA_TEXT_SIG); - g_string_append(g_metadata_text, " */\n\n"); + rewind(metadata_fp); + decoder_status = ctf_metadata_decoder_append_content(decoder, + metadata_fp); + if (decoder_status) { + BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, + "Cannot update metadata decoder's content: path=\"%s\".", + path); + goto error; } - g_string_append(g_metadata_text, metadata_text); - ret = bt_value_map_insert_string_entry(result, "text", - g_metadata_text->str); + ctf_metadata_decoder_get_text(decoder)); if (ret) { BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, "Cannot insert metadata text into query result."); @@ -195,14 +151,14 @@ error: } end: - free(metadata_text); - - if (g_metadata_text) { - g_string_free(g_metadata_text, TRUE); - } + ctf_metadata_decoder_destroy(decoder); if (metadata_fp) { - fclose(metadata_fp); + ret = fclose(metadata_fp); + if (ret) { + BT_LOGE_ERRNO("Cannot close metatada file stream", + ": path=\"%s\"", path); + } } *user_result = result; @@ -309,28 +265,27 @@ end: } static -int populate_trace_info(const struct ctf_fs_trace *trace, bt_value *trace_info) +int populate_trace_info(const struct ctf_fs_trace *trace, bt_value *trace_info, + bt_logging_level log_level, + bt_self_component_class *self_comp_class) { int ret = 0; size_t group_idx; bt_value_map_insert_entry_status insert_status; bt_value_array_append_element_status append_status; bt_value *file_groups = NULL; - struct range trace_intersection = { - .begin_ns = 0, - .end_ns = INT64_MAX, - .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; + BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, + "Trace has no streams: trace-path=%s", trace->path->str); goto end; } insert_status = bt_value_map_insert_empty_array_entry(trace_info, - "streams", &file_groups); + "stream-infos", &file_groups); if (insert_status != BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK) { ret = -1; goto end; @@ -355,22 +310,6 @@ int populate_trace_info(const struct ctf_fs_trace *trace, bt_value *trace_info) if (ret) { goto end; } - - if (group_range.set) { - trace_intersection.begin_ns = MAX(trace_intersection.begin_ns, - group_range.begin_ns); - trace_intersection.end_ns = MIN(trace_intersection.end_ns, - group_range.end_ns); - trace_intersection.set = true; - } - } - - if (trace_intersection.begin_ns < trace_intersection.end_ns) { - ret = add_range(trace_info, &trace_intersection, - "intersection-range-ns"); - if (ret) { - goto end; - } } end: @@ -378,7 +317,7 @@ end: } BT_HIDDEN -bt_component_class_query_method_status trace_info_query( +bt_component_class_query_method_status trace_infos_query( bt_self_component_class_source *self_comp_class_src, const bt_value *params, bt_logging_level log_level, const bt_value **user_result) @@ -391,8 +330,10 @@ bt_component_class_query_method_status trace_info_query( self_comp_class_src); bt_value *result = NULL; const bt_value *inputs_value = NULL; + const bt_value *trace_name_value; int ret = 0; - guint i; + bt_value *trace_info = NULL; + bt_value_array_append_element_status append_status; BT_ASSERT(params); @@ -408,14 +349,14 @@ bt_component_class_query_method_status trace_info_query( goto error; } - if (!read_src_fs_parameters(params, &inputs_value, ctf_fs, NULL, - self_comp_class)) { + if (!read_src_fs_parameters(params, &inputs_value, &trace_name_value, + ctf_fs, NULL, self_comp_class)) { status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_ERROR; goto error; } - if (ctf_fs_component_create_ctf_fs_traces(ctf_fs, inputs_value, NULL, - self_comp_class)) { + if (ctf_fs_component_create_ctf_fs_trace(ctf_fs, inputs_value, + trace_name_value, NULL, self_comp_class)) { goto error; } @@ -425,33 +366,24 @@ bt_component_class_query_method_status trace_info_query( goto error; } - for (i = 0; i < ctf_fs->traces->len; i++) { - struct ctf_fs_trace *trace; - bt_value *trace_info; - bt_value_array_append_element_status append_status; - - trace = g_ptr_array_index(ctf_fs->traces, i); - BT_ASSERT(trace); - - append_status = bt_value_array_append_empty_map_element(result, - &trace_info); - if (append_status != BT_VALUE_ARRAY_APPEND_ELEMENT_STATUS_OK) { - BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, - "Failed to create trace info map."); - goto error; - } + append_status = bt_value_array_append_empty_map_element(result, + &trace_info); + if (append_status != BT_VALUE_ARRAY_APPEND_ELEMENT_STATUS_OK) { + BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, + "Failed to create trace info map."); + goto error; + } - ret = populate_trace_info(trace, trace_info); - if (ret) { - goto error; - } + ret = populate_trace_info(ctf_fs->trace, trace_info, log_level, + self_comp_class); + if (ret) { + goto error; } goto end; error: BT_VALUE_PUT_REF_AND_RESET(result); - result = NULL; if (status >= 0) { status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_ERROR; @@ -476,59 +408,100 @@ bt_component_class_query_method_status support_info_query( const bt_value *input_type_value; const char *input_type; bt_component_class_query_method_status status; + bt_value_map_insert_entry_status insert_entry_status; double weight = 0; gchar *metadata_path = NULL; bt_value *result = NULL; + struct ctf_metadata_decoder *metadata_decoder = NULL; + FILE *metadata_file = NULL; + char uuid_str[BT_UUID_STR_LEN + 1]; + bool has_uuid = false; + const bt_value *input_value; + const char *input; input_type_value = bt_value_map_borrow_entry_value_const(params, "type"); BT_ASSERT(input_type_value); BT_ASSERT(bt_value_get_type(input_type_value) == BT_VALUE_TYPE_STRING); input_type = bt_value_string_get(input_type_value); - result = bt_value_map_create(); - if (!result) { + if (strcmp(input_type, "directory") != 0) { + goto create_result; + } + + input_value = bt_value_map_borrow_entry_value_const(params, "input"); + BT_ASSERT(input_value); + BT_ASSERT(bt_value_get_type(input_value) == BT_VALUE_TYPE_STRING); + input = bt_value_string_get(input_value); + + metadata_path = g_build_filename(input, CTF_FS_METADATA_FILENAME, NULL); + if (!metadata_path) { status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_MEMORY_ERROR; goto end; } - if (strcmp(input_type, "directory") == 0) { - const bt_value *input_value; - const char *path; + metadata_file = g_fopen(metadata_path, "rb"); + if (metadata_file) { + struct ctf_metadata_decoder_config metadata_decoder_config = { 0 }; + enum ctf_metadata_decoder_status decoder_status; + bt_uuid_t uuid; - input_value = bt_value_map_borrow_entry_value_const(params, "input"); - BT_ASSERT(input_value); - BT_ASSERT(bt_value_get_type(input_value) == BT_VALUE_TYPE_STRING); - path = bt_value_string_get(input_value); + metadata_decoder_config.log_level = log_level; + metadata_decoder_config.self_comp_class = + bt_self_component_class_source_as_self_component_class(comp_class); - metadata_path = g_build_filename(path, CTF_FS_METADATA_FILENAME, NULL); - if (!metadata_path) { - status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_MEMORY_ERROR; + metadata_decoder = ctf_metadata_decoder_create( + &metadata_decoder_config); + if (!metadata_decoder) { + status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_ERROR; + goto end; + } + + decoder_status = ctf_metadata_decoder_append_content( + metadata_decoder, metadata_file); + if (decoder_status != CTF_METADATA_DECODER_STATUS_OK) { + BT_LOGW("cannot append metadata content: metadata-decoder-status=%d", + decoder_status); + status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_ERROR; goto end; } /* - * If the metadata file exists in this directory, consider it to - * be a CTF trace. + * We were able to parse the metadata file, so we are + * confident it's a CTF trace. */ - if (g_file_test(metadata_path, G_FILE_TEST_EXISTS)) { - weight = 0.5; + weight = 0.75; + + /* If the trace has a UUID, return the stringified UUID as the group. */ + if (ctf_metadata_decoder_get_trace_class_uuid(metadata_decoder, uuid) == 0) { + bt_uuid_to_str(uuid, uuid_str); + has_uuid = true; } } - if (bt_value_map_insert_real_entry(result, "weight", weight) != BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK) { +create_result: + result = bt_value_map_create(); + if (!result) { status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_MEMORY_ERROR; goto end; } - /* - * Use the arbitrary constant string "ctf" as the group, such that all - * found ctf traces are passed to the same instance of src.ctf.fs. - */ - if (bt_value_map_insert_string_entry(result, "group", "ctf") != BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK) { - status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_MEMORY_ERROR; + insert_entry_status = bt_value_map_insert_real_entry(result, "weight", weight); + if (insert_entry_status != BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK) { + status = (int) insert_entry_status; goto end; } + /* We are not supposed to have weight == 0 and a UUID. */ + BT_ASSERT(weight > 0 || !has_uuid); + + if (weight > 0 && has_uuid) { + insert_entry_status = bt_value_map_insert_string_entry(result, "group", uuid_str); + if (insert_entry_status != BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK) { + status = (int) insert_entry_status; + goto end; + } + } + *user_result = result; result = NULL; status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_OK; @@ -536,6 +509,7 @@ bt_component_class_query_method_status support_info_query( end: g_free(metadata_path); bt_value_put_ref(result); + ctf_metadata_decoder_destroy(metadata_decoder); return status; }