src.ctf.lttng-live: return unsigned integers in `sessions` query object
[babeltrace.git] / src / cli / babeltrace2.c
index bafda3b5697019d59258ef90ddebd6486b8392c8..e32e1a0930f63160c3dbff47f2cea5305dd77dbc 100644 (file)
@@ -29,7 +29,6 @@
 #include "common/common.h"
 #include <unistd.h>
 #include <stdlib.h>
-#include <popt.h>
 #include <string.h>
 #include <stdio.h>
 #include <glib.h>
 #include "babeltrace2-cfg.h"
 #include "babeltrace2-cfg-cli-args.h"
 #include "babeltrace2-cfg-cli-args-default.h"
+#include "babeltrace2-log-level.h"
 #include "babeltrace2-plugins.h"
+#include "babeltrace2-query.h"
 
 #define ENV_BABELTRACE_WARN_COMMAND_NAME_DIRECTORY_CLASH "BABELTRACE_CLI_WARN_COMMAND_NAME_DIRECTORY_CLASH"
-#define ENV_BABELTRACE_CLI_LOG_LEVEL "BABELTRACE_CLI_LOG_LEVEL"
 #define NSEC_PER_SEC   1000000000LL
 
-/*
- * Known environment variable names for the log levels of the project's
- * modules.
- */
-static const char* log_level_env_var_names[] = {
-       "BABELTRACE_PLUGIN_CTF_METADATA_LOG_LEVEL",
-       "BABELTRACE_PYTHON_BT2_LOG_LEVEL",
-       NULL,
-};
-
 /* Application's interrupter (owned by this) */
 static bt_interrupter *the_interrupter;
 
@@ -115,93 +105,10 @@ int query(struct bt_config *cfg, const bt_component_class *comp_cls,
                const char *obj, const bt_value *params,
                const bt_value **user_result, const char **fail_reason)
 {
-       const bt_value *result = NULL;
-       bt_query_executor_query_status query_status;
-       bt_query_executor *query_exec;
-       *fail_reason = "unknown error";
-       int ret = 0;
-
-       BT_ASSERT(fail_reason);
-       BT_ASSERT(user_result);
-       query_exec = bt_query_executor_create();
-       if (!query_exec) {
-               BT_CLI_LOGE_APPEND_CAUSE("Cannot create a query executor.");
-               goto error;
-       }
-
-       bt_query_executor_add_interrupter(query_exec, the_interrupter);
-
-       while (true) {
-               query_status = bt_query_executor_query(
-                       query_exec, comp_cls, obj, params,
-                       cfg->log_level, &result);
-               switch (query_status) {
-               case BT_QUERY_EXECUTOR_QUERY_STATUS_OK:
-                       goto ok;
-               case BT_QUERY_EXECUTOR_QUERY_STATUS_AGAIN:
-               {
-                       const uint64_t sleep_time_us = 100000;
-
-                       if (bt_interrupter_is_set(the_interrupter)) {
-                               *fail_reason = "interrupted by user";
-                               goto error;
-                       }
-
-                       /* Wait 100 ms and retry */
-                       BT_LOGD("Got BT_QUERY_EXECUTOR_QUERY_STATUS_AGAIN: sleeping: "
-                               "time-us=%" PRIu64, sleep_time_us);
-
-                       if (usleep(sleep_time_us)) {
-                               if (bt_interrupter_is_set(the_interrupter)) {
-                                       BT_CLI_LOGW_APPEND_CAUSE(
-                                               "Query was interrupted by user: "
-                                               "comp-cls-addr=%p, comp-cls-name=\"%s\", "
-                                               "query-obj=\"%s\"", comp_cls,
-                                               bt_component_class_get_name(comp_cls),
-                                               obj);
-                                       *fail_reason = "interrupted by user";
-                                       goto error;
-                               }
-                       }
-
-                       continue;
-               }
-               case BT_QUERY_EXECUTOR_QUERY_STATUS_ERROR:
-                       if (bt_interrupter_is_set(the_interrupter)) {
-                               *fail_reason = "interrupted by user";
-                               goto error;
-                       }
-
-                       goto error;
-               case BT_QUERY_EXECUTOR_QUERY_STATUS_INVALID_OBJECT:
-                       *fail_reason = "invalid or unknown query object";
-                       goto error;
-               case BT_QUERY_EXECUTOR_QUERY_STATUS_MEMORY_ERROR:
-                       *fail_reason = "not enough memory";
-                       goto error;
-               default:
-                       BT_LOGF("Unknown query status: status=%s",
-                               bt_common_func_status_string(query_status));
-                       abort();
-               }
-       }
-
-ok:
-       *user_result = result;
-       result = NULL;
-       goto end;
-
-error:
-       ret = -1;
-
-end:
-       bt_query_executor_put_ref(query_exec);
-       bt_value_put_ref(result);
-       return ret;
+       return cli_query(comp_cls, obj, params, cfg->log_level,
+               the_interrupter, user_result, fail_reason);
 }
 
