cli: apply parameters (`--params` option) to leftovers
[babeltrace.git] / src / cli / babeltrace2-cfg-src-auto-disc.c
CommitLineData
a1040187
SM
1/*
2 * Copyright (c) 2019 EfficiOS Inc. and Linux Foundation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 * SOFTWARE.
21 */
22
23#define BT_LOG_TAG "CLI-CFG-SRC-AUTO-DISC"
24#include "logging.h"
25
26#include "babeltrace2-cfg-src-auto-disc.h"
27#include "babeltrace2-plugins.h"
bf403eb2 28#include "babeltrace2-query.h"
a1040187
SM
29#include "common/common.h"
30
31/* Finalize and free a `struct auto_source_discovery_result`. */
32
33static
34void auto_source_discovery_result_destroy(struct auto_source_discovery_result *res)
35{
36 if (res) {
37 g_free(res->group);
38 bt_value_put_ref(res->inputs);
39 g_free(res);
40 }
41}
42
43/* Allocate and initialize a `struct auto_source_discovery_result`. */
44
45static
46struct auto_source_discovery_result *auto_source_discovery_result_create(
47 const char *plugin_name, const char *source_cc_name,
48 const char *group)
49{
50 struct auto_source_discovery_result *res;
51
52 res = g_new0(struct auto_source_discovery_result, 1);
53 if (!res) {
54 BT_CLI_LOGE_APPEND_CAUSE(
55 "Failed to allocate a auto_source_discovery_result structure.");
56 goto error;
57 }
58
59 res->plugin_name = plugin_name;
60 res->source_cc_name = source_cc_name;
61 res->group = g_strdup(group);
62 if (group && !res->group) {
63 BT_CLI_LOGE_APPEND_CAUSE("Failed to allocate a string.");
64 goto error;
65 }
66
67 res->inputs = bt_value_array_create();
68 if (!res->inputs) {
69 BT_CLI_LOGE_APPEND_CAUSE("Failed to allocate an array value.");
70 goto error;
71 }
72
459f81ca
SM
73 res->original_input_indices = bt_value_array_create();
74 if (!res->original_input_indices) {
75 BT_CLI_LOGE_APPEND_CAUSE("Failed to allocate an array value.");
76 goto error;
77 }
78
a1040187
SM
79 goto end;
80error:
81 auto_source_discovery_result_destroy(res);
82
83end:
84 return res;
85}
86
87/* Finalize a `struct auto_source_discovery`. */
88
89void auto_source_discovery_fini(struct auto_source_discovery *auto_disc)
90{
91 if (auto_disc->results) {
92 g_ptr_array_free(auto_disc->results, TRUE);
93 }
94}
95
96/* Initialize an already allocated `struct auto_source_discovery`. */
97
98int auto_source_discovery_init(struct auto_source_discovery *auto_disc)
99{
100 int status;
101
102 auto_disc->results = g_ptr_array_new_with_free_func(
103 (GDestroyNotify) auto_source_discovery_result_destroy);
104
105 if (!auto_disc->results) {
106 goto error;
107 }
108
109 status = 0;
110 goto end;
111
112error:
113 auto_source_discovery_fini(auto_disc);
114 status = -1;
115
116end:
117
118 return status;
119}
120
459f81ca
SM
121static
122const bt_value *borrow_array_value_last_element_const(const bt_value *array)
123{
124 uint64_t last_index = bt_value_array_get_size(array) - 1;
125
126 return bt_value_array_borrow_element_by_index_const(array, last_index);
127}
128
a1040187
SM
129/*
130 * Assign `input` to source component class `source_cc_name` of plugin
131 * `plugin_name`, in the group with key `group`.
132 */
133
134static
135int auto_source_discovery_add(struct auto_source_discovery *auto_disc,
136 const char *plugin_name,
137 const char *source_cc_name,
138 const char *group,
459f81ca
SM
139 const char *input,
140 uint64_t original_input_index)
a1040187
SM
141{
142 int status;
143 bt_value_array_append_element_status append_status;
144 guint len;
145 guint i;
146 struct auto_source_discovery_result *res = NULL;
459f81ca 147 bool append_index;
a1040187
SM
148
149 len = auto_disc->results->len;
150 i = len;
151
152 if (group) {
153 for (i = 0; i < len; i++) {
154 res = g_ptr_array_index(auto_disc->results, i);
155
156 if (strcmp(res->plugin_name, plugin_name) != 0) {
157 continue;
158 }
159
160 if (strcmp(res->source_cc_name, source_cc_name) != 0) {
161 continue;
162 }
163
164 if (g_strcmp0(res->group, group) != 0) {
165 continue;
166 }
167
168 break;
169 }
170 }
171
172 if (i == len) {
173 /* Add a new result entry. */
174 res = auto_source_discovery_result_create(plugin_name,
175 source_cc_name, group);
176 if (!res) {
177 goto error;
178 }
179
180 g_ptr_array_add(auto_disc->results, res);
181 }
182
183 append_status = bt_value_array_append_string_element(res->inputs, input);
184 if (append_status != BT_VALUE_ARRAY_APPEND_ELEMENT_STATUS_OK) {
185 BT_CLI_LOGE_APPEND_CAUSE("Failed to append a string value.");
186 goto error;
187 }
188
459f81ca
SM
189 /*
190 * Append `original_input_index` to `original_input_indices` if not
191 * there already. We process the `inputs` array in order, so if it is
192 * present, it has to be the last element.
193 */
194 if (bt_value_array_is_empty(res->original_input_indices)) {
195 append_index = true;
196 } else {
197 const bt_value *last_index_value;
198 uint64_t last_index;
199
200 last_index_value =
201 borrow_array_value_last_element_const(res->original_input_indices);
202 last_index = bt_value_integer_unsigned_get(last_index_value);
203
204 BT_ASSERT(last_index <= original_input_index);
205
206 append_index = (last_index != original_input_index);
207 }
208
209 if (append_index) {
210 append_status = bt_value_array_append_unsigned_integer_element(
211 res->original_input_indices, original_input_index);
212
213 if (append_status != BT_VALUE_ARRAY_APPEND_ELEMENT_STATUS_OK) {
214 BT_CLI_LOGE_APPEND_CAUSE("Failed to append an unsigned integer value.");
215 goto error;
216 }
217 }
a1040187
SM
218
219 status = 0;
220 goto end;
221
222error:
223 status = -1;
224
225end:
226 return status;
227}
228
229static
230int convert_weight_value(const bt_value *weight_value, double *weight,
231 const char *plugin_name, const char *source_cc_name,
232 const char *input, const char *input_type)
233{
234 enum bt_value_type weight_value_type;
235 int status;
236
237 weight_value_type = bt_value_get_type(weight_value);
238
239 if (weight_value_type == BT_VALUE_TYPE_REAL) {
240 *weight = bt_value_real_get(weight_value);
241 } else if (weight_value_type == BT_VALUE_TYPE_SIGNED_INTEGER) {
242 /* Accept signed integer as a convenience for "return 0" or "return 1" in Python. */
243 *weight = bt_value_integer_signed_get(weight_value);
244 } else {
9e534aae 245 BT_LOGW("babeltrace.support-info query: unexpected type for weight: "
a1040187
SM
246 "component-class-name=source.%s.%s, input=%s, input-type=%s, "
247 "expected-entry-type=%s, actual-entry-type=%s",
248 plugin_name, source_cc_name, input, input_type,
249 bt_common_value_type_string(BT_VALUE_TYPE_REAL),
250 bt_common_value_type_string(bt_value_get_type(weight_value)));
251 goto error;
252 }
253
254 if (*weight < 0.0 || *weight > 1.0) {
9e534aae 255 BT_LOGW("babeltrace.support-info query: weight value is out of range [0.0, 1.0]: "
a1040187
SM
256 "component-class-name=source.%s.%s, input=%s, input-type=%s, "
257 "weight=%f",
258 plugin_name, source_cc_name, input, input_type, *weight);
259 goto error;
260 }
261
262 status = 0;
263 goto end;
264
265error:
266 status = -1;
267
268end:
269 return status;
270}
271
272/*
273 * Query all known source components to see if any of them can handle `input`
274 * as the given `type`(arbitrary string, directory or file).
275 *
276 * If `plugin_restrict` is non-NULL, only query source component classes provided
277 * by the plugin with that name.
278 *
279 * If `component_class_restrict` is non-NULL, only query source component classes
280 * with that name.
281 *
282 * Return:
283 *
284 * - > 0 on success, if no source component class has reported that it handles `input`
285 * - 0 on success, if a source component class has reported that it handles `input`
286 * - < 0 on failure (e.g. memory error)
287 */
288static
289int support_info_query_all_sources(const char *input,
459f81ca
SM
290 const char *input_type,
291 uint64_t original_input_index,
292 size_t plugin_count,
a1040187
SM
293 const char *plugin_restrict,
294 const char *component_class_restrict,
295 enum bt_logging_level log_level,
296 struct auto_source_discovery *auto_disc)
297{
298 bt_value_map_insert_entry_status insert_status;
299 bt_value *query_params = NULL;
300 int status;
301 size_t i_plugins;
302 const struct bt_value *query_result = NULL;
303 struct {
304 const bt_component_class_source *source;
305 const bt_plugin *plugin;
306 const bt_value *group;
307 double weigth;
308 } winner = { NULL, NULL, NULL, 0 };
309
310 query_params = bt_value_map_create();
311 if (!query_params) {
312 BT_CLI_LOGE_APPEND_CAUSE("Failed to allocate a map value.");
313 goto error;
314 }
315
316 insert_status = bt_value_map_insert_string_entry(query_params, "input", input);
317 if (insert_status != BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK) {
318 BT_CLI_LOGE_APPEND_CAUSE("Failed to insert a map entry.");
319 goto error;
320 }
321
322 insert_status = bt_value_map_insert_string_entry(query_params, "type", input_type);
323 if (insert_status != BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK) {
324 BT_CLI_LOGE_APPEND_CAUSE("Failed to insert a map entry.");
325 goto error;
326 }
327
328 for (i_plugins = 0; i_plugins < plugin_count; i_plugins++) {
329 const bt_plugin *plugin;
330 const char *plugin_name;
331 uint64_t source_count;
332 uint64_t i_sources;
333
334 plugin = borrow_loaded_plugin(i_plugins);
335 plugin_name = bt_plugin_get_name(plugin);
336
337 /*
338 * If the search is restricted to a specific plugin, only consider
339 * the plugin with that name.
340 */
341 if (plugin_restrict && strcmp(plugin_restrict, plugin_name) != 0) {
342 continue;
343 }
344
345 source_count = bt_plugin_get_source_component_class_count(plugin);
346
347 for (i_sources = 0; i_sources < source_count; i_sources++) {
348 const bt_component_class_source *source_cc;
349 const bt_component_class *cc;
350 const char *source_cc_name;
351 bt_query_executor_query_status query_status;
352
353 source_cc = bt_plugin_borrow_source_component_class_by_index_const(plugin, i_sources);
354 cc = bt_component_class_source_as_component_class_const(source_cc);
355 source_cc_name = bt_component_class_get_name(cc);
356
357 /*
358 * If the search is restricted to a specific component class, only consider the
359 * component classes with that name.
360 */
361 if (component_class_restrict && strcmp(component_class_restrict, source_cc_name) != 0) {
362 continue;
363 }
364
9e534aae 365 BT_LOGD("babeltrace.support-info query: before: component-class-name=source.%s.%s, input=%s, "
a1040187
SM
366 "type=%s", plugin_name, source_cc_name, input, input_type);
367
368 BT_VALUE_PUT_REF_AND_RESET(query_result);
bf403eb2
PP
369 query_status = cli_query(cc, "babeltrace.support-info",
370 query_params, log_level, NULL, &query_result,
371 NULL);
a1040187
SM
372
373 if (query_status == BT_QUERY_EXECUTOR_QUERY_STATUS_OK) {
374 double weight;
375 const bt_value *group_value = NULL;
376 enum bt_value_type query_result_type;
377
378 BT_ASSERT(query_result);
379
380 query_result_type = bt_value_get_type(query_result);
381
382 if (query_result_type == BT_VALUE_TYPE_REAL || query_result_type == BT_VALUE_TYPE_SIGNED_INTEGER) {
383 if (convert_weight_value(query_result, &weight, plugin_name, source_cc_name, input, input_type) != 0) {
384 /* convert_weight_value has already warned. */
385 continue;
386 }
387 } else if (query_result_type == BT_VALUE_TYPE_MAP) {
388 const bt_value *weight_value;
389
390 if (!bt_value_map_has_entry(query_result, "weight")) {
9e534aae 391 BT_LOGW("babeltrace.support-info query: result is missing `weight` entry: "
a1040187
SM
392 "component-class-name=source.%s.%s, input=%s, input-type=%s",
393 bt_plugin_get_name(plugin),
394 bt_component_class_get_name(cc), input,
395 input_type);
396 continue;
397 }
398
399 weight_value = bt_value_map_borrow_entry_value_const(query_result, "weight");
400 BT_ASSERT(weight_value);
401
402 if (convert_weight_value(weight_value, &weight, plugin_name, source_cc_name, input, input_type) != 0) {
403 /* convert_weight_value has already warned. */
404 continue;
405 }
406
407 if (bt_value_map_has_entry(query_result, "group")) {
408 enum bt_value_type group_value_type;
409
410 group_value = bt_value_map_borrow_entry_value_const(query_result, "group");
411 BT_ASSERT(group_value);
412
413 group_value_type = bt_value_get_type(group_value);
414
415 if (group_value_type == BT_VALUE_TYPE_NULL) {
416 /* Do as if no value was passed. */
417 group_value = NULL;
418 } else if (bt_value_get_type(group_value) != BT_VALUE_TYPE_STRING) {
9e534aae 419 BT_LOGW("babeltrace.support-info query: unexpected type for entry `group`: "
a1040187
SM
420 "component-class-name=source.%s.%s, input=%s, input-type=%s, "
421 "expected-entry-type=%s,%s, actual-entry-type=%s",
422 bt_plugin_get_name(plugin),
423 bt_component_class_get_name(cc), input,
424 input_type,
425 bt_common_value_type_string(BT_VALUE_TYPE_NULL),
426 bt_common_value_type_string(BT_VALUE_TYPE_STRING),
427 bt_common_value_type_string(bt_value_get_type(group_value)));
428 continue;
429 }
430 }
431 } else {
9e534aae 432 BT_LOGW("babeltrace.support-info query: unexpected result type: "
a1040187
SM
433 "component-class-name=source.%s.%s, input=%s, input-type=%s, "
434 "expected-types=%s,%s,%s, actual-type=%s",
435 bt_plugin_get_name(plugin),
436 bt_component_class_get_name(cc), input,
437 input_type,
438 bt_common_value_type_string(BT_VALUE_TYPE_REAL),
439 bt_common_value_type_string(BT_VALUE_TYPE_MAP),
440 bt_common_value_type_string(BT_VALUE_TYPE_SIGNED_INTEGER),
441 bt_common_value_type_string(bt_value_get_type(query_result)));
442 continue;
443 }
444
9e534aae 445 BT_LOGD("babeltrace.support-info query: success: component-class-name=source.%s.%s, input=%s, "
a1040187
SM
446 "type=%s, weight=%f\n",
447 bt_plugin_get_name(plugin), bt_component_class_get_name(cc), input,
448 input_type, weight);
449
450 if (weight > winner.weigth) {
451 winner.source = source_cc;
452 winner.plugin = plugin;
453
454 bt_value_put_ref(winner.group);
455 winner.group = group_value;
456 bt_value_get_ref(winner.group);
457
458 winner.weigth = weight;
459 }
460 } else if (query_status == BT_QUERY_EXECUTOR_QUERY_STATUS_ERROR) {
9e534aae 461 BT_CLI_LOGE_APPEND_CAUSE("babeltrace.support-info query failed.");
a1040187
SM
462 goto error;
463 } else if (query_status == BT_QUERY_EXECUTOR_QUERY_STATUS_MEMORY_ERROR) {
464 BT_CLI_LOGE_APPEND_CAUSE("Memory error.");
465 goto error;
466 } else {
9e534aae 467 BT_LOGD("babeltrace.support-info query: failure: component-class-name=source.%s.%s, input=%s, "
a1040187
SM
468 "type=%s, status=%s\n",
469 bt_plugin_get_name(plugin), bt_component_class_get_name(cc), input,
470 input_type,
471 bt_common_func_status_string(query_status));
472 }
473 }
474 }
475
476 if (winner.source) {
477 const char *source_name;
478 const char *plugin_name;
479 const char *group;
480
481 source_name = bt_component_class_get_name(
482 bt_component_class_source_as_component_class_const(winner.source));
483 plugin_name = bt_plugin_get_name(winner.plugin);
484 group = winner.group ? bt_value_string_get(winner.group) : NULL;
485
486 BT_LOGI("Input %s is awarded to component class source.%s.%s with weight %f",
487 input, plugin_name, source_name, winner.weigth);
488
459f81ca
SM
489 status = auto_source_discovery_add(auto_disc, plugin_name,
490 source_name, group, input, original_input_index);
a1040187
SM
491 if (status != 0) {
492 goto error;
493 }
494 } else {
495 BT_LOGI("Input %s (%s) was not recognized by any source component class.",
496 input, input_type);
497 status = 1;
498 }
499
500 goto end;
501
502error:
503 status = -1;
504
505end:
506 bt_value_put_ref(query_result);
507 bt_value_put_ref(query_params);
508 bt_value_put_ref(winner.group);
509
510 return status;
511}
512
513/*
514 * Look for a source component class that recognizes `input` as an arbitrary
515 * string.
516 *
517 * Same return value semantic as `support_info_query_all_sources`.
518 */
519
520static
521int auto_discover_source_for_input_as_string(const char *input,
459f81ca 522 uint64_t original_input_index,
bf403eb2 523 size_t plugin_count, const char *plugin_restrict,
a1040187
SM
524 const char *component_class_restrict,
525 enum bt_logging_level log_level,
526 struct auto_source_discovery *auto_disc)
527{
528 return support_info_query_all_sources(input, "string",
459f81ca
SM
529 original_input_index, plugin_count, plugin_restrict,
530 component_class_restrict, log_level, auto_disc);
a1040187
SM
531}
532
533static
534int auto_discover_source_for_input_as_dir_or_file_rec(GString *input,
459f81ca 535 uint64_t original_input_index,
bf403eb2 536 size_t plugin_count, const char *plugin_restrict,
a1040187
SM
537 const char *component_class_restrict,
538 enum bt_logging_level log_level,
539 struct auto_source_discovery *auto_disc)
540{
541 int status;
542 GError *error = NULL;
543
544 if (g_file_test(input->str, G_FILE_TEST_IS_REGULAR)) {
545 /* It's a file. */
546 status = support_info_query_all_sources(input->str,
459f81ca 547 "file", original_input_index, plugin_count,
a1040187
SM
548 plugin_restrict, component_class_restrict, log_level, auto_disc);
549 } else if (g_file_test(input->str, G_FILE_TEST_IS_DIR)) {
550 GDir *dir;
551 const gchar *dirent;
552 gsize saved_input_len;
553 int dir_status = 1;
554
555 /* It's a directory. */
556 status = support_info_query_all_sources(input->str,
459f81ca 557 "directory", original_input_index, plugin_count,
a1040187
SM
558 plugin_restrict, component_class_restrict, log_level,
559 auto_disc);
560
561 if (status < 0) {
562 /* Fatal error. */
563 goto error;
564 } else if (status == 0) {
565 /*
566 * A component class claimed this input as a directory,
567 * don't recurse.
568 */
569 goto end;
570 }
571
572 dir = g_dir_open(input->str, 0, &error);
573 if (!dir) {
574 const char *fmt = "Failed to open directory %s: %s";
575 BT_LOGW(fmt, input->str, error->message);
576
07415a8f 577 if (error->code == G_FILE_ERROR_ACCES) {
a1040187
SM
578 /* This is not a fatal error, we just skip it. */
579 status = 1;
580 goto end;
581 } else {
582 BT_CLI_LOGE_APPEND_CAUSE(fmt, input->str,
583 error->message);
584 goto error;
585 }
586 }
587
588 saved_input_len = input->len;
589
590 do {
591 errno = 0;
592 dirent = g_dir_read_name(dir);
593 if (dirent) {
594 g_string_append_c_inline(input, G_DIR_SEPARATOR);
595 g_string_append(input, dirent);
596
597 status = auto_discover_source_for_input_as_dir_or_file_rec(
459f81ca 598 input, original_input_index, plugin_count,
a1040187
SM
599 plugin_restrict, component_class_restrict,
600 log_level, auto_disc);
601
602 g_string_truncate(input, saved_input_len);
603
604 if (status < 0) {
605 /* Fatal error. */
606 goto error;
607 } else if (status == 0) {
608 dir_status = 0;
609 }
610 } else if (errno != 0) {
611 BT_LOGW_ERRNO("Failed to read directory entry", ": dir=%s", input->str);
612 goto error;
613 }
8e01f2d9 614 } while (dirent);
a1040187
SM
615
616 status = dir_status;
617
618 g_dir_close(dir);
619 } else {
620 BT_LOGD("Skipping %s, not a file or directory", input->str);
621 status = 1;
622 }
623
624 goto end;
625
626error:
627 status = -1;
628
629end:
630
631 if (error) {
632 g_error_free(error);
633 }
634
635 return status;
636}
637
638/*
639 * Look for a source component class that recognizes `input` as a directory or
640 * file. If `input` is a directory and is not directly recognized, recurse and
641 * apply the same logic to children nodes.
642 *
643 * Same return value semantic as `support_info_query_all_sources`.
644 */
645
646static
647int auto_discover_source_for_input_as_dir_or_file(const char *input,
459f81ca 648 uint64_t original_input_index,
bf403eb2 649 size_t plugin_count, const char *plugin_restrict,
a1040187
SM
650 const char *component_class_restrict,
651 enum bt_logging_level log_level,
652 struct auto_source_discovery *auto_disc)
653{
654 GString *mutable_input;
655 int status;
656
657 mutable_input = g_string_new(input);
658 if (!mutable_input) {
659 status = -1;
660 goto end;
661 }
662
663 status = auto_discover_source_for_input_as_dir_or_file_rec(
459f81ca 664 mutable_input, original_input_index, plugin_count, plugin_restrict,
a1040187
SM
665 component_class_restrict, log_level, auto_disc);
666
667 g_string_free(mutable_input, TRUE);
668end:
669 return status;
670}
671
672int auto_discover_source_components(
673 const bt_value *plugin_paths,
674 const bt_value *inputs,
675 const char *plugin_restrict,
676 const char *component_class_restrict,
677 enum bt_logging_level log_level,
678 struct auto_source_discovery *auto_disc)
679{
680 uint64_t i_inputs, input_count;
681 int status;
682 size_t plugin_count;
a1040187
SM
683
684 input_count = bt_value_array_get_size(inputs);
685
686 status = require_loaded_plugins(plugin_paths);
687 if (status != 0) {
688 goto end;
689 }
690
691 plugin_count = get_loaded_plugins_count();
692
a1040187
SM
693 for (i_inputs = 0; i_inputs < input_count; i_inputs++) {
694 const bt_value *input_value;
695 const char *input;
696
697 input_value = bt_value_array_borrow_element_by_index_const(inputs, i_inputs);
698 input = bt_value_string_get(input_value);
459f81ca 699 status = auto_discover_source_for_input_as_string(input, i_inputs,
a1040187
SM
700 plugin_count, plugin_restrict, component_class_restrict,
701 log_level, auto_disc);
702 if (status < 0) {
703 /* Fatal error. */
704 goto end;
705 } else if (status == 0) {
706 /* A component class has claimed this input as an arbitrary string. */
707 continue;
708 }
709
710 status = auto_discover_source_for_input_as_dir_or_file(input,
459f81ca
SM
711 i_inputs, plugin_count, plugin_restrict,
712 component_class_restrict, log_level, auto_disc);
a1040187
SM
713 if (status < 0) {
714 /* Fatal error. */
715 goto end;
716 } else if (status == 0) {
717 /*
718 * This input (or something under it) was recognized.
719 */
720 continue;
721 }
722
723 BT_LOGW("No trace was found based on input `%s`.", input);
724 }
725
726 status = 0;
727end:
a1040187
SM
728 return status;
729}
This page took 0.053417 seconds and 4 git commands to generate.