From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 1C1D2A00C2; Fri, 24 Apr 2020 22:50:39 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 961A21C25E; Fri, 24 Apr 2020 22:50:38 +0200 (CEST) Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by dpdk.org (Postfix) with ESMTP id 3D4D11B53 for ; Fri, 24 Apr 2020 22:50:36 +0200 (CEST) IronPort-SDR: gDQKeQVlLBZ+CTUjpjcFqWveddh+zU9hOyXNN2nsPXoUIsyBJVIZRhPgKDl4UFZ2vrVTPwtCon 8igKUhSb5mgQ== X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Apr 2020 13:50:35 -0700 IronPort-SDR: MS6D0cv9qKf1gAqLB39twjtAOWA4cCEPE47gko3JKR5YRh1QMlMkVn04Y/sdgv6FbHwaPrT4WC xp2nM9Dhyn5A== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.73,313,1583222400"; d="scan'208";a="291705625" Received: from fmsmsx103.amr.corp.intel.com ([10.18.124.201]) by fmsmga002.fm.intel.com with ESMTP; 24 Apr 2020 13:50:35 -0700 Received: from fmsmsx161.amr.corp.intel.com (10.18.125.9) by FMSMSX103.amr.corp.intel.com (10.18.124.201) with Microsoft SMTP Server (TLS) id 14.3.439.0; Fri, 24 Apr 2020 13:50:30 -0700 Received: from FMSEDG001.ED.cps.intel.com (10.1.192.133) by FMSMSX161.amr.corp.intel.com (10.18.125.9) with Microsoft SMTP Server (TLS) id 14.3.439.0; Fri, 24 Apr 2020 13:50:30 -0700 Received: from NAM12-BN8-obe.outbound.protection.outlook.com (104.47.55.173) by edgegateway.intel.com (192.55.55.68) with Microsoft SMTP Server (TLS) id 14.3.439.0; Fri, 24 Apr 2020 13:50:30 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=DfAETeBe9PDR+OwdVa3Ufl76yz1Rd6ZHzaH0Le+8lNmZH5dVcqlslnrzUUKt5xDQm74hzIUNuO4/tlpYgm2StvMHQqEcJ5yntP8eIErgzXChatcvDlfgl9CuNNAh4AOLqorKI0F1HSTitdRN5d/4V7Hq1LAFqYkmBQ1a/diLvDg6eSt5c9OJSEnZdmEpc51wNPZtPjY47ZMjpFXMrziWUegA/5o/ehbij2dSsej1r0ZRvJCR7EVBAz8I1W4OCJBSI7Nel984ciIcN0y01Svo9zuV4v99mMtFhdxVilC0+kLLd8Pr5nngeLH6ybxoY4kqqigwYtL8Wdtxv1CQbbyvdA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=5XHst51n5acf75QlTZSYBGpQZ7LbFhfup1BiN8u0Hn0=; b=gsdgtoCbgOyU5w8R9h3ZeNTLC8pKRf3B2gcIjvtkkW667x7nS4gyDo1sM2ZamJcTjN5okz6NaFgE20JDtsbW6bmD02MMNYFskRPZeEtCgHj1ItvxtMKHPnkQpYNl9VN+uAcfuWTtdiajLlknZv6hjiJ3dc1/xrRL5/2t5x0ZdW6MVCERvEQGOTjqqdNgkjVKGJuHFvJJbwb3GdCETLUgh6qQCMRN6QqSepgJtXUMMAUGkhkUS6jPghiUDLhyxD8o1kcKwV3FIQzDmUheH8uxkQleVoc936DshR2GNzLWpa/4135CLkcNRKiFi529cud2CxfCKmpEyiNwkRVmRa1eng== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=intel.com; dmarc=pass action=none header.from=intel.com; dkim=pass header.d=intel.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=intel.onmicrosoft.com; s=selector2-intel-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=5XHst51n5acf75QlTZSYBGpQZ7LbFhfup1BiN8u0Hn0=; b=kxJcdJ0/A5wslpZ/8OcVmIldt8X/T298sJvZ6fFGLqET6wSftFflSiiA9mx4VwyKpH892u3eSM84FrMpvggJkuD/jbn2lk4B3bItwibbQupkOS/8dKvDMeuqICxI10WanVzw1FTjz6vPKePxoqh4LgUrZ2sp3bB3zHfu4ucKeCc= Received: from DM6PR11MB4593.namprd11.prod.outlook.com (2603:10b6:5:2a3::8) by DM6PR11MB2570.namprd11.prod.outlook.com (2603:10b6:5:ce::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2921.27; Fri, 24 Apr 2020 20:50:28 +0000 Received: from DM6PR11MB4593.namprd11.prod.outlook.com ([fe80::acee:4fa2:2a9e:7cd6]) by DM6PR11MB4593.namprd11.prod.outlook.com ([fe80::acee:4fa2:2a9e:7cd6%3]) with mapi id 15.20.2937.020; Fri, 24 Apr 2020 20:50:28 +0000 From: "Wiles, Keith" To: "Power, Ciara" CC: dev , "Laatz, Kevin" , "Pattan, Reshma" , "jerinjacobk@gmail.com" , "david.marchand@redhat.com" , "mb@smartsharesystems.com" , "thomas@monjalon.net" , "Richardson, Bruce" Thread-Topic: [PATCH v4 06/18] telemetry: introduce new telemetry functionality Thread-Index: AQHWGjikhat/Ikcrh0qDbK6i0mzSL6iIv4aA Date: Fri, 24 Apr 2020 20:50:27 +0000 Message-ID: <497D7C7E-EAAE-4343-A249-716824D1386A@intel.com> References: <20200319171907.60891-1-ciara.power@intel.com> <20200424124159.45989-1-ciara.power@intel.com> <20200424124159.45989-7-ciara.power@intel.com> In-Reply-To: <20200424124159.45989-7-ciara.power@intel.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: authentication-results: spf=none (sender IP is ) smtp.mailfrom=keith.wiles@intel.com; x-originating-ip: [47.24.6.94] x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: b0155f92-b3b0-4128-e39d-08d7e8911ed3 x-ms-traffictypediagnostic: DM6PR11MB2570: x-ld-processed: 46c98d88-e344-4ed4-8496-4ed7712e255d,ExtAddr x-ms-exchange-transport-forked: True x-microsoft-antispam-prvs: x-ms-oob-tlc-oobclassifiers: OLM:2803; x-forefront-prvs: 03838E948C x-forefront-antispam-report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:DM6PR11MB4593.namprd11.prod.outlook.com; PTR:; CAT:NONE; SFTY:; SFS:(10019020)(346002)(366004)(39860400002)(396003)(376002)(136003)(26005)(8936002)(66446008)(91956017)(76116006)(66946007)(5660300002)(66556008)(66476007)(81156014)(86362001)(64756008)(6636002)(36756003)(71200400001)(30864003)(186003)(53546011)(478600001)(37006003)(6862004)(107886003)(8676002)(54906003)(6512007)(316002)(33656002)(4326008)(6506007)(6486002)(2906002)(2616005); DIR:OUT; SFP:1102; x-ms-exchange-senderadcheck: 1 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: KnR4OMQ0AfZC273ISGAAmjENpOQME16f4Bxbk9+48uD19e1dYwj0GpUgmgPr4+5Rhw8g/g0UFd9vuVGEp1EL/ABezXMIybxLj8chwDalU2oRq/Fyu2dzXX+dSRUVUzlHxxLQIZJyhdFju+0EwmW2R+HRR56Q2d6upLwwjtAT6CcvWG25jDsC/TnUdlzE6Zgvju/eJE6GaA+5If+dOE1X4MAX10UOr/VUWNeGa7K+2aTggod1QLdKeORoFZiZWhg/giqlfMDvDIrEvkwDwCMeH7EHHqYPGqd2DG7rYTVThyyuB2+9PbA/xrDN0bUcCtt3afaAov0SkRcxvrwyTL7ilf4m1p8T3gBtqXh1Sy7Ejxnj03eBixdFNzeR26EgdmhlJihhXhnUh5DCISR+Hp2MZR4Pc2KMzUr0OftINHostJn1lyHgZ/CLRJyBZVjmpkcf x-ms-exchange-antispam-messagedata: LOcfHpxttqHXIbLP3aPoMaT8mQRvk2qbPy3crwZHDxVgdG5LI0aGrYm1dBlyquP/6b9aaalPb3idy7nmBkuDQy1B9sJR79cjL1pmc4NZptMZoUJwRkWpjM/D+4V+Ysk8iAsdq6850UPSSrT9p0HPX3OR3yPt0QmSZTcydmOSP7ucLmmDgXAe3oZJFp4q6UFHx5y1C73nRUluFPsVHlaCvAixYvkLq8L6jBjv1brd93t7zdNR/1wtrMvY5FxGY5Gf+TpH87A2HeCFQjqsLqSSficRDGhBNQ2ZCHnuJgrzbh0YyJiJSqko0TgA1i5wJvaiC99rvVDezVtqPNsaSuq9OdHLcNXgAvSrjlT6Gw/p80gbSic66s7LinlXmNTQ7wVefvzJkm2yNHUGr6/G1Gy+ewMkkICt1cPZ218L7X8ZjLrKlpnrog8baajOzrhyq/RR5NiAtX1SA9Yk2fcVvkCNUhKlxJulZUDaS5GlZ01j5Jjp1Pv0mX6EGGbLHrE5cNCU91Gh4YoF8foJsU8a7u6wA7JkRUdzUORmCVCLblV+fYo65rMG+eI72mIkCaDi5BmRFWLlrQKnl0lpbekBptD+h15z5p8u6ugBlVyIA6KTTf7lhEs5QBYTPLaXjw9+qIlm9ukAIe5sbGOm6h54vKNGmjAAulvlzDoC4eHrJ4krE98QqZsyy3GIvWtn8luQVNI4uLAapS0qsXDSkul9FCVpejdCV3gDj3Zuubn0NK1+eyeJu8zNyUlTL40nf+/08fxsm3wzBfv3oY8h3Zd1C8RzHziVDDUMYYFJnswXaIFUd50= Content-Type: text/plain; charset="us-ascii" Content-ID: <00568D2AB8634A479AE19ED2E3E7FA86@namprd11.prod.outlook.com> Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-MS-Exchange-CrossTenant-Network-Message-Id: b0155f92-b3b0-4128-e39d-08d7e8911ed3 X-MS-Exchange-CrossTenant-originalarrivaltime: 24 Apr 2020 20:50:27.9686 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 46c98d88-e344-4ed4-8496-4ed7712e255d X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: FI6tFz/XxVqScdwIjnS2x4Hp7nENL+lFcVsIRd0J7uBFeuSU9Zo0nBwU4VivBNOXzJuvGczuj2OlmN2aA9gLBw== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM6PR11MB2570 X-OriginatorOrg: intel.com Subject: Re: [dpdk-dev] [PATCH v4 06/18] telemetry: introduce new telemetry functionality X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" > On Apr 24, 2020, at 7:41 AM, Power, Ciara wrote: >=20 > From: Bruce Richardson >=20 > This patch introduces a new telemetry connection socket and handling > functionality. Like the existing telemetry implementation (which is > unaffected by this change) it uses a unix socket, but unlike the > existing one it does not have a fixed list of commands - instead > libraries or applications can register telemetry commands and callbacks > to provide a full-extensible solution for all kinds of telemetry across > DPDK. >=20 > Signed-off-by: Bruce Richardson > Signed-off-by: Ciara Power >=20 > --- > v4: > - Added initial non-json internal representation prototypes. > v2: > - Added DPDK information message on client connection. > - Added /info command to get DPDK information post-connect. > - Replaced pid in socket name with v2. > - Increased output buffer size to 16k. > - Telemetry default callbacks now registered by init function. > --- > lib/librte_telemetry/Makefile | 4 + > lib/librte_telemetry/meson.build | 5 +- > lib/librte_telemetry/rte_telemetry.c | 3 + > lib/librte_telemetry/rte_telemetry.h | 95 ++++- > .../rte_telemetry_version.map | 2 + > lib/librte_telemetry/telemetry.c | 327 ++++++++++++++++++ > lib/librte_telemetry/telemetry_data.h | 46 +++ > 7 files changed, 480 insertions(+), 2 deletions(-) > create mode 100644 lib/librte_telemetry/telemetry.c > create mode 100644 lib/librte_telemetry/telemetry_data.h >=20 > diff --git a/lib/librte_telemetry/Makefile b/lib/librte_telemetry/Makefil= e > index 2d7e442ab0..270e1aac54 100644 > --- a/lib/librte_telemetry/Makefile > +++ b/lib/librte_telemetry/Makefile > @@ -9,6 +9,9 @@ LIB =3D librte_telemetry.a > CFLAGS +=3D -O3 > CFLAGS +=3D $(WERROR_FLAGS) -I$(SRCDIR) > CFLAGS +=3D -I$(RTE_SDK)/lib/librte_metrics/ > +CFLAGS +=3D -I$(RTE_SDK)/lib/librte_eal/include > +CFLAGS +=3D -I$(RTE_SDK)/lib/librte_eal/$(ARCH_DIR)/include > +CFLAGS +=3D -pthread >=20 > LDLIBS +=3D -lrte_eal > LDLIBS +=3D -lpthread > @@ -20,6 +23,7 @@ EXPORT_MAP :=3D rte_telemetry_version.map > SRCS-$(CONFIG_RTE_LIBRTE_TELEMETRY) :=3D rte_telemetry.c > SRCS-$(CONFIG_RTE_LIBRTE_TELEMETRY) +=3D rte_telemetry_parser.c > SRCS-$(CONFIG_RTE_LIBRTE_TELEMETRY) +=3D rte_telemetry_parser_test.c > +SRCS-$(CONFIG_RTE_LIBRTE_TELEMETRY) +=3D telemetry.c >=20 > # export include files > SYMLINK-$(CONFIG_RTE_LIBRTE_TELEMETRY)-include :=3D rte_telemetry.h > diff --git a/lib/librte_telemetry/meson.build b/lib/librte_telemetry/meso= n.build > index 18b214a8e8..0cdae414a4 100644 > --- a/lib/librte_telemetry/meson.build > +++ b/lib/librte_telemetry/meson.build > @@ -1,7 +1,10 @@ > # SPDX-License-Identifier: BSD-3-Clause > # Copyright(c) 2018 Intel Corporation >=20 > -sources =3D files('rte_telemetry.c', 'rte_telemetry_parser.c', 'rte_tele= metry_parser_test.c') > +includes =3D [global_inc] > + > +sources =3D files('rte_telemetry.c', 'rte_telemetry_parser.c', 'rte_tele= metry_parser_test.c', > + 'telemetry.c') > headers =3D files('rte_telemetry.h', 'rte_telemetry_internal.h', 'rte_tel= emetry_parser.h') > includes +=3D include_directories('../librte_metrics') >=20 > diff --git a/lib/librte_telemetry/rte_telemetry.c b/lib/librte_telemetry/= rte_telemetry.c > index 2fb8ffe873..45b6d9d948 100644 > --- a/lib/librte_telemetry/rte_telemetry.c > +++ b/lib/librte_telemetry/rte_telemetry.c > @@ -503,6 +503,9 @@ rte_telemetry_init(void) > return -EPERM; > } >=20 > + if (rte_telemetry_new_init() !=3D 0) > + return -1; > + > return 0; > } >=20 > diff --git a/lib/librte_telemetry/rte_telemetry.h b/lib/librte_telemetry/= rte_telemetry.h > index aedb318598..66290a3fdf 100644 > --- a/lib/librte_telemetry/rte_telemetry.h > +++ b/lib/librte_telemetry/rte_telemetry.h > @@ -3,19 +3,80 @@ > */ >=20 > #include > +#include >=20 > #ifndef _RTE_TELEMETRY_H_ > #define _RTE_TELEMETRY_H_ >=20 > +/** Maximum number of telemetry callbacks. */ > +#define TELEMETRY_MAX_CALLBACKS 64 > +/** Maximum length for string used in object. */ > +#define RTE_TEL_MAX_STRING_LEN 64 > +/** Maximum length of string. */ > +#define RTE_TEL_MAX_SINGLE_STRING_LEN 8192 > +/** Maximum number of dictionary entries. */ > +#define RTE_TEL_MAX_DICT_ENTRIES 256 > +/** Maximum number of array entries. */ > +#define RTE_TEL_MAX_ARRAY_ENTRIES 512 > + > /** > + * @warning > + * @b EXPERIMENTAL: all functions in this file may change without prior = notice > + * > * @file > * RTE Telemetry > * > * The telemetry library provides a method to retrieve statistics from > - * DPDK by sending a JSON encoded message over a socket. DPDK will send > + * DPDK by sending a request message over a socket. DPDK will send > * a JSON encoded response containing telemetry data. > ***/ >=20 > +/** opaque structure used internally for managing data from callbacks */ > +struct rte_tel_data; > + > +/** > + * The types of data that can be managed in arrays or dicts. > + * For arrays, this must be specified at creation time, while for > + * dicts this is specified implicitly each time an element is added > + * via calling a type-specific function. > + */ > +enum rte_tel_value_type { > + RTE_TEL_STRING_VAL, /** a string value */ > + RTE_TEL_INT_VAL, /** a signed 32-bit int value */ > + RTE_TEL_U64_VAL, /** an unsigned 64-bit int value */ > +}; > + > +/** > + * This telemetry callback is used when registering a telemetry command. > + * It handles getting and formatting information to be returned to telem= etry > + * when requested. > + * > + * @param cmd > + * The cmd that was requested by the client. > + * @param params > + * Contains data required by the callback function. > + * @param info > + * The information to be returned to the caller. > + * > + * @return > + * Length of buffer used on success. > + * @return > + * Negative integer on error. > + */ > +typedef int (*telemetry_cb)(const char *cmd, const char *params, > + struct rte_tel_data *info); > + > +/** > + * Used for handling data received over a telemetry socket. > + * > + * @param sock_id > + * ID for the socket to be used by the handler. > + * > + * @return > + * Void. > + */ > +typedef void * (*handler)(void *sock_id); > + > /** > * @warning > * @b EXPERIMENTAL: this API may change without prior notice > @@ -66,4 +127,36 @@ __rte_experimental > int32_t > rte_telemetry_selftest(void); >=20 > +/** > + * Used when registering a command and callback function with telemetry. > + * > + * @param cmd > + * The command to register with telemetry. > + * @param fn > + * Callback function to be called when the command is requested. > + * @param help > + * Help text for the command. > + * > + * @return > + * 0 on success. > + * @return > + * -EINVAL for invalid parameters failure. > + * @return > + * -ENOENT if max callbacks limit has been reached. > + */ > +__rte_experimental > +int > +rte_telemetry_register_cmd(const char *cmd, telemetry_cb fn, const char = *help); > + > +/** > + * Initialize new version of Telemetry. > + * > + * @return > + * 0 on success. > + * @return > + * -1 on failure. > + */ > +__rte_experimental > +int > +rte_telemetry_new_init(void); > #endif > diff --git a/lib/librte_telemetry/rte_telemetry_version.map b/lib/librte_= telemetry/rte_telemetry_version.map > index a80058c59c..831bbd59ad 100644 > --- a/lib/librte_telemetry/rte_telemetry_version.map > +++ b/lib/librte_telemetry/rte_telemetry_version.map > @@ -6,6 +6,8 @@ EXPERIMENTAL { > rte_telemetry_parse; > rte_telemetry_selftest; > rte_telemetry_set_metrics_fns; > + rte_telemetry_new_init; > + rte_telemetry_register_cmd; >=20 > local: *; > }; > diff --git a/lib/librte_telemetry/telemetry.c b/lib/librte_telemetry/tele= metry.c > new file mode 100644 > index 0000000000..b71915bb69 > --- /dev/null > +++ b/lib/librte_telemetry/telemetry.c > @@ -0,0 +1,327 @@ > +/* SPDX-License-Identifier: BSD-3-Clause > + * Copyright(c) 2020 Intel Corporation > + */ > + > +#include > +#include > +#include > +#include > +#include > + > +/* we won't link against libbsd, so just always use DPDKs-specific strlc= py */ > +#undef RTE_USE_LIBBSD > +#include > +#include > +#include > +#include > + > +#include "rte_telemetry.h" > +#include "telemetry_json.h" > +#include "telemetry_data.h" > + > +#define MAX_CMD_LEN 56 > +#define MAX_HELP_LEN 64 > +#define MAX_OUTPUT_LEN (1024 * 16) > + > +static void * > +client_handler(void *socket); > + > +struct cmd_callback { > + char cmd[MAX_CMD_LEN]; > + telemetry_cb fn; > + char help[MAX_HELP_LEN]; > +}; > + > +struct socket { > + int sock; > + char path[sizeof(((struct sockaddr_un *)0)->sun_path)]; > + handler fn; > +}; > +static struct socket v2_socket; /* socket for v2 telemetry */ > +static char telemetry_log_error[1024]; /* Will contain error on init fai= lure */ > +/* 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 =3D RTE_SPINLOCK_INITIALIZER; > + > +int > +rte_telemetry_register_cmd(const char *cmd, telemetry_cb fn, const char = *help) > +{ > + int i =3D 0; > + > + if (strlen(cmd) >=3D MAX_CMD_LEN || fn =3D=3D NULL || cmd[0] !=3D '/' > + || strlen(help) >=3D MAX_HELP_LEN) > + return -EINVAL; > + if (num_callbacks >=3D TELEMETRY_MAX_CALLBACKS) > + return -ENOENT; > + > + rte_spinlock_lock(&callback_sl); > + while (i < num_callbacks && strcmp(cmd, callbacks[i].cmd) > 0) > + i++; > + if (i !=3D num_callbacks) > + /* Move elements to keep the list alphabetical */ > + memmove(callbacks + i + 1, callbacks + i, > + sizeof(struct cmd_callback) * (num_callbacks - i)); > + > + strlcpy(callbacks[i].cmd, cmd, MAX_CMD_LEN); > + callbacks[i].fn =3D fn; > + strlcpy(callbacks[i].help, help, MAX_HELP_LEN); > + num_callbacks++; > + rte_spinlock_unlock(&callback_sl); > + > + return 0; > +} > + > +static void > +output_json(const char *cmd, const struct rte_tel_data *d, int s) > +{ > + char out_buf[MAX_OUTPUT_LEN]; > + > + char *cb_data_buf; > + size_t buf_len, prefix_used, used =3D 0; > + unsigned int i; > + > + RTE_BUILD_BUG_ON(sizeof(out_buf) < MAX_CMD_LEN + > + RTE_TEL_MAX_SINGLE_STRING_LEN + 10); > + switch (d->type) { > + case RTE_TEL_NULL: > + used =3D snprintf(out_buf, sizeof(out_buf), "{\"%.*s\":null}", > + MAX_CMD_LEN, cmd); > + break; > + case RTE_TEL_STRING: > + used =3D snprintf(out_buf, sizeof(out_buf), "{\"%.*s\":\"%.*s\"}", > + MAX_CMD_LEN, cmd, > + RTE_TEL_MAX_SINGLE_STRING_LEN, d->data.str); > + break; > + case RTE_TEL_DICT: > + prefix_used =3D snprintf(out_buf, sizeof(out_buf), "{\"%.*s\":", > + MAX_CMD_LEN, cmd); > + cb_data_buf =3D &out_buf[prefix_used]; > + buf_len =3D sizeof(out_buf) - prefix_used - 1; /* space for '}' */ > + > + used =3D rte_tel_json_empty_obj(cb_data_buf, buf_len, 0); > + for (i =3D 0; i < d->data_len; i++) { > + const struct tel_dict_entry *v =3D &d->data.dict[i]; > + switch (v->type) { > + case RTE_TEL_STRING_VAL: > + used =3D rte_tel_json_add_obj_str(cb_data_buf, > + buf_len, used, > + v->name, v->value.sval); > + break; > + case RTE_TEL_INT_VAL: > + used =3D rte_tel_json_add_obj_int(cb_data_buf, > + buf_len, used, > + v->name, v->value.ival); > + break; > + case RTE_TEL_U64_VAL: > + used =3D rte_tel_json_add_obj_u64(cb_data_buf, > + buf_len, used, > + v->name, v->value.u64val); > + break; > + } > + } > + used +=3D prefix_used; > + used +=3D strlcat(out_buf + used, "}", sizeof(out_buf) - used); > + break; > + case RTE_TEL_ARRAY_STRING: > + case RTE_TEL_ARRAY_INT: > + case RTE_TEL_ARRAY_U64: > + prefix_used =3D snprintf(out_buf, sizeof(out_buf), "{\"%.*s\":", > + MAX_CMD_LEN, cmd); > + cb_data_buf =3D &out_buf[prefix_used]; > + buf_len =3D sizeof(out_buf) - prefix_used - 1; /* space for '}' */ > + > + used =3D rte_tel_json_empty_array(cb_data_buf, buf_len, 0); > + for (i =3D 0; i < d->data_len; i++) > + if (d->type =3D=3D RTE_TEL_ARRAY_STRING) > + used =3D rte_tel_json_add_array_string( > + cb_data_buf, > + buf_len, used, > + d->data.array[i].sval); > + else if (d->type =3D=3D RTE_TEL_ARRAY_INT) > + used =3D rte_tel_json_add_array_int(cb_data_buf, > + buf_len, used, > + d->data.array[i].ival); > + else if (d->type =3D=3D RTE_TEL_ARRAY_U64) > + used =3D rte_tel_json_add_array_u64(cb_data_buf, > + buf_len, used, > + d->data.array[i].u64val); > + used +=3D prefix_used; > + used +=3D strlcat(out_buf + used, "}", sizeof(out_buf) - used); > + break; > + } > + if (write(s, out_buf, used) < 0) > + perror("Error writing to socket"); > +} > + > +static void > +perform_command(telemetry_cb fn, const char *cmd, const char *param, int= s) > +{ > + struct rte_tel_data data; > + > + int ret =3D fn(cmd, param, &data); > + if (ret < 0) { > + char out_buf[MAX_CMD_LEN + 10]; > + int used =3D snprintf(out_buf, sizeof(out_buf), "{\"%.*s\":null}", > + MAX_CMD_LEN, cmd ?: "none"); > + if (write(s, out_buf, used) < 0) > + perror("Error writing to socket"); > + return; > + } > + output_json(cmd, &data, s); > +} > + > +static int > +unknown_command(const char *cmd __rte_unused, const char *params __rte_u= nused, > + struct rte_tel_data *d) > +{ > + return d->type =3D RTE_TEL_NULL; > +} > + > +static void * > +client_handler(void *sock_id) > +{ > + int s =3D (int)(uintptr_t)sock_id; > + char buffer[1024]; > + char info_str[1024]; > + snprintf(info_str, sizeof(info_str), > + "{\"version\":\"%s\",\"pid\":%d,\"max_output_len\":%d}", > + rte_version(), getpid(), MAX_OUTPUT_LEN); > + if (write(s, info_str, strlen(info_str)) < 0) { > + close(s); > + return NULL; > + } > + > + /* receive data is not null terminated */ > + int bytes =3D read(s, buffer, sizeof(buffer) - 1); > + buffer[bytes] =3D 0; Bytes could be a negative number from read returning an error. > + while (bytes > 0) { > + const char *cmd =3D strtok(buffer, ","); > + const char *param =3D strtok(NULL, ","); > + telemetry_cb fn =3D unknown_command; > + int i; > + > + if (cmd && strlen(cmd) < MAX_CMD_LEN) { > + rte_spinlock_lock(&callback_sl); > + for (i =3D 0; i < num_callbacks; i++) > + if (strcmp(cmd, callbacks[i].cmd) =3D=3D 0) { > + fn =3D callbacks[i].fn; > + break; > + } > + rte_spinlock_unlock(&callback_sl); > + } > + perform_command(fn, cmd, param, s); > + > + bytes =3D read(s, buffer, sizeof(buffer) - 1); > + buffer[bytes] =3D 0; Same here. > + } > + close(s); > + return NULL; > +} > + > +static void * > +socket_listener(void *socket) > +{ > + while (1) { > + pthread_t th; > + struct socket *s =3D (struct socket *)socket; > + int s_accepted =3D accept(s->sock, NULL, NULL); > + if (s_accepted < 0) { > + snprintf(telemetry_log_error, > + sizeof(telemetry_log_error), > + "Error with accept, telemetry thread quitting\n"); > + return NULL; > + } > + pthread_create(&th, NULL, s->fn, (void *)(uintptr_t)s_accepted); > + pthread_detach(th); > + } > + return NULL; > +} > + > +static inline char * > +get_socket_path(const char *runtime_dir, const int version) > +{ > + static char path[PATH_MAX]; > + snprintf(path, sizeof(path), "%s/dpdk_telemetry.v%d", > + strlen(runtime_dir) ? runtime_dir : "/tmp", version); > + return path; > +} > + > +static void > +unlink_sockets(void) > +{ > + if (v2_socket.path[0]) > + unlink(v2_socket.path); > +} > + > +static int > +create_socket(char *path) > +{ > + int sock =3D socket(AF_UNIX, SOCK_SEQPACKET, 0); > + if (sock < 0) { > + snprintf(telemetry_log_error, sizeof(telemetry_log_error), > + "Error with socket creation, %s", > + strerror(errno)); > + return -1; > + } > + > + struct sockaddr_un sun =3D {.sun_family =3D AF_UNIX}; > + strlcpy(sun.sun_path, path, sizeof(sun.sun_path)); > + unlink(sun.sun_path); > + if (bind(sock, (void *) &sun, sizeof(sun)) < 0) { > + snprintf(telemetry_log_error, sizeof(telemetry_log_error), > + "Error binding socket: %s", > + strerror(errno)); > + sun.sun_path[0] =3D 0; > + goto error; > + } > + > + if (listen(sock, 1) < 0) { > + snprintf(telemetry_log_error, sizeof(telemetry_log_error), > + "Error calling listen for socket: %s", > + strerror(errno)); > + goto error; > + } > + > + return sock; > + > +error: > + close(sock); > + unlink_sockets(); > + return -1; > +} > + > +static int > +telemetry_v2_init(const char *runtime_dir) > +{ > + pthread_t t_new; > + > + v2_socket.fn =3D client_handler; > + if (strlcpy(v2_socket.path, get_socket_path(runtime_dir, 2), > + sizeof(v2_socket.path)) >=3D sizeof(v2_socket.path)) { > + snprintf(telemetry_log_error, sizeof(telemetry_log_error), > + "Error with socket binding, path too long"); > + return -1; > + } > + > + v2_socket.sock =3D create_socket(v2_socket.path); > + if (v2_socket.sock < 0) > + return -1; > + pthread_create(&t_new, NULL, socket_listener, &v2_socket); > + atexit(unlink_sockets); > + > + return 0; > +} > + > +int32_t > +rte_telemetry_new_init(void) > +{ > + const char *error_str; > + if (telemetry_v2_init(rte_eal_get_runtime_dir()) !=3D 0) { > + error_str =3D telemetry_log_error; > + printf("Error initialising telemetry - %s", error_str); > + return -1; > + } > + return 0; > +} > diff --git a/lib/librte_telemetry/telemetry_data.h b/lib/librte_telemetry= /telemetry_data.h > new file mode 100644 > index 0000000000..ff3a371a33 > --- /dev/null > +++ b/lib/librte_telemetry/telemetry_data.h > @@ -0,0 +1,46 @@ > +/* SPDX-License-Identifier: BSD-3-Clause > + * Copyright(c) 2020 Intel Corporation > + */ > + > +#ifndef _TELEMETRY_DATA_H_ > +#define _TELEMETRY_DATA_H_ > + > +#include > +#include "rte_telemetry.h" > + > +enum tel_container_types { > + RTE_TEL_NULL, /** null, used as error value */ > + RTE_TEL_STRING, /** basic string type, no included data */ > + RTE_TEL_DICT, /** name-value pairs, of individual value type */ > + RTE_TEL_ARRAY_STRING, /** array of string values only */ > + RTE_TEL_ARRAY_INT, /** array of signed, 32-bit int values */ > + RTE_TEL_ARRAY_U64, /** array of unsigned 64-bit int values */ > +}; > + > +/* each type here must have an equivalent enum in the value types enum i= n > + * telemetry.h and an array type defined above, and have appropriate > + * type assignment in the RTE_TEL_data_start_array() function > + */ > +union tel_value { > + char sval[RTE_TEL_MAX_STRING_LEN]; > + int ival; > + uint64_t u64val; > +}; > + > +struct tel_dict_entry { > + char name[RTE_TEL_MAX_STRING_LEN]; > + enum rte_tel_value_type type; > + union tel_value value; > +}; > + > +struct rte_tel_data { > + enum tel_container_types type; > + unsigned int data_len; /* for array or object, how many items */ > + union { > + char str[RTE_TEL_MAX_SINGLE_STRING_LEN]; > + struct tel_dict_entry dict[RTE_TEL_MAX_DICT_ENTRIES]; > + union tel_value array[RTE_TEL_MAX_ARRAY_ENTRIES]; > + } data; /* data container */ > +}; > + > +#endif > --=20 > 2.17.1 >=20