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 #include <babeltrace/babeltrace.h>
30 #include <babeltrace/plugin/plugin.h>
31 #include <babeltrace/common-internal.h>
32 #include <babeltrace/graph/component.h>
33 #include <babeltrace/graph/component-source.h>
34 #include <babeltrace/graph/component-sink.h>
35 #include <babeltrace/graph/component-filter.h>
36 #include <babeltrace/graph/component-class.h>
37 #include <babeltrace/graph/port.h>
38 #include <babeltrace/graph/graph.h>
39 #include <babeltrace/graph/connection.h>
40 #include <babeltrace/graph/notification-iterator.h>
41 #include <babeltrace/ref.h>
42 #include <babeltrace/values.h>
50 #include "babeltrace-cfg.h"
51 #include "babeltrace-cfg-connect.h"
52 #include "default-cfg.h"
54 GPtrArray
*loaded_plugins
;
57 void init_loaded_plugins_array(void)
59 loaded_plugins
= g_ptr_array_new_full(8, bt_put
);
63 void fini_loaded_plugins_array(void)
65 g_ptr_array_free(loaded_plugins
, TRUE
);
69 struct bt_plugin
*find_plugin(const char *name
)
72 struct bt_plugin
*plugin
= NULL
;
74 for (i
= 0; i
< loaded_plugins
->len
; i
++) {
75 plugin
= g_ptr_array_index(loaded_plugins
, i
);
77 if (strcmp(name
, bt_plugin_get_name(plugin
)) == 0) {
84 return bt_get(plugin
);
88 struct bt_component_class
*find_component_class(const char *plugin_name
,
89 const char *comp_class_name
,
90 enum bt_component_class_type comp_class_type
)
92 struct bt_component_class
*comp_class
= NULL
;
93 struct bt_plugin
*plugin
= find_plugin(plugin_name
);
99 comp_class
= bt_plugin_get_component_class_by_name_and_type(plugin
,
100 comp_class_name
, comp_class_type
);
107 void print_indent(size_t indent
)
111 for (i
= 0; i
< indent
; i
++) {
116 static char *escape_name_for_shell(const char *input
)
118 char *output
= g_malloc0(strlen(input
) * 5 + 1);
126 for (in
= input
; *in
!= '\0'; in
++) {
154 const char *component_type_str(enum bt_component_class_type type
)
157 case BT_COMPONENT_CLASS_TYPE_SOURCE
:
159 case BT_COMPONENT_CLASS_TYPE_SINK
:
161 case BT_COMPONENT_CLASS_TYPE_FILTER
:
163 case BT_COMPONENT_CLASS_TYPE_UNKNOWN
:
169 static void print_plugin_comp_cls_opt(FILE *fh
, const char *plugin_name
,
170 const char *comp_cls_name
, enum bt_component_class_type type
)
172 char *shell_plugin_name
= NULL
;
173 char *shell_comp_cls_name
= NULL
;
175 shell_plugin_name
= escape_name_for_shell(plugin_name
);
176 if (!shell_plugin_name
) {
180 shell_comp_cls_name
= escape_name_for_shell(comp_cls_name
);
181 if (!shell_comp_cls_name
) {
185 fprintf(fh
, "%s%s--%s%s %s'%s%s%s%s.%s%s%s'",
186 bt_common_color_bold(),
187 bt_common_color_fg_cyan(),
188 component_type_str(type
),
189 bt_common_color_reset(),
190 bt_common_color_fg_default(),
191 bt_common_color_bold(),
192 bt_common_color_fg_blue(),
194 bt_common_color_fg_default(),
195 bt_common_color_fg_yellow(),
197 bt_common_color_reset());
200 g_free(shell_plugin_name
);
201 g_free(shell_comp_cls_name
);
205 void print_value(struct bt_value
*, size_t);
208 void print_value_rec(struct bt_value
*, size_t);
211 bool print_map_value(const char *key
, struct bt_value
*object
, void *data
)
213 size_t *indent
= data
;
215 print_indent(*indent
);
218 if (bt_value_is_array(object
) &&
219 bt_value_array_is_empty(object
)) {
224 if (bt_value_is_map(object
) &&
225 bt_value_map_is_empty(object
)) {
230 if (bt_value_is_array(object
) ||
231 bt_value_is_map(object
)) {
235 print_value_rec(object
, *indent
+ 2);
240 void print_value_rec(struct bt_value
*value
, size_t indent
)
253 switch (bt_value_get_type(value
)) {
254 case BT_VALUE_TYPE_NULL
:
255 printf("%snull%s\n", bt_common_color_bold(),
256 bt_common_color_reset());
258 case BT_VALUE_TYPE_BOOL
:
259 bt_value_bool_get(value
, &bool_val
);
260 printf("%s%s%s%s\n", bt_common_color_bold(),
261 bt_common_color_fg_cyan(), bool_val
? "yes" : "no",
262 bt_common_color_reset());
264 case BT_VALUE_TYPE_INTEGER
:
265 bt_value_integer_get(value
, &int_val
);
266 printf("%s%s%" PRId64
"%s\n", bt_common_color_bold(),
267 bt_common_color_fg_red(), int_val
,
268 bt_common_color_reset());
270 case BT_VALUE_TYPE_FLOAT
:
271 bt_value_float_get(value
, &dbl_val
);
272 printf("%s%s%lf%s\n", bt_common_color_bold(),
273 bt_common_color_fg_red(), dbl_val
,
274 bt_common_color_reset());
276 case BT_VALUE_TYPE_STRING
:
277 bt_value_string_get(value
, &str_val
);
278 printf("%s%s%s%s\n", bt_common_color_bold(),
279 bt_common_color_fg_green(), str_val
,
280 bt_common_color_reset());
282 case BT_VALUE_TYPE_ARRAY
:
283 size
= bt_value_array_size(value
);
287 print_indent(indent
);
292 for (i
= 0; i
< size
; i
++) {
293 struct bt_value
*element
=
294 bt_value_array_get(value
, i
);
297 print_indent(indent
);
300 if (bt_value_is_array(element
) &&
301 bt_value_array_is_empty(element
)) {
306 if (bt_value_is_map(element
) &&
307 bt_value_map_is_empty(element
)) {
312 if (bt_value_is_array(element
) ||
313 bt_value_is_map(element
)) {
317 print_value_rec(element
, indent
+ 2);
321 case BT_VALUE_TYPE_MAP
:
322 if (bt_value_map_is_empty(value
)) {
323 print_indent(indent
);
328 bt_value_map_foreach(value
, print_map_value
, &indent
);
336 void print_value(struct bt_value
*value
, size_t indent
)
338 if (!bt_value_is_array(value
) && !bt_value_is_map(value
)) {
339 print_indent(indent
);
342 print_value_rec(value
, indent
);
346 void print_bt_config_component(struct bt_config_component
*bt_config_component
)
349 print_plugin_comp_cls_opt(stdout
, bt_config_component
->plugin_name
->str
,
350 bt_config_component
->comp_cls_name
->str
,
351 bt_config_component
->type
);
354 if (bt_config_component
->instance_name
->len
> 0) {
355 printf(" Name: %s\n",
356 bt_config_component
->instance_name
->str
);
359 printf(" Parameters:\n");
360 print_value(bt_config_component
->params
, 8);
364 void print_bt_config_components(GPtrArray
*array
)
368 for (i
= 0; i
< array
->len
; i
++) {
369 struct bt_config_component
*cfg_component
=
370 bt_config_get_component(array
, i
);
371 print_bt_config_component(cfg_component
);
372 BT_PUT(cfg_component
);
377 void print_plugin_paths(struct bt_value
*plugin_paths
)
379 printf(" Plugin paths:\n");
380 print_value(plugin_paths
, 4);
384 void print_cfg_run(struct bt_config
*cfg
)
388 print_plugin_paths(cfg
->plugin_paths
);
389 printf(" Source component instances:\n");
390 print_bt_config_components(cfg
->cmd_data
.run
.sources
);
392 if (cfg
->cmd_data
.run
.filters
->len
> 0) {
393 printf(" Filter component instances:\n");
394 print_bt_config_components(cfg
->cmd_data
.run
.filters
);
397 printf(" Sink component instances:\n");
398 print_bt_config_components(cfg
->cmd_data
.run
.sinks
);
399 printf(" Connections:\n");
401 for (i
= 0; i
< cfg
->cmd_data
.run
.connections
->len
; i
++) {
402 struct bt_config_connection
*cfg_connection
=
403 g_ptr_array_index(cfg
->cmd_data
.run
.connections
,
406 printf(" %s%s%s -> %s%s%s\n",
407 cfg_connection
->src_instance_name
->str
,
408 cfg_connection
->src_port_name
->len
> 0 ? "." : "",
409 cfg_connection
->src_port_name
->str
,
410 cfg_connection
->dst_instance_name
->str
,
411 cfg_connection
->dst_port_name
->len
> 0 ? "." : "",
412 cfg_connection
->dst_port_name
->str
);
417 void print_cfg_list_plugins(struct bt_config
*cfg
)
419 print_plugin_paths(cfg
->plugin_paths
);
423 void print_cfg_help(struct bt_config
*cfg
)
425 print_plugin_paths(cfg
->plugin_paths
);
429 void print_cfg_print_ctf_metadata(struct bt_config
*cfg
)
431 print_plugin_paths(cfg
->plugin_paths
);
432 printf(" Path: %s\n", cfg
->cmd_data
.print_ctf_metadata
.path
->str
);
436 void print_cfg_print_lttng_live_sessions(struct bt_config
*cfg
)
438 print_plugin_paths(cfg
->plugin_paths
);
439 printf(" URL: %s\n", cfg
->cmd_data
.print_lttng_live_sessions
.url
->str
);
443 void print_cfg_query(struct bt_config
*cfg
)
445 print_plugin_paths(cfg
->plugin_paths
);
446 printf(" Object: `%s`\n", cfg
->cmd_data
.query
.object
->str
);
447 printf(" Component class:\n");
448 print_bt_config_component(cfg
->cmd_data
.query
.cfg_component
);
452 void print_cfg(struct bt_config
*cfg
)
454 if (!babeltrace_verbose
) {
458 printf("Configuration:\n");
459 printf(" Debug mode: %s\n", cfg
->debug
? "yes" : "no");
460 printf(" Verbose mode: %s\n", cfg
->verbose
? "yes" : "no");
462 switch (cfg
->command
) {
463 case BT_CONFIG_COMMAND_RUN
:
466 case BT_CONFIG_COMMAND_LIST_PLUGINS
:
467 print_cfg_list_plugins(cfg
);
469 case BT_CONFIG_COMMAND_HELP
:
472 case BT_CONFIG_COMMAND_QUERY
:
473 print_cfg_query(cfg
);
475 case BT_CONFIG_COMMAND_PRINT_CTF_METADATA
:
476 print_cfg_print_ctf_metadata(cfg
);
478 case BT_CONFIG_COMMAND_PRINT_LTTNG_LIVE_SESSIONS
:
479 print_cfg_print_lttng_live_sessions(cfg
);
487 struct bt_component
*create_trimmer(struct bt_config_component
*source_cfg
)
489 struct bt_component
*trimmer
= NULL
;
490 struct bt_component_class
*trimmer_class
= NULL
;
491 struct bt_value
*trimmer_params
= NULL
;
492 struct bt_value
*value
;
494 trimmer_params
= bt_value_map_create();
495 if (!trimmer_params
) {
499 value
= bt_value_map_get(source_cfg
->params
, "begin");
501 enum bt_value_status ret
;
503 ret
= bt_value_map_insert(trimmer_params
, "begin",
510 value
= bt_value_map_get(source_cfg
->params
, "end");
512 enum bt_value_status ret
;
514 ret
= bt_value_map_insert(trimmer_params
, "end",
521 value
= bt_value_map_get(source_cfg
->params
, "clock-gmt");
523 enum bt_value_status ret
;
525 ret
= bt_value_map_insert(trimmer_params
, "clock-gmt",
533 trimmer_class
= find_component_class("utils", "trimmer",
534 BT_COMPONENT_CLASS_TYPE_FILTER
);
535 if (!trimmer_class
) {
536 fprintf(stderr
, "Could not find trimmer component class. Aborting...\n");
539 trimmer
= bt_component_create(trimmer_class
, "source_trimmer",
545 bt_put(trimmer_params
);
546 bt_put(trimmer_class
);
551 int connect_source_sink(struct bt_graph
*graph
,
552 struct bt_component
*source
,
553 struct bt_config_component
*source_cfg
,
554 struct bt_component
*sink
)
559 struct bt_connection
*connection
= NULL
;
560 struct bt_component
*trimmer
= NULL
;
561 struct bt_port
*source_port
=
562 bt_component_source_get_default_output_port(source
);
563 struct bt_port
*sink_port
=
564 bt_component_sink_get_default_input_port(sink
);
565 struct bt_port
*to_sink_port
= NULL
;
566 struct bt_port
*trimmer_input_port
= NULL
;
569 fprintf(stderr
, "Failed to find default source output port. Aborting...\n");
574 fprintf(stderr
, "Failed to find default sink input port. Aborting...\n");
579 if (bt_value_map_has_key(source_cfg
->params
, "begin")
580 || bt_value_map_has_key(source_cfg
->params
, "end")) {
581 /* A trimmer must be inserted in the graph. */
582 trimmer
= create_trimmer(source_cfg
);
584 fprintf(stderr
, "Failed to create trimmer component. Aborting...\n");
589 trimmer_input_port
= bt_component_filter_get_default_input_port(
591 if (!trimmer_input_port
) {
592 fprintf(stderr
, "Failed to find trimmer input port. Aborting...\n");
596 to_sink_port
= bt_component_filter_get_default_output_port(
599 fprintf(stderr
, "Failed to find trimmer output port. Aborting...\n");
604 connection
= bt_graph_connect_ports(graph
, source_port
,
607 fprintf(stderr
, "Failed to connect source to trimmer. Aborting...\n");
613 BT_MOVE(to_sink_port
, source_port
);
616 connection
= bt_graph_connect_ports(graph
, to_sink_port
, sink_port
);
618 fprintf(stderr
, "Failed to connect to sink. Aborting...\n");
626 bt_put(to_sink_port
);
634 void add_to_loaded_plugins(struct bt_plugin_set
*plugin_set
)
639 count
= bt_plugin_set_get_plugin_count(plugin_set
);
642 for (i
= 0; i
< count
; i
++) {
643 struct bt_plugin
*plugin
=
644 bt_plugin_set_get_plugin(plugin_set
, i
);
645 struct bt_plugin
*loaded_plugin
=
646 find_plugin(bt_plugin_get_name(plugin
));
651 printf_verbose("Not loading plugin `%s`: already loaded from `%s`\n",
652 bt_plugin_get_path(plugin
),
653 bt_plugin_get_path(loaded_plugin
));
654 bt_put(loaded_plugin
);
656 /* Add to global array. */
657 g_ptr_array_add(loaded_plugins
, bt_get(plugin
));
665 int load_dynamic_plugins(struct bt_value
*plugin_paths
)
667 int nr_paths
, i
, ret
= 0;
669 nr_paths
= bt_value_array_size(plugin_paths
);
675 for (i
= 0; i
< nr_paths
; i
++) {
676 struct bt_value
*plugin_path_value
= NULL
;
677 const char *plugin_path
;
678 struct bt_plugin_set
*plugin_set
;
680 plugin_path_value
= bt_value_array_get(plugin_paths
, i
);
681 if (bt_value_string_get(plugin_path_value
,
683 BT_PUT(plugin_path_value
);
687 plugin_set
= bt_plugin_create_all_from_dir(plugin_path
, false);
689 printf_debug("Unable to dynamically load plugins from path %s.\n",
691 BT_PUT(plugin_path_value
);
695 add_to_loaded_plugins(plugin_set
);
697 BT_PUT(plugin_path_value
);
704 int load_static_plugins(void)
707 struct bt_plugin_set
*plugin_set
;
709 plugin_set
= bt_plugin_create_all_from_static();
711 printf_debug("Unable to load static plugins.\n");
716 add_to_loaded_plugins(plugin_set
);
722 static int load_all_plugins(struct bt_value
*plugin_paths
)
726 if (load_dynamic_plugins(plugin_paths
)) {
727 fprintf(stderr
, "Failed to load dynamic plugins.\n");
732 if (load_static_plugins()) {
733 fprintf(stderr
, "Failed to load static plugins.\n");
742 static void print_plugin_info(struct bt_plugin
*plugin
)
744 unsigned int major
, minor
, patch
;
746 enum bt_plugin_status version_status
;
747 const char *plugin_name
;
751 const char *plugin_description
;
753 plugin_name
= bt_plugin_get_name(plugin
);
754 path
= bt_plugin_get_path(plugin
);
755 author
= bt_plugin_get_author(plugin
);
756 license
= bt_plugin_get_license(plugin
);
757 plugin_description
= bt_plugin_get_description(plugin
);
758 version_status
= bt_plugin_get_version(plugin
, &major
, &minor
,
760 printf("%s%s%s%s:\n", bt_common_color_bold(),
761 bt_common_color_fg_blue(), plugin_name
,
762 bt_common_color_reset());
763 printf(" %sPath%s: %s\n", bt_common_color_bold(),
764 bt_common_color_reset(), path
? path
: "(None)");
766 if (version_status
== BT_PLUGIN_STATUS_OK
) {
767 printf(" %sVersion%s: %u.%u.%u",
768 bt_common_color_bold(), bt_common_color_reset(),
769 major
, minor
, patch
);
778 printf(" %sDescription%s: %s\n", bt_common_color_bold(),
779 bt_common_color_reset(),
780 plugin_description
? plugin_description
: "(None)");
781 printf(" %sAuthor%s: %s\n", bt_common_color_bold(),
782 bt_common_color_reset(), author
? author
: "(Unknown)");
783 printf(" %sLicense%s: %s\n", bt_common_color_bold(),
784 bt_common_color_reset(),
785 license
? license
: "(Unknown)");
788 static int cmd_query(struct bt_config
*cfg
)
791 struct bt_component_class
*comp_cls
= NULL
;
792 struct bt_value
*results
= NULL
;
794 ret
= load_all_plugins(cfg
->plugin_paths
);
799 comp_cls
= find_component_class(cfg
->cmd_data
.query
.cfg_component
->plugin_name
->str
,
800 cfg
->cmd_data
.query
.cfg_component
->comp_cls_name
->str
,
801 cfg
->cmd_data
.query
.cfg_component
->type
);
803 fprintf(stderr
, "%s%sCannot find component class %s",
804 bt_common_color_bold(),
805 bt_common_color_fg_red(),
806 bt_common_color_reset());
807 print_plugin_comp_cls_opt(stderr
,
808 cfg
->cmd_data
.query
.cfg_component
->plugin_name
->str
,
809 cfg
->cmd_data
.query
.cfg_component
->comp_cls_name
->str
,
810 cfg
->cmd_data
.query
.cfg_component
->type
);
811 fprintf(stderr
, "\n");
816 results
= bt_component_class_query(comp_cls
,
817 cfg
->cmd_data
.query
.object
->str
,
818 cfg
->cmd_data
.query
.cfg_component
->params
);
820 fprintf(stderr
, "%s%sFailed to query info to %s",
821 bt_common_color_bold(),
822 bt_common_color_fg_red(),
823 bt_common_color_reset());
824 print_plugin_comp_cls_opt(stderr
,
825 cfg
->cmd_data
.query
.cfg_component
->plugin_name
->str
,
826 cfg
->cmd_data
.query
.cfg_component
->comp_cls_name
->str
,
827 cfg
->cmd_data
.query
.cfg_component
->type
);
828 fprintf(stderr
, "%s%s with object `%s`%s\n",
829 bt_common_color_bold(),
830 bt_common_color_fg_red(),
831 cfg
->cmd_data
.query
.object
->str
,
832 bt_common_color_reset());
837 print_value(results
, 0);
845 static int cmd_help(struct bt_config
*cfg
)
848 struct bt_plugin
*plugin
= NULL
;
851 ret
= load_all_plugins(cfg
->plugin_paths
);
856 plugin
= find_plugin(cfg
->cmd_data
.help
.cfg_component
->plugin_name
->str
);
858 fprintf(stderr
, "%s%sCannot find plugin %s%s%s\n",
859 bt_common_color_bold(), bt_common_color_fg_red(),
860 bt_common_color_fg_blue(),
861 cfg
->cmd_data
.help
.cfg_component
->plugin_name
->str
,
862 bt_common_color_reset());
867 print_plugin_info(plugin
);
868 printf(" %sComponent classes%s: %d\n",
869 bt_common_color_bold(),
870 bt_common_color_reset(),
871 (int) bt_plugin_get_component_class_count(plugin
));
874 if (cfg
->cmd_data
.help
.cfg_component
->type
!=
875 BT_COMPONENT_CLASS_TYPE_UNKNOWN
) {
876 struct bt_component_class
*needed_comp_cls
=
877 find_component_class(
878 cfg
->cmd_data
.help
.cfg_component
->plugin_name
->str
,
879 cfg
->cmd_data
.help
.cfg_component
->comp_cls_name
->str
,
880 cfg
->cmd_data
.help
.cfg_component
->type
);
882 if (!needed_comp_cls
) {
883 fprintf(stderr
, "\n%s%sCannot find component class %s",
884 bt_common_color_bold(),
885 bt_common_color_fg_red(),
886 bt_common_color_reset());
887 print_plugin_comp_cls_opt(stderr
,
888 cfg
->cmd_data
.help
.cfg_component
->plugin_name
->str
,
889 cfg
->cmd_data
.help
.cfg_component
->comp_cls_name
->str
,
890 cfg
->cmd_data
.help
.cfg_component
->type
);
891 fprintf(stderr
, "\n");
896 bt_put(needed_comp_cls
);
899 for (i
= 0; i
< bt_plugin_get_component_class_count(plugin
); i
++) {
900 struct bt_component_class
*comp_cls
=
901 bt_plugin_get_component_class_by_index(plugin
, i
);
902 const char *comp_class_name
=
903 bt_component_class_get_name(comp_cls
);
904 const char *comp_class_description
=
905 bt_component_class_get_description(comp_cls
);
906 const char *comp_class_help
=
907 bt_component_class_get_help(comp_cls
);
908 enum bt_component_class_type type
=
909 bt_component_class_get_type(comp_cls
);
913 if (cfg
->cmd_data
.help
.cfg_component
->type
!=
914 BT_COMPONENT_CLASS_TYPE_UNKNOWN
) {
915 if (strcmp(cfg
->cmd_data
.help
.cfg_component
->comp_cls_name
->str
,
916 comp_class_name
) != 0 &&
918 cfg
->cmd_data
.help
.cfg_component
->type
) {
925 print_plugin_comp_cls_opt(stdout
,
926 cfg
->cmd_data
.help
.cfg_component
->plugin_name
->str
,
930 printf(" %sDescription%s: %s\n", bt_common_color_bold(),
931 bt_common_color_reset(),
932 comp_class_description
? comp_class_description
: "(None)");
934 if (comp_class_help
) {
935 printf("\n%s\n", comp_class_help
);
946 static int cmd_list_plugins(struct bt_config
*cfg
)
949 int plugins_count
, component_classes_count
= 0, i
;
951 ret
= load_all_plugins(cfg
->plugin_paths
);
956 printf("From the following plugin paths:\n\n");
957 print_value(cfg
->plugin_paths
, 2);
959 plugins_count
= loaded_plugins
->len
;
960 if (plugins_count
== 0) {
961 fprintf(stderr
, "%s%sNo plugins found.%s\n",
962 bt_common_color_bold(), bt_common_color_fg_red(),
963 bt_common_color_reset());
964 fprintf(stderr
, "\n");
965 fprintf(stderr
, "Please make sure your plugin search path is set correctly. You can use\n");
966 fprintf(stderr
, "the --plugin-path command-line option or the BABELTRACE_PLUGIN_PATH\n");
967 fprintf(stderr
, "environment variable.\n");
972 for (i
= 0; i
< plugins_count
; i
++) {
973 struct bt_plugin
*plugin
= g_ptr_array_index(loaded_plugins
, i
);
975 component_classes_count
+= bt_plugin_get_component_class_count(plugin
);
978 printf("Found %s%d%s component classes in %s%d%s plugins.\n",
979 bt_common_color_bold(),
980 component_classes_count
,
981 bt_common_color_reset(),
982 bt_common_color_bold(),
984 bt_common_color_reset());
986 for (i
= 0; i
< plugins_count
; i
++) {
988 struct bt_plugin
*plugin
= g_ptr_array_index(loaded_plugins
, i
);
990 component_classes_count
=
991 bt_plugin_get_component_class_count(plugin
);
993 print_plugin_info(plugin
);
995 if (component_classes_count
== 0) {
996 printf(" %sComponent classes%s: (None)\n",
997 bt_common_color_bold(),
998 bt_common_color_reset());
1000 printf(" %sComponent classes%s:\n",
1001 bt_common_color_bold(),
1002 bt_common_color_reset());
1005 for (j
= 0; j
< component_classes_count
; j
++) {
1006 struct bt_component_class
*comp_class
=
1007 bt_plugin_get_component_class_by_index(
1009 const char *comp_class_name
=
1010 bt_component_class_get_name(comp_class
);
1011 const char *comp_class_description
=
1012 bt_component_class_get_description(comp_class
);
1013 enum bt_component_class_type type
=
1014 bt_component_class_get_type(comp_class
);
1017 print_plugin_comp_cls_opt(stdout
,
1018 bt_plugin_get_name(plugin
), comp_class_name
,
1021 if (comp_class_description
) {
1022 printf(": %s", comp_class_description
);
1034 static int cmd_print_lttng_live_sessions(struct bt_config
*cfg
)
1040 static int cmd_print_ctf_metadata(struct bt_config
*cfg
)
1043 struct bt_component_class
*comp_cls
= NULL
;
1044 struct bt_value
*results
= NULL
;
1045 struct bt_value
*params
= NULL
;
1046 struct bt_value
*metadata_text_value
= NULL
;
1047 const char *metadata_text
= NULL
;
1048 static const char * const plugin_name
= "ctf";
1049 static const char * const comp_cls_name
= "fs";
1050 static const enum bt_component_class_type comp_cls_type
=
1051 BT_COMPONENT_CLASS_TYPE_SOURCE
;
1053 assert(cfg
->cmd_data
.print_ctf_metadata
.path
);
1054 comp_cls
= find_component_class(plugin_name
, comp_cls_name
,
1057 fprintf(stderr
, "%s%sCannot find component class %s",
1058 bt_common_color_bold(),
1059 bt_common_color_fg_red(),
1060 bt_common_color_reset());
1061 print_plugin_comp_cls_opt(stderr
, plugin_name
,
1062 comp_cls_name
, comp_cls_type
);
1063 fprintf(stderr
, "\n");
1068 params
= bt_value_map_create();
1074 ret
= bt_value_map_insert_string(params
, "path",
1075 cfg
->cmd_data
.print_ctf_metadata
.path
->str
);
1081 results
= bt_component_class_query(comp_cls
, "metadata-info",
1085 fprintf(stderr
, "%s%sFailed to request metadata info%s\n",
1086 bt_common_color_bold(),
1087 bt_common_color_fg_red(),
1088 bt_common_color_reset());
1092 metadata_text_value
= bt_value_map_get(results
, "text");
1093 if (!metadata_text_value
) {
1098 ret
= bt_value_string_get(metadata_text_value
, &metadata_text
);
1100 printf("%s\n", metadata_text
);
1105 bt_put(metadata_text_value
);
1110 static int cmd_run(struct bt_config
*cfg
)
1113 struct bt_component_class
*source_class
= NULL
;
1114 struct bt_component_class
*sink_class
= NULL
;
1115 struct bt_component
*source
= NULL
, *sink
= NULL
;
1116 struct bt_value
*source_params
= NULL
, *sink_params
= NULL
;
1117 struct bt_config_component
*source_cfg
= NULL
, *sink_cfg
= NULL
;
1118 struct bt_graph
*graph
= NULL
;
1120 ret
= load_all_plugins(cfg
->plugin_paths
);
1125 /* TODO handle more than 1 source and 1 sink. */
1126 if (cfg
->cmd_data
.run
.sources
->len
!= 1 ||
1127 cfg
->cmd_data
.run
.sinks
->len
!= 1) {
1128 fprintf(stderr
, "Only one source and one sink component class are supported. Aborting...\n");
1133 source_cfg
= bt_config_get_component(cfg
->cmd_data
.run
.sources
, 0);
1134 source_params
= bt_get(source_cfg
->params
);
1135 source_class
= find_component_class(source_cfg
->plugin_name
->str
,
1136 source_cfg
->comp_cls_name
->str
,
1137 BT_COMPONENT_CLASS_TYPE_SOURCE
);
1138 if (!source_class
) {
1139 fprintf(stderr
, "Could not find ");
1140 print_plugin_comp_cls_opt(stderr
, source_cfg
->plugin_name
->str
,
1141 source_cfg
->comp_cls_name
->str
, BT_COMPONENT_CLASS_TYPE_SOURCE
);
1142 fprintf(stderr
, ". Aborting...\n");
1147 sink_cfg
= bt_config_get_component(cfg
->cmd_data
.run
.sinks
, 0);
1148 sink_params
= bt_get(sink_cfg
->params
);
1149 sink_class
= find_component_class(sink_cfg
->plugin_name
->str
,
1150 sink_cfg
->comp_cls_name
->str
,
1151 BT_COMPONENT_CLASS_TYPE_SINK
);
1153 fprintf(stderr
, "Could not find ");
1154 print_plugin_comp_cls_opt(stderr
, sink_cfg
->plugin_name
->str
,
1155 sink_cfg
->comp_cls_name
->str
, BT_COMPONENT_CLASS_TYPE_SINK
);
1156 fprintf(stderr
, ". Aborting...\n");
1161 graph
= bt_graph_create();
1167 source
= bt_component_create(source_class
, "source", source_params
);
1169 fprintf(stderr
, "Failed to instantiate selected source component. Aborting...\n");
1174 sink
= bt_component_create(sink_class
, "sink", sink_params
);
1176 fprintf(stderr
, "Failed to instantiate selected output component. Aborting...\n");
1181 ret
= connect_source_sink(graph
, source
, source_cfg
, sink
);
1188 enum bt_graph_status graph_status
;
1190 graph_status
= bt_graph_run(graph
);
1191 switch (graph_status
) {
1192 case BT_GRAPH_STATUS_AGAIN
:
1193 /* Wait for an arbitraty 500 ms. */
1196 case BT_COMPONENT_STATUS_END
:
1199 fprintf(stderr
, "Sink component returned an error, aborting...\n");
1207 bt_put(source_class
);
1210 bt_put(source_params
);
1211 bt_put(sink_params
);
1218 static void warn_command_name_and_directory_clash(struct bt_config
*cfg
)
1220 if (!cfg
->command_name
) {
1224 if (g_file_test(cfg
->command_name
,
1225 G_FILE_TEST_EXISTS
| G_FILE_TEST_IS_DIR
)) {
1226 fprintf(stderr
, "\nNOTE: The `%s` command was executed. If you meant to convert a\n",
1228 fprintf(stderr
, "trace located in the local `%s` directory, please use:\n",
1230 fprintf(stderr
, "\n");
1231 fprintf(stderr
, " babeltrace convert %s [OPTIONS]\n",
1236 int main(int argc
, const char **argv
)
1240 struct bt_config
*cfg
;
1242 init_loaded_plugins_array();
1243 cfg
= bt_config_from_args_with_defaults(argc
, argv
, &retcode
);
1246 /* Quit without errors; typically usage/version */
1256 fprintf(stderr
, "Failed to create Babeltrace configuration\n");
1261 babeltrace_debug
= cfg
->debug
;
1262 babeltrace_verbose
= cfg
->verbose
;
1265 if (cfg
->command_needs_plugins
) {
1266 ret
= load_all_plugins(cfg
->plugin_paths
);
1273 switch (cfg
->command
) {
1274 case BT_CONFIG_COMMAND_RUN
:
1277 case BT_CONFIG_COMMAND_LIST_PLUGINS
:
1278 ret
= cmd_list_plugins(cfg
);
1280 case BT_CONFIG_COMMAND_HELP
:
1281 ret
= cmd_help(cfg
);
1283 case BT_CONFIG_COMMAND_QUERY
:
1284 ret
= cmd_query(cfg
);
1286 case BT_CONFIG_COMMAND_PRINT_CTF_METADATA
:
1287 ret
= cmd_print_ctf_metadata(cfg
);
1289 case BT_CONFIG_COMMAND_PRINT_LTTNG_LIVE_SESSIONS
:
1290 ret
= cmd_print_lttng_live_sessions(cfg
);
1296 warn_command_name_and_directory_clash(cfg
);
1297 retcode
= ret
? 1 : 0;
1301 fini_loaded_plugins_array();