-
-
 typedef const void *(*plugin_borrow_comp_cls_func_t)(
                const bt_plugin *, const char *);
 
@@ -458,7 +365,7 @@ void print_value_rec(FILE *fp, const bt_value *value, size_t indent)
                        bt_common_color_reset());
                break;
        case BT_VALUE_TYPE_ARRAY:
-               size = bt_value_array_get_size(value);
+               size = bt_value_array_get_length(value);
                if (size < 0) {
                        goto error;
                }
@@ -652,8 +559,6 @@ void print_cfg(struct bt_config *cfg)
        }
 
        BT_LOGI_STR("CLI configuration:");
-       BT_LOGI("  Debug mode: %s\n", cfg->debug ? "yes" : "no");
-       BT_LOGI("  Verbose mode: %s\n", cfg->verbose ? "yes" : "no");
 
        switch (cfg->command) {
        case BT_CONFIG_COMMAND_RUN:
@@ -1049,7 +954,7 @@ int cmd_print_lttng_live_sessions(struct bt_config *cfg)
                }
        }
 
-       array_size = bt_value_array_get_size(results);
+       array_size = bt_value_array_get_length(results);
        for (i = 0; i < array_size; i++) {
                const char *url_text;
                int64_t timer_us, streams, clients;
@@ -1076,7 +981,7 @@ int cmd_print_lttng_live_sessions(struct bt_config *cfg)
                        BT_CLI_LOGE_APPEND_CAUSE("Missing `timer-us` entry.");
                        goto error;
                }
-               timer_us = bt_value_integer_signed_get(v);
+               timer_us = bt_value_integer_unsigned_get(v);
                fprintf(out_stream, " (timer = %" PRIu64 ", ", timer_us);
                v = bt_value_map_borrow_entry_value_const(map, "stream-count");
                if (!v) {
@@ -1084,7 +989,7 @@ int cmd_print_lttng_live_sessions(struct bt_config *cfg)
                                "Missing `stream-count` entry.");
                        goto error;
                }
-               streams = bt_value_integer_signed_get(v);
+               streams = bt_value_integer_unsigned_get(v);
                fprintf(out_stream, "%" PRIu64 " stream(s), ", streams);
                v = bt_value_map_borrow_entry_value_const(map, "client-count");
                if (!v) {
@@ -1092,7 +997,7 @@ int cmd_print_lttng_live_sessions(struct bt_config *cfg)
                                "Missing `client-count` entry.");
                        goto error;
                }
-               clients = bt_value_integer_signed_get(v);
+               clients = bt_value_integer_unsigned_get(v);
                fprintf(out_stream, "%" PRIu64 " client(s) connected)\n", clients);
        }
 
@@ -1793,11 +1698,138 @@ void cmd_run_ctx_destroy(struct cmd_run_ctx *ctx)
        ctx->cfg = NULL;
 }
 
