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