X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=lib%2Flibrte_telemetry%2Ftelemetry.c;h=b142729da48b0a57a240bbe0c2bfca15ebb9dcb7;hb=f454f2dbf1e934704040e876729aa50987ae8825;hp=9f4234c049c49016161848bf1892fc942cfac8ca;hpb=f38748736eb2010d2771259e3584e9fda7c72edd;p=dpdk.git diff --git a/lib/librte_telemetry/telemetry.c b/lib/librte_telemetry/telemetry.c index 9f4234c049..b142729da4 100644 --- a/lib/librte_telemetry/telemetry.c +++ b/lib/librte_telemetry/telemetry.c @@ -2,11 +2,13 @@ * Copyright(c) 2020 Intel Corporation */ +#ifndef RTE_EXEC_ENV_WINDOWS #include #include #include #include #include +#endif /* !RTE_EXEC_ENV_WINDOWS */ /* we won't link against libbsd, so just always use DPDKs-specific strlcpy */ #undef RTE_USE_LIBBSD @@ -18,13 +20,17 @@ #include "rte_telemetry.h" #include "telemetry_json.h" #include "telemetry_data.h" +#include "rte_telemetry_legacy.h" #define MAX_CMD_LEN 56 #define MAX_HELP_LEN 64 #define MAX_OUTPUT_LEN (1024 * 16) +#define MAX_CONNECTIONS 10 +#ifndef RTE_EXEC_ENV_WINDOWS static void * client_handler(void *socket); +#endif /* !RTE_EXEC_ENV_WINDOWS */ struct cmd_callback { char cmd[MAX_CMD_LEN]; @@ -32,18 +38,25 @@ struct cmd_callback { char help[MAX_HELP_LEN]; }; +#ifndef RTE_EXEC_ENV_WINDOWS struct socket { int sock; char path[sizeof(((struct sockaddr_un *)0)->sun_path)]; handler fn; + uint16_t *num_clients; }; static struct socket v2_socket; /* socket for v2 telemetry */ +static struct socket v1_socket; /* socket for v1 telemetry */ +#endif /* !RTE_EXEC_ENV_WINDOWS */ static char telemetry_log_error[1024]; /* Will contain error on init failure */ /* list of command callbacks, with one command registered by default */ static struct cmd_callback callbacks[TELEMETRY_MAX_CALLBACKS]; static int num_callbacks; /* How many commands are registered */ /* Used when accessing or modifying list of command callbacks */ static rte_spinlock_t callback_sl = RTE_SPINLOCK_INITIALIZER; +#ifndef RTE_EXEC_ENV_WINDOWS +static uint16_t v2_clients; +#endif /* !RTE_EXEC_ENV_WINDOWS */ int rte_telemetry_register_cmd(const char *cmd, telemetry_cb fn, const char *help) @@ -73,6 +86,8 @@ rte_telemetry_register_cmd(const char *cmd, telemetry_cb fn, const char *help) return 0; } +#ifndef RTE_EXEC_ENV_WINDOWS + static int list_commands(const char *cmd __rte_unused, const char *params __rte_unused, struct rte_tel_data *d) @@ -118,6 +133,35 @@ command_help(const char *cmd __rte_unused, const char *params, return 0; } +static int +container_to_json(const struct rte_tel_data *d, char *out_buf, size_t buf_len) +{ + size_t used = 0; + unsigned int i; + + if (d->type != RTE_TEL_ARRAY_U64 && d->type != RTE_TEL_ARRAY_INT + && d->type != RTE_TEL_ARRAY_STRING) + return snprintf(out_buf, buf_len, "null"); + + used = rte_tel_json_empty_array(out_buf, buf_len, 0); + if (d->type == RTE_TEL_ARRAY_U64) + for (i = 0; i < d->data_len; i++) + used = rte_tel_json_add_array_u64(out_buf, + buf_len, used, + d->data.array[i].u64val); + if (d->type == RTE_TEL_ARRAY_INT) + for (i = 0; i < d->data_len; i++) + used = rte_tel_json_add_array_int(out_buf, + buf_len, used, + d->data.array[i].ival); + if (d->type == RTE_TEL_ARRAY_STRING) + for (i = 0; i < d->data_len; i++) + used = rte_tel_json_add_array_string(out_buf, + buf_len, used, + d->data.array[i].sval); + return used; +} + static void output_json(const char *cmd, const struct rte_tel_data *d, int s) { @@ -164,6 +208,20 @@ output_json(const char *cmd, const struct rte_tel_data *d, int s) buf_len, used, v->name, v->value.u64val); break; + case RTE_TEL_CONTAINER: + { + char temp[buf_len]; + const struct container *cont = + &v->value.container; + if (container_to_json(cont->data, + temp, buf_len) != 0) + used = rte_tel_json_add_obj_json( + cb_data_buf, + buf_len, used, + v->name, temp); + if (!cont->keep) + rte_tel_data_free(cont->data); + } } } used += prefix_used; @@ -172,6 +230,7 @@ output_json(const char *cmd, const struct rte_tel_data *d, int s) case RTE_TEL_ARRAY_STRING: case RTE_TEL_ARRAY_INT: case RTE_TEL_ARRAY_U64: + case RTE_TEL_ARRAY_CONTAINER: prefix_used = snprintf(out_buf, sizeof(out_buf), "{\"%.*s\":", MAX_CMD_LEN, cmd); cb_data_buf = &out_buf[prefix_used]; @@ -192,6 +251,18 @@ output_json(const char *cmd, const struct rte_tel_data *d, int s) used = rte_tel_json_add_array_u64(cb_data_buf, buf_len, used, d->data.array[i].u64val); + else if (d->type == RTE_TEL_ARRAY_CONTAINER) { + char temp[buf_len]; + const struct container *rec_data = + &d->data.array[i].container; + if (container_to_json(rec_data->data, + temp, buf_len) != 0) + used = rte_tel_json_add_array_json( + cb_data_buf, + buf_len, used, temp); + if (!rec_data->keep) + rte_tel_data_free(rec_data->data); + } used += prefix_used; used += strlcat(out_buf + used, "}", sizeof(out_buf) - used); break; @@ -243,7 +314,7 @@ client_handler(void *sock_id) while (bytes > 0) { buffer[bytes] = 0; const char *cmd = strtok(buffer, ","); - const char *param = strtok(NULL, ","); + const char *param = strtok(NULL, "\0"); telemetry_cb fn = unknown_command; int i; @@ -261,6 +332,7 @@ client_handler(void *sock_id) bytes = read(s, buffer, sizeof(buffer) - 1); } close(s); + __atomic_sub_fetch(&v2_clients, 1, __ATOMIC_RELAXED); return NULL; } @@ -273,10 +345,20 @@ socket_listener(void *socket) int s_accepted = accept(s->sock, NULL, NULL); if (s_accepted < 0) { snprintf(telemetry_log_error, - sizeof(telemetry_log_error), - "Error with accept, telemetry thread quitting\n"); + sizeof(telemetry_log_error), + "Error with accept, telemetry thread quitting"); return NULL; } + if (s->num_clients != NULL) { + uint16_t conns = __atomic_load_n(s->num_clients, + __ATOMIC_RELAXED); + if (conns >= MAX_CONNECTIONS) { + close(s_accepted); + continue; + } + __atomic_add_fetch(s->num_clients, 1, + __ATOMIC_RELAXED); + } pthread_create(&th, NULL, s->fn, (void *)(uintptr_t)s_accepted); pthread_detach(th); } @@ -297,6 +379,8 @@ unlink_sockets(void) { if (v2_socket.path[0]) unlink(v2_socket.path); + if (v1_socket.path[0]) + unlink(v1_socket.path); } static int @@ -337,10 +421,39 @@ error: } static int -telemetry_v2_init(const char *runtime_dir) +telemetry_legacy_init(const char *runtime_dir, rte_cpuset_t *cpuset) +{ + pthread_t t_old; + + if (num_legacy_callbacks == 1) { + snprintf(telemetry_log_error, sizeof(telemetry_log_error), + "No legacy callbacks, legacy socket not created"); + return -1; + } + + v1_socket.fn = legacy_client_handler; + if ((size_t) snprintf(v1_socket.path, sizeof(v1_socket.path), + "%s/telemetry", runtime_dir) + >= sizeof(v1_socket.path)) { + snprintf(telemetry_log_error, sizeof(telemetry_log_error), + "Error with socket binding, path too long"); + return -1; + } + v1_socket.sock = create_socket(v1_socket.path); + if (v1_socket.sock < 0) + return -1; + pthread_create(&t_old, NULL, socket_listener, &v1_socket); + pthread_setaffinity_np(t_old, sizeof(*cpuset), cpuset); + + return 0; +} + +static int +telemetry_v2_init(const char *runtime_dir, rte_cpuset_t *cpuset) { pthread_t t_new; + v2_socket.num_clients = &v2_clients; rte_telemetry_register_cmd("/", list_commands, "Returns list of available commands, Takes no parameters"); rte_telemetry_register_cmd("/info", json_info, @@ -359,19 +472,34 @@ telemetry_v2_init(const char *runtime_dir) if (v2_socket.sock < 0) return -1; pthread_create(&t_new, NULL, socket_listener, &v2_socket); + pthread_setaffinity_np(t_new, sizeof(*cpuset), cpuset); atexit(unlink_sockets); return 0; } +#endif /* !RTE_EXEC_ENV_WINDOWS */ + int32_t -rte_telemetry_new_init(void) +rte_telemetry_init(const char *runtime_dir, rte_cpuset_t *cpuset, + const char **err_str) { - const char *error_str; - if (telemetry_v2_init(rte_eal_get_runtime_dir()) != 0) { - error_str = telemetry_log_error; - printf("Error initialising telemetry - %s", error_str); +#ifndef RTE_EXEC_ENV_WINDOWS + if (telemetry_v2_init(runtime_dir, cpuset) != 0) { + *err_str = telemetry_log_error; return -1; } + if (telemetry_legacy_init(runtime_dir, cpuset) != 0) { + *err_str = telemetry_log_error; + } +#else /* RTE_EXEC_ENV_WINDOWS */ + RTE_SET_USED(runtime_dir); + RTE_SET_USED(cpuset); + RTE_SET_USED(err_str); + + snprintf(telemetry_log_error, sizeof(telemetry_log_error), + "DPDK Telemetry is not supported on Windows."); +#endif /* RTE_EXEC_ENV_WINDOWS */ + return 0; }