+static
+int add_descriptor_to_component_descriptor_set(
+               bt_component_descriptor_set *comp_descr_set,
+               const char *plugin_name, const char *comp_cls_name,
+               bt_component_class_type comp_cls_type,
+               const bt_value *params)
+{
+       const bt_component_class *comp_cls;
+       int status = 0;
+
+       comp_cls = find_component_class(plugin_name, comp_cls_name,
+               comp_cls_type);
+       if (!comp_cls) {
+               BT_CLI_LOGE_APPEND_CAUSE(
+                       "Cannot find component class: plugin-name=\"%s\", "
+                       "comp-cls-name=\"%s\", comp-cls-type=%d",
+                       plugin_name, comp_cls_name, comp_cls_type);
+               status = -1;
+               goto end;
+       }
+
+       status = bt_component_descriptor_set_add_descriptor(
+               comp_descr_set, comp_cls, params);
+       if (status != BT_COMPONENT_DESCRIPTOR_SET_ADD_DESCRIPTOR_STATUS_OK) {
+               BT_CLI_LOGE_APPEND_CAUSE(
+                       "Cannot append descriptor to component descriptor set: "
+                       "status=%s", bt_common_func_status_string(status));
+               goto end;
+       }
+
+end:
+       bt_component_class_put_ref(comp_cls);
+       return status;
+}
+
+static
+int append_descriptors_from_bt_config_component_array(
+               bt_component_descriptor_set *comp_descr_set,
+               GPtrArray *component_configs)
+{
+       int ret = 0;
+       uint64_t i;
+
+       for (i = 0; i < component_configs->len; i++) {
+               struct bt_config_component *cfg_comp =
+                       component_configs->pdata[i];
+
+               ret = add_descriptor_to_component_descriptor_set(
+                       comp_descr_set,
+                       cfg_comp->plugin_name->str,
+                       cfg_comp->comp_cls_name->str,
+                       cfg_comp->type, cfg_comp->params);
+               if (ret) {
+                       goto end;
+               }
+       }
+
+end:
+       return ret;
+}
+
+static
+bt_get_greatest_operative_mip_version_status get_greatest_operative_mip_version(
+               struct bt_config *cfg, uint64_t *mip_version)
+{
+       bt_get_greatest_operative_mip_version_status status =
+               BT_GET_GREATEST_OPERATIVE_MIP_VERSION_STATUS_OK;
+       bt_component_descriptor_set *comp_descr_set = NULL;
+       int ret;
+
+       BT_ASSERT(cfg);
+       BT_ASSERT(mip_version);
+       comp_descr_set = bt_component_descriptor_set_create();
+       if (!comp_descr_set) {
+               BT_CLI_LOGE_APPEND_CAUSE(
+                       "Failed to create a component descriptor set object.");
+               status = BT_GET_GREATEST_OPERATIVE_MIP_VERSION_STATUS_MEMORY_ERROR;
+               goto end;
+       }
+
+       ret = append_descriptors_from_bt_config_component_array(
+               comp_descr_set, cfg->cmd_data.run.sources);
+       if (ret) {
+               status = BT_GET_GREATEST_OPERATIVE_MIP_VERSION_STATUS_ERROR;
+               goto end;
+       }
+
+       ret = append_descriptors_from_bt_config_component_array(
+               comp_descr_set, cfg->cmd_data.run.filters);
+       if (ret) {
+               status = BT_GET_GREATEST_OPERATIVE_MIP_VERSION_STATUS_ERROR;
+               goto end;
+       }
+
+       ret = append_descriptors_from_bt_config_component_array(
+               comp_descr_set, cfg->cmd_data.run.sinks);
+       if (ret) {
+               status = BT_GET_GREATEST_OPERATIVE_MIP_VERSION_STATUS_ERROR;
+               goto end;
+       }
+
+       if (cfg->cmd_data.run.stream_intersection_mode) {
+               /*
+                * Stream intersection mode adds `flt.utils.trimmer`
+                * components; we need to include this type of component
+                * in the component descriptor set to get the real
+                * greatest operative MIP version.
+                */
+               ret = add_descriptor_to_component_descriptor_set(
+                       comp_descr_set, "utils", "trimmer",
+                       BT_COMPONENT_CLASS_TYPE_FILTER, NULL);
+               if (ret) {
+                       status = BT_GET_GREATEST_OPERATIVE_MIP_VERSION_STATUS_ERROR;
+                       goto end;
+               }
+       }
+
+       status = bt_get_greatest_operative_mip_version(comp_descr_set,
+               bt_cli_log_level, mip_version);
+
+end:
+       bt_component_descriptor_set_put_ref(comp_descr_set);
+       return status;
+}
+
 static
 int cmd_run_ctx_init(struct cmd_run_ctx *ctx, struct bt_config *cfg)
 {
        int ret = 0;
        bt_graph_add_listener_status add_listener_status;
+       bt_get_greatest_operative_mip_version_status mip_version_status;
+       uint64_t mip_version = UINT64_C(-1);
 
        ctx->cfg = cfg;
        ctx->connect_ports = false;
@@ -1828,7 +1860,32 @@ int cmd_run_ctx_init(struct cmd_run_ctx *ctx, struct bt_config *cfg)
                }
        }
 
