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);
1181 enum bt_graph_status status
= BT_GRAPH_STATUS_ERROR
;
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 status
= bt_graph_connect_ports(ctx
->graph
,
1247 upstream_port
, downstream_port
, NULL
);
1248 bt_put(downstream_port
);
1250 case BT_GRAPH_STATUS_OK
:
1252 case BT_GRAPH_STATUS_CANCELED
:
1253 BT_LOGI_STR("Graph was canceled by user.");
1254 status
= BT_GRAPH_STATUS_OK
;
1256 case BT_GRAPH_STATUS_COMPONENT_REFUSES_PORT_CONNECTION
:
1257 BT_LOGE("A component refused a connection to one of its ports: "
1258 "upstream-comp-addr=%p, upstream-comp-name=\"%s\", "
1259 "upstream-port-addr=%p, upstream-port-name=\"%s\", "
1260 "downstream-comp-addr=%p, downstream-comp-name=\"%s\", "
1261 "downstream-port-addr=%p, downstream-port-name=\"%s\", "
1263 upstream_comp
, bt_component_get_name(upstream_comp
),
1264 upstream_port
, bt_port_get_name(upstream_port
),
1265 downstream_comp
, cfg_conn
->downstream_comp_name
->str
,
1266 downstream_port
, downstream_port_name
,
1267 cfg_conn
->arg
->str
);
1269 "A component refused a connection to one of its ports (`%s` to `%s`): %s\n",
1270 bt_port_get_name(upstream_port
),
1271 downstream_port_name
,
1272 cfg_conn
->arg
->str
);
1275 BT_LOGE("Cannot create connection: graph refuses to connect ports: "
1276 "upstream-comp-addr=%p, upstream-comp-name=\"%s\", "
1277 "upstream-port-addr=%p, upstream-port-name=\"%s\", "
1278 "downstream-comp-addr=%p, downstream-comp-name=\"%s\", "
1279 "downstream-port-addr=%p, downstream-port-name=\"%s\", "
1281 upstream_comp
, bt_component_get_name(upstream_comp
),
1282 upstream_port
, bt_port_get_name(upstream_port
),
1283 downstream_comp
, cfg_conn
->downstream_comp_name
->str
,
1284 downstream_port
, downstream_port_name
,
1285 cfg_conn
->arg
->str
);
1287 "Cannot create connection: graph refuses to connect ports (`%s` to `%s`): %s\n",
1288 bt_port_get_name(upstream_port
),
1289 downstream_port_name
,
1290 cfg_conn
->arg
->str
);
1294 BT_LOGI("Connected component ports: "
1295 "upstream-comp-addr=%p, upstream-comp-name=\"%s\", "
1296 "upstream-port-addr=%p, upstream-port-name=\"%s\", "
1297 "downstream-comp-addr=%p, downstream-comp-name=\"%s\", "
1298 "downstream-port-addr=%p, downstream-port-name=\"%s\", "
1300 upstream_comp
, bt_component_get_name(upstream_comp
),
1301 upstream_port
, bt_port_get_name(upstream_port
),
1302 downstream_comp
, cfg_conn
->downstream_comp_name
->str
,
1303 downstream_port
, downstream_port_name
,
1304 cfg_conn
->arg
->str
);
1309 bt_put(downstream_port
);
1312 if (status
!= BT_GRAPH_STATUS_OK
) {
1313 BT_LOGE("Cannot create connection: cannot find a matching downstream port for upstream port: "
1314 "upstream-port-addr=%p, upstream-port-name=\"%s\", "
1315 "downstream-comp-name=\"%s\", conn-arg=\"%s\"",
1316 upstream_port
, bt_port_get_name(upstream_port
),
1317 cfg_conn
->downstream_comp_name
->str
,
1318 cfg_conn
->arg
->str
);
1320 "Cannot create connection: cannot find a matching downstream port for upstream port `%s`: %s\n",
1321 bt_port_get_name(upstream_port
), cfg_conn
->arg
->str
);
1335 int cmd_run_ctx_connect_upstream_port(struct cmd_run_ctx
*ctx
,
1336 struct bt_port
*upstream_port
)
1339 const char *upstream_port_name
;
1340 const char *upstream_comp_name
;
1341 struct bt_component
*upstream_comp
= NULL
;
1345 assert(upstream_port
);
1346 upstream_port_name
= bt_port_get_name(upstream_port
);
1347 assert(upstream_port_name
);
1348 upstream_comp
= bt_port_get_component(upstream_port
);
1349 if (!upstream_comp
) {
1350 BT_LOGW("Upstream port to connect is not part of a component: "
1351 "port-addr=%p, port-name=\"%s\"",
1352 upstream_port
, upstream_port_name
);
1357 upstream_comp_name
= bt_component_get_name(upstream_comp
);
1358 assert(upstream_comp_name
);
1359 BT_LOGI("Connecting upstream port: comp-addr=%p, comp-name=\"%s\", "
1360 "port-addr=%p, port-name=\"%s\"",
1361 upstream_comp
, upstream_comp_name
,
1362 upstream_port
, upstream_port_name
);
1364 for (i
= 0; i
< ctx
->cfg
->cmd_data
.run
.connections
->len
; i
++) {
1365 struct bt_config_connection
*cfg_conn
=
1367 ctx
->cfg
->cmd_data
.run
.connections
, i
);
1369 if (strcmp(cfg_conn
->upstream_comp_name
->str
,
1370 upstream_comp_name
) == 0) {
1371 if (bt_common_star_glob_match(
1372 cfg_conn
->upstream_port_glob
->str
,
1373 -1ULL, upstream_port_name
, -1ULL)) {
1374 ret
= cmd_run_ctx_connect_upstream_port_to_downstream_component(
1375 ctx
, upstream_comp
, upstream_port
,
1378 BT_LOGE("Cannot connect upstream port: "
1379 "port-addr=%p, port-name=\"%s\"",
1381 upstream_port_name
);
1383 "Cannot connect port `%s` of component `%s` to a downstream port: %s\n",
1386 cfg_conn
->arg
->str
);
1395 BT_LOGE("Cannot connect upstream port: port does not match any connection argument: "
1396 "port-addr=%p, port-name=\"%s\"", upstream_port
,
1397 upstream_port_name
);
1399 "Cannot create connection: upstream port `%s` does not match any connection\n",
1400 upstream_port_name
);
1406 bt_put(upstream_comp
);
1411 void graph_port_added_listener(struct bt_port
*port
, void *data
)
1413 struct bt_component
*comp
= NULL
;
1414 struct cmd_run_ctx
*ctx
= data
;
1416 comp
= bt_port_get_component(port
);
1417 BT_LOGI("Port added to a graph's component: comp-addr=%p, "
1418 "comp-name=\"%s\", port-addr=%p, port-name=\"%s\"",
1419 comp
, comp
? bt_component_get_name(comp
) : "",
1420 port
, bt_port_get_name(port
));
1422 if (!ctx
->connect_ports
) {
1427 BT_LOGW_STR("Port has no component.");
1431 if (bt_port_is_connected(port
)) {
1432 BT_LOGW_STR("Port is already connected.");
1436 if (!bt_port_is_output(port
)) {
1437 BT_LOGI_STR("Skipping input port.");
1441 if (cmd_run_ctx_connect_upstream_port(ctx
, port
)) {
1442 BT_LOGF_STR("Cannot connect upstream port.");
1443 fprintf(stderr
, "Added port could not be connected: aborting\n");
1453 void graph_port_removed_listener(struct bt_component
*component
,
1454 struct bt_port
*port
, void *data
)
1456 BT_LOGI("Port removed from a graph's component: comp-addr=%p, "
1457 "comp-name=\"%s\", port-addr=%p, port-name=\"%s\"",
1458 component
, bt_component_get_name(component
),
1459 port
, bt_port_get_name(port
));
1463 void graph_ports_connected_listener(struct bt_port
*upstream_port
,
1464 struct bt_port
*downstream_port
, void *data
)
1466 struct bt_component
*upstream_comp
= bt_port_get_component(upstream_port
);
1467 struct bt_component
*downstream_comp
= bt_port_get_component(downstream_port
);
1469 assert(upstream_comp
);
1470 assert(downstream_comp
);
1471 BT_LOGI("Graph's component ports connected: "
1472 "upstream-comp-addr=%p, upstream-comp-name=\"%s\", "
1473 "upstream-port-addr=%p, upstream-port-name=\"%s\", "
1474 "downstream-comp-addr=%p, downstream-comp-name=\"%s\", "
1475 "downstream-port-addr=%p, downstream-port-name=\"%s\"",
1476 upstream_comp
, bt_component_get_name(upstream_comp
),
1477 upstream_port
, bt_port_get_name(upstream_port
),
1478 downstream_comp
, bt_component_get_name(downstream_comp
),
1479 downstream_port
, bt_port_get_name(downstream_port
));
1480 bt_put(upstream_comp
);
1481 bt_put(downstream_comp
);
1485 void graph_ports_disconnected_listener(
1486 struct bt_component
*upstream_component
,
1487 struct bt_component
*downstream_component
,
1488 struct bt_port
*upstream_port
, struct bt_port
*downstream_port
,
1491 BT_LOGI("Graph's component ports disconnected: "
1492 "upstream-port-addr=%p, upstream-port-name=\"%s\", "
1493 "downstream-port-addr=%p, downstream-port-name=\"%s\"",
1494 upstream_port
, bt_port_get_name(upstream_port
),
1495 downstream_port
, bt_port_get_name(downstream_port
));
1499 void cmd_run_ctx_destroy(struct cmd_run_ctx
*ctx
)
1505 if (ctx
->components
) {
1506 g_hash_table_destroy(ctx
->components
);
1507 ctx
->components
= NULL
;
1516 int cmd_run_ctx_init(struct cmd_run_ctx
*ctx
, struct bt_config
*cfg
)
1521 ctx
->connect_ports
= false;
1522 ctx
->components
= g_hash_table_new_full(g_direct_hash
, g_direct_equal
,
1524 if (!ctx
->components
) {
1528 ctx
->graph
= bt_graph_create();
1533 the_graph
= ctx
->graph
;
1534 ret
= bt_graph_add_port_added_listener(ctx
->graph
,
1535 graph_port_added_listener
, ctx
);
1537 BT_LOGE_STR("Cannot add \"port added\" listener to graph.");
1541 ret
= bt_graph_add_port_removed_listener(ctx
->graph
,
1542 graph_port_removed_listener
, ctx
);
1544 BT_LOGE_STR("Cannot add \"port removed\" listener to graph.");
1548 ret
= bt_graph_add_ports_connected_listener(ctx
->graph
,
1549 graph_ports_connected_listener
, ctx
);
1551 BT_LOGE_STR("Cannot add \"ports connected\" listener to graph.");
1555 ret
= bt_graph_add_ports_disconnected_listener(ctx
->graph
,
1556 graph_ports_disconnected_listener
, ctx
);
1558 BT_LOGE_STR("Cannot add \"ports disconnected\" listener to graph.");
1565 cmd_run_ctx_destroy(ctx
);
1573 int cmd_run_ctx_create_components_from_config_components(
1574 struct cmd_run_ctx
*ctx
, GPtrArray
*cfg_components
)
1577 struct bt_component_class
*comp_cls
= NULL
;
1578 struct bt_component
*comp
= NULL
;
1581 for (i
= 0; i
< cfg_components
->len
; i
++) {
1582 struct bt_config_component
*cfg_comp
=
1583 g_ptr_array_index(cfg_components
, i
);
1586 comp_cls
= find_component_class(cfg_comp
->plugin_name
->str
,
1587 cfg_comp
->comp_cls_name
->str
, cfg_comp
->type
);
1589 BT_LOGE("Cannot find component class: plugin-name=\"%s\", "
1590 "comp-cls-name=\"%s\", comp-cls-type=%d",
1591 cfg_comp
->plugin_name
->str
,
1592 cfg_comp
->comp_cls_name
->str
,
1594 fprintf(stderr
, "%s%sCannot find component class %s",
1595 bt_common_color_bold(),
1596 bt_common_color_fg_red(),
1597 bt_common_color_reset());
1598 print_plugin_comp_cls_opt(stderr
,
1599 cfg_comp
->plugin_name
->str
,
1600 cfg_comp
->comp_cls_name
->str
,
1602 fprintf(stderr
, "\n");
1606 ret
= bt_graph_add_component(ctx
->graph
, comp_cls
,
1607 cfg_comp
->instance_name
->str
, cfg_comp
->params
, &comp
);
1609 BT_LOGE("Cannot create component: plugin-name=\"%s\", "
1610 "comp-cls-name=\"%s\", comp-cls-type=%d, "
1612 cfg_comp
->plugin_name
->str
,
1613 cfg_comp
->comp_cls_name
->str
,
1614 cfg_comp
->type
, cfg_comp
->instance_name
->str
);
1615 fprintf(stderr
, "%s%sCannot create component `%s`%s\n",
1616 bt_common_color_bold(),
1617 bt_common_color_fg_red(),
1618 cfg_comp
->instance_name
->str
,
1619 bt_common_color_reset());
1623 BT_LOGI("Created and inserted component: comp-addr=%p, comp-name=\"%s\"",
1624 comp
, cfg_comp
->instance_name
->str
);
1625 quark
= g_quark_from_string(cfg_comp
->instance_name
->str
);
1627 g_hash_table_insert(ctx
->components
,
1628 GUINT_TO_POINTER(quark
), comp
);
1645 int cmd_run_ctx_create_components(struct cmd_run_ctx
*ctx
)
1650 * Make sure that, during this phase, our graph's "port added"
1651 * listener does not connect ports while we are creating the
1652 * components because we have a special, initial phase for
1655 ctx
->connect_ports
= false;
1657 ret
= cmd_run_ctx_create_components_from_config_components(
1658 ctx
, ctx
->cfg
->cmd_data
.run
.sources
);
1664 ret
= cmd_run_ctx_create_components_from_config_components(
1665 ctx
, ctx
->cfg
->cmd_data
.run
.filters
);
1671 ret
= cmd_run_ctx_create_components_from_config_components(
1672 ctx
, ctx
->cfg
->cmd_data
.run
.sinks
);
1683 int cmd_run_ctx_connect_comp_ports(struct cmd_run_ctx
*ctx
,
1684 struct bt_component
*comp
,
1685 int64_t (*port_count_fn
)(struct bt_component
*),
1686 struct bt_port
*(*port_by_index_fn
)(struct bt_component
*, uint64_t))
1692 count
= port_count_fn(comp
);
1695 for (i
= 0; i
< count
; i
++) {
1696 struct bt_port
*upstream_port
= port_by_index_fn(comp
, i
);
1698 assert(upstream_port
);
1699 ret
= cmd_run_ctx_connect_upstream_port(ctx
, upstream_port
);
1700 bt_put(upstream_port
);
1711 int cmd_run_ctx_connect_ports(struct cmd_run_ctx
*ctx
)
1714 GHashTableIter iter
;
1715 gpointer g_name_quark
, g_comp
;
1717 ctx
->connect_ports
= true;
1718 g_hash_table_iter_init(&iter
, ctx
->components
);
1720 while (g_hash_table_iter_next(&iter
, &g_name_quark
, &g_comp
)) {
1721 if (bt_component_is_source(g_comp
)) {
1722 ret
= cmd_run_ctx_connect_comp_ports(ctx
,
1723 g_comp
, bt_component_source_get_output_port_count
,
1724 bt_component_source_get_output_port_by_index
);
1725 } else if (bt_component_is_filter(g_comp
)) {
1726 ret
= cmd_run_ctx_connect_comp_ports(ctx
,
1727 g_comp
, bt_component_filter_get_output_port_count
,
1728 bt_component_filter_get_output_port_by_index
);
1741 const char *bt_graph_status_str(enum bt_graph_status status
)
1744 case BT_GRAPH_STATUS_CANCELED
:
1745 return "BT_GRAPH_STATUS_CANCELED";
1746 case BT_GRAPH_STATUS_AGAIN
:
1747 return "BT_GRAPH_STATUS_AGAIN";
1748 case BT_GRAPH_STATUS_END
:
1749 return "BT_GRAPH_STATUS_END";
1750 case BT_GRAPH_STATUS_OK
:
1751 return "BT_GRAPH_STATUS_OK";
1752 case BT_GRAPH_STATUS_INVALID
:
1753 return "BT_GRAPH_STATUS_INVALID";
1754 case BT_GRAPH_STATUS_NO_SINK
:
1755 return "BT_GRAPH_STATUS_NO_SINK";
1756 case BT_GRAPH_STATUS_ERROR
:
1757 return "BT_GRAPH_STATUS_ERROR";
1764 int cmd_run(struct bt_config
*cfg
)
1767 struct cmd_run_ctx ctx
= { 0 };
1769 /* Initialize the command's context and the graph object */
1770 if (cmd_run_ctx_init(&ctx
, cfg
)) {
1771 BT_LOGE_STR("Cannot initialize the command's context.");
1772 fprintf(stderr
, "Cannot initialize the command's context\n");
1777 BT_LOGI_STR("Canceled by user before creating components.");
1781 BT_LOGI_STR("Creating components.");
1783 /* Create the requested component instances */
1784 if (cmd_run_ctx_create_components(&ctx
)) {
1785 BT_LOGE_STR("Cannot create components.");
1786 fprintf(stderr
, "Cannot create components\n");
1791 BT_LOGI_STR("Canceled by user before connecting components.");
1795 BT_LOGI_STR("Connecting components.");
1797 /* Connect the initially visible component ports */
1798 if (cmd_run_ctx_connect_ports(&ctx
)) {
1799 BT_LOGE_STR("Cannot connect initial component ports.");
1800 fprintf(stderr
, "Cannot connect initial component ports\n");
1805 BT_LOGI_STR("Canceled by user before running the graph.");
1809 BT_LOGI_STR("Running the graph.");
1813 enum bt_graph_status graph_status
= bt_graph_run(ctx
.graph
);
1816 * Reset console in case something messed with console
1817 * codes during the graph's execution.
1819 printf("%s", bt_common_color_reset());
1821 fprintf(stderr
, "%s", bt_common_color_reset());
1822 BT_LOGV("bt_graph_run() returned: status=%s",
1823 bt_graph_status_str(graph_status
));
1825 switch (graph_status
) {
1826 case BT_GRAPH_STATUS_OK
:
1828 case BT_GRAPH_STATUS_CANCELED
:
1829 BT_LOGI_STR("Graph was canceled by user.");
1831 case BT_GRAPH_STATUS_AGAIN
:
1832 if (bt_graph_is_canceled(ctx
.graph
)) {
1833 BT_LOGI_STR("Graph was canceled by user.");
1837 if (cfg
->cmd_data
.run
.retry_duration_us
> 0) {
1838 BT_LOGV("Got BT_GRAPH_STATUS_AGAIN: sleeping: "
1840 cfg
->cmd_data
.run
.retry_duration_us
);
1842 if (usleep(cfg
->cmd_data
.run
.retry_duration_us
)) {
1843 if (bt_graph_is_canceled(ctx
.graph
)) {
1844 BT_LOGI_STR("Graph was canceled by user.");
1850 case BT_COMPONENT_STATUS_END
:
1853 BT_LOGE_STR("Graph failed to complete successfully");
1854 fprintf(stderr
, "Graph failed to complete successfully\n");
1867 cmd_run_ctx_destroy(&ctx
);
1872 void warn_command_name_and_directory_clash(struct bt_config
*cfg
)
1874 const char *env_clash
;
1876 if (!cfg
->command_name
) {
1880 env_clash
= getenv(ENV_BABELTRACE_WARN_COMMAND_NAME_DIRECTORY_CLASH
);
1881 if (env_clash
&& strcmp(env_clash
, "0") == 0) {
1885 if (g_file_test(cfg
->command_name
,
1886 G_FILE_TEST_EXISTS
| G_FILE_TEST_IS_DIR
)) {
1887 fprintf(stderr
, "\nNOTE: The `%s` command was executed. If you meant to convert a\n",
1889 fprintf(stderr
, "trace located in the local `%s` directory, please use:\n",
1891 fprintf(stderr
, "\n");
1892 fprintf(stderr
, " babeltrace convert %s [OPTIONS]\n",
1898 void init_log_level(void)
1900 bt_cli_log_level
= bt_log_get_level_from_env("BABELTRACE_CLI_LOG_LEVEL");
1903 void set_sigint_handler(void)
1905 struct sigaction new_action
, old_action
;
1907 new_action
.sa_handler
= sigint_handler
;
1908 sigemptyset(&new_action
.sa_mask
);
1909 new_action
.sa_flags
= 0;
1910 sigaction(SIGINT
, NULL
, &old_action
);
1912 if (old_action
.sa_handler
!= SIG_IGN
) {
1913 sigaction(SIGINT
, &new_action
, NULL
);
1917 int main(int argc
, const char **argv
)
1921 struct bt_config
*cfg
;
1924 set_sigint_handler();
1926 cfg
= bt_config_cli_args_create_with_default(argc
, argv
, &retcode
);
1929 /* Quit without errors; typically usage/version */
1931 BT_LOGI_STR("Quitting without errors.");
1936 BT_LOGE("Command-line error: retcode=%d", retcode
);
1941 BT_LOGE_STR("Failed to create a valid Babeltrace configuration.");
1942 fprintf(stderr
, "Failed to create Babeltrace configuration\n");
1948 bt_cli_log_level
= BT_LOGGING_LEVEL_VERBOSE
;
1949 bt_logging_set_global_level(BT_LOGGING_LEVEL_VERBOSE
);
1950 // TODO: for backward compat., set the log level
1951 // environment variables of the known plugins
1953 } else if (cfg
->debug
) {
1954 bt_cli_log_level
= BT_LOGGING_LEVEL_DEBUG
;
1955 bt_logging_set_global_level(BT_LOGGING_LEVEL_DEBUG
);
1956 // TODO: for backward compat., set the log level
1957 // environment variables of the known plugins
1961 babeltrace_debug
= cfg
->debug
;
1962 babeltrace_verbose
= cfg
->verbose
;
1965 if (cfg
->command_needs_plugins
) {
1966 ret
= load_all_plugins(cfg
->plugin_paths
);
1968 BT_LOGE("Failed to load plugins: ret=%d", ret
);
1974 BT_LOGI("Executing command: cmd=%d, command-name=\"%s\"",
1975 cfg
->command
, cfg
->command_name
);
1977 switch (cfg
->command
) {
1978 case BT_CONFIG_COMMAND_RUN
:
1981 case BT_CONFIG_COMMAND_LIST_PLUGINS
:
1982 ret
= cmd_list_plugins(cfg
);
1984 case BT_CONFIG_COMMAND_HELP
:
1985 ret
= cmd_help(cfg
);
1987 case BT_CONFIG_COMMAND_QUERY
:
1988 ret
= cmd_query(cfg
);
1990 case BT_CONFIG_COMMAND_PRINT_CTF_METADATA
:
1991 ret
= cmd_print_ctf_metadata(cfg
);
1993 case BT_CONFIG_COMMAND_PRINT_LTTNG_LIVE_SESSIONS
:
1994 ret
= cmd_print_lttng_live_sessions(cfg
);
1997 BT_LOGF("Invalid/unknown command: cmd=%d", cfg
->command
);
2001 BT_LOGI("Command completed: cmd=%d, command-name=\"%s\", ret=%d",
2002 cfg
->command
, cfg
->command_name
, ret
);
2003 warn_command_name_and_directory_clash(cfg
);
2004 retcode
= ret
? 1 : 0;