4 * Babeltrace Trace Converter
6 * Copyright 2010-2011 EfficiOS Inc. and Linux Foundation
8 * Author: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
10 * Permission is hereby granted, free of charge, to any person obtaining a copy
11 * of this software and associated documentation files (the "Software"), to deal
12 * in the Software without restriction, including without limitation the rights
13 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 * copies of the Software, and to permit persons to whom the Software is
15 * furnished to do so, subject to the following conditions:
17 * The above copyright notice and this permission notice shall be included in
18 * all copies or substantial portions of the Software.
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29 #define BT_LOG_TAG "CLI"
32 #include <babeltrace/babeltrace.h>
33 #include <babeltrace/plugin/plugin.h>
34 #include <babeltrace/common-internal.h>
35 #include <babeltrace/graph/component.h>
36 #include <babeltrace/graph/component-source.h>
37 #include <babeltrace/graph/component-sink.h>
38 #include <babeltrace/graph/component-filter.h>
39 #include <babeltrace/graph/component-class.h>
40 #include <babeltrace/graph/port.h>
41 #include <babeltrace/graph/graph.h>
42 #include <babeltrace/graph/connection.h>
43 #include <babeltrace/graph/notification-iterator.h>
44 #include <babeltrace/ref.h>
45 #include <babeltrace/values.h>
46 #include <babeltrace/logging.h>
56 #include "babeltrace-cfg.h"
57 #include "babeltrace-cfg-cli-args.h"
58 #include "babeltrace-cfg-cli-args-default.h"
60 #define ENV_BABELTRACE_WARN_COMMAND_NAME_DIRECTORY_CLASH "BABELTRACE_CLI_WARN_COMMAND_NAME_DIRECTORY_CLASH"
62 /* Application's processing graph (weak) */
63 static struct bt_graph
*the_graph
;
64 static bool canceled
= false;
66 GPtrArray
*loaded_plugins
;
69 void sigint_handler(int signum
)
71 if (signum
!= SIGINT
) {
76 bt_graph_cancel(the_graph
);
83 void init_static_data(void)
85 loaded_plugins
= g_ptr_array_new_with_free_func(bt_put
);
89 void fini_static_data(void)
91 g_ptr_array_free(loaded_plugins
, TRUE
);
95 struct bt_plugin
*find_plugin(const char *name
)
98 struct bt_plugin
*plugin
= NULL
;
101 BT_LOGD("Finding plugin: name=\"%s\"", name
);
103 for (i
= 0; i
< loaded_plugins
->len
; i
++) {
104 plugin
= g_ptr_array_index(loaded_plugins
, i
);
106 if (strcmp(name
, bt_plugin_get_name(plugin
)) == 0) {
113 if (BT_LOG_ON_DEBUG
) {
115 BT_LOGD("Found plugin: plugin-addr=%p", plugin
);
117 BT_LOGD("Cannot find plugin.");
121 return bt_get(plugin
);
125 struct bt_component_class
*find_component_class(const char *plugin_name
,
126 const char *comp_class_name
,
127 enum bt_component_class_type comp_class_type
)
129 struct bt_component_class
*comp_class
= NULL
;
130 struct bt_plugin
*plugin
;
132 BT_LOGD("Finding component class: plugin-name=\"%s\", "
133 "comp-cls-name=\"%s\", comp-cls-type=%d",
134 plugin_name
, comp_class_name
, comp_class_type
);
136 plugin
= find_plugin(plugin_name
);
142 comp_class
= bt_plugin_get_component_class_by_name_and_type(plugin
,
143 comp_class_name
, comp_class_type
);
147 if (BT_LOG_ON_DEBUG
) {
149 BT_LOGD("Found component class: comp-cls-addr=%p",
152 BT_LOGD("Cannot find component class.");
160 void print_indent(FILE *fp
, size_t indent
)
164 for (i
= 0; i
< indent
; i
++) {
170 const char *component_type_str(enum bt_component_class_type type
)
173 case BT_COMPONENT_CLASS_TYPE_SOURCE
:
175 case BT_COMPONENT_CLASS_TYPE_SINK
:
177 case BT_COMPONENT_CLASS_TYPE_FILTER
:
179 case BT_COMPONENT_CLASS_TYPE_UNKNOWN
:
186 void print_plugin_comp_cls_opt(FILE *fh
, const char *plugin_name
,
187 const char *comp_cls_name
, enum bt_component_class_type type
)
189 GString
*shell_plugin_name
= NULL
;
190 GString
*shell_comp_cls_name
= NULL
;
192 shell_plugin_name
= bt_common_shell_quote(plugin_name
, false);
193 if (!shell_plugin_name
) {
197 shell_comp_cls_name
= bt_common_shell_quote(comp_cls_name
, false);
198 if (!shell_comp_cls_name
) {
202 fprintf(fh
, "%s%s--%s%s %s'%s%s%s%s.%s%s%s'",
203 bt_common_color_bold(),
204 bt_common_color_fg_cyan(),
205 component_type_str(type
),
206 bt_common_color_reset(),
207 bt_common_color_fg_default(),
208 bt_common_color_bold(),
209 bt_common_color_fg_blue(),
210 shell_plugin_name
->str
,
211 bt_common_color_fg_default(),
212 bt_common_color_fg_yellow(),
213 shell_comp_cls_name
->str
,
214 bt_common_color_reset());
217 if (shell_plugin_name
) {
218 g_string_free(shell_plugin_name
, TRUE
);
221 if (shell_comp_cls_name
) {
222 g_string_free(shell_comp_cls_name
, TRUE
);
227 void print_value(FILE *, struct bt_value
*, size_t);
230 void print_value_rec(FILE *, struct bt_value
*, size_t);
232 struct print_map_value_data
{
238 bt_bool
print_map_value(const char *key
, struct bt_value
*object
, void *data
)
240 struct print_map_value_data
*print_map_value_data
= data
;
242 print_indent(print_map_value_data
->fp
, print_map_value_data
->indent
);
243 fprintf(print_map_value_data
->fp
, "%s: ", key
);
245 if (bt_value_is_array(object
) &&
246 bt_value_array_is_empty(object
)) {
247 fprintf(print_map_value_data
->fp
, "[ ]\n");
251 if (bt_value_is_map(object
) &&
252 bt_value_map_is_empty(object
)) {
253 fprintf(print_map_value_data
->fp
, "{ }\n");
257 if (bt_value_is_array(object
) ||
258 bt_value_is_map(object
)) {
259 fprintf(print_map_value_data
->fp
, "\n");
262 print_value_rec(print_map_value_data
->fp
, object
,
263 print_map_value_data
->indent
+ 2);
268 void print_value_rec(FILE *fp
, struct bt_value
*value
, size_t indent
)
281 switch (bt_value_get_type(value
)) {
282 case BT_VALUE_TYPE_NULL
:
283 fprintf(fp
, "%snull%s\n", bt_common_color_bold(),
284 bt_common_color_reset());
286 case BT_VALUE_TYPE_BOOL
:
287 bt_value_bool_get(value
, &bool_val
);
288 fprintf(fp
, "%s%s%s%s\n", bt_common_color_bold(),
289 bt_common_color_fg_cyan(), bool_val
? "yes" : "no",
290 bt_common_color_reset());
292 case BT_VALUE_TYPE_INTEGER
:
293 bt_value_integer_get(value
, &int_val
);
294 fprintf(fp
, "%s%s%" PRId64
"%s\n", bt_common_color_bold(),
295 bt_common_color_fg_red(), int_val
,
296 bt_common_color_reset());
298 case BT_VALUE_TYPE_FLOAT
:
299 bt_value_float_get(value
, &dbl_val
);
300 fprintf(fp
, "%s%s%lf%s\n", bt_common_color_bold(),
301 bt_common_color_fg_red(), dbl_val
,
302 bt_common_color_reset());
304 case BT_VALUE_TYPE_STRING
:
305 bt_value_string_get(value
, &str_val
);
306 fprintf(fp
, "%s%s%s%s\n", bt_common_color_bold(),
307 bt_common_color_fg_green(), str_val
,
308 bt_common_color_reset());
310 case BT_VALUE_TYPE_ARRAY
:
311 size
= bt_value_array_size(value
);
315 print_indent(fp
, indent
);
316 fprintf(fp
, "[ ]\n");
320 for (i
= 0; i
< size
; i
++) {
321 struct bt_value
*element
=
322 bt_value_array_get(value
, i
);
325 print_indent(fp
, indent
);
328 if (bt_value_is_array(element
) &&
329 bt_value_array_is_empty(element
)) {
330 fprintf(fp
, "[ ]\n");
334 if (bt_value_is_map(element
) &&
335 bt_value_map_is_empty(element
)) {
336 fprintf(fp
, "{ }\n");
340 if (bt_value_is_array(element
) ||
341 bt_value_is_map(element
)) {
345 print_value_rec(fp
, element
, indent
+ 2);
349 case BT_VALUE_TYPE_MAP
:
351 struct print_map_value_data data
= {
356 if (bt_value_map_is_empty(value
)) {
357 print_indent(fp
, indent
);
358 fprintf(fp
, "{ }\n");
362 bt_value_map_foreach(value
, print_map_value
, &data
);
371 void print_value(FILE *fp
, struct bt_value
*value
, size_t indent
)
373 if (!bt_value_is_array(value
) && !bt_value_is_map(value
)) {
374 print_indent(fp
, indent
);
377 print_value_rec(fp
, value
, indent
);
381 void print_bt_config_component(struct bt_config_component
*bt_config_component
)
383 fprintf(stderr
, " ");
384 print_plugin_comp_cls_opt(stderr
, bt_config_component
->plugin_name
->str
,
385 bt_config_component
->comp_cls_name
->str
,
386 bt_config_component
->type
);
387 fprintf(stderr
, ":\n");
389 if (bt_config_component
->instance_name
->len
> 0) {
390 fprintf(stderr
, " Name: %s\n",
391 bt_config_component
->instance_name
->str
);
394 fprintf(stderr
, " Parameters:\n");
395 print_value(stderr
, bt_config_component
->params
, 8);
399 void print_bt_config_components(GPtrArray
*array
)
403 for (i
= 0; i
< array
->len
; i
++) {
404 struct bt_config_component
*cfg_component
=
405 bt_config_get_component(array
, i
);
406 print_bt_config_component(cfg_component
);
407 BT_PUT(cfg_component
);
412 void print_plugin_paths(struct bt_value
*plugin_paths
)
414 fprintf(stderr
, " Plugin paths:\n");
415 print_value(stderr
, plugin_paths
, 4);
419 void print_cfg_run(struct bt_config
*cfg
)
423 print_plugin_paths(cfg
->plugin_paths
);
424 fprintf(stderr
, " Source component instances:\n");
425 print_bt_config_components(cfg
->cmd_data
.run
.sources
);
427 if (cfg
->cmd_data
.run
.filters
->len
> 0) {
428 fprintf(stderr
, " Filter component instances:\n");
429 print_bt_config_components(cfg
->cmd_data
.run
.filters
);
432 fprintf(stderr
, " Sink component instances:\n");
433 print_bt_config_components(cfg
->cmd_data
.run
.sinks
);
434 fprintf(stderr
, " Connections:\n");
436 for (i
= 0; i
< cfg
->cmd_data
.run
.connections
->len
; i
++) {
437 struct bt_config_connection
*cfg_connection
=
438 g_ptr_array_index(cfg
->cmd_data
.run
.connections
,
441 fprintf(stderr
, " %s%s%s -> %s%s%s\n",
442 cfg_connection
->upstream_comp_name
->str
,
443 cfg_connection
->upstream_port_glob
->len
> 0 ? "." : "",
444 cfg_connection
->upstream_port_glob
->str
,
445 cfg_connection
->downstream_comp_name
->str
,
446 cfg_connection
->downstream_port_glob
->len
> 0 ? "." : "",
447 cfg_connection
->downstream_port_glob
->str
);
452 void print_cfg_list_plugins(struct bt_config
*cfg
)
454 print_plugin_paths(cfg
->plugin_paths
);
458 void print_cfg_help(struct bt_config
*cfg
)
460 print_plugin_paths(cfg
->plugin_paths
);
464 void print_cfg_print_ctf_metadata(struct bt_config
*cfg
)
466 print_plugin_paths(cfg
->plugin_paths
);
467 fprintf(stderr
, " Path: %s\n",
468 cfg
->cmd_data
.print_ctf_metadata
.path
->str
);
472 void print_cfg_print_lttng_live_sessions(struct bt_config
*cfg
)
474 print_plugin_paths(cfg
->plugin_paths
);
475 fprintf(stderr
, " URL: %s\n",
476 cfg
->cmd_data
.print_lttng_live_sessions
.url
->str
);
480 void print_cfg_query(struct bt_config
*cfg
)
482 print_plugin_paths(cfg
->plugin_paths
);
483 fprintf(stderr
, " Object: `%s`\n", cfg
->cmd_data
.query
.object
->str
);
484 fprintf(stderr
, " Component class:\n");
485 print_bt_config_component(cfg
->cmd_data
.query
.cfg_component
);
489 void print_cfg(struct bt_config
*cfg
)
491 if (!BT_LOG_ON_INFO
) {
495 BT_LOGI_STR("Configuration:");
496 fprintf(stderr
, " Debug mode: %s\n", cfg
->debug
? "yes" : "no");
497 fprintf(stderr
, " Verbose mode: %s\n", cfg
->verbose
? "yes" : "no");
499 switch (cfg
->command
) {
500 case BT_CONFIG_COMMAND_RUN
:
503 case BT_CONFIG_COMMAND_LIST_PLUGINS
:
504 print_cfg_list_plugins(cfg
);
506 case BT_CONFIG_COMMAND_HELP
:
509 case BT_CONFIG_COMMAND_QUERY
:
510 print_cfg_query(cfg
);
512 case BT_CONFIG_COMMAND_PRINT_CTF_METADATA
:
513 print_cfg_print_ctf_metadata(cfg
);
515 case BT_CONFIG_COMMAND_PRINT_LTTNG_LIVE_SESSIONS
:
516 print_cfg_print_lttng_live_sessions(cfg
);
524 void add_to_loaded_plugins(struct bt_plugin_set
*plugin_set
)
529 count
= bt_plugin_set_get_plugin_count(plugin_set
);
532 for (i
= 0; i
< count
; i
++) {
533 struct bt_plugin
*plugin
=
534 bt_plugin_set_get_plugin(plugin_set
, i
);
535 struct bt_plugin
*loaded_plugin
=
536 find_plugin(bt_plugin_get_name(plugin
));
541 BT_LOGI("Not using plugin: another one already exists with the same name: "
542 "plugin-name=\"%s\", plugin-path=\"%s\", "
543 "existing-plugin-path=\"%s\"",
544 bt_plugin_get_name(plugin
),
545 bt_plugin_get_path(plugin
),
546 bt_plugin_get_path(loaded_plugin
));
547 bt_put(loaded_plugin
);
549 /* Add to global array. */
550 BT_LOGD("Adding plugin to loaded plugins: plugin-path=\"%s\"",
551 bt_plugin_get_name(plugin
));
552 g_ptr_array_add(loaded_plugins
, bt_get(plugin
));
560 int load_dynamic_plugins(struct bt_value
*plugin_paths
)
562 int nr_paths
, i
, ret
= 0;
564 nr_paths
= bt_value_array_size(plugin_paths
);
566 BT_LOGE_STR("Cannot load dynamic plugins: no plugin path.");
571 BT_LOGI("Loading dynamic plugins.");
573 for (i
= 0; i
< nr_paths
; i
++) {
574 struct bt_value
*plugin_path_value
= NULL
;
575 const char *plugin_path
;
576 struct bt_plugin_set
*plugin_set
;
578 plugin_path_value
= bt_value_array_get(plugin_paths
, i
);
579 bt_value_string_get(plugin_path_value
, &plugin_path
);
583 * Skip this if the directory does not exist because
584 * bt_plugin_create_all_from_dir() expects an existing
587 if (!g_file_test(plugin_path
, G_FILE_TEST_IS_DIR
)) {
588 BT_LOGV("Skipping nonexistent directory path: "
589 "path=\"%s\"", plugin_path
);
590 BT_PUT(plugin_path_value
);
594 plugin_set
= bt_plugin_create_all_from_dir(plugin_path
, false);
596 BT_LOGD("Unable to load dynamic plugins: path=\"%s\"",
598 BT_PUT(plugin_path_value
);
602 add_to_loaded_plugins(plugin_set
);
604 BT_PUT(plugin_path_value
);
611 int load_static_plugins(void)
614 struct bt_plugin_set
*plugin_set
;
616 BT_LOGI("Loading static plugins.");
617 plugin_set
= bt_plugin_create_all_from_static();
619 BT_LOGE("Unable to load static plugins.");
624 add_to_loaded_plugins(plugin_set
);
631 int load_all_plugins(struct bt_value
*plugin_paths
)
635 if (load_dynamic_plugins(plugin_paths
)) {
640 if (load_static_plugins()) {
645 BT_LOGI("Loaded all plugins: count=%u", loaded_plugins
->len
);
652 void print_plugin_info(struct bt_plugin
*plugin
)
654 unsigned int major
, minor
, patch
;
656 enum bt_plugin_status version_status
;
657 const char *plugin_name
;
661 const char *plugin_description
;
663 plugin_name
= bt_plugin_get_name(plugin
);
664 path
= bt_plugin_get_path(plugin
);
665 author
= bt_plugin_get_author(plugin
);
666 license
= bt_plugin_get_license(plugin
);
667 plugin_description
= bt_plugin_get_description(plugin
);
668 version_status
= bt_plugin_get_version(plugin
, &major
, &minor
,
670 printf("%s%s%s%s:\n", bt_common_color_bold(),
671 bt_common_color_fg_blue(), plugin_name
,
672 bt_common_color_reset());
673 printf(" %sPath%s: %s\n", bt_common_color_bold(),
674 bt_common_color_reset(), path
? path
: "(None)");
676 if (version_status
== BT_PLUGIN_STATUS_OK
) {
677 printf(" %sVersion%s: %u.%u.%u",
678 bt_common_color_bold(), bt_common_color_reset(),
679 major
, minor
, patch
);
688 printf(" %sDescription%s: %s\n", bt_common_color_bold(),
689 bt_common_color_reset(),
690 plugin_description
? plugin_description
: "(None)");
691 printf(" %sAuthor%s: %s\n", bt_common_color_bold(),
692 bt_common_color_reset(), author
? author
: "(Unknown)");
693 printf(" %sLicense%s: %s\n", bt_common_color_bold(),
694 bt_common_color_reset(),
695 license
? license
: "(Unknown)");
699 int cmd_query(struct bt_config
*cfg
)
702 struct bt_component_class
*comp_cls
= NULL
;
703 struct bt_value
*results
= NULL
;
705 comp_cls
= find_component_class(cfg
->cmd_data
.query
.cfg_component
->plugin_name
->str
,
706 cfg
->cmd_data
.query
.cfg_component
->comp_cls_name
->str
,
707 cfg
->cmd_data
.query
.cfg_component
->type
);
709 BT_LOGE("Cannot find component class: plugin-name=\"%s\", "
710 "comp-cls-name=\"%s\", comp-cls-type=%d",
711 cfg
->cmd_data
.query
.cfg_component
->plugin_name
->str
,
712 cfg
->cmd_data
.query
.cfg_component
->comp_cls_name
->str
,
713 cfg
->cmd_data
.query
.cfg_component
->type
);
714 fprintf(stderr
, "%s%sCannot find component class %s",
715 bt_common_color_bold(),
716 bt_common_color_fg_red(),
717 bt_common_color_reset());
718 print_plugin_comp_cls_opt(stderr
,
719 cfg
->cmd_data
.query
.cfg_component
->plugin_name
->str
,
720 cfg
->cmd_data
.query
.cfg_component
->comp_cls_name
->str
,
721 cfg
->cmd_data
.query
.cfg_component
->type
);
722 fprintf(stderr
, "\n");
727 results
= bt_component_class_query(comp_cls
,
728 cfg
->cmd_data
.query
.object
->str
,
729 cfg
->cmd_data
.query
.cfg_component
->params
);
731 BT_LOGE("Failed to query component class: plugin-name=\"%s\", "
732 "comp-cls-name=\"%s\", comp-cls-type=%d "
734 cfg
->cmd_data
.query
.cfg_component
->plugin_name
->str
,
735 cfg
->cmd_data
.query
.cfg_component
->comp_cls_name
->str
,
736 cfg
->cmd_data
.query
.cfg_component
->type
,
737 cfg
->cmd_data
.query
.object
->str
);
738 fprintf(stderr
, "%s%sFailed to query info to %s",
739 bt_common_color_bold(),
740 bt_common_color_fg_red(),
741 bt_common_color_reset());
742 print_plugin_comp_cls_opt(stderr
,
743 cfg
->cmd_data
.query
.cfg_component
->plugin_name
->str
,
744 cfg
->cmd_data
.query
.cfg_component
->comp_cls_name
->str
,
745 cfg
->cmd_data
.query
.cfg_component
->type
);
746 fprintf(stderr
, "%s%s with object `%s`%s\n",
747 bt_common_color_bold(),
748 bt_common_color_fg_red(),
749 cfg
->cmd_data
.query
.object
->str
,
750 bt_common_color_reset());
755 print_value(stdout
, results
, 0);
764 int cmd_help(struct bt_config
*cfg
)
767 struct bt_plugin
*plugin
= NULL
;
770 plugin
= find_plugin(cfg
->cmd_data
.help
.cfg_component
->plugin_name
->str
);
772 BT_LOGE("Cannot find plugin: plugin-name=\"%s\"",
773 cfg
->cmd_data
.help
.cfg_component
->plugin_name
->str
);
774 fprintf(stderr
, "%s%sCannot find plugin %s%s%s\n",
775 bt_common_color_bold(), bt_common_color_fg_red(),
776 bt_common_color_fg_blue(),
777 cfg
->cmd_data
.help
.cfg_component
->plugin_name
->str
,
778 bt_common_color_reset());
783 print_plugin_info(plugin
);
784 printf(" %sComponent classes%s: %d\n",
785 bt_common_color_bold(),
786 bt_common_color_reset(),
787 (int) bt_plugin_get_component_class_count(plugin
));
790 if (cfg
->cmd_data
.help
.cfg_component
->type
!=
791 BT_COMPONENT_CLASS_TYPE_UNKNOWN
) {
792 struct bt_component_class
*needed_comp_cls
=
793 find_component_class(
794 cfg
->cmd_data
.help
.cfg_component
->plugin_name
->str
,
795 cfg
->cmd_data
.help
.cfg_component
->comp_cls_name
->str
,
796 cfg
->cmd_data
.help
.cfg_component
->type
);
798 if (!needed_comp_cls
) {
799 BT_LOGE("Cannot find component class: plugin-name=\"%s\", "
800 "comp-cls-name=\"%s\", comp-cls-type=%d",
801 cfg
->cmd_data
.help
.cfg_component
->plugin_name
->str
,
802 cfg
->cmd_data
.help
.cfg_component
->comp_cls_name
->str
,
803 cfg
->cmd_data
.help
.cfg_component
->type
);
804 fprintf(stderr
, "\n%s%sCannot find component class %s",
805 bt_common_color_bold(),
806 bt_common_color_fg_red(),
807 bt_common_color_reset());
808 print_plugin_comp_cls_opt(stderr
,
809 cfg
->cmd_data
.help
.cfg_component
->plugin_name
->str
,
810 cfg
->cmd_data
.help
.cfg_component
->comp_cls_name
->str
,
811 cfg
->cmd_data
.help
.cfg_component
->type
);
812 fprintf(stderr
, "\n");
817 bt_put(needed_comp_cls
);
820 for (i
= 0; i
< bt_plugin_get_component_class_count(plugin
); i
++) {
821 struct bt_component_class
*comp_cls
=
822 bt_plugin_get_component_class_by_index(plugin
, i
);
823 const char *comp_class_name
=
824 bt_component_class_get_name(comp_cls
);
825 const char *comp_class_description
=
826 bt_component_class_get_description(comp_cls
);
827 const char *comp_class_help
=
828 bt_component_class_get_help(comp_cls
);
829 enum bt_component_class_type type
=
830 bt_component_class_get_type(comp_cls
);
834 if (cfg
->cmd_data
.help
.cfg_component
->type
!=
835 BT_COMPONENT_CLASS_TYPE_UNKNOWN
) {
836 if (strcmp(cfg
->cmd_data
.help
.cfg_component
->comp_cls_name
->str
,
837 comp_class_name
) != 0 &&
839 cfg
->cmd_data
.help
.cfg_component
->type
) {
846 print_plugin_comp_cls_opt(stdout
,
847 cfg
->cmd_data
.help
.cfg_component
->plugin_name
->str
,
851 printf(" %sDescription%s: %s\n", bt_common_color_bold(),
852 bt_common_color_reset(),
853 comp_class_description
? comp_class_description
: "(None)");
855 if (comp_class_help
) {
856 printf("\n%s\n", comp_class_help
);
868 int cmd_list_plugins(struct bt_config
*cfg
)
871 int plugins_count
, component_classes_count
= 0, i
;
873 printf("From the following plugin paths:\n\n");
874 print_value(stdout
, cfg
->plugin_paths
, 2);
876 plugins_count
= loaded_plugins
->len
;
877 if (plugins_count
== 0) {
878 printf("No plugins found.\n");
882 for (i
= 0; i
< plugins_count
; i
++) {
883 struct bt_plugin
*plugin
= g_ptr_array_index(loaded_plugins
, i
);
885 component_classes_count
+= bt_plugin_get_component_class_count(plugin
);
888 printf("Found %s%d%s component classes in %s%d%s plugins.\n",
889 bt_common_color_bold(),
890 component_classes_count
,
891 bt_common_color_reset(),
892 bt_common_color_bold(),
894 bt_common_color_reset());
896 for (i
= 0; i
< plugins_count
; i
++) {
898 struct bt_plugin
*plugin
= g_ptr_array_index(loaded_plugins
, i
);
900 component_classes_count
=
901 bt_plugin_get_component_class_count(plugin
);
903 print_plugin_info(plugin
);
905 if (component_classes_count
== 0) {
906 printf(" %sComponent classes%s: (none)\n",
907 bt_common_color_bold(),
908 bt_common_color_reset());
910 printf(" %sComponent classes%s:\n",
911 bt_common_color_bold(),
912 bt_common_color_reset());
915 for (j
= 0; j
< component_classes_count
; j
++) {
916 struct bt_component_class
*comp_class
=
917 bt_plugin_get_component_class_by_index(
919 const char *comp_class_name
=
920 bt_component_class_get_name(comp_class
);
921 const char *comp_class_description
=
922 bt_component_class_get_description(comp_class
);
923 enum bt_component_class_type type
=
924 bt_component_class_get_type(comp_class
);
927 print_plugin_comp_cls_opt(stdout
,
928 bt_plugin_get_name(plugin
), comp_class_name
,
931 if (comp_class_description
) {
932 printf(": %s", comp_class_description
);
945 int cmd_print_lttng_live_sessions(struct bt_config
*cfg
)
948 struct bt_component_class
*comp_cls
= NULL
;
949 struct bt_value
*results
= NULL
;
950 struct bt_value
*params
= NULL
;
951 struct bt_value
*map
= NULL
;
952 struct bt_value
*v
= NULL
;
953 static const char * const plugin_name
= "ctf";
954 static const char * const comp_cls_name
= "lttng-live";
955 static const enum bt_component_class_type comp_cls_type
=
956 BT_COMPONENT_CLASS_TYPE_SOURCE
;
957 int64_t array_size
, i
;
959 assert(cfg
->cmd_data
.print_lttng_live_sessions
.url
);
960 comp_cls
= find_component_class(plugin_name
, comp_cls_name
,
963 BT_LOGE("Cannot find component class: plugin-name=\"%s\", "
964 "comp-cls-name=\"%s\", comp-cls-type=%d",
965 plugin_name
, comp_cls_name
,
966 BT_COMPONENT_CLASS_TYPE_SOURCE
);
967 fprintf(stderr
, "%s%sCannot find component class %s",
968 bt_common_color_bold(),
969 bt_common_color_fg_red(),
970 bt_common_color_reset());
971 print_plugin_comp_cls_opt(stderr
, plugin_name
,
972 comp_cls_name
, comp_cls_type
);
973 fprintf(stderr
, "\n");
977 params
= bt_value_map_create();
982 ret
= bt_value_map_insert_string(params
, "url",
983 cfg
->cmd_data
.print_lttng_live_sessions
.url
->str
);
988 results
= bt_component_class_query(comp_cls
, "sessions",
991 BT_LOGE_STR("Failed to query for sessions.");
992 fprintf(stderr
, "%s%sFailed to request sessions%s\n",
993 bt_common_color_bold(),
994 bt_common_color_fg_red(),
995 bt_common_color_reset());
999 if (!bt_value_is_array(results
)) {
1000 BT_LOGE_STR("Expecting an array for sessions query.");
1001 fprintf(stderr
, "%s%sUnexpected type returned by session query%s\n",
1002 bt_common_color_bold(),
1003 bt_common_color_fg_red(),
1004 bt_common_color_reset());
1008 array_size
= bt_value_array_size(results
);
1009 for (i
= 0; i
< array_size
; i
++) {
1010 const char *url_text
;
1011 int64_t timer_us
, streams
, clients
;
1013 map
= bt_value_array_get(results
, i
);
1015 BT_LOGE_STR("Unexpected empty array entry.");
1018 if (!bt_value_is_map(map
)) {
1019 BT_LOGE_STR("Unexpected entry type.");
1023 v
= bt_value_map_get(map
, "url");
1025 BT_LOGE_STR("Unexpected empty array \"url\" entry.");
1028 ret
= bt_value_string_get(v
, &url_text
);
1030 printf("%s", url_text
);
1033 v
= bt_value_map_get(map
, "timer-us");
1035 BT_LOGE_STR("Unexpected empty array \"timer-us\" entry.");
1038 ret
= bt_value_integer_get(v
, &timer_us
);
1040 printf(" (timer = %" PRIu64
", ", timer_us
);
1043 v
= bt_value_map_get(map
, "stream-count");
1045 BT_LOGE_STR("Unexpected empty array \"stream-count\" entry.");
1048 ret
= bt_value_integer_get(v
, &streams
);
1050 printf("%" PRIu64
" stream(s), ", streams
);
1053 v
= bt_value_map_get(map
, "client-count");
1055 BT_LOGE_STR("Unexpected empty array \"client-count\" entry.");
1058 ret
= bt_value_integer_get(v
, &clients
);
1060 printf("%" PRIu64
" client(s) connected)\n", clients
);
1079 int cmd_print_ctf_metadata(struct bt_config
*cfg
)
1082 struct bt_component_class
*comp_cls
= NULL
;
1083 struct bt_value
*results
= NULL
;
1084 struct bt_value
*params
= NULL
;
1085 struct bt_value
*metadata_text_value
= NULL
;
1086 const char *metadata_text
= NULL
;
1087 static const char * const plugin_name
= "ctf";
1088 static const char * const comp_cls_name
= "fs";
1089 static const enum bt_component_class_type comp_cls_type
=
1090 BT_COMPONENT_CLASS_TYPE_SOURCE
;
1092 assert(cfg
->cmd_data
.print_ctf_metadata
.path
);
1093 comp_cls
= find_component_class(plugin_name
, comp_cls_name
,
1096 BT_LOGE("Cannot find component class: plugin-name=\"%s\", "
1097 "comp-cls-name=\"%s\", comp-cls-type=%d",
1098 plugin_name
, comp_cls_name
,
1099 BT_COMPONENT_CLASS_TYPE_SOURCE
);
1100 fprintf(stderr
, "%s%sCannot find component class %s",
1101 bt_common_color_bold(),
1102 bt_common_color_fg_red(),
1103 bt_common_color_reset());
1104 print_plugin_comp_cls_opt(stderr
, plugin_name
,
1105 comp_cls_name
, comp_cls_type
);
1106 fprintf(stderr
, "\n");
1111 params
= bt_value_map_create();
1117 ret
= bt_value_map_insert_string(params
, "path",
1118 cfg
->cmd_data
.print_ctf_metadata
.path
->str
);
1124 results
= bt_component_class_query(comp_cls
, "metadata-info",
1128 BT_LOGE_STR("Failed to query for metadata info.");
1129 fprintf(stderr
, "%s%sFailed to request metadata info%s\n",
1130 bt_common_color_bold(),
1131 bt_common_color_fg_red(),
1132 bt_common_color_reset());
1136 metadata_text_value
= bt_value_map_get(results
, "text");
1137 if (!metadata_text_value
) {
1138 BT_LOGE_STR("Cannot find `text` string value in the resulting metadata info object.");
1143 ret
= bt_value_string_get(metadata_text_value
, &metadata_text
);
1145 printf("%s\n", metadata_text
);
1150 bt_put(metadata_text_value
);
1155 struct cmd_run_ctx
{
1157 GHashTable
*components
;
1160 struct bt_graph
*graph
;
1163 struct bt_config
*cfg
;
1169 int cmd_run_ctx_connect_upstream_port_to_downstream_component(
1170 struct cmd_run_ctx
*ctx
, struct bt_component
*upstream_comp
,
1171 struct bt_port
*upstream_port
,
1172 struct bt_config_connection
*cfg_conn
)
1175 GQuark downstreamp_comp_name_quark
;
1176 struct bt_component
*downstream_comp
;
1177 int64_t downstream_port_count
;
1179 int64_t (*port_count_fn
)(struct bt_component
*);
1180 struct bt_port
*(*port_by_index_fn
)(struct bt_component
*, uint64_t);
1183 BT_LOGI("Connecting upstream port to the next available downstream port: "
1184 "upstream-port-addr=%p, upstream-port-name=\"%s\", "
1185 "downstream-comp-name=\"%s\", conn-arg=\"%s\"",
1186 upstream_port
, bt_port_get_name(upstream_port
),
1187 cfg_conn
->downstream_comp_name
->str
,
1188 cfg_conn
->arg
->str
);
1189 downstreamp_comp_name_quark
= g_quark_from_string(
1190 cfg_conn
->downstream_comp_name
->str
);
1191 assert(downstreamp_comp_name_quark
> 0);
1192 downstream_comp
= g_hash_table_lookup(ctx
->components
,
1193 GUINT_TO_POINTER(downstreamp_comp_name_quark
));
1194 if (!downstream_comp
) {
1195 BT_LOGE("Cannot find downstream component: comp-name=\"%s\", "
1196 "conn-arg=\"%s\"", cfg_conn
->downstream_comp_name
->str
,
1197 cfg_conn
->arg
->str
);
1198 fprintf(stderr
, "Cannot create connection: cannot find downstream component: %s\n",
1199 cfg_conn
->arg
->str
);
1203 if (bt_component_is_filter(downstream_comp
)) {
1204 port_count_fn
= bt_component_filter_get_input_port_count
;
1205 port_by_index_fn
= bt_component_filter_get_input_port_by_index
;
1206 } else if (bt_component_is_sink(downstream_comp
)) {
1207 port_count_fn
= bt_component_sink_get_input_port_count
;
1208 port_by_index_fn
= bt_component_sink_get_input_port_by_index
;
1211 * Should never happen because the connections are
1212 * validated before we get here.
1214 BT_LOGF("Invalid connection: downstream component is a source: "
1215 "conn-arg=\"%s\"", cfg_conn
->arg
->str
);
1219 downstream_port_count
= port_count_fn(downstream_comp
);
1220 assert(downstream_port_count
>= 0);
1222 for (i
= 0; i
< downstream_port_count
; i
++) {
1223 struct bt_port
*downstream_port
=
1224 port_by_index_fn(downstream_comp
, i
);
1225 const char *downstream_port_name
;
1227 assert(downstream_port
);
1229 /* Skip port if it's already connected */
1230 if (bt_port_is_connected(downstream_port
)) {
1231 bt_put(downstream_port
);
1232 BT_LOGD("Skipping downstream port: already connected: "
1233 "port-addr=%p, port-name=\"%s\"",
1235 bt_port_get_name(downstream_port
));
1239 downstream_port_name
= bt_port_get_name(downstream_port
);
1240 assert(downstream_port_name
);
1242 if (bt_common_star_glob_match(
1243 cfg_conn
->downstream_port_glob
->str
, -1ULL,
1244 downstream_port_name
, -1ULL)) {
1245 /* We have a winner! */
1246 conn
= bt_graph_connect_ports(ctx
->graph
,
1247 upstream_port
, downstream_port
);
1248 bt_put(downstream_port
);
1250 BT_LOGE("Cannot create connection: graph refuses to connect ports: "
1251 "upstream-comp-addr=%p, upstream-comp-name=\"%s\", "
1252 "upstream-port-addr=%p, upstream-port-name=\"%s\", "
1253 "downstream-comp-addr=%p, downstream-comp-name=\"%s\", "
1254 "downstream-port-addr=%p, downstream-port-name=\"%s\", "
1256 upstream_comp
, bt_component_get_name(upstream_comp
),
1257 upstream_port
, bt_port_get_name(upstream_port
),
1258 downstream_comp
, cfg_conn
->downstream_comp_name
->str
,
1259 downstream_port
, downstream_port_name
,
1260 cfg_conn
->arg
->str
);
1262 "Cannot create connection: graph refuses to connect ports (`%s` to `%s`): %s\n",
1263 bt_port_get_name(upstream_port
),
1264 downstream_port_name
,
1265 cfg_conn
->arg
->str
);
1269 BT_LOGI("Connected component ports: "
1270 "upstream-comp-addr=%p, upstream-comp-name=\"%s\", "
1271 "upstream-port-addr=%p, upstream-port-name=\"%s\", "
1272 "downstream-comp-addr=%p, downstream-comp-name=\"%s\", "
1273 "downstream-port-addr=%p, downstream-port-name=\"%s\", "
1275 upstream_comp
, bt_component_get_name(upstream_comp
),
1276 upstream_port
, bt_port_get_name(upstream_port
),
1277 downstream_comp
, cfg_conn
->downstream_comp_name
->str
,
1278 downstream_port
, downstream_port_name
,
1279 cfg_conn
->arg
->str
);
1284 bt_put(downstream_port
);
1288 BT_LOGE("Cannot create connection: cannot find a matching downstream port for upstream port: "
1289 "upstream-port-addr=%p, upstream-port-name=\"%s\", "
1290 "downstream-comp-name=\"%s\", conn-arg=\"%s\"",
1291 upstream_port
, bt_port_get_name(upstream_port
),
1292 cfg_conn
->downstream_comp_name
->str
,
1293 cfg_conn
->arg
->str
);
1295 "Cannot create connection: cannot find a matching downstream port for upstream port `%s`: %s\n",
1296 bt_port_get_name(upstream_port
), cfg_conn
->arg
->str
);
1311 int cmd_run_ctx_connect_upstream_port(struct cmd_run_ctx
*ctx
,
1312 struct bt_port
*upstream_port
)
1315 const char *upstream_port_name
;
1316 const char *upstream_comp_name
;
1317 struct bt_component
*upstream_comp
= NULL
;
1321 assert(upstream_port
);
1322 upstream_port_name
= bt_port_get_name(upstream_port
);
1323 assert(upstream_port_name
);
1324 upstream_comp
= bt_port_get_component(upstream_port
);
1325 if (!upstream_comp
) {
1326 BT_LOGW("Upstream port to connect is not part of a component: "
1327 "port-addr=%p, port-name=\"%s\"",
1328 upstream_port
, upstream_port_name
);
1333 upstream_comp_name
= bt_component_get_name(upstream_comp
);
1334 assert(upstream_comp_name
);
1335 BT_LOGI("Connecting upstream port: comp-addr=%p, comp-name=\"%s\", "
1336 "port-addr=%p, port-name=\"%s\"",
1337 upstream_comp
, upstream_comp_name
,
1338 upstream_port
, upstream_port_name
);
1340 for (i
= 0; i
< ctx
->cfg
->cmd_data
.run
.connections
->len
; i
++) {
1341 struct bt_config_connection
*cfg_conn
=
1343 ctx
->cfg
->cmd_data
.run
.connections
, i
);
1345 if (strcmp(cfg_conn
->upstream_comp_name
->str
,
1346 upstream_comp_name
) == 0) {
1347 if (bt_common_star_glob_match(
1348 cfg_conn
->upstream_port_glob
->str
,
1349 -1ULL, upstream_port_name
, -1ULL)) {
1350 ret
= cmd_run_ctx_connect_upstream_port_to_downstream_component(
1351 ctx
, upstream_comp
, upstream_port
,
1354 BT_LOGE("Cannot connect upstream port: "
1355 "port-addr=%p, port-name=\"%s\"",
1357 upstream_port_name
);
1359 "Cannot connect port `%s` of component `%s` to a downstream port: %s\n",
1362 cfg_conn
->arg
->str
);
1371 BT_LOGE("Cannot connect upstream port: port does not match any connection argument: "
1372 "port-addr=%p, port-name=\"%s\"", upstream_port
,
1373 upstream_port_name
);
1375 "Cannot create connection: upstream port `%s` does not match any connection\n",
1376 upstream_port_name
);
1382 bt_put(upstream_comp
);
1387 void graph_port_added_listener(struct bt_port
*port
, void *data
)
1389 struct bt_component
*comp
= NULL
;
1390 struct cmd_run_ctx
*ctx
= data
;
1392 comp
= bt_port_get_component(port
);
1393 BT_LOGI("Port added to a graph's component: comp-addr=%p, "
1394 "comp-name=\"%s\", port-addr=%p, port-name=\"%s\"",
1395 comp
, comp
? bt_component_get_name(comp
) : "",
1396 port
, bt_port_get_name(port
));
1398 BT_LOGW_STR("Port has no component.");
1402 if (bt_port_is_connected(port
)) {
1403 BT_LOGW_STR("Port is already connected.");
1407 if (!bt_port_is_output(port
)) {
1408 BT_LOGI_STR("Skipping input port.");
1412 if (cmd_run_ctx_connect_upstream_port(ctx
, port
)) {
1413 BT_LOGF_STR("Cannot connect upstream port.");
1414 fprintf(stderr
, "Added port could not be connected: aborting\n");
1424 void graph_port_removed_listener(struct bt_component
*component
,
1425 struct bt_port
*port
, void *data
)
1427 BT_LOGI("Port removed from a graph's component: comp-addr=%p, "
1428 "comp-name=\"%s\", port-addr=%p, port-name=\"%s\"",
1429 component
, bt_component_get_name(component
),
1430 port
, bt_port_get_name(port
));
1434 void graph_ports_connected_listener(struct bt_port
*upstream_port
,
1435 struct bt_port
*downstream_port
, void *data
)
1437 struct bt_component
*upstream_comp
= bt_port_get_component(upstream_port
);
1438 struct bt_component
*downstream_comp
= bt_port_get_component(downstream_port
);
1440 assert(upstream_comp
);
1441 assert(downstream_comp
);
1442 BT_LOGI("Graph's component ports connected: "
1443 "upstream-comp-addr=%p, upstream-comp-name=\"%s\", "
1444 "upstream-port-addr=%p, upstream-port-name=\"%s\", "
1445 "downstream-comp-addr=%p, downstream-comp-name=\"%s\", "
1446 "downstream-port-addr=%p, downstream-port-name=\"%s\"",
1447 upstream_comp
, bt_component_get_name(upstream_comp
),
1448 upstream_port
, bt_port_get_name(upstream_port
),
1449 downstream_comp
, bt_component_get_name(downstream_comp
),
1450 downstream_port
, bt_port_get_name(downstream_port
));
1451 bt_put(upstream_comp
);
1452 bt_put(downstream_comp
);
1456 void graph_ports_disconnected_listener(
1457 struct bt_component
*upstream_component
,
1458 struct bt_component
*downstream_component
,
1459 struct bt_port
*upstream_port
, struct bt_port
*downstream_port
,
1462 BT_LOGI("Graph's component ports disconnected: "
1463 "upstream-port-addr=%p, upstream-port-name=\"%s\", "
1464 "downstream-port-addr=%p, downstream-port-name=\"%s\"",
1465 upstream_port
, bt_port_get_name(upstream_port
),
1466 downstream_port
, bt_port_get_name(downstream_port
));
1470 void cmd_run_ctx_destroy(struct cmd_run_ctx
*ctx
)
1476 if (ctx
->components
) {
1477 g_hash_table_destroy(ctx
->components
);
1478 ctx
->components
= NULL
;
1487 int cmd_run_ctx_init(struct cmd_run_ctx
*ctx
, struct bt_config
*cfg
)
1492 ctx
->connect_ports
= false;
1493 ctx
->components
= g_hash_table_new_full(g_direct_hash
, g_direct_equal
,
1495 if (!ctx
->components
) {
1499 ctx
->graph
= bt_graph_create();
1504 the_graph
= ctx
->graph
;
1505 ret
= bt_graph_add_port_added_listener(ctx
->graph
,
1506 graph_port_added_listener
, ctx
);
1508 BT_LOGE_STR("Cannot add \"port added\" listener to graph.");
1512 ret
= bt_graph_add_port_removed_listener(ctx
->graph
,
1513 graph_port_removed_listener
, ctx
);
1515 BT_LOGE_STR("Cannot add \"port removed\" listener to graph.");
1519 ret
= bt_graph_add_ports_connected_listener(ctx
->graph
,
1520 graph_ports_connected_listener
, ctx
);
1522 BT_LOGE_STR("Cannot add \"ports connected\" listener to graph.");
1526 ret
= bt_graph_add_ports_disconnected_listener(ctx
->graph
,
1527 graph_ports_disconnected_listener
, ctx
);
1529 BT_LOGE_STR("Cannot add \"ports disconnected\" listener to graph.");
1536 cmd_run_ctx_destroy(ctx
);
1544 int cmd_run_ctx_create_components_from_config_components(
1545 struct cmd_run_ctx
*ctx
, GPtrArray
*cfg_components
)
1548 struct bt_component_class
*comp_cls
= NULL
;
1549 struct bt_component
*comp
= NULL
;
1552 for (i
= 0; i
< cfg_components
->len
; i
++) {
1553 struct bt_config_component
*cfg_comp
=
1554 g_ptr_array_index(cfg_components
, i
);
1557 comp_cls
= find_component_class(cfg_comp
->plugin_name
->str
,
1558 cfg_comp
->comp_cls_name
->str
, cfg_comp
->type
);
1560 BT_LOGE("Cannot find component class: plugin-name=\"%s\", "
1561 "comp-cls-name=\"%s\", comp-cls-type=%d",
1562 cfg_comp
->plugin_name
->str
,
1563 cfg_comp
->comp_cls_name
->str
,
1565 fprintf(stderr
, "%s%sCannot find component class %s",
1566 bt_common_color_bold(),
1567 bt_common_color_fg_red(),
1568 bt_common_color_reset());
1569 print_plugin_comp_cls_opt(stderr
,
1570 cfg_comp
->plugin_name
->str
,
1571 cfg_comp
->comp_cls_name
->str
,
1573 fprintf(stderr
, "\n");
1577 comp
= bt_component_create(comp_cls
,
1578 cfg_comp
->instance_name
->str
, cfg_comp
->params
);
1580 BT_LOGE("Cannot create component: plugin-name=\"%s\", "
1581 "comp-cls-name=\"%s\", comp-cls-type=%d, "
1583 cfg_comp
->plugin_name
->str
,
1584 cfg_comp
->comp_cls_name
->str
,
1585 cfg_comp
->type
, cfg_comp
->instance_name
->str
);
1586 fprintf(stderr
, "%s%sCannot create component `%s`%s\n",
1587 bt_common_color_bold(),
1588 bt_common_color_fg_red(),
1589 cfg_comp
->instance_name
->str
,
1590 bt_common_color_reset());
1594 BT_LOGI("Created and inserted component: comp-addr=%p, comp-name=\"%s\"",
1595 comp
, cfg_comp
->instance_name
->str
);
1596 quark
= g_quark_from_string(cfg_comp
->instance_name
->str
);
1598 g_hash_table_insert(ctx
->components
,
1599 GUINT_TO_POINTER(quark
), comp
);
1616 int cmd_run_ctx_create_components(struct cmd_run_ctx
*ctx
)
1621 * Make sure that, during this phase, our graph's "port added"
1622 * listener does not connect ports while we are creating the
1623 * components because we have a special, initial phase for
1626 ctx
->connect_ports
= false;
1628 ret
= cmd_run_ctx_create_components_from_config_components(
1629 ctx
, ctx
->cfg
->cmd_data
.run
.sources
);
1635 ret
= cmd_run_ctx_create_components_from_config_components(
1636 ctx
, ctx
->cfg
->cmd_data
.run
.filters
);
1642 ret
= cmd_run_ctx_create_components_from_config_components(
1643 ctx
, ctx
->cfg
->cmd_data
.run
.sinks
);
1654 int cmd_run_ctx_connect_comp_ports(struct cmd_run_ctx
*ctx
,
1655 struct bt_component
*comp
,
1656 int64_t (*port_count_fn
)(struct bt_component
*),
1657 struct bt_port
*(*port_by_index_fn
)(struct bt_component
*, uint64_t))
1663 count
= port_count_fn(comp
);
1666 for (i
= 0; i
< count
; i
++) {
1667 struct bt_port
*upstream_port
= port_by_index_fn(comp
, i
);
1669 assert(upstream_port
);
1670 ret
= cmd_run_ctx_connect_upstream_port(ctx
, upstream_port
);
1671 bt_put(upstream_port
);
1682 int cmd_run_ctx_connect_ports(struct cmd_run_ctx
*ctx
)
1685 GHashTableIter iter
;
1686 gpointer g_name_quark
, g_comp
;
1688 ctx
->connect_ports
= true;
1689 g_hash_table_iter_init(&iter
, ctx
->components
);
1691 while (g_hash_table_iter_next(&iter
, &g_name_quark
, &g_comp
)) {
1692 if (bt_component_is_source(g_comp
)) {
1693 ret
= cmd_run_ctx_connect_comp_ports(ctx
,
1694 g_comp
, bt_component_source_get_output_port_count
,
1695 bt_component_source_get_output_port_by_index
);
1696 } else if (bt_component_is_filter(g_comp
)) {
1697 ret
= cmd_run_ctx_connect_comp_ports(ctx
,
1698 g_comp
, bt_component_filter_get_output_port_count
,
1699 bt_component_filter_get_output_port_by_index
);
1712 const char *bt_graph_status_str(enum bt_graph_status status
)
1715 case BT_GRAPH_STATUS_CANCELED
:
1716 return "BT_GRAPH_STATUS_CANCELED";
1717 case BT_GRAPH_STATUS_AGAIN
:
1718 return "BT_GRAPH_STATUS_AGAIN";
1719 case BT_GRAPH_STATUS_END
:
1720 return "BT_GRAPH_STATUS_END";
1721 case BT_GRAPH_STATUS_OK
:
1722 return "BT_GRAPH_STATUS_OK";
1723 case BT_GRAPH_STATUS_ALREADY_IN_A_GRAPH
:
1724 return "BT_GRAPH_STATUS_ALREADY_IN_A_GRAPH";
1725 case BT_GRAPH_STATUS_INVALID
:
1726 return "BT_GRAPH_STATUS_INVALID";
1727 case BT_GRAPH_STATUS_NO_SINK
:
1728 return "BT_GRAPH_STATUS_NO_SINK";
1729 case BT_GRAPH_STATUS_ERROR
:
1730 return "BT_GRAPH_STATUS_ERROR";
1737 int cmd_run(struct bt_config
*cfg
)
1740 struct cmd_run_ctx ctx
= { 0 };
1742 /* Initialize the command's context and the graph object */
1743 if (cmd_run_ctx_init(&ctx
, cfg
)) {
1744 BT_LOGE_STR("Cannot initialize the command's context.");
1745 fprintf(stderr
, "Cannot initialize the command's context\n");
1750 BT_LOGI_STR("Canceled by user before creating components.");
1754 BT_LOGI_STR("Creating components.");
1756 /* Create the requested component instances */
1757 if (cmd_run_ctx_create_components(&ctx
)) {
1758 BT_LOGE_STR("Cannot create components.");
1759 fprintf(stderr
, "Cannot create components\n");
1764 BT_LOGI_STR("Canceled by user before connecting components.");
1768 BT_LOGI_STR("Connecting components.");
1770 /* Connect the initially visible component ports */
1771 if (cmd_run_ctx_connect_ports(&ctx
)) {
1772 BT_LOGE_STR("Cannot connect initial component ports.");
1773 fprintf(stderr
, "Cannot connect initial component ports\n");
1778 BT_LOGI_STR("Canceled by user before running the graph.");
1782 BT_LOGI_STR("Running the graph.");
1786 enum bt_graph_status graph_status
= bt_graph_run(ctx
.graph
);
1789 * Reset console in case something messed with console
1790 * codes during the graph's execution.
1792 printf("%s", bt_common_color_reset());
1794 fprintf(stderr
, "%s", bt_common_color_reset());
1795 BT_LOGV("bt_graph_run() returned: status=%s",
1796 bt_graph_status_str(graph_status
));
1798 switch (graph_status
) {
1799 case BT_GRAPH_STATUS_OK
:
1801 case BT_GRAPH_STATUS_CANCELED
:
1802 BT_LOGI_STR("Graph was canceled by user.");
1804 case BT_GRAPH_STATUS_AGAIN
:
1805 if (bt_graph_is_canceled(ctx
.graph
)) {
1806 BT_LOGI_STR("Graph was canceled by user.");
1810 if (cfg
->cmd_data
.run
.retry_duration_us
> 0) {
1811 BT_LOGV("Got BT_GRAPH_STATUS_AGAIN: sleeping: "
1813 cfg
->cmd_data
.run
.retry_duration_us
);
1815 if (usleep(cfg
->cmd_data
.run
.retry_duration_us
)) {
1816 if (bt_graph_is_canceled(ctx
.graph
)) {
1817 BT_LOGI_STR("Graph was canceled by user.");
1823 case BT_COMPONENT_STATUS_END
:
1826 BT_LOGE_STR("Graph failed to complete successfully");
1827 fprintf(stderr
, "Graph failed to complete successfully\n");
1840 cmd_run_ctx_destroy(&ctx
);
1845 void warn_command_name_and_directory_clash(struct bt_config
*cfg
)
1847 const char *env_clash
;
1849 if (!cfg
->command_name
) {
1853 env_clash
= getenv(ENV_BABELTRACE_WARN_COMMAND_NAME_DIRECTORY_CLASH
);
1854 if (env_clash
&& strcmp(env_clash
, "0") == 0) {
1858 if (g_file_test(cfg
->command_name
,
1859 G_FILE_TEST_EXISTS
| G_FILE_TEST_IS_DIR
)) {
1860 fprintf(stderr
, "\nNOTE: The `%s` command was executed. If you meant to convert a\n",
1862 fprintf(stderr
, "trace located in the local `%s` directory, please use:\n",
1864 fprintf(stderr
, "\n");
1865 fprintf(stderr
, " babeltrace convert %s [OPTIONS]\n",
1871 void init_log_level(void)
1873 bt_cli_log_level
= bt_log_get_level_from_env("BABELTRACE_CLI_LOG_LEVEL");
1876 void set_sigint_handler(void)
1878 struct sigaction new_action
, old_action
;
1880 new_action
.sa_handler
= sigint_handler
;
1881 sigemptyset(&new_action
.sa_mask
);
1882 new_action
.sa_flags
= 0;
1883 sigaction(SIGINT
, NULL
, &old_action
);
1885 if (old_action
.sa_handler
!= SIG_IGN
) {
1886 sigaction(SIGINT
, &new_action
, NULL
);
1890 int main(int argc
, const char **argv
)
1894 struct bt_config
*cfg
;
1897 set_sigint_handler();
1899 cfg
= bt_config_cli_args_create_with_default(argc
, argv
, &retcode
);
1902 /* Quit without errors; typically usage/version */
1904 BT_LOGI_STR("Quitting without errors.");
1909 BT_LOGE("Command-line error: retcode=%d", retcode
);
1914 BT_LOGE_STR("Failed to create a valid Babeltrace configuration.");
1915 fprintf(stderr
, "Failed to create Babeltrace configuration\n");
1921 bt_cli_log_level
= BT_LOGGING_LEVEL_VERBOSE
;
1922 bt_logging_set_global_level(BT_LOGGING_LEVEL_VERBOSE
);
1923 // TODO: for backward compat., set the log level
1924 // environment variables of the known plugins
1926 } else if (cfg
->debug
) {
1927 bt_cli_log_level
= BT_LOGGING_LEVEL_DEBUG
;
1928 bt_logging_set_global_level(BT_LOGGING_LEVEL_DEBUG
);
1929 // TODO: for backward compat., set the log level
1930 // environment variables of the known plugins
1934 babeltrace_debug
= cfg
->debug
;
1935 babeltrace_verbose
= cfg
->verbose
;
1938 if (cfg
->command_needs_plugins
) {
1939 ret
= load_all_plugins(cfg
->plugin_paths
);
1941 BT_LOGE("Failed to load plugins: ret=%d", ret
);
1947 BT_LOGI("Executing command: cmd=%d, command-name=\"%s\"",
1948 cfg
->command
, cfg
->command_name
);
1950 switch (cfg
->command
) {
1951 case BT_CONFIG_COMMAND_RUN
:
1954 case BT_CONFIG_COMMAND_LIST_PLUGINS
:
1955 ret
= cmd_list_plugins(cfg
);
1957 case BT_CONFIG_COMMAND_HELP
:
1958 ret
= cmd_help(cfg
);
1960 case BT_CONFIG_COMMAND_QUERY
:
1961 ret
= cmd_query(cfg
);
1963 case BT_CONFIG_COMMAND_PRINT_CTF_METADATA
:
1964 ret
= cmd_print_ctf_metadata(cfg
);
1966 case BT_CONFIG_COMMAND_PRINT_LTTNG_LIVE_SESSIONS
:
1967 ret
= cmd_print_lttng_live_sessions(cfg
);
1970 BT_LOGF("Invalid/unknown command: cmd=%d", cfg
->command
);
1974 BT_LOGI("Command completed: cmd=%d, command-name=\"%s\", ret=%d",
1975 cfg
->command
, cfg
->command_name
, ret
);
1976 warn_command_name_and_directory_clash(cfg
);
1977 retcode
= ret
? 1 : 0;