-       ctx->graph = bt_graph_create();
+       /*
+        * Get the greatest operative MIP version to use to configure
+        * the graph to create.
+        */
+       mip_version_status = get_greatest_operative_mip_version(
+               cfg, &mip_version);
+       if (mip_version_status == BT_GET_GREATEST_OPERATIVE_MIP_VERSION_STATUS_NO_MATCH) {
+               BT_CLI_LOGE_APPEND_CAUSE(
+                       "Failed to find an operative message interchange "
+                       "protocol version to use to create the `run` command's "
+                       "graph (components are not interoperable).");
+               goto error;
+       } else if (mip_version_status < 0) {
+               BT_CLI_LOGE_APPEND_CAUSE(
+                       "Cannot find an operative message interchange "
+                       "protocol version to use to create the `run` command's "
+                       "graph: status=%s",
+                       bt_common_func_status_string(mip_version_status));
+               goto error;
+       }
+
+       BT_ASSERT(mip_version_status == BT_GET_GREATEST_OPERATIVE_MIP_VERSION_STATUS_OK);
+       BT_LOGI("Found operative message interchange protocol version to "
+               "configure the `run` command's graph: mip-version=%" PRIu64,
+               mip_version);
+       ctx->graph = bt_graph_create(mip_version);
        if (!ctx->graph) {
                goto error;
        }
