Skip to content

Commit

Permalink
telemetry: register command with private argument
Browse files Browse the repository at this point in the history
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.

Signed-off-by: Robin Jarry <[email protected]>
Acked-by: Bruce Richardson <[email protected]>
  • Loading branch information
rjarry authored and david-marchand committed Oct 15, 2024
1 parent 19d463a commit ceb5914
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 8 deletions.
5 changes: 5 additions & 0 deletions doc/guides/rel_notes/release_24_11.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
-------------
Expand Down
46 changes: 46 additions & 0 deletions lib/telemetry/rte_telemetry.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand Down Expand Up @@ -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
Expand Down
38 changes: 30 additions & 8 deletions lib/telemetry/telemetry.c
Original file line number Diff line number Diff line change
Expand Up @@ -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];
};

Expand Down Expand Up @@ -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;

Expand All @@ -102,13 +105,27 @@ 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);

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
Expand Down Expand Up @@ -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}",
Expand Down Expand Up @@ -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);
}
Expand Down
3 changes: 3 additions & 0 deletions lib/telemetry/version.map
Original file line number Diff line number Diff line change
Expand Up @@ -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: *;
};

Expand Down

0 comments on commit ceb5914

Please sign in to comment.