get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/69016/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 69016,
    "url": "http://patches.dpdk.org/api/patches/69016/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20200421123949.38270-6-ciara.power@intel.com/",
    "project": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<20200421123949.38270-6-ciara.power@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20200421123949.38270-6-ciara.power@intel.com",
    "date": "2020-04-21T12:39:37",
    "name": "[v3,05/17] telemetry: introduce new telemetry functionality",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "4d8b9443f986dd7cdf7268fca43c113417bce208",
    "submitter": {
        "id": 978,
        "url": "http://patches.dpdk.org/api/people/978/?format=api",
        "name": "Power, Ciara",
        "email": "ciara.power@intel.com"
    },
    "delegate": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/users/1/?format=api",
        "username": "tmonjalo",
        "first_name": "Thomas",
        "last_name": "Monjalon",
        "email": "thomas@monjalon.net"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/20200421123949.38270-6-ciara.power@intel.com/mbox/",
    "series": [
        {
            "id": 9543,
            "url": "http://patches.dpdk.org/api/series/9543/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=9543",
            "date": "2020-04-21T12:39:32",
            "name": "update and simplify telemetry library.",
            "version": 3,
            "mbox": "http://patches.dpdk.org/series/9543/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/69016/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/69016/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "Received": [
            "from dpdk.org (dpdk.org [92.243.14.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 2671CA0597;\n\tTue, 21 Apr 2020 15:00:39 +0200 (CEST)",
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 9CBB51D58F;\n\tTue, 21 Apr 2020 14:59:38 +0200 (CEST)",
            "from mga11.intel.com (mga11.intel.com [192.55.52.93])\n by dpdk.org (Postfix) with ESMTP id EAF751D570\n for <dev@dpdk.org>; Tue, 21 Apr 2020 14:59:36 +0200 (CEST)",
            "from fmsmga004.fm.intel.com ([10.253.24.48])\n by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 21 Apr 2020 05:59:36 -0700",
            "from silpixa00399953.ir.intel.com (HELO\n silpixa00399953.ger.corp.intel.com) ([10.237.222.53])\n by fmsmga004.fm.intel.com with ESMTP; 21 Apr 2020 05:59:33 -0700"
        ],
        "IronPort-SDR": [
            "\n 3ATeYFbUYLRWu+nKzheVyaRwnMhpoUHIycm2ux9wmi3XKyihd9IQEUae6MOidTDmWi/Fyy0wvS\n R1Th2gUE1fHw==",
            "\n AwdgZfvP3DWZ/33X/Sh0Hf7b7EKEOkMVe2XEYtEbBjG7BYsn/HzQ0uRHbk3zxUzO9d4WWGkcQ9\n onPGGv4QRIRg=="
        ],
        "X-Amp-Result": "SKIPPED(no attachment in message)",
        "X-Amp-File-Uploaded": "False",
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.72,410,1580803200\"; d=\"scan'208\";a=\"279629089\"",
        "From": "Ciara Power <ciara.power@intel.com>",
        "To": "dev@dpdk.org,\n\tkevin.laatz@intel.com",
        "Cc": "reshma.pattan@intel.com, jerinjacobk@gmail.com, david.marchand@redhat.com,\n keith.wiles@intel.com, mb@smartsharesystems.com, thomas@monjalon.net,\n Bruce Richardson <bruce.richardson@intel.com>,\n Ciara Power <ciara.power@intel.com>",
        "Date": "Tue, 21 Apr 2020 13:39:37 +0100",
        "Message-Id": "<20200421123949.38270-6-ciara.power@intel.com>",
        "X-Mailer": "git-send-email 2.17.1",
        "In-Reply-To": "<20200421123949.38270-1-ciara.power@intel.com>",
        "References": "<20200319171907.60891-1-ciara.power@intel.com>\n <20200421123949.38270-1-ciara.power@intel.com>",
        "Subject": "[dpdk-dev] [PATCH v3 05/17] telemetry: introduce new telemetry\n\tfunctionality",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n <mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "From: Bruce Richardson <bruce.richardson@intel.com>\n\nThis patch introduces a new telemetry connection socket and handling\nfunctionality. Like the existing telemetry implementation (which is\nunaffected by this change) it uses a unix socket, but unlike the\nexisting one it does not have a fixed list of commands - instead\nlibraries or applications can register telemetry commands and callbacks\nto provide a full-extensible solution for all kinds of telemetry across\nDPDK.\n\nSigned-off-by: Bruce Richardson <bruce.richardson@intel.com>\nSigned-off-by: Ciara Power <ciara.power@intel.com>\n\n---\nv2:\n  - Added DPDK information message on client connection.\n  - Added /info command to get DPDK information post-connect.\n  - Replaced pid in socket name with v2.\n  - Increased output buffer size to 16k.\n  - Telemetry default callbacks now registered by init function.\n---\n lib/librte_telemetry/Makefile                 |   4 +\n lib/librte_telemetry/meson.build              |   5 +-\n lib/librte_telemetry/rte_telemetry.c          |   3 +\n lib/librte_telemetry/rte_telemetry.h          |  72 ++++-\n .../rte_telemetry_version.map                 |   2 +\n lib/librte_telemetry/telemetry.c              | 278 ++++++++++++++++++\n 6 files changed, 362 insertions(+), 2 deletions(-)\n create mode 100644 lib/librte_telemetry/telemetry.c",
    "diff": "diff --git a/lib/librte_telemetry/Makefile b/lib/librte_telemetry/Makefile\nindex 2d7e442ab0..270e1aac54 100644\n--- a/lib/librte_telemetry/Makefile\n+++ b/lib/librte_telemetry/Makefile\n@@ -9,6 +9,9 @@ LIB = librte_telemetry.a\n CFLAGS += -O3\n CFLAGS += $(WERROR_FLAGS) -I$(SRCDIR)\n CFLAGS += -I$(RTE_SDK)/lib/librte_metrics/\n+CFLAGS += -I$(RTE_SDK)/lib/librte_eal/include\n+CFLAGS += -I$(RTE_SDK)/lib/librte_eal/$(ARCH_DIR)/include\n+CFLAGS += -pthread\n \n LDLIBS += -lrte_eal\n LDLIBS += -lpthread\n@@ -20,6 +23,7 @@ EXPORT_MAP := rte_telemetry_version.map\n SRCS-$(CONFIG_RTE_LIBRTE_TELEMETRY) := rte_telemetry.c\n SRCS-$(CONFIG_RTE_LIBRTE_TELEMETRY) += rte_telemetry_parser.c\n SRCS-$(CONFIG_RTE_LIBRTE_TELEMETRY) += rte_telemetry_parser_test.c\n+SRCS-$(CONFIG_RTE_LIBRTE_TELEMETRY) += telemetry.c\n \n # export include files\n SYMLINK-$(CONFIG_RTE_LIBRTE_TELEMETRY)-include := rte_telemetry.h\ndiff --git a/lib/librte_telemetry/meson.build b/lib/librte_telemetry/meson.build\nindex 18b214a8e8..0cdae414a4 100644\n--- a/lib/librte_telemetry/meson.build\n+++ b/lib/librte_telemetry/meson.build\n@@ -1,7 +1,10 @@\n # SPDX-License-Identifier: BSD-3-Clause\n # Copyright(c) 2018 Intel Corporation\n \n-sources = files('rte_telemetry.c', 'rte_telemetry_parser.c', 'rte_telemetry_parser_test.c')\n+includes = [global_inc]\n+\n+sources = files('rte_telemetry.c', 'rte_telemetry_parser.c', 'rte_telemetry_parser_test.c',\n+\t'telemetry.c')\n headers = files('rte_telemetry.h', 'rte_telemetry_internal.h', 'rte_telemetry_parser.h')\n includes += include_directories('../librte_metrics')\n \ndiff --git a/lib/librte_telemetry/rte_telemetry.c b/lib/librte_telemetry/rte_telemetry.c\nindex 2fb8ffe873..45b6d9d948 100644\n--- a/lib/librte_telemetry/rte_telemetry.c\n+++ b/lib/librte_telemetry/rte_telemetry.c\n@@ -503,6 +503,9 @@ rte_telemetry_init(void)\n \t\treturn -EPERM;\n \t}\n \n+\tif (rte_telemetry_new_init() != 0)\n+\t\treturn -1;\n+\n \treturn 0;\n }\n \ndiff --git a/lib/librte_telemetry/rte_telemetry.h b/lib/librte_telemetry/rte_telemetry.h\nindex aedb318598..27067b1250 100644\n--- a/lib/librte_telemetry/rte_telemetry.h\n+++ b/lib/librte_telemetry/rte_telemetry.h\n@@ -3,19 +3,59 @@\n  */\n \n #include <stdint.h>\n+#include <rte_compat.h>\n \n #ifndef _RTE_TELEMETRY_H_\n #define _RTE_TELEMETRY_H_\n \n+/** Maximum number of telemetry callbacks. */\n+#define TELEMETRY_MAX_CALLBACKS 64\n+\n /**\n+ * @warning\n+ * @b EXPERIMENTAL: all functions in this file may change without prior notice\n+ *\n  * @file\n  * RTE Telemetry\n  *\n  * The telemetry library provides a method to retrieve statistics from\n- * DPDK by sending a JSON encoded message over a socket. DPDK will send\n+ * DPDK by sending a request message over a socket. DPDK will send\n  * a JSON encoded response containing telemetry data.\n  ***/\n \n+/**\n+ * This telemetry callback is used when registering a command.\n+ * It handles getting and formatting stats to be returned to telemetry when\n+ * requested. Stats up to buf_len in length are put in the buffer.\n+ *\n+ * @param cmd\n+ * The cmd that was requested by the client.\n+ * @param params\n+ * Contains data required by the callback function.\n+ * @param buffer\n+ * A buffer to hold the formatted response.\n+ * @param buf_len\n+ * Length of the buffer.\n+ *\n+ * @return\n+ * Length of buffer used on success.\n+ * @return\n+ * Negative integer on error.\n+ */\n+typedef int (*telemetry_cb)(const char *cmd, const char *params,\n+\t\tchar *buffer, int buf_len);\n+\n+/**\n+ * Used for handling data received over a telemetry socket.\n+ *\n+ * @param sock_id\n+ * ID for the socket to be used by the handler.\n+ *\n+ * @return\n+ * Void.\n+ */\n+typedef void * (*handler)(void *sock_id);\n+\n /**\n  * @warning\n  * @b EXPERIMENTAL: this API may change without prior notice\n@@ -66,4 +106,34 @@ __rte_experimental\n int32_t\n rte_telemetry_selftest(void);\n \n+/**\n+ * Used when registering a command and callback function with telemetry.\n+ *\n+ * @param cmd\n+ * The command to register with telemetry.\n+ * @param fn\n+ * Callback function to be called when the command is requested.\n+ *\n+ * @return\n+ *  0 on success.\n+ * @return\n+ *  -EINVAL for invalid parameters failure.\n+ *  @return\n+ *  -ENOENT if max callbacks limit has been reached.\n+ */\n+__rte_experimental\n+int\n+rte_telemetry_register_cmd(const char *cmd, telemetry_cb fn);\n+\n+/**\n+ * Initialize new version of Telemetry.\n+ *\n+ * @return\n+ *  0 on success.\n+ * @return\n+ *  -1 on failure.\n+ */\n+__rte_experimental\n+int\n+rte_telemetry_new_init(void);\n #endif\ndiff --git a/lib/librte_telemetry/rte_telemetry_version.map b/lib/librte_telemetry/rte_telemetry_version.map\nindex a80058c59c..831bbd59ad 100644\n--- a/lib/librte_telemetry/rte_telemetry_version.map\n+++ b/lib/librte_telemetry/rte_telemetry_version.map\n@@ -6,6 +6,8 @@ EXPERIMENTAL {\n \trte_telemetry_parse;\n \trte_telemetry_selftest;\n \trte_telemetry_set_metrics_fns;\n+\trte_telemetry_new_init;\n+\trte_telemetry_register_cmd;\n \n \tlocal: *;\n };\ndiff --git a/lib/librte_telemetry/telemetry.c b/lib/librte_telemetry/telemetry.c\nnew file mode 100644\nindex 0000000000..ed450df501\n--- /dev/null\n+++ b/lib/librte_telemetry/telemetry.c\n@@ -0,0 +1,278 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2020 Intel Corporation\n+ */\n+\n+#include <unistd.h>\n+#include <pthread.h>\n+#include <sys/socket.h>\n+#include <sys/un.h>\n+#include <dlfcn.h>\n+\n+/* we won't link against libbsd, so just always use DPDKs-specific strlcpy */\n+#undef RTE_USE_LIBBSD\n+#include <rte_string_fns.h>\n+#include <rte_common.h>\n+#include <rte_spinlock.h>\n+#include <rte_version.h>\n+\n+#include \"rte_telemetry.h\"\n+\n+#define MAX_CMD_LEN 56\n+#define MAX_OUTPUT_LEN (1024 * 16)\n+\n+static int\n+list_commands(const char *cmd __rte_unused, const char *params __rte_unused,\n+\t\tchar *buffer, int buf_len);\n+\n+static int\n+handle_info(const char *cmd __rte_unused, const char *params __rte_unused,\n+\t\tchar *buffer, int buf_len);\n+\n+static void *\n+client_handler(void *socket);\n+\n+struct cmd_callback {\n+\tchar cmd[MAX_CMD_LEN];\n+\ttelemetry_cb fn;\n+};\n+\n+struct socket {\n+\tint sock;\n+\tchar path[sizeof(((struct sockaddr_un *)0)->sun_path)];\n+\thandler fn;\n+};\n+static struct socket v2_socket; /* socket for v2 telemetry */\n+static char telemetry_log_error[1024]; /* Will contain error on init failure */\n+/* list of command callbacks, with one command registered by default */\n+static struct cmd_callback callbacks[TELEMETRY_MAX_CALLBACKS];\n+static int num_callbacks; /* How many commands are registered */\n+/* Used when accessing or modifying list of command callbacks */\n+static rte_spinlock_t callback_sl = RTE_SPINLOCK_INITIALIZER;\n+\n+int\n+rte_telemetry_register_cmd(const char *cmd, telemetry_cb fn)\n+{\n+\tint i = 0;\n+\n+\tif (strlen(cmd) >= MAX_CMD_LEN || fn == NULL || cmd[0] != '/')\n+\t\treturn -EINVAL;\n+\tif (num_callbacks >= TELEMETRY_MAX_CALLBACKS)\n+\t\treturn -ENOENT;\n+\n+\trte_spinlock_lock(&callback_sl);\n+\twhile (i < num_callbacks && strcmp(cmd, callbacks[i].cmd) > 0)\n+\t\ti++;\n+\tif (i != num_callbacks)\n+\t\t/* Move elements to keep the list alphabetical */\n+\t\tmemmove(callbacks + i + 1, callbacks + i,\n+\t\t\tsizeof(struct cmd_callback) * (num_callbacks - i));\n+\n+\tstrlcpy(callbacks[i].cmd, cmd, MAX_CMD_LEN);\n+\tcallbacks[i].fn = fn;\n+\tnum_callbacks++;\n+\trte_spinlock_unlock(&callback_sl);\n+\n+\treturn 0;\n+}\n+\n+static int\n+list_commands(const char *cmd __rte_unused, const char *params __rte_unused,\n+\t\tchar *buffer, int buf_len)\n+{\n+\tint i, ret, used = 0;\n+\n+\tused += strlcpy(buffer, \"[\", buf_len);\n+\tfor (i = 0; i < num_callbacks; i++) {\n+\t\tret = snprintf(buffer + used, buf_len - used, \"\\\"%s\\\",\",\n+\t\t\t\tcallbacks[i].cmd);\n+\t\tif (ret + used >= buf_len)\n+\t\t\tbreak;\n+\t\tused += ret;\n+\t}\n+\tbuffer[used - 1] = ']';\n+\treturn used;\n+}\n+\n+static int\n+handle_info(const char *cmd __rte_unused, const char *params __rte_unused,\n+\t\tchar *buffer, int buf_len)\n+{\n+\tint ret = snprintf(buffer, buf_len,\n+\t\t\t\"{\\\"pid\\\":%d,\\\"version\\\":\\\"%s\\\",\\\"max_output_len\\\":%d}\",\n+\t\t\tgetpid(), rte_version(), MAX_OUTPUT_LEN);\n+\treturn ret >= buf_len ? -1 : ret;\n+}\n+\n+static void\n+perform_command(telemetry_cb fn, const char *cmd, const char *param, int s)\n+{\n+\tchar out_buf[MAX_OUTPUT_LEN];\n+\n+\tint used = snprintf(out_buf,\n+\t\t\tsizeof(out_buf), \"{\\\"%s\\\":\", cmd ?: \"none\");\n+\tint ret = fn(cmd, param, out_buf + used, sizeof(out_buf) - used);\n+\tif (ret < 0) {\n+\t\tused += strlcpy(out_buf + used, \"null}\",\n+\t\t\t\tsizeof(out_buf) - used);\n+\t\tif (write(s, out_buf, used) < 0)\n+\t\t\tperror(\"Error writing to socket\");\n+\t\treturn;\n+\t}\n+\tused += ret;\n+\tused += strlcpy(out_buf + used, \"}\", sizeof(out_buf) - used);\n+\tif (write(s, out_buf, used) < 0)\n+\t\tperror(\"Error writing to socket\");\n+}\n+\n+static int\n+unknown_command(const char *cmd __rte_unused, const char *params __rte_unused,\n+\t\tchar *buffer, int buf_len)\n+{\n+\treturn snprintf(buffer, buf_len, \"null\");\n+}\n+\n+static void *\n+client_handler(void *sock_id)\n+{\n+\tint s = (int)(uintptr_t)sock_id;\n+\tchar buffer[1024];\n+\n+\t/* receive data is not null terminated */\n+\tint bytes = read(s, buffer, sizeof(buffer) - 1);\n+\tbuffer[bytes] = 0;\n+\twhile (bytes > 0) {\n+\t\tconst char *cmd = strtok(buffer, \",\");\n+\t\tconst char *param = strtok(NULL, \",\");\n+\t\ttelemetry_cb fn = unknown_command;\n+\t\tint i;\n+\n+\t\tif (cmd) {\n+\t\t\trte_spinlock_lock(&callback_sl);\n+\t\t\tfor (i = 0; i < num_callbacks; i++)\n+\t\t\t\tif (strcmp(cmd, callbacks[i].cmd) == 0) {\n+\t\t\t\t\tfn = callbacks[i].fn;\n+\t\t\t\t\tbreak;\n+\t\t\t\t}\n+\t\t\trte_spinlock_unlock(&callback_sl);\n+\t\t}\n+\t\tperform_command(fn, cmd, param, s);\n+\n+\t\tbytes = read(s, buffer, sizeof(buffer) - 1);\n+\t\tbuffer[bytes] = 0;\n+\t}\n+\tclose(s);\n+\treturn NULL;\n+}\n+\n+static void *\n+socket_listener(void *socket)\n+{\n+\twhile (1) {\n+\t\tpthread_t th;\n+\t\tstruct socket *s = (struct socket *)socket;\n+\t\tint s_accepted = accept(s->sock, NULL, NULL);\n+\t\tif (s_accepted < 0) {\n+\t\t\tsnprintf(telemetry_log_error,\n+\t\t\t\t\tsizeof(telemetry_log_error),\n+\t\t\t\t\t\"Error with accept, telemetry thread quitting\\n\");\n+\t\t\treturn NULL;\n+\t\t}\n+\t\tchar info_buf[1024];\n+\t\tif (handle_info(NULL, NULL, info_buf, sizeof(info_buf)) < 0)\n+\t\t\tstrlcpy(info_buf, \"{}\", sizeof(info_buf));\n+\t\tif (write(s_accepted, info_buf, strlen(info_buf)) < 0)\n+\t\t\tperror(\"Error writing to socket\");\n+\t\tpthread_create(&th, NULL, s->fn, (void *)(uintptr_t)s_accepted);\n+\t\tpthread_detach(th);\n+\t}\n+\treturn NULL;\n+}\n+\n+static inline char *\n+get_socket_path(const char *runtime_dir, const int version)\n+{\n+\tstatic char path[PATH_MAX];\n+\tsnprintf(path, sizeof(path), \"%s/dpdk_telemetry.v%d\",\n+\t\t\tstrlen(runtime_dir) ? runtime_dir : \"/tmp\", version);\n+\treturn path;\n+}\n+\n+static void\n+unlink_sockets(void)\n+{\n+\tif (v2_socket.path[0])\n+\t\tunlink(v2_socket.path);\n+}\n+\n+static int\n+create_socket(char *path)\n+{\n+\tint sock = socket(AF_UNIX, SOCK_SEQPACKET, 0);\n+\tif (sock < 0) {\n+\t\tsnprintf(telemetry_log_error, sizeof(telemetry_log_error),\n+\t\t\t\t\"Error with socket creation, %s\",\n+\t\t\t\tstrerror(errno));\n+\t\treturn -1;\n+\t}\n+\n+\tstruct sockaddr_un sun = {.sun_family = AF_UNIX};\n+\tstrlcpy(sun.sun_path, path, sizeof(sun.sun_path));\n+\tunlink(sun.sun_path);\n+\tif (bind(sock, (void *) &sun, sizeof(sun)) < 0) {\n+\t\tsnprintf(telemetry_log_error, sizeof(telemetry_log_error),\n+\t\t\t\t\"Error binding socket: %s\",\n+\t\t\t\tstrerror(errno));\n+\t\tsun.sun_path[0] = 0;\n+\t\tgoto error;\n+\t}\n+\n+\tif (listen(sock, 1) < 0) {\n+\t\tsnprintf(telemetry_log_error, sizeof(telemetry_log_error),\n+\t\t\t\t\"Error calling listen for socket: %s\",\n+\t\t\t\tstrerror(errno));\n+\t\tgoto error;\n+\t}\n+\n+\treturn sock;\n+\n+error:\n+\tclose(sock);\n+\tunlink_sockets();\n+\treturn -1;\n+}\n+\n+static int\n+telemetry_v2_init(const char *runtime_dir)\n+{\n+\tpthread_t t_new;\n+\n+\trte_telemetry_register_cmd(\"/\", list_commands);\n+\trte_telemetry_register_cmd(\"/info\", handle_info);\n+\tv2_socket.fn = client_handler;\n+\tif (strlcpy(v2_socket.path, get_socket_path(runtime_dir, 2),\n+\t\t\tsizeof(v2_socket.path)) >= sizeof(v2_socket.path)) {\n+\t\tsnprintf(telemetry_log_error, sizeof(telemetry_log_error),\n+\t\t\t\t\"Error with socket binding, path too long\");\n+\t\treturn -1;\n+\t}\n+\n+\tv2_socket.sock = create_socket(v2_socket.path);\n+\tif (v2_socket.sock < 0)\n+\t\treturn -1;\n+\tpthread_create(&t_new, NULL, socket_listener, &v2_socket);\n+\tatexit(unlink_sockets);\n+\n+\treturn 0;\n+}\n+\n+int32_t\n+rte_telemetry_new_init(void)\n+{\n+\tconst char *error_str;\n+\tif (telemetry_v2_init(rte_eal_get_runtime_dir()) != 0) {\n+\t\terror_str = telemetry_log_error;\n+\t\tprintf(\"Error initialising telemetry - %s\", error_str);\n+\t\treturn -1;\n+\t}\n+\treturn 0;\n+}\n",
    "prefixes": [
        "v3",
        "05/17"
    ]
}