@@ -1884,11 +1941,11 @@ int set_stream_intersections(struct cmd_run_ctx *ctx,
        const bt_component_class *comp_cls =
                bt_component_class_source_as_component_class_const(src_comp_cls);
 
-       ret = query(ctx->cfg, comp_cls, "trace-info",
+       ret = query(ctx->cfg, comp_cls, "babeltrace.trace-info",
                cfg_comp->params, &query_result,
                &fail_reason);
        if (ret) {
-               BT_LOGD("Component class does not support the `trace-info` query: %s: "
+               BT_LOGD("Component class does not support the `babeltrace.trace-info` query: %s: "
                        "comp-class-name=\"%s\"", fail_reason,
                        bt_component_class_get_name(comp_cls));
                ret = -1;
@@ -1898,14 +1955,14 @@ int set_stream_intersections(struct cmd_run_ctx *ctx,
        BT_ASSERT(query_result);
 
        if (!bt_value_is_array(query_result)) {
-               BT_LOGD("Unexpected format of \'trace-info\' query result: "
+               BT_LOGD("Unexpected format of `babeltrace.trace-info` query result: "
                        "component-class-name=%s",
                        bt_component_class_get_name(comp_cls));
                ret = -1;
                goto error;
        }
 
-       trace_count = bt_value_array_get_size(query_result);
+       trace_count = bt_value_array_get_length(query_result);
        if (trace_count < 0) {
                ret = -1;
                goto error;
@@ -1969,7 +2026,7 @@ int set_stream_intersections(struct cmd_run_ctx *ctx,
                        goto error;
                }
 
-               stream_count = bt_value_array_get_size(stream_infos);
+               stream_count = bt_value_array_get_length(stream_infos);
                if (stream_count < 0) {
                        ret = -1;
                        goto error;
@@ -2425,87 +2482,6 @@ void init_log_level(void)
        bt_cli_log_level = bt_log_get_level_from_env(ENV_BABELTRACE_CLI_LOG_LEVEL);
 }
 
-static
-void set_auto_log_levels(struct bt_config *cfg)
-{
-       const char **env_var_name;
-
-       /*
-        * Override the configuration's default log level if
-        * BABELTRACE_VERBOSE or BABELTRACE_DEBUG environment variables
-        * are found for backward compatibility with legacy Babetrace 1.
-        */
-       if (getenv("BABELTRACE_DEBUG") &&
-                       strcmp(getenv("BABELTRACE_DEBUG"), "1") == 0) {
-               cfg->log_level = BT_LOG_TRACE;
-       } else if (getenv("BABELTRACE_VERBOSE") &&
-                       strcmp(getenv("BABELTRACE_VERBOSE"), "1") == 0) {
-               cfg->log_level = BT_LOG_INFO;
-       }
-
-       /*
-        * Set log levels according to --debug or --verbose. For
-        * backward compatibility, --debug is more verbose than
-        * --verbose. So:
-        *
-        *     --verbose: INFO log level
-        *     --debug:   TRACE log level (includes DEBUG, which is
-        *                is less verbose than TRACE in the internal
-        *                logging framework)
-        */
-       if (!getenv("LIBBABELTRACE2_INIT_LOG_LEVEL")) {
-               if (cfg->verbose) {
-                       bt_logging_set_global_level(BT_LOG_INFO);
-               } else if (cfg->debug) {
-                       bt_logging_set_global_level(BT_LOG_TRACE);
-               } else {
-                       /*
-                        * Set library's default log level if not
-                        * explicitly specified.
-                        */
-                       bt_logging_set_global_level(cfg->log_level);
-               }
-       }
-
-       if (!getenv(ENV_BABELTRACE_CLI_LOG_LEVEL)) {
-               if (cfg->verbose) {
-                       bt_cli_log_level = BT_LOG_INFO;
-               } else if (cfg->debug) {
-                       bt_cli_log_level = BT_LOG_TRACE;
-               } else {
-                       /*
-                        * Set CLI's default log level if not explicitly
-                        * specified.
-                        */
-                       bt_cli_log_level = cfg->log_level;
-               }
-       }
-
-       env_var_name = log_level_env_var_names;
-
-       while (*env_var_name) {
-               if (!getenv(*env_var_name)) {
-                       if (cfg->verbose) {
-                               g_setenv(*env_var_name, "INFO", 1);
-                       } else if (cfg->debug) {
-                               g_setenv(*env_var_name, "TRACE", 1);
-                       } else {
-                               char val[2] = { 0 };
-
-                               /*
-                                * Set module's default log level if not
-                                * explicitly specified.
-                                */
-                               val[0] = bt_log_get_letter_from_level(
-                                       cfg->log_level);
-                               g_setenv(*env_var_name, val, 1);
-                       }
-               }
-
-               env_var_name++;
-       }
-}
-
 static
 void print_error_causes(void)
 {
@@ -2614,9 +2590,7 @@ void print_error_causes(void)
        }
 
 end:
-       if (folded) {
-               g_string_free(folded, TRUE);
-       }
+       BT_ASSERT(!folded);
 
        if (error) {
                bt_error_release(error);
@@ -2649,12 +2623,11 @@ int main(int argc, const char **argv)
 
        if (!cfg) {
                BT_CLI_LOGE_APPEND_CAUSE(
-                       "Failed to create a valid Babeltrace configuration.");
+                       "Failed to create a valid Babeltrace CLI configuration.");
                retcode = 1;
                goto end;
        }
 
-       set_auto_log_levels(cfg);
        print_cfg(cfg);
 
        if (cfg->command_needs_plugins) {
This page took 0.028339 seconds and 4 git commands to generate.