4 * Babeltrace CTF file system Reader Component queries
6 * Copyright 2017 Jérémie Galarneau <jeremie.galarneau@efficios.com>
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:
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
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
31 #include "../common/metadata/decoder.h"
32 #include <babeltrace/common-internal.h>
33 #include <babeltrace/babeltrace-internal.h>
34 #include <babeltrace/ctf-ir/stream.h>
37 #define BT_LOG_TAG "PLUGIN-CTF-FS-QUERY-SRC"
40 #define METADATA_TEXT_SIG "/* CTF 1.8"
49 struct bt_value
*metadata_info_query(struct bt_component_class
*comp_class
,
50 struct bt_value
*params
)
52 struct bt_value
*result
= NULL
;
53 struct bt_value
*path_value
= NULL
;
54 char *metadata_text
= NULL
;
55 FILE *metadata_fp
= NULL
;
56 GString
*g_metadata_text
= NULL
;
62 result
= bt_value_map_create();
67 if (!bt_value_is_map(params
)) {
69 "Query parameters is not a map value object\n");
73 path_value
= bt_value_map_get(params
, "path");
74 ret
= bt_value_string_get(path_value
, &path
);
77 "Cannot get `path` string parameter\n");
82 metadata_fp
= ctf_fs_metadata_open_file(path
);
85 "Cannot open trace at path `%s`\n", path
);
89 is_packetized
= ctf_metadata_decoder_is_packetized(metadata_fp
,
93 ret
= ctf_metadata_decoder_packetized_file_stream_to_buf(
94 metadata_fp
, &metadata_text
, bo
);
97 "Cannot decode packetized metadata file\n");
103 fseek(metadata_fp
, 0, SEEK_END
);
104 filesize
= ftell(metadata_fp
);
106 metadata_text
= malloc(filesize
+ 1);
107 if (!metadata_text
) {
109 "Cannot allocate buffer for metadata text\n");
113 if (fread(metadata_text
, filesize
, 1, metadata_fp
) != 1) {
115 "Cannot read metadata file\n");
119 metadata_text
[filesize
] = '\0';
122 g_metadata_text
= g_string_new(NULL
);
123 if (!g_metadata_text
) {
127 if (strncmp(metadata_text
, METADATA_TEXT_SIG
,
128 sizeof(METADATA_TEXT_SIG
) - 1) != 0) {
129 g_string_assign(g_metadata_text
, METADATA_TEXT_SIG
);
130 g_string_append(g_metadata_text
, " */\n\n");
133 g_string_append(g_metadata_text
, metadata_text
);
135 ret
= bt_value_map_insert_string(result
, "text",
136 g_metadata_text
->str
);
138 fprintf(stderr
, "Cannot insert metadata text into result\n");
142 ret
= bt_value_map_insert_bool(result
, "is-packetized",
145 fprintf(stderr
, "Cannot insert is packetized into result\n");
158 if (g_metadata_text
) {
159 g_string_free(g_metadata_text
, TRUE
);
168 int add_range(struct bt_value
*info
, struct range
*range
,
169 const char *range_name
)
172 enum bt_value_status status
;
173 struct bt_value
*range_map
= NULL
;
180 range_map
= bt_value_map_create();
186 status
= bt_value_map_insert_integer(range_map
, "begin",
188 if (status
!= BT_VALUE_STATUS_OK
) {
193 status
= bt_value_map_insert_integer(range_map
, "end",
195 if (status
!= BT_VALUE_STATUS_OK
) {
200 status
= bt_value_map_insert(info
, range_name
, range_map
);
201 if (status
!= BT_VALUE_STATUS_OK
) {
211 int add_stream_ids(struct bt_value
*info
, struct bt_ctf_stream
*stream
)
214 int64_t stream_class_id
, stream_instance_id
;
215 enum bt_value_status status
;
216 struct bt_ctf_stream_class
*stream_class
;
218 stream_instance_id
= bt_ctf_stream_get_id(stream
);
219 if (stream_instance_id
!= -1) {
220 status
= bt_value_map_insert_integer(info
, "id",
222 if (status
!= BT_VALUE_STATUS_OK
) {
228 stream_class
= bt_ctf_stream_get_class(stream
);
234 stream_class_id
= bt_ctf_stream_class_get_id(stream_class
);
235 if (stream_class_id
== -1) {
240 status
= bt_value_map_insert_integer(info
, "class-id", stream_class_id
);
241 if (status
!= BT_VALUE_STATUS_OK
) {
246 bt_put(stream_class
);
251 int populate_stream_info(struct ctf_fs_ds_file_group
*group
,
252 struct bt_value
*group_info
,
253 struct range
*stream_range
)
257 enum bt_value_status status
;
258 struct bt_value
*file_paths
;
260 stream_range
->begin_ns
= INT64_MAX
;
261 stream_range
->end_ns
= 0;
263 file_paths
= bt_value_array_create();
269 for (file_idx
= 0; file_idx
< group
->ds_file_infos
->len
; file_idx
++) {
270 int64_t file_begin_epoch
, file_end_epoch
;
271 struct ctf_fs_ds_file_info
*info
=
272 g_ptr_array_index(group
->ds_file_infos
,
275 if (!info
->index
|| info
->index
->entries
->len
== 0) {
276 BT_LOGW("Cannot determine range of unindexed stream file \'%s\'",
282 status
= bt_value_array_append_string(file_paths
,
284 if (status
!= BT_VALUE_STATUS_OK
) {
290 * file range is from timestamp_begin of the first entry to the
291 * timestamp_end of the last entry.
293 file_begin_epoch
= ((struct ctf_fs_ds_index_entry
*) &g_array_index(info
->index
->entries
,
294 struct ctf_fs_ds_index_entry
, 0))->timestamp_begin_ns
;
295 file_end_epoch
= ((struct ctf_fs_ds_index_entry
*) &g_array_index(info
->index
->entries
,
296 struct ctf_fs_ds_index_entry
, info
->index
->entries
->len
- 1))->timestamp_end_ns
;
298 stream_range
->begin_ns
= min(stream_range
->begin_ns
, file_begin_epoch
);
299 stream_range
->end_ns
= max(stream_range
->end_ns
, file_end_epoch
);
300 stream_range
->set
= true;
303 if (stream_range
->set
) {
304 ret
= add_range(group_info
, stream_range
, "range-ns");
310 status
= bt_value_map_insert(group_info
, "paths", file_paths
);
311 if (status
!= BT_VALUE_STATUS_OK
) {
316 ret
= add_stream_ids(group_info
, group
->stream
);
326 int populate_trace_info(const char *trace_path
, const char *trace_name
,
327 struct bt_value
*trace_info
)
331 struct ctf_fs_trace
*trace
= NULL
;
332 enum bt_value_status status
;
333 struct bt_value
*file_groups
;
334 struct range trace_range
= {
335 .begin_ns
= INT64_MAX
,
339 struct range trace_intersection
= {
345 file_groups
= bt_value_array_create();
350 status
= bt_value_map_insert_string(trace_info
, "name",
352 if (status
!= BT_VALUE_STATUS_OK
) {
356 status
= bt_value_map_insert_string(trace_info
, "path",
358 if (status
!= BT_VALUE_STATUS_OK
) {
363 trace
= ctf_fs_trace_create(trace_path
, trace_name
, NULL
);
365 BT_LOGE("Failed to create fs trace at \'%s\'", trace_path
);
370 assert(trace
->ds_file_groups
);
371 /* Add trace range info only if it contains streams. */
372 if (trace
->ds_file_groups
->len
== 0) {
377 /* Find range of all stream groups, and of the trace. */
378 for (group_idx
= 0; group_idx
< trace
->ds_file_groups
->len
;
380 struct bt_value
*group_info
;
381 struct range group_range
= { .set
= false };
382 struct ctf_fs_ds_file_group
*group
= g_ptr_array_index(
383 trace
->ds_file_groups
, group_idx
);
385 group_info
= bt_value_map_create();
391 ret
= populate_stream_info(group
, group_info
, &group_range
);
397 if (group_range
.set
) {
398 trace_range
.begin_ns
= min(trace_range
.begin_ns
,
399 group_range
.begin_ns
);
400 trace_range
.end_ns
= max(trace_range
.end_ns
,
402 trace_range
.set
= true;
404 trace_intersection
.begin_ns
= max(trace_intersection
.begin_ns
,
405 group_range
.begin_ns
);
406 trace_intersection
.end_ns
= min(trace_intersection
.end_ns
,
408 trace_intersection
.set
= true;
409 status
= bt_value_array_append(file_groups
, group_info
);
411 if (status
!= BT_VALUE_STATUS_OK
) {
417 ret
= add_range(trace_info
, &trace_range
, "range-ns");
421 ret
= add_range(trace_info
, &trace_intersection
,
422 "intersection-range-ns");
427 status
= bt_value_map_insert(trace_info
, "streams", file_groups
);
429 if (status
!= BT_VALUE_STATUS_OK
) {
436 ctf_fs_trace_destroy(trace
);
441 struct bt_value
*trace_info_query(struct bt_component_class
*comp_class
,
442 struct bt_value
*params
)
444 struct bt_value
*trace_infos
= NULL
;
445 struct bt_value
*path_value
= NULL
;
447 const char *path
= NULL
;
448 GList
*trace_paths
= NULL
;
449 GList
*trace_names
= NULL
;
450 GList
*tp_node
= NULL
;
451 GList
*tn_node
= NULL
;
452 GString
*normalized_path
= NULL
;
454 if (!bt_value_is_map(params
)) {
455 BT_LOGE("Query parameters is not a map value object.");
459 path_value
= bt_value_map_get(params
, "path");
460 ret
= bt_value_string_get(path_value
, &path
);
462 BT_LOGE("Cannot get `path` string parameter.");
466 normalized_path
= bt_common_normalize_path(path
, NULL
);
467 if (!normalized_path
) {
468 BT_LOGE("Failed to normalize path: `%s`.", path
);
473 ret
= ctf_fs_find_traces(&trace_paths
, normalized_path
->str
);
478 trace_names
= ctf_fs_create_trace_names(trace_paths
,
479 normalized_path
->str
);
481 BT_LOGE("Cannot create trace names from trace paths.");
485 trace_infos
= bt_value_array_create();
490 /* Iterates over both trace paths and names simultaneously. */
491 for (tp_node
= trace_paths
, tn_node
= trace_names
; tp_node
;
492 tp_node
= g_list_next(tp_node
),
493 tn_node
= g_list_next(tn_node
)) {
494 GString
*trace_path
= tp_node
->data
;
495 GString
*trace_name
= tn_node
->data
;
496 enum bt_value_status status
;
497 struct bt_value
*trace_info
;
499 trace_info
= bt_value_map_create();
501 BT_LOGE("Failed to create trace info map.");
505 ret
= populate_trace_info(trace_path
->str
, trace_name
->str
,
512 status
= bt_value_array_append(trace_infos
, trace_info
);
514 if (status
!= BT_VALUE_STATUS_OK
) {
524 if (normalized_path
) {
525 g_string_free(normalized_path
, TRUE
);
528 for (tp_node
= trace_paths
; tp_node
; tp_node
= g_list_next(tp_node
)) {
530 g_string_free(tp_node
->data
, TRUE
);
533 g_list_free(trace_paths
);
536 for (tn_node
= trace_names
; tn_node
; tn_node
= g_list_next(tn_node
)) {
538 g_string_free(tn_node
->data
, TRUE
);
541 g_list_free(trace_names
);
543 /* "path" becomes invalid with the release of path_value. */
This page took 0.049247 seconds and 4 git commands to generate.