#include "rte_telemetry.h"
#include "rte_telemetry_internal.h"
#include "rte_telemetry_parser.h"
-#include "rte_telemetry_parser_test.h"
#include "rte_telemetry_socket_tests.h"
#define BUF_SIZE 1024
static telemetry_impl *static_telemetry;
struct telemetry_message_test {
- char *test_name;
+ const char *test_name;
int (*test_func_ptr)(struct telemetry_impl *telemetry, int fd);
};
struct json_data {
char *status_code;
- char *data;
+ const char *data;
int port;
char *stat_name;
int stat_value;
return 0;
}
-int32_t
+static int32_t
rte_telemetry_write_to_socket(struct telemetry_impl *telemetry,
const char *json_string)
{
static int32_t
rte_telemetry_json_format_port(struct telemetry_impl *telemetry,
uint32_t port_id, json_t *ports, uint32_t *metric_ids,
- uint32_t num_metric_ids)
+ int num_metric_ids)
{
struct rte_metric_value *metrics = 0;
struct rte_metric_name *names = 0;
int num_metrics, ret, err_ret;
json_t *port, *stats;
- uint32_t i;
+ int i;
num_metrics = rte_metrics_get_names(NULL, 0);
if (num_metrics < 0) {
static int32_t
rte_telemetry_encode_json_format(struct telemetry_impl *telemetry,
- uint32_t *port_ids, uint32_t num_port_ids, uint32_t *metric_ids,
- uint32_t num_metric_ids, char **json_buffer)
+ struct telemetry_encode_param *ep, char **json_buffer)
{
int ret;
json_t *root, *ports;
- uint32_t i;
-
- if (num_port_ids <= 0 || num_metric_ids <= 0) {
- TELEMETRY_LOG_ERR("Please provide port and metric ids to query");
- goto einval_fail;
- }
+ int i;
+ uint32_t port_id;
+ int num_port_ids;
+ int num_metric_ids;
ports = json_array();
if (ports == NULL) {
goto eperm_fail;
}
- for (i = 0; i < num_port_ids; i++) {
- if (!rte_eth_dev_is_valid_port(port_ids[i])) {
- TELEMETRY_LOG_ERR("Port: %d invalid", port_ids[i]);
+ if (ep->type == PORT_STATS) {
+ num_port_ids = ep->pp.num_port_ids;
+ num_metric_ids = ep->pp.num_metric_ids;
+
+ if (num_port_ids <= 0 || num_metric_ids <= 0) {
+ TELEMETRY_LOG_ERR("Please provide port and metric ids to query");
goto einval_fail;
}
- }
- for (i = 0; i < num_port_ids; i++) {
- ret = rte_telemetry_json_format_port(telemetry, port_ids[i],
- ports, metric_ids, num_metric_ids);
+ for (i = 0; i < num_port_ids; i++) {
+ port_id = ep->pp.port_ids[i];
+ if (!rte_eth_dev_is_valid_port(port_id)) {
+ TELEMETRY_LOG_ERR("Port: %d invalid",
+ port_id);
+ goto einval_fail;
+ }
+ }
+
+ for (i = 0; i < num_port_ids; i++) {
+ port_id = ep->pp.port_ids[i];
+ ret = rte_telemetry_json_format_port(telemetry,
+ port_id, ports, &ep->pp.metric_ids[0],
+ num_metric_ids);
+ if (ret < 0) {
+ TELEMETRY_LOG_ERR("Format port in JSON failed");
+ return -1;
+ }
+ }
+ } else if (ep->type == GLOBAL_STATS) {
+ /* Request Global Metrics */
+ ret = rte_telemetry_json_format_port(telemetry,
+ RTE_METRICS_GLOBAL,
+ ports, &ep->gp.metric_ids[0],
+ ep->gp.num_metric_ids);
if (ret < 0) {
- TELEMETRY_LOG_ERR("Format port in JSON failed");
+ TELEMETRY_LOG_ERR(" Request Global Metrics Failed");
return -1;
}
+ } else {
+ TELEMETRY_LOG_ERR(" Invalid metrics type in encode params");
+ goto einval_fail;
}
root = json_object();
}
int32_t
-rte_telemetry_send_ports_stats_values(uint32_t *metric_ids, int num_metric_ids,
- uint32_t *port_ids, int num_port_ids, struct telemetry_impl *telemetry)
+rte_telemetry_send_global_stats_values(struct telemetry_encode_param *ep,
+ struct telemetry_impl *telemetry)
{
- int ret, i;
+ int ret;
char *json_buffer = NULL;
if (telemetry == NULL) {
return -1;
}
- if (metric_ids == NULL) {
- TELEMETRY_LOG_ERR("Invalid metric_ids array");
+ if (ep->gp.num_metric_ids < 0) {
+ TELEMETRY_LOG_ERR("Invalid num_metric_ids, must be positive");
goto einval_fail;
}
- if (num_metric_ids < 0) {
- TELEMETRY_LOG_ERR("Invalid num_metric_ids, must be positive");
+ ret = rte_telemetry_encode_json_format(telemetry, ep,
+ &json_buffer);
+ if (ret < 0) {
+ TELEMETRY_LOG_ERR("JSON encode function failed");
+ return -1;
+ }
+
+ ret = rte_telemetry_write_to_socket(telemetry, json_buffer);
+ if (ret < 0) {
+ TELEMETRY_LOG_ERR("Could not write to socket");
+ return -1;
+ }
+
+ return 0;
+
+einval_fail:
+ ret = rte_telemetry_send_error_response(telemetry, -EINVAL);
+ if (ret < 0)
+ TELEMETRY_LOG_ERR("Could not send error");
+ return -1;
+}
+
+int32_t
+rte_telemetry_send_ports_stats_values(struct telemetry_encode_param *ep,
+ struct telemetry_impl *telemetry)
+{
+ int ret;
+ char *json_buffer = NULL;
+ uint32_t port_id;
+ int i;
+
+ if (telemetry == NULL) {
+ TELEMETRY_LOG_ERR("Invalid telemetry argument");
+ return -1;
+ }
+
+ if (ep == NULL) {
+ TELEMETRY_LOG_ERR("Invalid encode param argument");
goto einval_fail;
}
- if (port_ids == NULL) {
- TELEMETRY_LOG_ERR("Invalid port_ids array");
+ if (ep->pp.num_metric_ids < 0) {
+ TELEMETRY_LOG_ERR("Invalid num_metric_ids, must be positive");
goto einval_fail;
}
- if (num_port_ids < 0) {
+ if (ep->pp.num_port_ids < 0) {
TELEMETRY_LOG_ERR("Invalid num_port_ids, must be positive");
goto einval_fail;
}
- for (i = 0; i < num_port_ids; i++) {
- if (!rte_eth_dev_is_valid_port(port_ids[i])) {
- TELEMETRY_LOG_ERR("Port: %d invalid", port_ids[i]);
+ for (i = 0; i < ep->pp.num_port_ids; i++) {
+ port_id = ep->pp.port_ids[i];
+ if (!rte_eth_dev_is_valid_port(port_id)) {
+ TELEMETRY_LOG_ERR("Port: %d invalid", port_id);
goto einval_fail;
}
ret = rte_telemetry_update_metrics_ethdev(telemetry,
- port_ids[i], telemetry->reg_index);
+ port_id, telemetry->reg_index[i]);
if (ret < 0) {
TELEMETRY_LOG_ERR("Failed to update ethdev metrics");
return -1;
}
}
- ret = rte_telemetry_encode_json_format(telemetry, port_ids,
- num_port_ids, metric_ids, num_metric_ids, &json_buffer);
+ ret = rte_telemetry_encode_json_format(telemetry, ep, &json_buffer);
if (ret < 0) {
TELEMETRY_LOG_ERR("JSON encode function failed");
return -1;
static int32_t
rte_telemetry_initial_accept(struct telemetry_impl *telemetry)
{
+ struct driver_index {
+ const void *dev_ops;
+ int reg_index;
+ } drv_idx[RTE_MAX_ETHPORTS] = { {0} };
+ int nb_drv_idx = 0;
uint16_t pid;
int ret;
+ int selftest = 0;
RTE_ETH_FOREACH_DEV(pid) {
- telemetry->reg_index = rte_telemetry_reg_ethdev_to_metrics(pid);
- break;
- }
+ int i;
+ /* Different device types have different numbers of stats, so
+ * first check if the stats for this type of device have
+ * already been registered
+ */
+ for (i = 0; i < nb_drv_idx; i++) {
+ if (rte_eth_devices[pid].dev_ops == drv_idx[i].dev_ops) {
+ telemetry->reg_index[pid] = drv_idx[i].reg_index;
+ break;
+ }
+ }
+ if (i < nb_drv_idx)
+ continue; /* we found a match, go to next port */
- if (telemetry->reg_index < 0) {
- TELEMETRY_LOG_ERR("Failed to register ethdev metrics");
- return -1;
+ /* No match, register a new set of xstats for this port */
+ ret = rte_telemetry_reg_ethdev_to_metrics(pid);
+ if (ret < 0) {
+ TELEMETRY_LOG_ERR("Failed to register ethdev metrics");
+ return -1;
+ }
+ telemetry->reg_index[pid] = ret;
+ drv_idx[nb_drv_idx].dev_ops = rte_eth_devices[pid].dev_ops;
+ drv_idx[nb_drv_idx].reg_index = ret;
+ nb_drv_idx++;
}
telemetry->metrics_register_done = 1;
- ret = rte_telemetry_socket_messaging_testing(telemetry->reg_index,
- telemetry->server_fd);
- if (ret < 0)
- return -1;
+ if (selftest) {
+ ret = rte_telemetry_socket_messaging_testing(telemetry->reg_index[0],
+ telemetry->server_fd);
+ if (ret < 0)
+ return -1;
- ret = rte_telemetry_parser_test(telemetry);
- if (ret < 0) {
- TELEMETRY_LOG_ERR("Parser Tests Failed");
- return -1;
- }
+ ret = rte_telemetry_parser_test(telemetry);
+ if (ret < 0) {
+ TELEMETRY_LOG_ERR("Parser Tests Failed");
+ return -1;
+ }
- TELEMETRY_LOG_INFO("Success - All Parser Tests Passed");
+ TELEMETRY_LOG_INFO("Success - All Parser Tests Passed");
+ }
return 0;
}
return -1;
}
-int32_t __rte_experimental
-rte_telemetry_init()
+int32_t
+rte_telemetry_init(void)
{
int ret;
pthread_attr_t attr;
return 0;
}
-int32_t __rte_experimental
+int32_t
rte_telemetry_cleanup(void)
{
int ret;
return -1;
}
-int32_t
+static int32_t
rte_telemetry_dummy_client_socket(const char *valid_client_path)
{
int sockfd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
return sockfd;
}
-int32_t __rte_experimental
+int32_t
rte_telemetry_selftest(void)
{
const char *invalid_client_path = SELFTEST_INVALID_CLIENT;
}
telemetry->server_fd = socket;
- telemetry->reg_index = index;
+ telemetry->reg_index[0] = index;
TELEMETRY_LOG_INFO("Beginning Telemetry socket message Selftest");
rte_telemetry_socket_test_setup(telemetry, &send_fd, &recv_fd);
TELEMETRY_LOG_INFO("Register valid client test");
int ret;
char buf[BUF_SIZE];
int fail_count = 0;
- char *status = "Status Error: Invalid Argument 404";
- char *data = "null";
+ const char *status = "Status Error: Invalid Argument 404";
+ const char *data = "null";
struct json_data *data_struct;
const char *invalid_contents = "{\"action\":0,\"command\":"
"\"ports_stats_values_by_name\",\"data\":{\"ports\""
char buf[BUF_SIZE];
int fail_count = 0;
const char *status = "Status Error: Invalid Argument 404";
- char *data = "null";
+ const char *data = "null";
struct json_data *data_struct;
const char *empty_json = "{}";
int buffer_read = 0;
int telemetry_log_level;
static struct rte_option option = {
- .opt_str = "--telemetry",
+ .name = "telemetry",
+ .usage = "Enable telemetry backend",
.cb = &rte_telemetry_init,
.enabled = 0
};