From: Jérémie Galarneau Date: Thu, 20 May 2021 22:50:06 +0000 (-0400) Subject: error-query: add lttng_action_path to express the location of an action X-Git-Url: https://git.lttng.org./?a=commitdiff_plain;h=27993cc2e9edb3f5a59bc2c16439e063462235e5;p=lttng-tools.git error-query: add lttng_action_path to express the location of an action Signed-off-by: Jérémie Galarneau Change-Id: Icc3056029219cc8f0794b06e7021885e193724be --- diff --git a/include/Makefile.am b/include/Makefile.am index a49d37d5c..53e519067 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -128,6 +128,7 @@ lttngactioninclude_HEADERS= \ lttng/action/action.h \ lttng/action/list.h \ lttng/action/notify.h \ + lttng/action/path.h \ lttng/action/rotate-session.h \ lttng/action/snapshot-session.h \ lttng/action/start-session.h \ @@ -160,6 +161,7 @@ noinst_HEADERS = \ lttng/action/action-internal.h \ lttng/action/list-internal.h \ lttng/action/notify-internal.h \ + lttng/action/path-internal.h \ lttng/action/rotate-session-internal.h \ lttng/action/snapshot-session-internal.h \ lttng/action/start-session-internal.h \ diff --git a/include/lttng/action/path-internal.h b/include/lttng/action/path-internal.h new file mode 100644 index 000000000..23f87ef9b --- /dev/null +++ b/include/lttng/action/path-internal.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2021 Jérémie Galarneau + * + * SPDX-License-Identifier: LGPL-2.1-only + * + */ + +#ifndef LTTNG_ACTION_PATH_INTERNAL_H +#define LTTNG_ACTION_PATH_INTERNAL_H + +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct lttng_action_path { + struct lttng_dynamic_array indexes; +}; + +/* Assumes that 'dst' is uninitialized. */ +LTTNG_HIDDEN +int lttng_action_path_copy(const struct lttng_action_path *src, + struct lttng_action_path *dst); + +LTTNG_HIDDEN +ssize_t lttng_action_path_create_from_payload( + struct lttng_payload_view *view, + struct lttng_action_path **action_path); + +LTTNG_HIDDEN +int lttng_action_path_serialize(const struct lttng_action_path *action_path, + struct lttng_payload *payload); + +#ifdef __cplusplus +} +#endif + +#endif /* LTTNG_ACTION_PATH_INTERNAL_H */ diff --git a/include/lttng/action/path.h b/include/lttng/action/path.h new file mode 100644 index 000000000..507b4ab49 --- /dev/null +++ b/include/lttng/action/path.h @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2021 Jérémie Galarneau + * + * SPDX-License-Identifier: LGPL-2.1-only + * + */ + +#ifndef LTTNG_ACTION_PATH_H +#define LTTNG_ACTION_PATH_H + +#include +#include + +struct lttng_action_path; + +#ifdef __cplusplus +extern "C" { +#endif + +enum lttng_action_path_status { + LTTNG_ACTION_PATH_STATUS_OK = 0, + LTTNG_ACTION_PATH_STATUS_INVALID = -1, +}; + +/* + * Create a path to an action. + * + * An action path indicates how to reach a given action from the action + * of a trigger. The action of a trigger is implicitly the root of an action + * path. + * + * The indexes of an action path allow the resolution of an action. + * The indexes that make-up an action path indicate the index of the successive + * action lists that must be traversed to reach the target action. + * + * For instance, an action path that has a single index 'N' implies that: + * - The root action is a list, + * - The target action is the 'N'-th action in that list. + * + * An action path with two indexes, N1 and N2 implies that: + * - The root action is an action list (L1), + * - The N1-th action of the action list (L1) is also a list (L2), + * - The target action is the N2-th action of the L2 list. + * + * The `indexes` are copied internally and can be disposed-of by the caller. + */ +extern struct lttng_action_path *lttng_action_path_create( + const uint64_t *indexes, size_t index_count); + +/* + * Get the count of indexes in an action path. + */ +extern enum lttng_action_path_status lttng_action_path_get_index_count( + const struct lttng_action_path *path, size_t *index_count); + +/* + * Get an index from an action path. + */ +extern enum lttng_action_path_status lttng_action_path_get_index_at_index( + const struct lttng_action_path *path, + size_t path_index, + uint64_t *out_index); + +/* + * Destroy an action path object. + */ +extern void lttng_action_path_destroy(struct lttng_action_path *action_path); + +#ifdef __cplusplus +} +#endif + +#endif /* LTTNG_ACTION_PATH_H */ diff --git a/include/lttng/lttng.h b/include/lttng/lttng.h index 0ee2d2abd..4736e8b34 100644 --- a/include/lttng/lttng.h +++ b/include/lttng/lttng.h @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include diff --git a/src/common/Makefile.am b/src/common/Makefile.am index 317ce37ba..a38325d5a 100644 --- a/src/common/Makefile.am +++ b/src/common/Makefile.am @@ -37,6 +37,7 @@ libcommon_la_SOURCES = \ actions/action.c \ actions/list.c \ actions/notify.c \ + actions/path.c \ actions/rotate-session.c \ actions/snapshot-session.c \ actions/start-session.c \ diff --git a/src/common/actions/path.c b/src/common/actions/path.c new file mode 100644 index 000000000..dbae34b9e --- /dev/null +++ b/src/common/actions/path.c @@ -0,0 +1,220 @@ +/* + * Copyright (C) 2021 Jérémie Galarneau + * + * SPDX-License-Identifier: LGPL-2.1-only + * + */ + +#include + +struct lttng_action_path_comm { + uint32_t index_count; + uint64_t indexes[]; +} LTTNG_PACKED; + +struct lttng_action_path *lttng_action_path_create( + const uint64_t *indexes, size_t index_count) +{ + int ret; + size_t i; + struct lttng_action_path *path = NULL; + + if (!indexes && index_count > 0) { + goto error; + } + + path = zmalloc(sizeof(*path)); + if (!path) { + goto error; + } + + lttng_dynamic_array_init(&path->indexes, sizeof(uint64_t), NULL); + ret = lttng_dynamic_array_set_count(&path->indexes, index_count); + if (ret) { + goto error; + } + + for (i = 0; i < index_count; i++) { + ret = lttng_dynamic_array_add_element( + &path->indexes, &indexes[i]); + if (ret) { + goto error; + } + } + + goto end; +error: + lttng_action_path_destroy(path); + path = NULL; +end: + return path; +} + +enum lttng_action_path_status lttng_action_path_get_index_count( + const struct lttng_action_path *path, size_t *index_count) +{ + enum lttng_action_path_status status; + + if (!path || !index_count) { + status = LTTNG_ACTION_PATH_STATUS_INVALID; + goto end; + } + + *index_count = lttng_dynamic_array_get_count(&path->indexes); + status = LTTNG_ACTION_PATH_STATUS_OK; +end: + return status; +} + +enum lttng_action_path_status lttng_action_path_get_index_at_index( + const struct lttng_action_path *path, + size_t path_index, + uint64_t *out_index) +{ + enum lttng_action_path_status status; + + if (!path || !out_index || + path_index >= lttng_dynamic_array_get_count( + &path->indexes)) { + status = LTTNG_ACTION_PATH_STATUS_INVALID; + goto end; + } + + *out_index = *((typeof(out_index)) lttng_dynamic_array_get_element( + &path->indexes, path_index)); + status = LTTNG_ACTION_PATH_STATUS_OK; +end: + return status; +} + +void lttng_action_path_destroy(struct lttng_action_path *action_path) +{ + if (!action_path) { + goto end; + } + + lttng_dynamic_array_reset(&action_path->indexes); + free(action_path); +end: + return; +} + +LTTNG_HIDDEN +int lttng_action_path_copy(const struct lttng_action_path *src, + struct lttng_action_path *dst) +{ + int ret; + size_t i, src_count; + + assert(src); + assert(dst); + + lttng_dynamic_array_init(&dst->indexes, sizeof(uint64_t), NULL); + src_count = lttng_dynamic_array_get_count(&src->indexes); + + ret = lttng_dynamic_array_set_count(&dst->indexes, src_count); + if (ret) { + goto error; + } + + for (i = 0; i < src_count; i++) { + const void *index = lttng_dynamic_array_get_element( + &src->indexes, i); + + ret = lttng_dynamic_array_add_element(&dst->indexes, index); + if (ret) { + goto error; + } + } + + ret = 0; + goto end; +error: + lttng_dynamic_array_reset(&dst->indexes); +end: + return ret; +} + +LTTNG_HIDDEN +ssize_t lttng_action_path_create_from_payload( + struct lttng_payload_view *view, + struct lttng_action_path **_action_path) +{ + ssize_t consumed_size = 0, ret = -1; + const struct lttng_action_path_comm *header; + struct lttng_action_path *action_path = NULL; + const struct lttng_payload_view header_view = + lttng_payload_view_from_view(view, 0, sizeof(*header)); + + if (!lttng_payload_view_is_valid(&header_view)) { + goto end; + } + + header = (typeof(header)) header_view.buffer.data; + consumed_size += header_view.buffer.size; + { + const struct lttng_payload_view indexes_view = + lttng_payload_view_from_view(view, + consumed_size, + header->index_count * + sizeof(uint64_t)); + + if (!lttng_payload_view_is_valid(&indexes_view)) { + goto end; + } + + consumed_size += indexes_view.buffer.size; + action_path = lttng_action_path_create( + (const uint64_t *) indexes_view.buffer.data, + header->index_count); + if (!action_path) { + goto end; + } + } + + ret = consumed_size; +end: + return ret; +} + +LTTNG_HIDDEN +int lttng_action_path_serialize(const struct lttng_action_path *action_path, + struct lttng_payload *payload) +{ + int ret; + size_t index_count, i; + enum lttng_action_path_status status; + + status = lttng_action_path_get_index_count(action_path, &index_count); + if (status != LTTNG_ACTION_PATH_STATUS_OK) { + ret = -1; + goto end; + } + + ret = lttng_dynamic_buffer_append(&payload->buffer, + &((struct lttng_action_path_comm) { + .index_count = index_count + }), + sizeof(struct lttng_action_path_comm)); + + for (i = 0; i < index_count; i++) { + uint64_t path_index; + + status = lttng_action_path_get_index_at_index( + action_path, i, &path_index); + if (status != LTTNG_ACTION_PATH_STATUS_OK) { + ret = -1; + goto end; + } + + ret = lttng_dynamic_buffer_append(&payload->buffer, &path_index, + sizeof(path_index)); + if (ret) { + goto end; + } + } + + ret = 0; +end: + return ret; +} diff --git a/src/common/error-query.c b/src/common/error-query.c index 01ed1ef21..c4a28e9c4 100644 --- a/src/common/error-query.c +++ b/src/common/error-query.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include