Add a new rte_telemetry_register_cmd_arg public function to register a telemetry endpoint with a callback that takes an additional private argument.
This will be used in the next commit to protect ethdev endpoints with a lock. Update perform_command() to take a struct callback object copied from the list of callbacks and invoke the correct function pointer. Update release notes. Signed-off-by: Robin Jarry <rja...@redhat.com> Acked-by: Bruce Richardson <bruce.richard...@intel.com> --- Notes: v3: reorder callback arguments doc/guides/rel_notes/release_24_11.rst | 5 +++ lib/telemetry/rte_telemetry.h | 46 ++++++++++++++++++++++++++ lib/telemetry/telemetry.c | 38 ++++++++++++++++----- lib/telemetry/version.map | 3 ++ 4 files changed, 84 insertions(+), 8 deletions(-) diff --git a/doc/guides/rel_notes/release_24_11.rst b/doc/guides/rel_notes/release_24_11.rst index dcee09b5d0b2..26590f1b2819 100644 --- a/doc/guides/rel_notes/release_24_11.rst +++ b/doc/guides/rel_notes/release_24_11.rst @@ -178,6 +178,11 @@ New Features This field is used to pass an extra configuration settings such as ability to lookup IPv4 addresses in network byte order. +* **Added new API to register telemetry endpoint callbacks with private arguments.** + + A new ``rte_telemetry_register_cmd_arg`` function is available to pass an opaque value to + telemetry endpoint callback. + Removed Items ------------- diff --git a/lib/telemetry/rte_telemetry.h b/lib/telemetry/rte_telemetry.h index 463819e2bfe5..2ccfc73a5f01 100644 --- a/lib/telemetry/rte_telemetry.h +++ b/lib/telemetry/rte_telemetry.h @@ -336,6 +336,30 @@ rte_tel_data_add_dict_uint_hex(struct rte_tel_data *d, const char *name, typedef int (*telemetry_cb)(const char *cmd, const char *params, struct rte_tel_data *info); +/** + * This telemetry callback is used when registering a telemetry command with + * rte_telemetry_register_cmd_arg(). + * + * It handles getting and formatting information to be returned to telemetry + * when requested. + * + * @param cmd + * The cmd that was requested by the client. + * @param params + * Contains data required by the callback function. + * @param arg + * The opaque value that was passed to rte_telemetry_register_cmd_arg(). + * @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_arg_cb)(const char *cmd, const char *params, void *arg, + struct rte_tel_data *info); + /** * Used for handling data received over a telemetry socket. * @@ -367,6 +391,28 @@ typedef void * (*handler)(void *sock_id); int rte_telemetry_register_cmd(const char *cmd, telemetry_cb fn, const char *help); +/** + * 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 arg + * An opaque value that will be passed to the callback function. + * @param help + * Help text for the command. + * + * @return + * 0 on success. + * @return + * -EINVAL for invalid parameters failure. + * @return + * -ENOMEM for mem allocation failure. + */ +__rte_experimental +int +rte_telemetry_register_cmd_arg(const char *cmd, telemetry_arg_cb fn, void *arg, const char *help); /** * Get a pointer to a container with memory allocated. The container is to be diff --git a/lib/telemetry/telemetry.c b/lib/telemetry/telemetry.c index c4c5a61a5cf8..31a2c91c0657 100644 --- a/lib/telemetry/telemetry.c +++ b/lib/telemetry/telemetry.c @@ -37,6 +37,8 @@ client_handler(void *socket); struct cmd_callback { char cmd[MAX_CMD_LEN]; telemetry_cb fn; + telemetry_arg_cb fn_arg; + void *arg; char help[RTE_TEL_MAX_STRING_LEN]; }; @@ -68,14 +70,15 @@ static rte_spinlock_t callback_sl = RTE_SPINLOCK_INITIALIZER; static RTE_ATOMIC(uint16_t) v2_clients; #endif /* !RTE_EXEC_ENV_WINDOWS */ -int -rte_telemetry_register_cmd(const char *cmd, telemetry_cb fn, const char *help) +static int +register_cmd(const char *cmd, const char *help, + telemetry_cb fn, telemetry_arg_cb fn_arg, void *arg) { struct cmd_callback *new_callbacks; const char *cmdp = cmd; int i = 0; - if (strlen(cmd) >= MAX_CMD_LEN || fn == NULL || cmd[0] != '/' + if (strlen(cmd) >= MAX_CMD_LEN || (fn == NULL && fn_arg == NULL) || cmd[0] != '/' || strlen(help) >= RTE_TEL_MAX_STRING_LEN) return -EINVAL; @@ -102,6 +105,8 @@ rte_telemetry_register_cmd(const char *cmd, telemetry_cb fn, const char *help) strlcpy(callbacks[i].cmd, cmd, MAX_CMD_LEN); callbacks[i].fn = fn; + callbacks[i].fn_arg = fn_arg; + callbacks[i].arg = arg; strlcpy(callbacks[i].help, help, RTE_TEL_MAX_STRING_LEN); num_callbacks++; rte_spinlock_unlock(&callback_sl); @@ -109,6 +114,18 @@ rte_telemetry_register_cmd(const char *cmd, telemetry_cb fn, const char *help) return 0; } +int +rte_telemetry_register_cmd(const char *cmd, telemetry_cb fn, const char *help) +{ + return register_cmd(cmd, help, fn, NULL, NULL); +} + +int +rte_telemetry_register_cmd_arg(const char *cmd, telemetry_arg_cb fn, void *arg, const char *help) +{ + return register_cmd(cmd, help, NULL, fn, arg); +} + #ifndef RTE_EXEC_ENV_WINDOWS static int @@ -349,11 +366,16 @@ output_json(const char *cmd, const struct rte_tel_data *d, int s) } static void -perform_command(telemetry_cb fn, const char *cmd, const char *param, int s) +perform_command(const struct cmd_callback *cb, const char *cmd, const char *param, int s) { struct rte_tel_data data = {0}; + int ret; + + if (cb->fn_arg != NULL) + ret = cb->fn_arg(cmd, param, cb->arg, &data); + else + ret = cb->fn(cmd, param, &data); - int ret = fn(cmd, param, &data); if (ret < 0) { char out_buf[MAX_CMD_LEN + 10]; int used = snprintf(out_buf, sizeof(out_buf), "{\"%.*s\":null}", @@ -392,19 +414,19 @@ client_handler(void *sock_id) buffer[bytes] = 0; const char *cmd = strtok(buffer, ","); const char *param = strtok(NULL, "\0"); - telemetry_cb fn = unknown_command; + struct cmd_callback cb = {.fn = unknown_command}; int i; if (cmd && strlen(cmd) < MAX_CMD_LEN) { rte_spinlock_lock(&callback_sl); for (i = 0; i < num_callbacks; i++) if (strcmp(cmd, callbacks[i].cmd) == 0) { - fn = callbacks[i].fn; + cb = callbacks[i]; break; } rte_spinlock_unlock(&callback_sl); } - perform_command(fn, cmd, param, s); + perform_command(&cb, cmd, param, s); bytes = read(s, buffer, sizeof(buffer) - 1); } diff --git a/lib/telemetry/version.map b/lib/telemetry/version.map index 2907d28aa03f..8f032bf53230 100644 --- a/lib/telemetry/version.map +++ b/lib/telemetry/version.map @@ -28,6 +28,9 @@ EXPERIMENTAL { rte_tel_data_add_array_uint_hex; rte_tel_data_add_dict_uint_hex; + # added in 24.11 + rte_telemetry_register_cmd_arg; + local: *; }; -- 2.46.2