2 * Copyright (C) 2021 Jérémie Galarneau <jeremie.galarneau@efficios.com>
4 * SPDX-License-Identifier: LGPL-2.1-only
8 #include <lttng/action/path-internal.hpp>
11 struct lttng_action_path_comm
{
17 struct lttng_action_path
*lttng_action_path_create(const uint64_t *indexes
, size_t index_count
)
21 struct lttng_action_path
*path
= nullptr;
23 if (!indexes
&& index_count
> 0) {
27 path
= zmalloc
<lttng_action_path
>();
32 lttng_dynamic_array_init(&path
->indexes
, sizeof(uint64_t), nullptr);
34 for (i
= 0; i
< index_count
; i
++) {
35 ret
= lttng_dynamic_array_add_element(&path
->indexes
, &indexes
[i
]);
43 lttng_action_path_destroy(path
);
49 enum lttng_action_path_status
50 lttng_action_path_get_index_count(const struct lttng_action_path
*path
, size_t *index_count
)
52 enum lttng_action_path_status status
;
54 if (!path
|| !index_count
) {
55 status
= LTTNG_ACTION_PATH_STATUS_INVALID
;
59 *index_count
= lttng_dynamic_array_get_count(&path
->indexes
);
60 status
= LTTNG_ACTION_PATH_STATUS_OK
;
65 enum lttng_action_path_status
lttng_action_path_get_index_at_index(
66 const struct lttng_action_path
*path
, size_t path_index
, uint64_t *out_index
)
68 enum lttng_action_path_status status
;
70 if (!path
|| !out_index
|| path_index
>= lttng_dynamic_array_get_count(&path
->indexes
)) {
71 status
= LTTNG_ACTION_PATH_STATUS_INVALID
;
76 *((typeof(out_index
)) lttng_dynamic_array_get_element(&path
->indexes
, path_index
));
77 status
= LTTNG_ACTION_PATH_STATUS_OK
;
82 void lttng_action_path_destroy(struct lttng_action_path
*action_path
)
88 lttng_dynamic_array_reset(&action_path
->indexes
);
94 int lttng_action_path_copy(const struct lttng_action_path
*src
, struct lttng_action_path
**dst
)
97 struct lttng_action_path
*new_path
;
102 new_path
= lttng_action_path_create(
103 (uint64_t *) lttng_dynamic_array_get_element(&src
->indexes
, 0),
104 lttng_dynamic_array_get_count(&src
->indexes
));
115 ssize_t
lttng_action_path_create_from_payload(struct lttng_payload_view
*view
,
116 struct lttng_action_path
**_action_path
)
118 ssize_t consumed_size
= 0, ret
= -1;
119 const struct lttng_action_path_comm
*header
;
120 struct lttng_action_path
*action_path
= nullptr;
121 const struct lttng_payload_view header_view
=
122 lttng_payload_view_from_view(view
, 0, sizeof(*header
));
124 if (!lttng_payload_view_is_valid(&header_view
)) {
128 header
= (typeof(header
)) header_view
.buffer
.data
;
129 consumed_size
+= header_view
.buffer
.size
;
132 * An action path of size 0 can exist and represents a trigger with a
133 * single non-list action. Handle it differently since a payload view of
134 * size 0 is considered invalid.
136 if (header
->index_count
!= 0) {
137 const struct lttng_payload_view indexes_view
= lttng_payload_view_from_view(
138 view
, consumed_size
, header
->index_count
* sizeof(uint64_t));
140 if (!lttng_payload_view_is_valid(&indexes_view
)) {
144 consumed_size
+= indexes_view
.buffer
.size
;
145 action_path
= lttng_action_path_create((const uint64_t *) indexes_view
.buffer
.data
,
146 header
->index_count
);
151 action_path
= lttng_action_path_create(nullptr, 0);
158 *_action_path
= action_path
;
163 int lttng_action_path_serialize(const struct lttng_action_path
*action_path
,
164 struct lttng_payload
*payload
)
167 size_t index_count
, i
;
168 enum lttng_action_path_status status
;
169 lttng_action_path_comm comm
;
171 status
= lttng_action_path_get_index_count(action_path
, &index_count
);
172 if (status
!= LTTNG_ACTION_PATH_STATUS_OK
) {
177 comm
.index_count
= (uint32_t) index_count
;
178 ret
= lttng_dynamic_buffer_append(
179 &payload
->buffer
, &comm
, sizeof(struct lttng_action_path_comm
));
181 for (i
= 0; i
< index_count
; i
++) {
184 status
= lttng_action_path_get_index_at_index(action_path
, i
, &path_index
);
185 if (status
!= LTTNG_ACTION_PATH_STATUS_OK
) {
190 ret
= lttng_dynamic_buffer_append(
191 &payload
->buffer
, &path_index
, sizeof(path_index
));