Commit | Line | Data |
---|---|---|
34ac0e6c MD |
1 | /* |
2 | * babeltrace.c | |
3 | * | |
4 | * Babeltrace Trace Converter | |
5 | * | |
64fa3fec MD |
6 | * Copyright 2010-2011 EfficiOS Inc. and Linux Foundation |
7 | * | |
8 | * Author: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> | |
34ac0e6c MD |
9 | * |
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: | |
16 | * | |
17 | * The above copyright notice and this permission notice shall be included in | |
18 | * all copies or substantial portions of the Software. | |
c462e188 MD |
19 | * |
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 | |
26 | * SOFTWARE. | |
34ac0e6c | 27 | */ |
4c8bfb7e | 28 | |
95d36295 | 29 | #include <babeltrace/babeltrace.h> |
7c7c0433 | 30 | #include <babeltrace/plugin/plugin.h> |
290725f7 | 31 | #include <babeltrace/common-internal.h> |
b2e0c907 PP |
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> | |
2e339de1 JG |
41 | #include <babeltrace/ref.h> |
42 | #include <babeltrace/values.h> | |
34ac0e6c | 43 | #include <stdlib.h> |
7f26a816 PP |
44 | #include <popt.h> |
45 | #include <string.h> | |
46 | #include <stdio.h> | |
33b34c43 | 47 | #include <glib.h> |
dc3fffef | 48 | #include <inttypes.h> |
c42c79ea | 49 | #include "babeltrace-cfg.h" |
ebba3338 | 50 | #include "babeltrace-cfg-connect.h" |
c1870f57 | 51 | #include "default-cfg.h" |
34ac0e6c | 52 | |
33b34c43 PP |
53 | GPtrArray *loaded_plugins; |
54 | ||
55 | static | |
56 | void init_loaded_plugins_array(void) | |
57 | { | |
58 | loaded_plugins = g_ptr_array_new_full(8, bt_put); | |
59 | } | |
60 | ||
61 | static | |
62 | void fini_loaded_plugins_array(void) | |
63 | { | |
64 | g_ptr_array_free(loaded_plugins, TRUE); | |
65 | } | |
66 | ||
67 | static | |
68 | struct bt_plugin *find_plugin(const char *name) | |
69 | { | |
70 | int i; | |
71 | struct bt_plugin *plugin = NULL; | |
72 | ||
73 | for (i = 0; i < loaded_plugins->len; i++) { | |
74 | plugin = g_ptr_array_index(loaded_plugins, i); | |
75 | ||
76 | if (strcmp(name, bt_plugin_get_name(plugin)) == 0) { | |
77 | break; | |
78 | } | |
79 | ||
80 | plugin = NULL; | |
81 | } | |
82 | ||
83 | return bt_get(plugin); | |
84 | } | |
85 | ||
86 | static | |
87 | struct bt_component_class *find_component_class(const char *plugin_name, | |
88 | const char *comp_class_name, | |
d3e4dcd8 | 89 | enum bt_component_class_type comp_class_type) |
33b34c43 PP |
90 | { |
91 | struct bt_component_class *comp_class = NULL; | |
92 | struct bt_plugin *plugin = find_plugin(plugin_name); | |
93 | ||
94 | if (!plugin) { | |
95 | goto end; | |
96 | } | |
97 | ||
98 | comp_class = bt_plugin_get_component_class_by_name_and_type(plugin, | |
99 | comp_class_name, comp_class_type); | |
100 | BT_PUT(plugin); | |
101 | end: | |
102 | return comp_class; | |
103 | } | |
6c2f3ee5 | 104 | |
c42c79ea PP |
105 | static |
106 | void print_indent(size_t indent) | |
107 | { | |
108 | size_t i; | |
109 | ||
110 | for (i = 0; i < indent; i++) { | |
00447e45 | 111 | printf(" "); |
c42c79ea PP |
112 | } |
113 | } | |
114 | ||
87796884 PP |
115 | static char *escape_name_for_shell(const char *input) |
116 | { | |
117 | char *output = g_malloc0(strlen(input) * 5 + 1); | |
118 | const char *in; | |
119 | char *out = output; | |
120 | ||
121 | if (!output) { | |
122 | goto end; | |
123 | } | |
124 | ||
125 | for (in = input; *in != '\0'; in++) { | |
126 | switch (*in) { | |
127 | case '\\': | |
128 | *out++ = '\\'; | |
129 | *out++ = '\\'; | |
130 | break; | |
131 | case '\'': | |
132 | *out++ = '\''; | |
133 | *out++ = '"'; | |
134 | *out++ = '\''; | |
135 | *out++ = '"'; | |
136 | *out++ = '\''; | |
137 | break; | |
138 | case '.': | |
139 | *out++ = '\\'; | |
140 | *out++ = '.'; | |
141 | break; | |
142 | default: | |
143 | *out++ = *in; | |
144 | break; | |
145 | } | |
146 | } | |
147 | ||
148 | end: | |
149 | return output; | |
150 | } | |
151 | ||
152 | static | |
153 | const char *component_type_str(enum bt_component_class_type type) | |
154 | { | |
155 | switch (type) { | |
156 | case BT_COMPONENT_CLASS_TYPE_SOURCE: | |
157 | return "source"; | |
158 | case BT_COMPONENT_CLASS_TYPE_SINK: | |
159 | return "sink"; | |
160 | case BT_COMPONENT_CLASS_TYPE_FILTER: | |
161 | return "filter"; | |
162 | case BT_COMPONENT_CLASS_TYPE_UNKNOWN: | |
163 | default: | |
164 | return "unknown"; | |
165 | } | |
166 | } | |
167 | ||
168 | static void print_plugin_comp_cls_opt(FILE *fh, const char *plugin_name, | |
169 | const char *comp_cls_name, enum bt_component_class_type type) | |
170 | { | |
171 | char *shell_plugin_name = NULL; | |
172 | char *shell_comp_cls_name = NULL; | |
173 | ||
174 | shell_plugin_name = escape_name_for_shell(plugin_name); | |
175 | if (!shell_plugin_name) { | |
176 | goto end; | |
177 | } | |
178 | ||
179 | shell_comp_cls_name = escape_name_for_shell(comp_cls_name); | |
180 | if (!shell_comp_cls_name) { | |
181 | goto end; | |
182 | } | |
183 | ||
184 | fprintf(fh, "%s%s--%s%s %s'%s%s%s%s.%s%s%s'", | |
185 | bt_common_color_bold(), | |
186 | bt_common_color_fg_cyan(), | |
187 | component_type_str(type), | |
188 | bt_common_color_reset(), | |
189 | bt_common_color_fg_default(), | |
190 | bt_common_color_bold(), | |
191 | bt_common_color_fg_blue(), | |
192 | shell_plugin_name, | |
193 | bt_common_color_fg_default(), | |
194 | bt_common_color_fg_yellow(), | |
195 | shell_comp_cls_name, | |
196 | bt_common_color_reset()); | |
197 | ||
198 | end: | |
199 | g_free(shell_plugin_name); | |
200 | g_free(shell_comp_cls_name); | |
201 | } | |
202 | ||
c42c79ea | 203 | static |
290725f7 | 204 | void print_value(struct bt_value *, size_t); |
c42c79ea | 205 | |
c1081aa6 PP |
206 | static |
207 | void print_value_rec(struct bt_value *, size_t); | |
208 | ||
c42c79ea PP |
209 | static |
210 | bool print_map_value(const char *key, struct bt_value *object, void *data) | |
211 | { | |
290725f7 PP |
212 | size_t *indent = data; |
213 | ||
214 | print_indent(*indent); | |
215 | printf("%s: ", key); | |
216 | ||
217 | if (bt_value_is_array(object) && | |
218 | bt_value_array_is_empty(object)) { | |
219 | printf("[ ]\n"); | |
220 | return true; | |
221 | } | |
222 | ||
223 | if (bt_value_is_map(object) && | |
224 | bt_value_map_is_empty(object)) { | |
225 | printf("{ }\n"); | |
226 | return true; | |
227 | } | |
c42c79ea | 228 | |
290725f7 PP |
229 | if (bt_value_is_array(object) || |
230 | bt_value_is_map(object)) { | |
231 | printf("\n"); | |
232 | } | |
c42c79ea | 233 | |
c1081aa6 | 234 | print_value_rec(object, *indent + 2); |
c42c79ea PP |
235 | return true; |
236 | } | |
237 | ||
238 | static | |
c1081aa6 | 239 | void print_value_rec(struct bt_value *value, size_t indent) |
c42c79ea PP |
240 | { |
241 | bool bool_val; | |
242 | int64_t int_val; | |
243 | double dbl_val; | |
244 | const char *str_val; | |
245 | int size; | |
246 | int i; | |
247 | ||
248 | if (!value) { | |
249 | return; | |
250 | } | |
251 | ||
c42c79ea PP |
252 | switch (bt_value_get_type(value)) { |
253 | case BT_VALUE_TYPE_NULL: | |
c1081aa6 PP |
254 | printf("%snull%s\n", bt_common_color_bold(), |
255 | bt_common_color_reset()); | |
c42c79ea PP |
256 | break; |
257 | case BT_VALUE_TYPE_BOOL: | |
258 | bt_value_bool_get(value, &bool_val); | |
c1081aa6 PP |
259 | printf("%s%s%s%s\n", bt_common_color_bold(), |
260 | bt_common_color_fg_cyan(), bool_val ? "yes" : "no", | |
261 | bt_common_color_reset()); | |
c42c79ea PP |
262 | break; |
263 | case BT_VALUE_TYPE_INTEGER: | |
264 | bt_value_integer_get(value, &int_val); | |
c1081aa6 PP |
265 | printf("%s%s%" PRId64 "%s\n", bt_common_color_bold(), |
266 | bt_common_color_fg_red(), int_val, | |
267 | bt_common_color_reset()); | |
c42c79ea PP |
268 | break; |
269 | case BT_VALUE_TYPE_FLOAT: | |
270 | bt_value_float_get(value, &dbl_val); | |
c1081aa6 PP |
271 | printf("%s%s%lf%s\n", bt_common_color_bold(), |
272 | bt_common_color_fg_red(), dbl_val, | |
273 | bt_common_color_reset()); | |
c42c79ea PP |
274 | break; |
275 | case BT_VALUE_TYPE_STRING: | |
276 | bt_value_string_get(value, &str_val); | |
c1081aa6 PP |
277 | printf("%s%s%s%s\n", bt_common_color_bold(), |
278 | bt_common_color_fg_green(), str_val, | |
279 | bt_common_color_reset()); | |
c42c79ea PP |
280 | break; |
281 | case BT_VALUE_TYPE_ARRAY: | |
282 | size = bt_value_array_size(value); | |
290725f7 PP |
283 | assert(size >= 0); |
284 | ||
285 | if (size == 0) { | |
286 | print_indent(indent); | |
287 | printf("[ ]\n"); | |
288 | break; | |
289 | } | |
c42c79ea PP |
290 | |
291 | for (i = 0; i < size; i++) { | |
292 | struct bt_value *element = | |
293 | bt_value_array_get(value, i); | |
294 | ||
290725f7 PP |
295 | assert(element); |
296 | print_indent(indent); | |
297 | printf("- "); | |
298 | ||
299 | if (bt_value_is_array(element) && | |
300 | bt_value_array_is_empty(element)) { | |
301 | printf("[ ]\n"); | |
302 | continue; | |
303 | } | |
304 | ||
305 | if (bt_value_is_map(element) && | |
306 | bt_value_map_is_empty(element)) { | |
307 | printf("{ }\n"); | |
308 | continue; | |
309 | } | |
310 | ||
311 | if (bt_value_is_array(element) || | |
312 | bt_value_is_map(element)) { | |
313 | printf("\n"); | |
314 | } | |
315 | ||
c1081aa6 | 316 | print_value_rec(element, indent + 2); |
c42c79ea PP |
317 | BT_PUT(element); |
318 | } | |
c42c79ea PP |
319 | break; |
320 | case BT_VALUE_TYPE_MAP: | |
321 | if (bt_value_map_is_empty(value)) { | |
290725f7 PP |
322 | print_indent(indent); |
323 | printf("{ }\n"); | |
324 | break; | |
c42c79ea PP |
325 | } |
326 | ||
290725f7 | 327 | bt_value_map_foreach(value, print_map_value, &indent); |
c42c79ea PP |
328 | break; |
329 | default: | |
330 | assert(false); | |
331 | } | |
332 | } | |
333 | ||
c1081aa6 PP |
334 | static |
335 | void print_value(struct bt_value *value, size_t indent) | |
336 | { | |
337 | if (!bt_value_is_array(value) && !bt_value_is_map(value)) { | |
338 | print_indent(indent); | |
339 | } | |
340 | ||
341 | print_value_rec(value, indent); | |
342 | } | |
343 | ||
c42c79ea PP |
344 | static |
345 | void print_bt_config_component(struct bt_config_component *bt_config_component) | |
346 | { | |
87796884 PP |
347 | printf(" "); |
348 | print_plugin_comp_cls_opt(stdout, bt_config_component->plugin_name->str, | |
db0f160a | 349 | bt_config_component->comp_cls_name->str, |
87796884 PP |
350 | bt_config_component->type); |
351 | printf(":\n"); | |
3b6cfcc5 PP |
352 | |
353 | if (bt_config_component->instance_name->len > 0) { | |
354 | printf(" Name: %s\n", | |
355 | bt_config_component->instance_name->str); | |
356 | } | |
357 | ||
290725f7 PP |
358 | printf(" Parameters:\n"); |
359 | print_value(bt_config_component->params, 8); | |
c42c79ea PP |
360 | } |
361 | ||
362 | static | |
363 | void print_bt_config_components(GPtrArray *array) | |
364 | { | |
365 | size_t i; | |
366 | ||
367 | for (i = 0; i < array->len; i++) { | |
368 | struct bt_config_component *cfg_component = | |
e5bc7f81 | 369 | bt_config_get_component(array, i); |
c42c79ea PP |
370 | print_bt_config_component(cfg_component); |
371 | BT_PUT(cfg_component); | |
372 | } | |
373 | } | |
374 | ||
290725f7 PP |
375 | static |
376 | void print_plugin_paths(struct bt_value *plugin_paths) | |
377 | { | |
378 | printf(" Plugin paths:\n"); | |
379 | print_value(plugin_paths, 4); | |
380 | } | |
381 | ||
382 | static | |
db0f160a | 383 | void print_cfg_run(struct bt_config *cfg) |
290725f7 | 384 | { |
ebba3338 PP |
385 | size_t i; |
386 | ||
db0f160a | 387 | print_plugin_paths(cfg->plugin_paths); |
290725f7 | 388 | printf(" Source component instances:\n"); |
db0f160a | 389 | print_bt_config_components(cfg->cmd_data.run.sources); |
ebba3338 | 390 | |
db0f160a | 391 | if (cfg->cmd_data.run.filters->len > 0) { |
ebba3338 | 392 | printf(" Filter component instances:\n"); |
db0f160a | 393 | print_bt_config_components(cfg->cmd_data.run.filters); |
ebba3338 PP |
394 | } |
395 | ||
290725f7 | 396 | printf(" Sink component instances:\n"); |
db0f160a | 397 | print_bt_config_components(cfg->cmd_data.run.sinks); |
ebba3338 PP |
398 | printf(" Connections:\n"); |
399 | ||
db0f160a | 400 | for (i = 0; i < cfg->cmd_data.run.connections->len; i++) { |
ebba3338 | 401 | struct bt_config_connection *cfg_connection = |
db0f160a | 402 | g_ptr_array_index(cfg->cmd_data.run.connections, |
ebba3338 PP |
403 | i); |
404 | ||
405 | printf(" %s%s%s -> %s%s%s\n", | |
406 | cfg_connection->src_instance_name->str, | |
407 | cfg_connection->src_port_name->len > 0 ? "." : "", | |
408 | cfg_connection->src_port_name->str, | |
409 | cfg_connection->dst_instance_name->str, | |
410 | cfg_connection->dst_port_name->len > 0 ? "." : "", | |
411 | cfg_connection->dst_port_name->str); | |
412 | } | |
290725f7 PP |
413 | } |
414 | ||
415 | static | |
416 | void print_cfg_list_plugins(struct bt_config *cfg) | |
417 | { | |
db0f160a | 418 | print_plugin_paths(cfg->plugin_paths); |
290725f7 PP |
419 | } |
420 | ||
c1081aa6 PP |
421 | static |
422 | void print_cfg_help(struct bt_config *cfg) | |
423 | { | |
db0f160a PP |
424 | print_plugin_paths(cfg->plugin_paths); |
425 | } | |
426 | ||
427 | static | |
428 | void print_cfg_print_ctf_metadata(struct bt_config *cfg) | |
429 | { | |
430 | print_plugin_paths(cfg->plugin_paths); | |
431 | printf(" Path: %s\n", cfg->cmd_data.print_ctf_metadata.path->str); | |
432 | } | |
433 | ||
434 | static | |
435 | void print_cfg_print_lttng_live_sessions(struct bt_config *cfg) | |
436 | { | |
437 | print_plugin_paths(cfg->plugin_paths); | |
438 | printf(" URL: %s\n", cfg->cmd_data.print_lttng_live_sessions.url->str); | |
c1081aa6 PP |
439 | } |
440 | ||
441 | static | |
a67681c1 | 442 | void print_cfg_query(struct bt_config *cfg) |
c1081aa6 | 443 | { |
db0f160a | 444 | print_plugin_paths(cfg->plugin_paths); |
a67681c1 | 445 | printf(" Object: `%s`\n", cfg->cmd_data.query.object->str); |
c1081aa6 | 446 | printf(" Component class:\n"); |
a67681c1 | 447 | print_bt_config_component(cfg->cmd_data.query.cfg_component); |
c1081aa6 PP |
448 | } |
449 | ||
c42c79ea PP |
450 | static |
451 | void print_cfg(struct bt_config *cfg) | |
452 | { | |
00447e45 PP |
453 | if (!babeltrace_verbose) { |
454 | return; | |
455 | } | |
456 | ||
290725f7 PP |
457 | printf("Configuration:\n"); |
458 | printf(" Debug mode: %s\n", cfg->debug ? "yes" : "no"); | |
459 | printf(" Verbose mode: %s\n", cfg->verbose ? "yes" : "no"); | |
460 | ||
461 | switch (cfg->command) { | |
db0f160a PP |
462 | case BT_CONFIG_COMMAND_RUN: |
463 | print_cfg_run(cfg); | |
290725f7 PP |
464 | break; |
465 | case BT_CONFIG_COMMAND_LIST_PLUGINS: | |
466 | print_cfg_list_plugins(cfg); | |
c1081aa6 PP |
467 | break; |
468 | case BT_CONFIG_COMMAND_HELP: | |
469 | print_cfg_help(cfg); | |
470 | break; | |
a67681c1 PP |
471 | case BT_CONFIG_COMMAND_QUERY: |
472 | print_cfg_query(cfg); | |
290725f7 | 473 | break; |
db0f160a PP |
474 | case BT_CONFIG_COMMAND_PRINT_CTF_METADATA: |
475 | print_cfg_print_ctf_metadata(cfg); | |
476 | break; | |
477 | case BT_CONFIG_COMMAND_PRINT_LTTNG_LIVE_SESSIONS: | |
478 | print_cfg_print_lttng_live_sessions(cfg); | |
479 | break; | |
290725f7 PP |
480 | default: |
481 | assert(false); | |
482 | } | |
c42c79ea PP |
483 | } |
484 | ||
6c2f3ee5 JG |
485 | static |
486 | struct bt_component *create_trimmer(struct bt_config_component *source_cfg) | |
487 | { | |
488 | struct bt_component *trimmer = NULL; | |
489 | struct bt_component_class *trimmer_class = NULL; | |
490 | struct bt_value *trimmer_params = NULL; | |
528debdf | 491 | struct bt_value *value; |
6c2f3ee5 | 492 | |
6c2f3ee5 JG |
493 | trimmer_params = bt_value_map_create(); |
494 | if (!trimmer_params) { | |
495 | goto end; | |
496 | } | |
497 | ||
528debdf MD |
498 | value = bt_value_map_get(source_cfg->params, "begin"); |
499 | if (value) { | |
6c2f3ee5 | 500 | enum bt_value_status ret; |
6c2f3ee5 | 501 | |
528debdf | 502 | ret = bt_value_map_insert(trimmer_params, "begin", |
6c2f3ee5 JG |
503 | value); |
504 | BT_PUT(value); | |
505 | if (ret) { | |
506 | goto end; | |
507 | } | |
508 | } | |
528debdf MD |
509 | value = bt_value_map_get(source_cfg->params, "end"); |
510 | if (value) { | |
6c2f3ee5 | 511 | enum bt_value_status ret; |
6c2f3ee5 | 512 | |
528debdf MD |
513 | ret = bt_value_map_insert(trimmer_params, "end", |
514 | value); | |
515 | BT_PUT(value); | |
516 | if (ret) { | |
6c2f3ee5 JG |
517 | goto end; |
518 | } | |
528debdf MD |
519 | } |
520 | value = bt_value_map_get(source_cfg->params, "clock-gmt"); | |
521 | if (value) { | |
522 | enum bt_value_status ret; | |
6c2f3ee5 | 523 | |
528debdf | 524 | ret = bt_value_map_insert(trimmer_params, "clock-gmt", |
6c2f3ee5 JG |
525 | value); |
526 | BT_PUT(value); | |
527 | if (ret) { | |
528 | goto end; | |
529 | } | |
530 | } | |
531 | ||
33b34c43 | 532 | trimmer_class = find_component_class("utils", "trimmer", |
d3e4dcd8 | 533 | BT_COMPONENT_CLASS_TYPE_FILTER); |
6c2f3ee5 JG |
534 | if (!trimmer_class) { |
535 | fprintf(stderr, "Could not find trimmer component class. Aborting...\n"); | |
536 | goto end; | |
537 | } | |
538 | trimmer = bt_component_create(trimmer_class, "source_trimmer", | |
539 | trimmer_params); | |
540 | if (!trimmer) { | |
541 | goto end; | |
542 | } | |
543 | end: | |
544 | bt_put(trimmer_params); | |
545 | bt_put(trimmer_class); | |
546 | return trimmer; | |
547 | } | |
548 | ||
549 | static | |
61ddbc8a JG |
550 | int connect_source_sink(struct bt_graph *graph, |
551 | struct bt_component *source, | |
6c2f3ee5 JG |
552 | struct bt_config_component *source_cfg, |
553 | struct bt_component *sink) | |
554 | { | |
555 | int ret = 0; | |
61ddbc8a | 556 | struct bt_connection *connection = NULL; |
6c2f3ee5 | 557 | struct bt_component *trimmer = NULL; |
61ddbc8a JG |
558 | struct bt_port *source_port = |
559 | bt_component_source_get_default_output_port(source); | |
560 | struct bt_port *sink_port = | |
561 | bt_component_sink_get_default_input_port(sink); | |
562 | struct bt_port *to_sink_port = NULL; | |
563 | struct bt_port *trimmer_input_port = NULL; | |
564 | ||
565 | if (!source_port) { | |
566 | fprintf(stderr, "Failed to find default source output port. Aborting...\n"); | |
567 | ret = -1; | |
568 | goto end; | |
569 | } | |
570 | if (!sink_port) { | |
571 | fprintf(stderr, "Failed to find default sink input port. Aborting...\n"); | |
572 | ret = -1; | |
573 | goto end; | |
574 | } | |
6c2f3ee5 | 575 | |
528debdf MD |
576 | if (bt_value_map_has_key(source_cfg->params, "begin") |
577 | || bt_value_map_has_key(source_cfg->params, "end")) { | |
6c2f3ee5 | 578 | /* A trimmer must be inserted in the graph. */ |
6c2f3ee5 JG |
579 | trimmer = create_trimmer(source_cfg); |
580 | if (!trimmer) { | |
581 | fprintf(stderr, "Failed to create trimmer component. Aborting...\n"); | |
582 | ret = -1; | |
583 | goto end; | |
584 | } | |
585 | ||
61ddbc8a JG |
586 | trimmer_input_port = bt_component_filter_get_default_input_port( |
587 | trimmer); | |
588 | if (!trimmer_input_port) { | |
589 | fprintf(stderr, "Failed to find trimmer input port. Aborting...\n"); | |
590 | ret = -1; | |
591 | goto end; | |
592 | } | |
593 | to_sink_port = bt_component_filter_get_default_output_port( | |
594 | trimmer); | |
595 | if (!to_sink_port) { | |
596 | fprintf(stderr, "Failed to find trimmer output port. Aborting...\n"); | |
6c2f3ee5 JG |
597 | ret = -1; |
598 | goto end; | |
599 | } | |
600 | ||
77a54f99 | 601 | connection = bt_graph_connect_ports(graph, source_port, |
61ddbc8a JG |
602 | trimmer_input_port); |
603 | if (!connection) { | |
604 | fprintf(stderr, "Failed to connect source to trimmer. Aborting...\n"); | |
6c2f3ee5 JG |
605 | ret = -1; |
606 | goto end; | |
607 | } | |
61ddbc8a | 608 | BT_PUT(connection); |
6c2f3ee5 | 609 | } else { |
61ddbc8a | 610 | BT_MOVE(to_sink_port, source_port); |
6c2f3ee5 JG |
611 | } |
612 | ||
77a54f99 | 613 | connection = bt_graph_connect_ports(graph, to_sink_port, sink_port); |
61ddbc8a JG |
614 | if (!connection) { |
615 | fprintf(stderr, "Failed to connect to sink. Aborting...\n"); | |
6c2f3ee5 JG |
616 | ret = -1; |
617 | goto end; | |
618 | } | |
619 | end: | |
620 | bt_put(trimmer); | |
61ddbc8a JG |
621 | bt_put(source_port); |
622 | bt_put(sink_port); | |
623 | bt_put(to_sink_port); | |
624 | bt_put(connection); | |
6c2f3ee5 JG |
625 | return ret; |
626 | } | |
627 | ||
33b34c43 PP |
628 | static |
629 | void add_to_loaded_plugins(struct bt_plugin **plugins) | |
98ecef32 | 630 | { |
33b34c43 PP |
631 | while (*plugins) { |
632 | struct bt_plugin *plugin = *plugins; | |
633 | /* Check if it's already loaded (from another path). */ | |
634 | struct bt_plugin *loaded_plugin = | |
635 | find_plugin(bt_plugin_get_name(plugin)); | |
636 | ||
637 | if (loaded_plugin) { | |
638 | printf_verbose("Not loading plugin `%s`: already loaded from `%s`\n", | |
639 | bt_plugin_get_path(plugin), | |
640 | bt_plugin_get_path(loaded_plugin)); | |
641 | BT_PUT(loaded_plugin); | |
642 | BT_PUT(plugin); | |
643 | } else { | |
644 | /* Transfer ownership to global array. */ | |
645 | g_ptr_array_add(loaded_plugins, plugin); | |
646 | } | |
647 | *(plugins++) = NULL; | |
648 | } | |
649 | } | |
650 | ||
651 | static | |
290725f7 | 652 | int load_dynamic_plugins(struct bt_value *plugin_paths) |
33b34c43 PP |
653 | { |
654 | int nr_paths, i, ret = 0; | |
98ecef32 | 655 | |
290725f7 | 656 | nr_paths = bt_value_array_size(plugin_paths); |
98ecef32 | 657 | if (nr_paths < 0) { |
33b34c43 PP |
658 | ret = -1; |
659 | goto end; | |
98ecef32 | 660 | } |
33b34c43 | 661 | |
98ecef32 MD |
662 | for (i = 0; i < nr_paths; i++) { |
663 | struct bt_value *plugin_path_value = NULL; | |
664 | const char *plugin_path; | |
33b34c43 | 665 | struct bt_plugin **plugins; |
98ecef32 | 666 | |
290725f7 | 667 | plugin_path_value = bt_value_array_get(plugin_paths, i); |
98ecef32 MD |
668 | if (bt_value_string_get(plugin_path_value, |
669 | &plugin_path)) { | |
670 | BT_PUT(plugin_path_value); | |
671 | continue; | |
672 | } | |
33b34c43 | 673 | |
5a3ee633 | 674 | plugins = bt_plugin_create_all_from_dir(plugin_path, false); |
33b34c43 | 675 | if (!plugins) { |
98ecef32 MD |
676 | printf_debug("Unable to dynamically load plugins from path %s.\n", |
677 | plugin_path); | |
33b34c43 PP |
678 | BT_PUT(plugin_path_value); |
679 | continue; | |
98ecef32 | 680 | } |
33b34c43 PP |
681 | |
682 | add_to_loaded_plugins(plugins); | |
683 | free(plugins); | |
684 | ||
98ecef32 MD |
685 | BT_PUT(plugin_path_value); |
686 | } | |
33b34c43 PP |
687 | end: |
688 | return ret; | |
689 | } | |
690 | ||
691 | static | |
692 | int load_static_plugins(void) | |
693 | { | |
694 | int ret = 0; | |
695 | struct bt_plugin **plugins; | |
696 | ||
697 | plugins = bt_plugin_create_all_from_static(); | |
698 | if (!plugins) { | |
699 | printf_debug("Unable to load static plugins.\n"); | |
700 | ret = -1; | |
701 | goto end; | |
702 | } | |
703 | ||
704 | add_to_loaded_plugins(plugins); | |
705 | free(plugins); | |
706 | end: | |
707 | return ret; | |
98ecef32 MD |
708 | } |
709 | ||
290725f7 PP |
710 | static int load_all_plugins(struct bt_value *plugin_paths) |
711 | { | |
712 | int ret = 0; | |
33b34c43 | 713 | |
290725f7 PP |
714 | if (load_dynamic_plugins(plugin_paths)) { |
715 | fprintf(stderr, "Failed to load dynamic plugins.\n"); | |
716 | ret = -1; | |
c1870f57 JG |
717 | goto end; |
718 | } | |
719 | ||
290725f7 PP |
720 | if (load_static_plugins()) { |
721 | fprintf(stderr, "Failed to load static plugins.\n"); | |
722 | ret = -1; | |
c1870f57 JG |
723 | goto end; |
724 | } | |
725 | ||
290725f7 PP |
726 | end: |
727 | return ret; | |
728 | } | |
729 | ||
22e22462 PP |
730 | static void print_plugin_info(struct bt_plugin *plugin) |
731 | { | |
732 | unsigned int major, minor, patch; | |
733 | const char *extra; | |
734 | enum bt_plugin_status version_status; | |
735 | const char *plugin_name; | |
736 | const char *path; | |
737 | const char *author; | |
738 | const char *license; | |
739 | const char *plugin_description; | |
740 | ||
741 | plugin_name = bt_plugin_get_name(plugin); | |
742 | path = bt_plugin_get_path(plugin); | |
743 | author = bt_plugin_get_author(plugin); | |
744 | license = bt_plugin_get_license(plugin); | |
745 | plugin_description = bt_plugin_get_description(plugin); | |
746 | version_status = bt_plugin_get_version(plugin, &major, &minor, | |
747 | &patch, &extra); | |
748 | printf("%s%s%s%s:\n", bt_common_color_bold(), | |
749 | bt_common_color_fg_blue(), plugin_name, | |
750 | bt_common_color_reset()); | |
751 | printf(" %sPath%s: %s\n", bt_common_color_bold(), | |
752 | bt_common_color_reset(), path ? path : "(None)"); | |
753 | ||
754 | if (version_status == BT_PLUGIN_STATUS_OK) { | |
755 | printf(" %sVersion%s: %u.%u.%u", | |
756 | bt_common_color_bold(), bt_common_color_reset(), | |
757 | major, minor, patch); | |
758 | ||
759 | if (extra) { | |
760 | printf("%s", extra); | |
761 | } | |
762 | ||
763 | printf("\n"); | |
764 | } | |
765 | ||
766 | printf(" %sDescription%s: %s\n", bt_common_color_bold(), | |
767 | bt_common_color_reset(), | |
768 | plugin_description ? plugin_description : "(None)"); | |
769 | printf(" %sAuthor%s: %s\n", bt_common_color_bold(), | |
770 | bt_common_color_reset(), author ? author : "(Unknown)"); | |
771 | printf(" %sLicense%s: %s\n", bt_common_color_bold(), | |
772 | bt_common_color_reset(), | |
773 | license ? license : "(Unknown)"); | |
774 | } | |
775 | ||
a67681c1 | 776 | static int cmd_query(struct bt_config *cfg) |
63ce0e1d PP |
777 | { |
778 | int ret; | |
779 | struct bt_component_class *comp_cls = NULL; | |
780 | struct bt_value *results = NULL; | |
781 | ||
db0f160a | 782 | ret = load_all_plugins(cfg->plugin_paths); |
63ce0e1d PP |
783 | if (ret) { |
784 | goto end; | |
785 | } | |
786 | ||
a67681c1 | 787 | comp_cls = find_component_class(cfg->cmd_data.query.cfg_component->plugin_name->str, |
db0f160a | 788 | cfg->cmd_data.query.cfg_component->comp_cls_name->str, |
a67681c1 | 789 | cfg->cmd_data.query.cfg_component->type); |
63ce0e1d PP |
790 | if (!comp_cls) { |
791 | fprintf(stderr, "%s%sCannot find component class %s", | |
792 | bt_common_color_bold(), | |
793 | bt_common_color_fg_red(), | |
794 | bt_common_color_reset()); | |
795 | print_plugin_comp_cls_opt(stderr, | |
a67681c1 | 796 | cfg->cmd_data.query.cfg_component->plugin_name->str, |
db0f160a | 797 | cfg->cmd_data.query.cfg_component->comp_cls_name->str, |
a67681c1 | 798 | cfg->cmd_data.query.cfg_component->type); |
63ce0e1d PP |
799 | fprintf(stderr, "\n"); |
800 | ret = -1; | |
801 | goto end; | |
802 | } | |
803 | ||
a67681c1 PP |
804 | results = bt_component_class_query(comp_cls, |
805 | cfg->cmd_data.query.object->str, | |
806 | cfg->cmd_data.query.cfg_component->params); | |
63ce0e1d PP |
807 | if (!results) { |
808 | fprintf(stderr, "%s%sFailed to query info to %s", | |
809 | bt_common_color_bold(), | |
810 | bt_common_color_fg_red(), | |
811 | bt_common_color_reset()); | |
812 | print_plugin_comp_cls_opt(stderr, | |
a67681c1 | 813 | cfg->cmd_data.query.cfg_component->plugin_name->str, |
db0f160a | 814 | cfg->cmd_data.query.cfg_component->comp_cls_name->str, |
a67681c1 PP |
815 | cfg->cmd_data.query.cfg_component->type); |
816 | fprintf(stderr, "%s%s with object `%s`%s\n", | |
63ce0e1d PP |
817 | bt_common_color_bold(), |
818 | bt_common_color_fg_red(), | |
a67681c1 | 819 | cfg->cmd_data.query.object->str, |
63ce0e1d PP |
820 | bt_common_color_reset()); |
821 | ret = -1; | |
822 | goto end; | |
823 | } | |
824 | ||
825 | print_value(results, 0); | |
826 | ||
827 | end: | |
828 | bt_put(comp_cls); | |
829 | bt_put(results); | |
830 | return ret; | |
831 | } | |
832 | ||
22e22462 PP |
833 | static int cmd_help(struct bt_config *cfg) |
834 | { | |
835 | int ret; | |
836 | struct bt_plugin *plugin = NULL; | |
837 | size_t i; | |
838 | ||
db0f160a | 839 | ret = load_all_plugins(cfg->plugin_paths); |
22e22462 PP |
840 | if (ret) { |
841 | goto end; | |
842 | } | |
843 | ||
90de159b | 844 | plugin = find_plugin(cfg->cmd_data.help.cfg_component->plugin_name->str); |
22e22462 PP |
845 | if (!plugin) { |
846 | fprintf(stderr, "%s%sCannot find plugin %s%s%s\n", | |
847 | bt_common_color_bold(), bt_common_color_fg_red(), | |
848 | bt_common_color_fg_blue(), | |
90de159b | 849 | cfg->cmd_data.help.cfg_component->plugin_name->str, |
22e22462 PP |
850 | bt_common_color_reset()); |
851 | ret = -1; | |
852 | goto end; | |
853 | } | |
854 | ||
855 | print_plugin_info(plugin); | |
856 | printf(" %sComponent classes%s: %d\n", | |
857 | bt_common_color_bold(), | |
858 | bt_common_color_reset(), | |
859 | bt_plugin_get_component_class_count(plugin)); | |
860 | ||
861 | ||
90de159b | 862 | if (cfg->cmd_data.help.cfg_component->type != |
22e22462 PP |
863 | BT_COMPONENT_CLASS_TYPE_UNKNOWN) { |
864 | struct bt_component_class *needed_comp_cls = | |
865 | find_component_class( | |
90de159b | 866 | cfg->cmd_data.help.cfg_component->plugin_name->str, |
db0f160a | 867 | cfg->cmd_data.help.cfg_component->comp_cls_name->str, |
90de159b | 868 | cfg->cmd_data.help.cfg_component->type); |
22e22462 PP |
869 | |
870 | if (!needed_comp_cls) { | |
871 | fprintf(stderr, "\n%s%sCannot find component class %s", | |
872 | bt_common_color_bold(), | |
873 | bt_common_color_fg_red(), | |
874 | bt_common_color_reset()); | |
875 | print_plugin_comp_cls_opt(stderr, | |
90de159b | 876 | cfg->cmd_data.help.cfg_component->plugin_name->str, |
db0f160a | 877 | cfg->cmd_data.help.cfg_component->comp_cls_name->str, |
90de159b | 878 | cfg->cmd_data.help.cfg_component->type); |
22e22462 PP |
879 | fprintf(stderr, "\n"); |
880 | ret = -1; | |
881 | goto end; | |
882 | } | |
883 | ||
884 | bt_put(needed_comp_cls); | |
885 | } | |
886 | ||
887 | for (i = 0; i < bt_plugin_get_component_class_count(plugin); i++) { | |
888 | struct bt_component_class *comp_cls = | |
889 | bt_plugin_get_component_class(plugin, i); | |
890 | const char *comp_class_name = | |
891 | bt_component_class_get_name(comp_cls); | |
892 | const char *comp_class_description = | |
893 | bt_component_class_get_description(comp_cls); | |
894 | const char *comp_class_help = | |
895 | bt_component_class_get_help(comp_cls); | |
896 | enum bt_component_class_type type = | |
897 | bt_component_class_get_type(comp_cls); | |
898 | ||
899 | assert(comp_cls); | |
900 | ||
90de159b | 901 | if (cfg->cmd_data.help.cfg_component->type != |
22e22462 | 902 | BT_COMPONENT_CLASS_TYPE_UNKNOWN) { |
db0f160a | 903 | if (strcmp(cfg->cmd_data.help.cfg_component->comp_cls_name->str, |
22e22462 PP |
904 | comp_class_name) != 0 && |
905 | type == | |
90de159b | 906 | cfg->cmd_data.help.cfg_component->type) { |
22e22462 PP |
907 | bt_put(comp_cls); |
908 | continue; | |
909 | } | |
910 | } | |
911 | ||
912 | printf("\n"); | |
913 | print_plugin_comp_cls_opt(stdout, | |
90de159b | 914 | cfg->cmd_data.help.cfg_component->plugin_name->str, |
22e22462 PP |
915 | comp_class_name, |
916 | type); | |
917 | printf("\n"); | |
918 | printf(" %sDescription%s: %s\n", bt_common_color_bold(), | |
919 | bt_common_color_reset(), | |
920 | comp_class_description ? comp_class_description : "(None)"); | |
921 | ||
922 | if (comp_class_help) { | |
923 | printf("\n%s\n", comp_class_help); | |
924 | } | |
925 | ||
926 | bt_put(comp_cls); | |
927 | } | |
928 | ||
929 | end: | |
930 | bt_put(plugin); | |
931 | return ret; | |
932 | } | |
933 | ||
290725f7 PP |
934 | static int cmd_list_plugins(struct bt_config *cfg) |
935 | { | |
936 | int ret; | |
937 | int plugins_count, component_classes_count = 0, i; | |
938 | ||
db0f160a | 939 | ret = load_all_plugins(cfg->plugin_paths); |
290725f7 | 940 | if (ret) { |
56a1cced JG |
941 | goto end; |
942 | } | |
943 | ||
22e22462 | 944 | printf("From the following plugin paths:\n\n"); |
db0f160a | 945 | print_value(cfg->plugin_paths, 2); |
22e22462 | 946 | printf("\n"); |
290725f7 PP |
947 | plugins_count = loaded_plugins->len; |
948 | if (plugins_count == 0) { | |
949 | fprintf(stderr, "%s%sNo plugins found.%s\n", | |
950 | bt_common_color_bold(), bt_common_color_fg_red(), | |
951 | bt_common_color_reset()); | |
952 | fprintf(stderr, "\n"); | |
953 | fprintf(stderr, "Please make sure your plugin search path is set correctly. You can use\n"); | |
954 | fprintf(stderr, "the --plugin-path command-line option or the BABELTRACE_PLUGIN_PATH\n"); | |
955 | fprintf(stderr, "environment variable.\n"); | |
56a1cced JG |
956 | ret = -1; |
957 | goto end; | |
958 | } | |
959 | ||
290725f7 PP |
960 | for (i = 0; i < plugins_count; i++) { |
961 | struct bt_plugin *plugin = g_ptr_array_index(loaded_plugins, i); | |
962 | ||
963 | component_classes_count += bt_plugin_get_component_class_count(plugin); | |
964 | } | |
33bceaf8 | 965 | |
290725f7 PP |
966 | printf("Found %s%d%s component classes in %s%d%s plugins.\n", |
967 | bt_common_color_bold(), | |
968 | component_classes_count, | |
969 | bt_common_color_reset(), | |
970 | bt_common_color_bold(), | |
971 | plugins_count, | |
972 | bt_common_color_reset()); | |
973 | ||
974 | for (i = 0; i < plugins_count; i++) { | |
975 | int j; | |
976 | struct bt_plugin *plugin = g_ptr_array_index(loaded_plugins, i); | |
290725f7 PP |
977 | |
978 | component_classes_count = | |
979 | bt_plugin_get_component_class_count(plugin); | |
22e22462 PP |
980 | printf("\n"); |
981 | print_plugin_info(plugin); | |
290725f7 PP |
982 | |
983 | if (component_classes_count == 0) { | |
984 | printf(" %sComponent classes%s: (None)\n", | |
985 | bt_common_color_bold(), | |
986 | bt_common_color_reset()); | |
987 | } else { | |
988 | printf(" %sComponent classes%s:\n", | |
989 | bt_common_color_bold(), | |
990 | bt_common_color_reset()); | |
991 | } | |
992 | ||
993 | for (j = 0; j < component_classes_count; j++) { | |
994 | struct bt_component_class *comp_class = | |
995 | bt_plugin_get_component_class(plugin, j); | |
996 | const char *comp_class_name = | |
997 | bt_component_class_get_name(comp_class); | |
998 | const char *comp_class_description = | |
999 | bt_component_class_get_description(comp_class); | |
1000 | enum bt_component_class_type type = | |
1001 | bt_component_class_get_type(comp_class); | |
1002 | ||
22e22462 PP |
1003 | printf(" "); |
1004 | print_plugin_comp_cls_opt(stdout, | |
1005 | bt_plugin_get_name(plugin), comp_class_name, | |
1006 | type); | |
290725f7 PP |
1007 | |
1008 | if (comp_class_description) { | |
1009 | printf(": %s", comp_class_description); | |
1010 | } | |
1011 | ||
1012 | printf("\n"); | |
1013 | bt_put(comp_class); | |
1014 | } | |
1015 | } | |
1016 | ||
1017 | end: | |
1018 | return ret; | |
1019 | } | |
1020 | ||
db0f160a PP |
1021 | static int cmd_print_lttng_live_sessions(struct bt_config *cfg) |
1022 | { | |
1023 | printf("TODO\n"); | |
1024 | return -1; | |
1025 | } | |
1026 | ||
1027 | static int cmd_print_ctf_metadata(struct bt_config *cfg) | |
05a67631 PP |
1028 | { |
1029 | int ret = 0; | |
1030 | struct bt_component_class *comp_cls = NULL; | |
05a67631 | 1031 | struct bt_value *results = NULL; |
05a67631 PP |
1032 | struct bt_value *params = NULL; |
1033 | struct bt_value *metadata_text_value = NULL; | |
1034 | const char *metadata_text = NULL; | |
db0f160a PP |
1035 | static const char * const plugin_name = "ctf"; |
1036 | static const char * const comp_cls_name = "fs"; | |
1037 | static const enum bt_component_class_type comp_cls_type = | |
1038 | BT_COMPONENT_CLASS_TYPE_SOURCE; | |
1039 | ||
1040 | assert(cfg->cmd_data.print_ctf_metadata.path); | |
1041 | comp_cls = find_component_class(plugin_name, comp_cls_name, | |
1042 | comp_cls_type); | |
05a67631 PP |
1043 | if (!comp_cls) { |
1044 | fprintf(stderr, "%s%sCannot find component class %s", | |
1045 | bt_common_color_bold(), | |
1046 | bt_common_color_fg_red(), | |
1047 | bt_common_color_reset()); | |
db0f160a PP |
1048 | print_plugin_comp_cls_opt(stderr, plugin_name, |
1049 | comp_cls_name, comp_cls_type); | |
05a67631 PP |
1050 | fprintf(stderr, "\n"); |
1051 | ret = -1; | |
1052 | goto end; | |
1053 | } | |
1054 | ||
05a67631 PP |
1055 | params = bt_value_map_create(); |
1056 | if (!params) { | |
1057 | ret = -1; | |
1058 | goto end; | |
1059 | } | |
1060 | ||
db0f160a PP |
1061 | ret = bt_value_map_insert_string(params, "path", |
1062 | cfg->cmd_data.print_ctf_metadata.path->str); | |
05a67631 PP |
1063 | if (ret) { |
1064 | ret = -1; | |
1065 | goto end; | |
1066 | } | |
1067 | ||
a67681c1 | 1068 | results = bt_component_class_query(comp_cls, "metadata-info", |
05a67631 PP |
1069 | params); |
1070 | if (!results) { | |
1071 | ret = -1; | |
a67681c1 | 1072 | fprintf(stderr, "%s%sFailed to request metadata info%s\n", |
05a67631 PP |
1073 | bt_common_color_bold(), |
1074 | bt_common_color_fg_red(), | |
1075 | bt_common_color_reset()); | |
1076 | goto end; | |
1077 | } | |
1078 | ||
1079 | metadata_text_value = bt_value_map_get(results, "text"); | |
1080 | if (!metadata_text_value) { | |
1081 | ret = -1; | |
1082 | goto end; | |
1083 | } | |
1084 | ||
1085 | ret = bt_value_string_get(metadata_text_value, &metadata_text); | |
1086 | assert(ret == 0); | |
1087 | printf("%s\n", metadata_text); | |
1088 | ||
1089 | end: | |
1090 | bt_put(results); | |
05a67631 PP |
1091 | bt_put(params); |
1092 | bt_put(metadata_text_value); | |
1093 | bt_put(comp_cls); | |
05a67631 PP |
1094 | return 0; |
1095 | } | |
1096 | ||
db0f160a | 1097 | static int cmd_run(struct bt_config *cfg) |
290725f7 PP |
1098 | { |
1099 | int ret = 0; | |
1100 | struct bt_component_class *source_class = NULL; | |
1101 | struct bt_component_class *sink_class = NULL; | |
1102 | struct bt_component *source = NULL, *sink = NULL; | |
1103 | struct bt_value *source_params = NULL, *sink_params = NULL; | |
290725f7 | 1104 | struct bt_config_component *source_cfg = NULL, *sink_cfg = NULL; |
61ddbc8a | 1105 | struct bt_graph *graph = NULL; |
290725f7 | 1106 | |
db0f160a | 1107 | ret = load_all_plugins(cfg->plugin_paths); |
05a67631 | 1108 | if (ret) { |
05a67631 PP |
1109 | goto end; |
1110 | } | |
1111 | ||
290725f7 | 1112 | /* TODO handle more than 1 source and 1 sink. */ |
db0f160a PP |
1113 | if (cfg->cmd_data.run.sources->len != 1 || |
1114 | cfg->cmd_data.run.sinks->len != 1) { | |
ebba3338 | 1115 | fprintf(stderr, "Only one source and one sink component class are supported. Aborting...\n"); |
98ecef32 MD |
1116 | ret = -1; |
1117 | goto end; | |
33bceaf8 JG |
1118 | } |
1119 | ||
db0f160a | 1120 | source_cfg = bt_config_get_component(cfg->cmd_data.run.sources, 0); |
e5bc7f81 | 1121 | source_params = bt_get(source_cfg->params); |
33b34c43 | 1122 | source_class = find_component_class(source_cfg->plugin_name->str, |
db0f160a | 1123 | source_cfg->comp_cls_name->str, |
d3e4dcd8 | 1124 | BT_COMPONENT_CLASS_TYPE_SOURCE); |
56a1cced | 1125 | if (!source_class) { |
87796884 PP |
1126 | fprintf(stderr, "Could not find "); |
1127 | print_plugin_comp_cls_opt(stderr, source_cfg->plugin_name->str, | |
db0f160a | 1128 | source_cfg->comp_cls_name->str, BT_COMPONENT_CLASS_TYPE_SOURCE); |
87796884 | 1129 | fprintf(stderr, ". Aborting...\n"); |
56a1cced JG |
1130 | ret = -1; |
1131 | goto end; | |
1132 | } | |
7c7c0433 | 1133 | |
db0f160a | 1134 | sink_cfg = bt_config_get_component(cfg->cmd_data.run.sinks, 0); |
e5bc7f81 | 1135 | sink_params = bt_get(sink_cfg->params); |
33b34c43 | 1136 | sink_class = find_component_class(sink_cfg->plugin_name->str, |
db0f160a | 1137 | sink_cfg->comp_cls_name->str, |
d3e4dcd8 | 1138 | BT_COMPONENT_CLASS_TYPE_SINK); |
7c7c0433 | 1139 | if (!sink_class) { |
87796884 PP |
1140 | fprintf(stderr, "Could not find "); |
1141 | print_plugin_comp_cls_opt(stderr, sink_cfg->plugin_name->str, | |
db0f160a | 1142 | sink_cfg->comp_cls_name->str, BT_COMPONENT_CLASS_TYPE_SINK); |
87796884 | 1143 | fprintf(stderr, ". Aborting...\n"); |
7c7c0433 JG |
1144 | ret = -1; |
1145 | goto end; | |
1146 | } | |
1147 | ||
61ddbc8a JG |
1148 | graph = bt_graph_create(); |
1149 | if (!graph) { | |
1150 | ret = -1; | |
1151 | goto end; | |
1152 | } | |
1153 | ||
e5bc7f81 | 1154 | source = bt_component_create(source_class, "source", source_params); |
56a1cced | 1155 | if (!source) { |
e5bc7f81 | 1156 | fprintf(stderr, "Failed to instantiate selected source component. Aborting...\n"); |
c42c79ea PP |
1157 | ret = -1; |
1158 | goto end; | |
1159 | } | |
56a1cced | 1160 | |
e5bc7f81 | 1161 | sink = bt_component_create(sink_class, "sink", sink_params); |
7c7c0433 | 1162 | if (!sink) { |
e5bc7f81 | 1163 | fprintf(stderr, "Failed to instantiate selected output component. Aborting...\n"); |
7c7c0433 | 1164 | ret = -1; |
2e339de1 JG |
1165 | goto end; |
1166 | } | |
1167 | ||
61ddbc8a | 1168 | ret = connect_source_sink(graph, source, source_cfg, sink); |
6c2f3ee5 | 1169 | if (ret) { |
290725f7 | 1170 | ret = -1; |
fec2a9f2 JG |
1171 | goto end; |
1172 | } | |
78586d8a | 1173 | |
fec2a9f2 | 1174 | while (true) { |
61ddbc8a JG |
1175 | enum bt_graph_status graph_status; |
1176 | ||
72b913fb | 1177 | graph_status = bt_graph_run(graph); |
61ddbc8a JG |
1178 | switch (graph_status) { |
1179 | case BT_GRAPH_STATUS_AGAIN: | |
fec2a9f2 JG |
1180 | /* Wait for an arbitraty 500 ms. */ |
1181 | usleep(500000); | |
78586d8a | 1182 | break; |
fec2a9f2 JG |
1183 | case BT_COMPONENT_STATUS_END: |
1184 | goto end; | |
1185 | default: | |
1186 | fprintf(stderr, "Sink component returned an error, aborting...\n"); | |
1187 | ret = -1; | |
1188 | goto end; | |
78586d8a | 1189 | } |
fec2a9f2 | 1190 | } |
290725f7 | 1191 | |
11e1d048 | 1192 | end: |
61ddbc8a JG |
1193 | bt_put(sink_class); |
1194 | bt_put(source_class); | |
1195 | bt_put(source); | |
1196 | bt_put(sink); | |
1197 | bt_put(source_params); | |
1198 | bt_put(sink_params); | |
1199 | bt_put(sink_cfg); | |
1200 | bt_put(source_cfg); | |
1201 | bt_put(graph); | |
290725f7 PP |
1202 | return ret; |
1203 | } | |
1204 | ||
1205 | static void warn_command_name_and_directory_clash(struct bt_config *cfg) | |
1206 | { | |
1207 | if (!cfg->command_name) { | |
1208 | return; | |
1209 | } | |
1210 | ||
1211 | if (g_file_test(cfg->command_name, | |
1212 | G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)) { | |
1213 | fprintf(stderr, "\nNOTE: The `%s` command was executed. If you meant to convert a\n", | |
1214 | cfg->command_name); | |
1215 | fprintf(stderr, "trace located in the local `%s` directory, please use:\n", | |
1216 | cfg->command_name); | |
1217 | fprintf(stderr, "\n"); | |
1218 | fprintf(stderr, " babeltrace convert %s [OPTIONS]\n", | |
1219 | cfg->command_name); | |
1220 | } | |
1221 | } | |
1222 | ||
1223 | int main(int argc, const char **argv) | |
1224 | { | |
1225 | int ret; | |
1226 | int retcode; | |
1227 | struct bt_config *cfg; | |
1228 | ||
1229 | init_loaded_plugins_array(); | |
1230 | cfg = bt_config_from_args_with_defaults(argc, argv, &retcode); | |
1231 | ||
1232 | if (retcode < 0) { | |
1233 | /* Quit without errors; typically usage/version */ | |
1234 | retcode = 0; | |
1235 | goto end; | |
1236 | } | |
1237 | ||
1238 | if (retcode > 0) { | |
1239 | goto end; | |
1240 | } | |
1241 | ||
1242 | if (!cfg) { | |
1243 | fprintf(stderr, "Failed to create Babeltrace configuration\n"); | |
db0f160a | 1244 | retcode = 1; |
290725f7 PP |
1245 | goto end; |
1246 | } | |
1247 | ||
1248 | babeltrace_debug = cfg->debug; | |
1249 | babeltrace_verbose = cfg->verbose; | |
1250 | print_cfg(cfg); | |
1251 | ||
db0f160a PP |
1252 | if (cfg->command_needs_plugins) { |
1253 | ret = load_all_plugins(cfg->plugin_paths); | |
1254 | if (ret) { | |
1255 | retcode = 1; | |
1256 | goto end; | |
1257 | } | |
1258 | } | |
1259 | ||
290725f7 | 1260 | switch (cfg->command) { |
db0f160a PP |
1261 | case BT_CONFIG_COMMAND_RUN: |
1262 | ret = cmd_run(cfg); | |
290725f7 PP |
1263 | break; |
1264 | case BT_CONFIG_COMMAND_LIST_PLUGINS: | |
1265 | ret = cmd_list_plugins(cfg); | |
1266 | break; | |
22e22462 PP |
1267 | case BT_CONFIG_COMMAND_HELP: |
1268 | ret = cmd_help(cfg); | |
1269 | break; | |
a67681c1 PP |
1270 | case BT_CONFIG_COMMAND_QUERY: |
1271 | ret = cmd_query(cfg); | |
63ce0e1d | 1272 | break; |
db0f160a PP |
1273 | case BT_CONFIG_COMMAND_PRINT_CTF_METADATA: |
1274 | ret = cmd_print_ctf_metadata(cfg); | |
1275 | break; | |
1276 | case BT_CONFIG_COMMAND_PRINT_LTTNG_LIVE_SESSIONS: | |
1277 | ret = cmd_print_lttng_live_sessions(cfg); | |
1278 | break; | |
290725f7 PP |
1279 | default: |
1280 | assert(false); | |
1281 | } | |
1282 | ||
1283 | warn_command_name_and_directory_clash(cfg); | |
1284 | retcode = ret ? 1 : 0; | |
1285 | ||
1286 | end: | |
1287 | BT_PUT(cfg); | |
33b34c43 | 1288 | fini_loaded_plugins_array(); |
290725f7 | 1289 | return retcode; |
4c8bfb7e | 1290 | } |