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