Commit | Line | Data |
---|---|---|
04c0ba87 JG |
1 | /* |
2 | * query.c | |
3 | * | |
4 | * Babeltrace CTF file system Reader Component queries | |
5 | * | |
6 | * Copyright 2017 Jérémie Galarneau <jeremie.galarneau@efficios.com> | |
7 | * | |
8 | * Permission is hereby granted, free of charge, to any person obtaining a copy | |
9 | * of this software and associated documentation files (the "Software"), to deal | |
10 | * in the Software without restriction, including without limitation the rights | |
11 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
12 | * copies of the Software, and to permit persons to whom the Software is | |
13 | * furnished to do so, subject to the following conditions: | |
14 | * | |
15 | * The above copyright notice and this permission notice shall be included in | |
16 | * all copies or substantial portions of the Software. | |
17 | * | |
18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
21 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
23 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
24 | * SOFTWARE. | |
25 | */ | |
26 | ||
98903a3e PP |
27 | #define BT_LOG_OUTPUT_LEVEL log_level |
28 | #define BT_LOG_TAG "PLUGIN/SRC.CTF.FS/QUERY" | |
29 | #include "logging/log.h" | |
30 | ||
04c0ba87 JG |
31 | #include "query.h" |
32 | #include <stdbool.h> | |
493917ba SM |
33 | #include <glib.h> |
34 | #include <glib/gstdio.h> | |
35 | #include <fcntl.h> | |
36 | #include <sys/types.h> | |
37 | #include <sys/stat.h> | |
578e048b | 38 | #include "common/assert.h" |
04c0ba87 JG |
39 | #include "metadata.h" |
40 | #include "../common/metadata/decoder.h" | |
578e048b | 41 | #include "common/common.h" |
91d81473 | 42 | #include "common/macros.h" |
3fadfbc0 | 43 | #include <babeltrace2/babeltrace.h> |
97ade20b | 44 | #include "fs.h" |
d23b766e | 45 | #include "logging/comp-logging.h" |
55314f2a | 46 | |
04c0ba87 JG |
47 | #define METADATA_TEXT_SIG "/* CTF 1.8" |
48 | ||
97ade20b JG |
49 | struct range { |
50 | int64_t begin_ns; | |
51 | int64_t end_ns; | |
52 | bool set; | |
53 | }; | |
54 | ||
04c0ba87 | 55 | BT_HIDDEN |
d24d5663 | 56 | bt_component_class_query_method_status metadata_info_query( |
d23b766e | 57 | bt_self_component_class_source *self_comp_class_src, |
98903a3e | 58 | const bt_value *params, bt_logging_level log_level, |
b19ff26f | 59 | const bt_value **user_result) |
04c0ba87 | 60 | { |
d24d5663 PP |
61 | bt_component_class_query_method_status status = |
62 | BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_OK; | |
d23b766e SM |
63 | bt_self_component_class *self_comp_class = |
64 | bt_self_component_class_source_as_self_component_class(self_comp_class_src); | |
b19ff26f PP |
65 | bt_value *result = NULL; |
66 | const bt_value *path_value = NULL; | |
04c0ba87 | 67 | FILE *metadata_fp = NULL; |
04c0ba87 JG |
68 | int ret; |
69 | int bo; | |
70 | const char *path; | |
71 | bool is_packetized; | |
06be9946 PP |
72 | struct ctf_metadata_decoder *decoder = NULL; |
73 | struct ctf_metadata_decoder_config decoder_cfg = { 0 }; | |
74 | enum ctf_metadata_decoder_status decoder_status; | |
04c0ba87 | 75 | |
05e21286 | 76 | result = bt_value_map_create(); |
da91b29a | 77 | if (!result) { |
d24d5663 | 78 | status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_MEMORY_ERROR; |
04c0ba87 JG |
79 | goto error; |
80 | } | |
81 | ||
f6ccaed9 PP |
82 | BT_ASSERT(params); |
83 | ||
04c0ba87 | 84 | if (!bt_value_is_map(params)) { |
d23b766e SM |
85 | BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, |
86 | "Query parameters is not a map value object."); | |
a635e507 | 87 | status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_ERROR; |
04c0ba87 JG |
88 | goto error; |
89 | } | |
90 | ||
05e21286 | 91 | path_value = bt_value_map_borrow_entry_value_const(params, "path"); |
07330b50 | 92 | if (!path_value) { |
d23b766e SM |
93 | BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, |
94 | "Mandatory `path` parameter missing"); | |
a635e507 | 95 | status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_ERROR; |
07330b50 FD |
96 | goto error; |
97 | } | |
98 | ||
99 | if (!bt_value_is_string(path_value)) { | |
d23b766e SM |
100 | BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, |
101 | "`path` parameter is required to be a string value"); | |
a635e507 | 102 | status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_ERROR; |
07330b50 FD |
103 | goto error; |
104 | } | |
105 | ||
601b0d3c | 106 | path = bt_value_string_get(path_value); |
04c0ba87 | 107 | |
f6ccaed9 | 108 | BT_ASSERT(path); |
04c0ba87 JG |
109 | metadata_fp = ctf_fs_metadata_open_file(path); |
110 | if (!metadata_fp) { | |
d23b766e SM |
111 | BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, |
112 | "Cannot open trace metadata: path=\"%s\".", path); | |
04c0ba87 JG |
113 | goto error; |
114 | } | |
115 | ||
06be9946 | 116 | ret = ctf_metadata_decoder_is_packetized(metadata_fp, &is_packetized, |
98903a3e | 117 | &bo, log_level, NULL); |
06be9946 PP |
118 | if (ret) { |
119 | BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, | |
120 | "Cannot check whether or not the metadata stream is packetized: path=\"%s\".", | |
121 | path); | |
122 | goto error; | |
04c0ba87 JG |
123 | } |
124 | ||
06be9946 PP |
125 | decoder_cfg.log_level = log_level; |
126 | decoder_cfg.keep_plain_text = true; | |
127 | decoder = ctf_metadata_decoder_create(&decoder_cfg); | |
128 | if (!decoder) { | |
129 | BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, | |
130 | "Cannot create metadata decoder: path=\"%s\".", path); | |
04c0ba87 JG |
131 | goto error; |
132 | } | |
133 | ||
06be9946 PP |
134 | rewind(metadata_fp); |
135 | decoder_status = ctf_metadata_decoder_append_content(decoder, | |
136 | metadata_fp); | |
137 | if (decoder_status) { | |
138 | BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, | |
139 | "Cannot update metadata decoder's content: path=\"%s\".", | |
140 | path); | |
141 | goto error; | |
04c0ba87 JG |
142 | } |
143 | ||
05e21286 | 144 | ret = bt_value_map_insert_string_entry(result, "text", |
06be9946 | 145 | ctf_metadata_decoder_get_text(decoder)); |
04c0ba87 | 146 | if (ret) { |
d23b766e SM |
147 | BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, |
148 | "Cannot insert metadata text into query result."); | |
04c0ba87 JG |
149 | goto error; |
150 | } | |
151 | ||
05e21286 | 152 | ret = bt_value_map_insert_bool_entry(result, "is-packetized", |
04c0ba87 JG |
153 | is_packetized); |
154 | if (ret) { | |
d23b766e SM |
155 | BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, |
156 | "Cannot insert \"is-packetized\" attribute into query result."); | |
04c0ba87 JG |
157 | goto error; |
158 | } | |
159 | ||
160 | goto end; | |
161 | ||
162 | error: | |
c5b9b441 | 163 | BT_VALUE_PUT_REF_AND_RESET(result); |
d94d92ac | 164 | result = NULL; |
c7eee084 | 165 | |
d94d92ac | 166 | if (status >= 0) { |
d24d5663 | 167 | status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_ERROR; |
c7eee084 | 168 | } |
04c0ba87 JG |
169 | |
170 | end: | |
06be9946 | 171 | ctf_metadata_decoder_destroy(decoder); |
04c0ba87 JG |
172 | |
173 | if (metadata_fp) { | |
a8bd1d0f FD |
174 | ret = fclose(metadata_fp); |
175 | if (ret) { | |
176 | BT_LOGE_ERRNO("Cannot close metatada file stream", | |
177 | ": path=\"%s\"", path); | |
178 | } | |
04c0ba87 | 179 | } |
c7eee084 | 180 | |
05e21286 | 181 | *user_result = result; |
d94d92ac | 182 | return status; |
97ade20b | 183 | } |
9ec238a8 | 184 | |
97ade20b | 185 | static |
b19ff26f | 186 | int add_range(bt_value *info, struct range *range, |
97ade20b JG |
187 | const char *range_name) |
188 | { | |
189 | int ret = 0; | |
d24d5663 | 190 | bt_value_map_insert_entry_status status; |
760b266c | 191 | bt_value *range_map; |
97ade20b JG |
192 | |
193 | if (!range->set) { | |
194 | /* Not an error. */ | |
195 | goto end; | |
196 | } | |
197 | ||
760b266c SM |
198 | status = bt_value_map_insert_empty_map_entry(info, range_name, |
199 | &range_map); | |
200 | if (status != BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK) { | |
97ade20b JG |
201 | ret = -1; |
202 | goto end; | |
203 | } | |
204 | ||
fdd3a2da | 205 | status = bt_value_map_insert_signed_integer_entry(range_map, "begin", |
97ade20b | 206 | range->begin_ns); |
d24d5663 | 207 | if (status != BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK) { |
97ade20b JG |
208 | ret = -1; |
209 | goto end; | |
210 | } | |
211 | ||
fdd3a2da | 212 | status = bt_value_map_insert_signed_integer_entry(range_map, "end", |
97ade20b | 213 | range->end_ns); |
d24d5663 | 214 | if (status != BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK) { |
97ade20b JG |
215 | ret = -1; |
216 | goto end; | |
217 | } | |
218 | ||
97ade20b | 219 | end: |
97ade20b JG |
220 | return ret; |
221 | } | |
222 | ||
97ade20b JG |
223 | static |
224 | int populate_stream_info(struct ctf_fs_ds_file_group *group, | |
b19ff26f | 225 | bt_value *group_info, struct range *stream_range) |
97ade20b JG |
226 | { |
227 | int ret = 0; | |
d24d5663 | 228 | bt_value_map_insert_entry_status insert_status; |
b1c001b6 | 229 | struct ctf_fs_ds_index_entry *first_ds_index_entry, *last_ds_index_entry; |
a38d7650 | 230 | gchar *port_name = NULL; |
97ade20b | 231 | |
b1c001b6 | 232 | /* |
7ed5243a FD |
233 | * Since each `struct ctf_fs_ds_file_group` has a sorted array of |
234 | * `struct ctf_fs_ds_index_entry`, we can compute the stream range from | |
235 | * the timestamp_begin of the first index entry and the timestamp_end | |
236 | * of the last index entry. | |
b1c001b6 | 237 | */ |
7ed5243a FD |
238 | BT_ASSERT(group->index); |
239 | BT_ASSERT(group->index->entries); | |
240 | BT_ASSERT(group->index->entries->len > 0); | |
b1c001b6 | 241 | |
7ed5243a FD |
242 | /* First entry. */ |
243 | first_ds_index_entry = (struct ctf_fs_ds_index_entry *) g_ptr_array_index( | |
244 | group->index->entries, 0); | |
b1c001b6 | 245 | |
7ed5243a FD |
246 | /* Last entry. */ |
247 | last_ds_index_entry = (struct ctf_fs_ds_index_entry *) g_ptr_array_index( | |
248 | group->index->entries, group->index->entries->len - 1); | |
b1c001b6 FD |
249 | |
250 | stream_range->begin_ns = first_ds_index_entry->timestamp_begin_ns; | |
251 | stream_range->end_ns = last_ds_index_entry->timestamp_end_ns; | |
b1c001b6 | 252 | |
1d4ac4b6 FD |
253 | /* |
254 | * If any of the begin and end timestamps is not set it means that | |
255 | * packets don't include `timestamp_begin` _and_ `timestamp_end` fields | |
256 | * in their packet context so we can't set the range. | |
257 | */ | |
258 | stream_range->set = stream_range->begin_ns != UINT64_C(-1) && | |
259 | stream_range->end_ns != UINT64_C(-1); | |
260 | ||
261 | ret = add_range(group_info, stream_range, "range-ns"); | |
262 | if (ret) { | |
263 | goto end; | |
97ade20b JG |
264 | } |
265 | ||
a38d7650 SM |
266 | port_name = ctf_fs_make_port_name(group); |
267 | if (!port_name) { | |
268 | ret = -1; | |
269 | goto end; | |
270 | } | |
271 | ||
d24d5663 PP |
272 | insert_status = bt_value_map_insert_string_entry(group_info, |
273 | "port-name", port_name); | |
274 | if (insert_status != BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK) { | |
a38d7650 SM |
275 | ret = -1; |
276 | goto end; | |
277 | } | |
278 | ||
97ade20b | 279 | end: |
19bbdc9b | 280 | g_free(port_name); |
97ade20b JG |
281 | return ret; |
282 | } | |
283 | ||
284 | static | |
064b8bc4 SM |
285 | int populate_trace_info(const struct ctf_fs_trace *trace, bt_value *trace_info, |
286 | bt_logging_level log_level, | |
287 | bt_self_component_class *self_comp_class) | |
97ade20b JG |
288 | { |
289 | int ret = 0; | |
290 | size_t group_idx; | |
d24d5663 PP |
291 | bt_value_map_insert_entry_status insert_status; |
292 | bt_value_array_append_element_status append_status; | |
f280892e | 293 | bt_value *file_groups = NULL; |
97ade20b | 294 | |
f280892e SM |
295 | BT_ASSERT(trace->ds_file_groups); |
296 | /* Add trace range info only if it contains streams. */ | |
297 | if (trace->ds_file_groups->len == 0) { | |
298 | ret = -1; | |
064b8bc4 SM |
299 | BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, |
300 | "Trace has no streams: trace-path=%s", trace->path->str); | |
f280892e SM |
301 | goto end; |
302 | } | |
303 | ||
760b266c | 304 | insert_status = bt_value_map_insert_empty_array_entry(trace_info, |
5f2a1585 | 305 | "stream-infos", &file_groups); |
760b266c SM |
306 | if (insert_status != BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK) { |
307 | ret = -1; | |
97ade20b JG |
308 | goto end; |
309 | } | |
310 | ||
97ade20b JG |
311 | /* Find range of all stream groups, and of the trace. */ |
312 | for (group_idx = 0; group_idx < trace->ds_file_groups->len; | |
313 | group_idx++) { | |
b19ff26f | 314 | bt_value *group_info; |
97ade20b JG |
315 | struct range group_range = { .set = false }; |
316 | struct ctf_fs_ds_file_group *group = g_ptr_array_index( | |
317 | trace->ds_file_groups, group_idx); | |
318 | ||
760b266c SM |
319 | append_status = bt_value_array_append_empty_map_element( |
320 | file_groups, &group_info); | |
321 | if (append_status != BT_VALUE_ARRAY_APPEND_ELEMENT_STATUS_OK) { | |
97ade20b JG |
322 | ret = -1; |
323 | goto end; | |
324 | } | |
325 | ||
326 | ret = populate_stream_info(group, group_info, &group_range); | |
327 | if (ret) { | |
7233204d FD |
328 | goto end; |
329 | } | |
97ade20b JG |
330 | } |
331 | ||
97ade20b | 332 | end: |
97ade20b JG |
333 | return ret; |
334 | } | |
335 | ||
336 | BT_HIDDEN | |
5f2a1585 | 337 | bt_component_class_query_method_status trace_infos_query( |
d23b766e | 338 | bt_self_component_class_source *self_comp_class_src, |
98903a3e | 339 | const bt_value *params, bt_logging_level log_level, |
b19ff26f | 340 | const bt_value **user_result) |
97ade20b | 341 | { |
f280892e | 342 | struct ctf_fs_component *ctf_fs = NULL; |
d24d5663 PP |
343 | bt_component_class_query_method_status status = |
344 | BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_OK; | |
d23b766e SM |
345 | bt_self_component_class *self_comp_class = |
346 | bt_self_component_class_source_as_self_component_class( | |
347 | self_comp_class_src); | |
b19ff26f | 348 | bt_value *result = NULL; |
73760435 | 349 | const bt_value *inputs_value = NULL; |
005d49d6 | 350 | const bt_value *trace_name_value; |
97ade20b | 351 | int ret = 0; |
a0cd55ad SM |
352 | bt_value *trace_info = NULL; |
353 | bt_value_array_append_element_status append_status; | |
97ade20b | 354 | |
f6ccaed9 PP |
355 | BT_ASSERT(params); |
356 | ||
97ade20b | 357 | if (!bt_value_is_map(params)) { |
d23b766e SM |
358 | BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, |
359 | "Query parameters is not a map value object."); | |
a635e507 | 360 | status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_ERROR; |
97ade20b JG |
361 | goto error; |
362 | } | |
363 | ||
4c65a157 | 364 | ctf_fs = ctf_fs_component_create(log_level, NULL); |
d907165c | 365 | if (!ctf_fs) { |
97ade20b JG |
366 | goto error; |
367 | } | |
97ade20b | 368 | |
005d49d6 SM |
369 | if (!read_src_fs_parameters(params, &inputs_value, &trace_name_value, |
370 | ctf_fs, NULL, self_comp_class)) { | |
a635e507 | 371 | status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_ERROR; |
97ade20b JG |
372 | goto error; |
373 | } | |
374 | ||
005d49d6 SM |
375 | if (ctf_fs_component_create_ctf_fs_trace(ctf_fs, inputs_value, |
376 | trace_name_value, NULL, self_comp_class)) { | |
97ade20b JG |
377 | goto error; |
378 | } | |
379 | ||
05e21286 | 380 | result = bt_value_array_create(); |
da91b29a | 381 | if (!result) { |
d24d5663 | 382 | status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_MEMORY_ERROR; |
97ade20b JG |
383 | goto error; |
384 | } | |
385 | ||
a0cd55ad SM |
386 | append_status = bt_value_array_append_empty_map_element(result, |
387 | &trace_info); | |
388 | if (append_status != BT_VALUE_ARRAY_APPEND_ELEMENT_STATUS_OK) { | |
389 | BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, | |
390 | "Failed to create trace info map."); | |
391 | goto error; | |
392 | } | |
97ade20b | 393 | |
064b8bc4 SM |
394 | ret = populate_trace_info(ctf_fs->trace, trace_info, log_level, |
395 | self_comp_class); | |
a0cd55ad SM |
396 | if (ret) { |
397 | goto error; | |
97ade20b JG |
398 | } |
399 | ||
400 | goto end; | |
401 | ||
402 | error: | |
c5b9b441 | 403 | BT_VALUE_PUT_REF_AND_RESET(result); |
c7eee084 | 404 | |
d94d92ac | 405 | if (status >= 0) { |
d24d5663 | 406 | status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_ERROR; |
c7eee084 PP |
407 | } |
408 | ||
97ade20b | 409 | end: |
f280892e SM |
410 | if (ctf_fs) { |
411 | ctf_fs_destroy(ctf_fs); | |
412 | ctf_fs = NULL; | |
97ade20b | 413 | } |
d94d92ac | 414 | |
05e21286 | 415 | *user_result = result; |
d94d92ac | 416 | return status; |
04c0ba87 | 417 | } |
73760435 SM |
418 | |
419 | BT_HIDDEN | |
420 | bt_component_class_query_method_status support_info_query( | |
421 | bt_self_component_class_source *comp_class, | |
422 | const bt_value *params, bt_logging_level log_level, | |
423 | const bt_value **user_result) | |
424 | { | |
425 | const bt_value *input_type_value; | |
426 | const char *input_type; | |
427 | bt_component_class_query_method_status status; | |
493917ba | 428 | bt_value_map_insert_entry_status insert_entry_status; |
73760435 SM |
429 | double weight = 0; |
430 | gchar *metadata_path = NULL; | |
431 | bt_value *result = NULL; | |
493917ba SM |
432 | struct ctf_metadata_decoder *metadata_decoder = NULL; |
433 | FILE *metadata_file = NULL; | |
434 | char uuid_str[BT_UUID_STR_LEN + 1]; | |
435 | bool has_uuid = false; | |
436 | const bt_value *input_value; | |
437 | const char *input; | |
73760435 SM |
438 | |
439 | input_type_value = bt_value_map_borrow_entry_value_const(params, "type"); | |
440 | BT_ASSERT(input_type_value); | |
441 | BT_ASSERT(bt_value_get_type(input_type_value) == BT_VALUE_TYPE_STRING); | |
442 | input_type = bt_value_string_get(input_type_value); | |
443 | ||
493917ba SM |
444 | if (strcmp(input_type, "directory") != 0) { |
445 | goto create_result; | |
446 | } | |
447 | ||
448 | input_value = bt_value_map_borrow_entry_value_const(params, "input"); | |
449 | BT_ASSERT(input_value); | |
450 | BT_ASSERT(bt_value_get_type(input_value) == BT_VALUE_TYPE_STRING); | |
451 | input = bt_value_string_get(input_value); | |
452 | ||
453 | metadata_path = g_build_filename(input, CTF_FS_METADATA_FILENAME, NULL); | |
454 | if (!metadata_path) { | |
73760435 SM |
455 | status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_MEMORY_ERROR; |
456 | goto end; | |
457 | } | |
458 | ||
8c41c571 | 459 | metadata_file = g_fopen(metadata_path, "rb"); |
493917ba SM |
460 | if (metadata_file) { |
461 | struct ctf_metadata_decoder_config metadata_decoder_config = { 0 }; | |
462 | enum ctf_metadata_decoder_status decoder_status; | |
463 | bt_uuid_t uuid; | |
73760435 | 464 | |
493917ba | 465 | metadata_decoder_config.log_level = log_level; |
73760435 | 466 | |
493917ba SM |
467 | metadata_decoder = ctf_metadata_decoder_create( |
468 | &metadata_decoder_config); | |
469 | if (!metadata_decoder) { | |
470 | status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_ERROR; | |
471 | goto end; | |
472 | } | |
473 | ||
474 | decoder_status = ctf_metadata_decoder_append_content( | |
475 | metadata_decoder, metadata_file); | |
476 | if (decoder_status != CTF_METADATA_DECODER_STATUS_OK) { | |
477 | BT_LOGW("cannot append metadata content: metadata-decoder-status=%d", | |
478 | decoder_status); | |
479 | status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_ERROR; | |
73760435 SM |
480 | goto end; |
481 | } | |
482 | ||
483 | /* | |
493917ba SM |
484 | * We were able to parse the metadata file, so we are |
485 | * confident it's a CTF trace. | |
73760435 | 486 | */ |
493917ba SM |
487 | weight = 0.75; |
488 | ||
489 | /* If the trace has a UUID, return the stringified UUID as the group. */ | |
490 | if (ctf_metadata_decoder_get_trace_class_uuid(metadata_decoder, uuid) == 0) { | |
491 | bt_uuid_to_str(uuid, uuid_str); | |
492 | has_uuid = true; | |
73760435 SM |
493 | } |
494 | } | |
495 | ||
493917ba SM |
496 | create_result: |
497 | result = bt_value_map_create(); | |
498 | if (!result) { | |
73760435 SM |
499 | status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_MEMORY_ERROR; |
500 | goto end; | |
501 | } | |
502 | ||
493917ba SM |
503 | insert_entry_status = bt_value_map_insert_real_entry(result, "weight", weight); |
504 | if (insert_entry_status != BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK) { | |
505 | status = (int) insert_entry_status; | |
73760435 SM |
506 | goto end; |
507 | } | |
508 | ||
493917ba SM |
509 | /* We are not supposed to have weight == 0 and a UUID. */ |
510 | BT_ASSERT(weight > 0 || !has_uuid); | |
511 | ||
512 | if (weight > 0 && has_uuid) { | |
513 | insert_entry_status = bt_value_map_insert_string_entry(result, "group", uuid_str); | |
514 | if (insert_entry_status != BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK) { | |
515 | status = (int) insert_entry_status; | |
516 | goto end; | |
517 | } | |
518 | } | |
519 | ||
73760435 SM |
520 | *user_result = result; |
521 | result = NULL; | |
522 | status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_OK; | |
523 | ||
524 | end: | |
525 | g_free(metadata_path); | |
526 | bt_value_put_ref(result); | |
493917ba | 527 | ctf_metadata_decoder_destroy(metadata_decoder); |
73760435 SM |
528 | |
529 | return status; | |
530 | } |