X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fcommon%2Factions%2Fpath.c;fp=src%2Fcommon%2Factions%2Fpath.c;h=dbae34b9eb44f2e8609c6adc6b7e4d8cb3e9999a;hp=0000000000000000000000000000000000000000;hb=27993cc2e9edb3f5a59bc2c16439e063462235e5;hpb=202486fa276e34e4c81d560bfd8897824c51af8c 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; +}