X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;ds=sidebyside;f=lib%2Flibrte_telemetry%2Ftelemetry.c;h=51e7ceeb1b2c29db515242eef5c41cb14e924879;hb=0f9ac2afa62ebacd24f36a3b98272b7146be3edd;hp=d1e92340dd1b142ce43fec31ee1ebc4e099cef07;hpb=6dd571fd07c3b79b0176f5aba3ae99cfbee582dd;p=dpdk.git diff --git a/lib/librte_telemetry/telemetry.c b/lib/librte_telemetry/telemetry.c index d1e92340dd..51e7ceeb1b 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,53 @@ 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) +{ + int i; + + rte_tel_data_start_array(d, RTE_TEL_STRING_VAL); + for (i = 0; i < num_callbacks; i++) + rte_tel_data_add_array_string(d, callbacks[i].cmd); + return 0; +} + +static int +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_int(d, "pid", getpid()); + rte_tel_data_add_dict_int(d, "max_output_len", MAX_OUTPUT_LEN); + return 0; +} + +static int +command_help(const char *cmd __rte_unused, const char *params, + struct rte_tel_data *d) +{ + int i; + + if (!params) + return -1; + rte_tel_data_start_dict(d); + rte_spinlock_lock(&callback_sl); + for (i = 0; i < num_callbacks; i++) + if (strcmp(params, callbacks[i].cmd) == 0) { + rte_tel_data_add_dict_string(d, params, + callbacks[i].help); + break; + } + rte_spinlock_unlock(&callback_sl); + if (i == num_callbacks) + return -1; + return 0; +} + static void output_json(const char *cmd, const struct rte_tel_data *d, int s) { @@ -216,6 +276,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; } @@ -228,10 +289,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); } @@ -252,6 +323,8 @@ unlink_sockets(void) { if (v2_socket.path[0]) unlink(v2_socket.path); + if (v1_socket.path[0]) + unlink(v1_socket.path); } static int @@ -292,10 +365,45 @@ 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, + "Returns DPDK Telemetry information. Takes no parameters"); + rte_telemetry_register_cmd("/help", command_help, + "Returns help text for a command. Parameters: string command"); v2_socket.fn = client_handler; if (strlcpy(v2_socket.path, get_socket_path(runtime_dir, 2), sizeof(v2_socket.path)) >= sizeof(v2_socket.path)) { @@ -308,19 +416,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; }