X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=lib%2Flibrte_telemetry%2Ftelemetry.c;h=14b4ff5ea7cd12c7ef1d42a4c607bb95e36de664;hb=5b637a848195c139829c4a7778528eba1978b50e;hp=9f4234c049c49016161848bf1892fc942cfac8ca;hpb=f38748736eb2010d2771259e3584e9fda7c72edd;p=dpdk.git diff --git a/lib/librte_telemetry/telemetry.c b/lib/librte_telemetry/telemetry.c index 9f4234c049..14b4ff5ea7 100644 --- a/lib/librte_telemetry/telemetry.c +++ b/lib/librte_telemetry/telemetry.c @@ -2,29 +2,34 @@ * 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 #include #include #include -#include #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 +37,27 @@ 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 const char *telemetry_version; /* save rte_version */ 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 +87,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) @@ -90,7 +106,7 @@ json_info(const char *cmd __rte_unused, const char *params __rte_unused, struct rte_tel_data *d) { rte_tel_data_start_dict(d); - rte_tel_data_add_dict_string(d, "version", rte_version()); + rte_tel_data_add_dict_string(d, "version", telemetry_version); rte_tel_data_add_dict_int(d, "pid", getpid()); rte_tel_data_add_dict_int(d, "max_output_len", MAX_OUTPUT_LEN); return 0; @@ -118,6 +134,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 +209,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 +231,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 +252,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; @@ -232,7 +304,7 @@ client_handler(void *sock_id) char info_str[1024]; snprintf(info_str, sizeof(info_str), "{\"version\":\"%s\",\"pid\":%d,\"max_output_len\":%d}", - rte_version(), getpid(), MAX_OUTPUT_LEN); + telemetry_version, getpid(), MAX_OUTPUT_LEN); if (write(s, info_str, strlen(info_str)) < 0) { close(s); return NULL; @@ -243,7 +315,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 +333,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 +346,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 +380,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 +422,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 +473,35 @@ 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, const char *rte_version, + 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); + telemetry_version = rte_version; +#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; }