X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=src%2Fplugins%2Fctf%2Ffs-src%2Fquery.c;h=cabb3683d8c97403ff5da73e05f367bba198fb2a;hb=a7d6bdfd05c148bcb6ceae846fcee1af582d37ed;hp=3a58e1ff23f4b9a311e2b8899133d1be4ac7ff71;hpb=b03487ab5e72f71a01bd7ac78dff3a420b5f9ef8;p=babeltrace.git diff --git a/src/plugins/ctf/fs-src/query.c b/src/plugins/ctf/fs-src/query.c index 3a58e1ff..cabb3683 100644 --- a/src/plugins/ctf/fs-src/query.c +++ b/src/plugins/ctf/fs-src/query.c @@ -24,8 +24,17 @@ * SOFTWARE. */ +#define BT_LOG_OUTPUT_LEVEL log_level +#define BT_LOG_TAG "PLUGIN/SRC.CTF.FS/QUERY" +#include "logging/log.h" + #include "query.h" #include +#include +#include +#include +#include +#include #include "common/assert.h" #include "metadata.h" #include "../common/metadata/decoder.h" @@ -33,9 +42,7 @@ #include "common/macros.h" #include #include "fs.h" - -#define BT_LOG_TAG "PLUGIN/SRC.CTF.FS/QUERY" -#include "logging.h" +#include "logging/comp-logging.h" #define METADATA_TEXT_SIG "/* CTF 1.8" @@ -46,46 +53,53 @@ struct range { }; BT_HIDDEN -bt_query_status metadata_info_query( - bt_self_component_class_source *comp_class, - const bt_value *params, +bt_component_class_query_method_status metadata_info_query( + bt_self_component_class_source *self_comp_class_src, + const bt_value *params, bt_logging_level log_level, const bt_value **user_result) { - bt_query_status status = BT_QUERY_STATUS_OK; + bt_component_class_query_method_status status = + BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_OK; + bt_self_component_class *self_comp_class = + 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) { - status = BT_QUERY_STATUS_NOMEM; + status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_MEMORY_ERROR; goto error; } BT_ASSERT(params); if (!bt_value_is_map(params)) { - BT_LOGE_STR("Query parameters is not a map value object."); - status = BT_QUERY_STATUS_INVALID_PARAMS; + BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, + "Query parameters is not a map value object."); + status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_ERROR; goto error; } path_value = bt_value_map_borrow_entry_value_const(params, "path"); if (!path_value) { - BT_LOGE_STR("Mandatory `path` parameter missing"); - status = BT_QUERY_STATUS_INVALID_PARAMS; + BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, + "Mandatory `path` parameter missing"); + status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_ERROR; goto error; } if (!bt_value_is_string(path_value)) { - BT_LOGE_STR("`path` parameter is required to be a string value"); - status = BT_QUERY_STATUS_INVALID_PARAMS; + BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, + "`path` parameter is required to be a string value"); + status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_ERROR; goto error; } @@ -94,76 +108,52 @@ bt_query_status metadata_info_query( BT_ASSERT(path); metadata_fp = ctf_fs_metadata_open_file(path); if (!metadata_fp) { - BT_LOGE("Cannot open trace metadata: path=\"%s\".", path); + BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, + "Cannot open trace metadata: path=\"%s\".", path); goto error; } - is_packetized = ctf_metadata_decoder_is_packetized(metadata_fp, - &bo); - - if (is_packetized) { - ret = ctf_metadata_decoder_packetized_file_stream_to_buf( - metadata_fp, &metadata_text, bo); - if (ret) { - BT_LOGE("Cannot decode packetized metadata file: path=\"%s\"", - path); - goto error; - } - } else { - long filesize; - - ret = fseek(metadata_fp, 0, SEEK_END); - if (ret) { - BT_LOGE_ERRNO("Failed to seek to the end of the metadata file", - ": path=\"%s\"", path); - goto error; - } - filesize = ftell(metadata_fp); - if (filesize < 0) { - BT_LOGE_ERRNO("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_LOGE_STR("Cannot allocate buffer for metadata text."); - goto error; - } - - if (fread(metadata_text, filesize, 1, metadata_fp) != 1) { - BT_LOGE_ERRNO("Cannot read metadata file", ": path=\"%s\"", - path); - goto error; - } - - metadata_text[filesize] = '\0'; + ret = ctf_metadata_decoder_is_packetized(metadata_fp, &is_packetized, + &bo, log_level, NULL); + 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.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_LOGE_STR("Cannot insert metadata text into query result."); + BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, + "Cannot insert metadata text into query result."); goto error; } ret = bt_value_map_insert_bool_entry(result, "is-packetized", is_packetized); if (ret) { - BT_LOGE_STR("Cannot insert \"is-packetized\" attribute into query result."); + BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, + "Cannot insert \"is-packetized\" attribute into query result."); goto error; } @@ -174,18 +164,18 @@ error: result = NULL; if (status >= 0) { - status = BT_QUERY_STATUS_ERROR; + status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_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; @@ -197,64 +187,31 @@ int add_range(bt_value *info, struct range *range, const char *range_name) { int ret = 0; - bt_value_status status; - bt_value *range_map = NULL; + bt_value_map_insert_entry_status status; + bt_value *range_map; if (!range->set) { /* Not an error. */ goto end; } - range_map = bt_value_map_create(); - if (!range_map) { + status = bt_value_map_insert_empty_map_entry(info, range_name, + &range_map); + if (status != BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK) { ret = -1; goto end; } status = bt_value_map_insert_signed_integer_entry(range_map, "begin", range->begin_ns); - if (status != BT_VALUE_STATUS_OK) { + if (status != BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK) { ret = -1; goto end; } status = bt_value_map_insert_signed_integer_entry(range_map, "end", range->end_ns); - if (status != BT_VALUE_STATUS_OK) { - ret = -1; - goto end; - } - - status = bt_value_map_insert_entry(info, range_name, - range_map); - if (status != BT_VALUE_STATUS_OK) { - ret = -1; - goto end; - } - -end: - bt_value_put_ref(range_map); - return ret; -} - -static -int add_stream_ids(bt_value *info, struct ctf_fs_ds_file_group *ds_file_group) -{ - int ret = 0; - bt_value_status status; - - if (ds_file_group->stream_id != UINT64_C(-1)) { - status = bt_value_map_insert_unsigned_integer_entry(info, "id", - ds_file_group->stream_id); - if (status != BT_VALUE_STATUS_OK) { - ret = -1; - goto end; - } - } - - status = bt_value_map_insert_unsigned_integer_entry(info, "class-id", - ds_file_group->sc->id); - if (status != BT_VALUE_STATUS_OK) { + if (status != BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK) { ret = -1; goto end; } @@ -268,31 +225,10 @@ int populate_stream_info(struct ctf_fs_ds_file_group *group, bt_value *group_info, struct range *stream_range) { int ret = 0; - size_t file_idx; - bt_value_status status; - bt_value *file_paths; + bt_value_map_insert_entry_status insert_status; struct ctf_fs_ds_index_entry *first_ds_index_entry, *last_ds_index_entry; gchar *port_name = NULL; - file_paths = bt_value_array_create(); - if (!file_paths) { - ret = -1; - goto end; - } - - for (file_idx = 0; file_idx < group->ds_file_infos->len; file_idx++) { - struct ctf_fs_ds_file_info *info = - g_ptr_array_index(group->ds_file_infos, - file_idx); - - status = bt_value_array_append_string_element(file_paths, - info->path->str); - if (status != BT_VALUE_STATUS_OK) { - ret = -1; - goto end; - } - } - /* * Since each `struct ctf_fs_ds_file_group` has a sorted array of * `struct ctf_fs_ds_index_entry`, we can compute the stream range from @@ -327,75 +263,47 @@ int populate_stream_info(struct ctf_fs_ds_file_group *group, goto end; } - status = bt_value_map_insert_entry(group_info, "paths", - file_paths); - if (status != BT_VALUE_STATUS_OK) { - ret = -1; - goto end; - } - - ret = add_stream_ids(group_info, group); - if (ret) { - goto end; - } - port_name = ctf_fs_make_port_name(group); if (!port_name) { ret = -1; goto end; } - status = bt_value_map_insert_string_entry(group_info, "port-name", - port_name); - if (status != BT_VALUE_STATUS_OK) { + insert_status = bt_value_map_insert_string_entry(group_info, + "port-name", port_name); + if (insert_status != BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK) { ret = -1; goto end; } end: - bt_value_put_ref(file_paths); + g_free(port_name); return ret; } 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_status status; + bt_value_map_insert_entry_status insert_status; + bt_value_array_append_element_status append_status; bt_value *file_groups = NULL; - struct range trace_range = { - .begin_ns = INT64_MAX, - .end_ns = 0, - .set = false, - }; - 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; } - file_groups = bt_value_array_create(); - if (!file_groups) { - goto end; - } - - status = bt_value_map_insert_string_entry(trace_info, "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->str); - if (status != BT_VALUE_STATUS_OK) { + insert_status = bt_value_map_insert_empty_array_entry(trace_info, + "stream-infos", &file_groups); + if (insert_status != BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK) { ret = -1; goto end; } @@ -408,141 +316,94 @@ int populate_trace_info(const struct ctf_fs_trace *trace, bt_value *trace_info) struct ctf_fs_ds_file_group *group = g_ptr_array_index( trace->ds_file_groups, group_idx); - group_info = bt_value_map_create(); - if (!group_info) { + append_status = bt_value_array_append_empty_map_element( + file_groups, &group_info); + if (append_status != BT_VALUE_ARRAY_APPEND_ELEMENT_STATUS_OK) { ret = -1; goto end; } ret = populate_stream_info(group, group_info, &group_range); if (ret) { - bt_value_put_ref(group_info); goto end; } - - status = bt_value_array_append_element(file_groups, group_info); - bt_value_put_ref(group_info); - if (status != BT_VALUE_STATUS_OK) { - goto end; - } - - if (group_range.set) { - trace_range.begin_ns = MIN(trace_range.begin_ns, - group_range.begin_ns); - trace_range.end_ns = MAX(trace_range.end_ns, - group_range.end_ns); - trace_range.set = true; - - 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; - } - } - - ret = add_range(trace_info, &trace_range, "range-ns"); - if (ret) { - goto end; - } - - if (trace_intersection.begin_ns < trace_intersection.end_ns) { - ret = add_range(trace_info, &trace_intersection, - "intersection-range-ns"); - if (ret) { - goto end; - } - } - - status = bt_value_map_insert_entry(trace_info, "streams", - file_groups); - BT_VALUE_PUT_REF_AND_RESET(file_groups); - if (status != BT_VALUE_STATUS_OK) { - ret = -1; - goto end; } end: - bt_value_put_ref(file_groups); return ret; } BT_HIDDEN -bt_query_status trace_info_query( - bt_self_component_class_source *comp_class, - const bt_value *params, +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) { struct ctf_fs_component *ctf_fs = NULL; - bt_query_status status = BT_QUERY_STATUS_OK; + bt_component_class_query_method_status status = + BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_OK; + bt_self_component_class *self_comp_class = + bt_self_component_class_source_as_self_component_class( + self_comp_class_src); bt_value *result = NULL; - const bt_value *paths_value = 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); if (!bt_value_is_map(params)) { - BT_LOGE("Query parameters is not a map value object."); - status = BT_QUERY_STATUS_INVALID_PARAMS; + BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, + "Query parameters is not a map value object."); + status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_ERROR; goto error; } - ctf_fs = ctf_fs_component_create(); + ctf_fs = ctf_fs_component_create(log_level, NULL); if (!ctf_fs) { goto error; } - if (!read_src_fs_parameters(params, &paths_value, ctf_fs)) { - status = BT_QUERY_STATUS_INVALID_PARAMS; + 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(NULL, ctf_fs, paths_value)) { + if (ctf_fs_component_create_ctf_fs_trace(ctf_fs, inputs_value, + trace_name_value, NULL, self_comp_class)) { goto error; } result = bt_value_array_create(); if (!result) { - status = BT_QUERY_STATUS_NOMEM; + status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_MEMORY_ERROR; goto error; } - 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) { - BT_LOGE("Failed to create trace info map."); - goto error; - } - - ret = populate_trace_info(trace, trace_info); - if (ret) { - bt_value_put_ref(trace_info); - 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; + } - status = bt_value_array_append_element(result, trace_info); - bt_value_put_ref(trace_info); - if (status != BT_VALUE_STATUS_OK) { - 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_QUERY_STATUS_ERROR; + status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_ERROR; } end: @@ -554,3 +415,116 @@ end: *user_result = result; return status; } + +BT_HIDDEN +bt_component_class_query_method_status support_info_query( + bt_self_component_class_source *comp_class, + const bt_value *params, bt_logging_level log_level, + const bt_value **user_result) +{ + 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); + + 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; + } + + 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; + + metadata_decoder_config.log_level = log_level; + + 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; + } + + /* + * We were able to parse the metadata file, so we are + * confident it's a CTF trace. + */ + 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; + } + } + +create_result: + result = bt_value_map_create(); + if (!result) { + status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_MEMORY_ERROR; + goto end; + } + + 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; + +end: + g_free(metadata_path); + bt_value_put_ref(result); + ctf_metadata_decoder_destroy(metadata_decoder); + + return status; +}