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(
18 const uint64_t *indexes
, size_t index_count
)
22 struct lttng_action_path
*path
= NULL
;
24 if (!indexes
&& index_count
> 0) {
28 path
= zmalloc
<lttng_action_path
>();
33 lttng_dynamic_array_init(&path
->indexes
, sizeof(uint64_t), NULL
);
35 for (i
= 0; i
< index_count
; i
++) {
36 ret
= lttng_dynamic_array_add_element(
37 &path
->indexes
, &indexes
[i
]);
45 lttng_action_path_destroy(path
);
51 enum lttng_action_path_status
lttng_action_path_get_index_count(
52 const struct lttng_action_path
*path
, size_t *index_count
)
54 enum lttng_action_path_status status
;
56 if (!path
|| !index_count
) {
57 status
= LTTNG_ACTION_PATH_STATUS_INVALID
;
61 *index_count
= lttng_dynamic_array_get_count(&path
->indexes
);
62 status
= LTTNG_ACTION_PATH_STATUS_OK
;
67 enum lttng_action_path_status
lttng_action_path_get_index_at_index(
68 const struct lttng_action_path
*path
,
72 enum lttng_action_path_status status
;
74 if (!path
|| !out_index
||
75 path_index
>= lttng_dynamic_array_get_count(
77 status
= LTTNG_ACTION_PATH_STATUS_INVALID
;
81 *out_index
= *((typeof(out_index
)) lttng_dynamic_array_get_element(
82 &path
->indexes
, path_index
));
83 status
= LTTNG_ACTION_PATH_STATUS_OK
;
88 void lttng_action_path_destroy(struct lttng_action_path
*action_path
)
94 lttng_dynamic_array_reset(&action_path
->indexes
);
100 int lttng_action_path_copy(const struct lttng_action_path
*src
,
101 struct lttng_action_path
*dst
)
109 lttng_dynamic_array_init(&dst
->indexes
, sizeof(uint64_t), NULL
);
110 src_count
= lttng_dynamic_array_get_count(&src
->indexes
);
112 for (i
= 0; i
< src_count
; i
++) {
113 const void *index
= lttng_dynamic_array_get_element(
116 ret
= lttng_dynamic_array_add_element(&dst
->indexes
, index
);
125 lttng_dynamic_array_reset(&dst
->indexes
);
130 ssize_t
lttng_action_path_create_from_payload(
131 struct lttng_payload_view
*view
,
132 struct lttng_action_path
**_action_path
)
134 ssize_t consumed_size
= 0, ret
= -1;
135 const struct lttng_action_path_comm
*header
;
136 struct lttng_action_path
*action_path
= NULL
;
137 const struct lttng_payload_view header_view
=
138 lttng_payload_view_from_view(view
, 0, sizeof(*header
));
140 if (!lttng_payload_view_is_valid(&header_view
)) {
144 header
= (typeof(header
)) header_view
.buffer
.data
;
145 consumed_size
+= header_view
.buffer
.size
;
148 * An action path of size 0 can exist and represents a trigger with a
149 * single non-list action. Handle it differently since a payload view of
150 * size 0 is considered invalid.
152 if (header
->index_count
!= 0)
154 const struct lttng_payload_view indexes_view
=
155 lttng_payload_view_from_view(view
,
157 header
->index_count
*
160 if (!lttng_payload_view_is_valid(&indexes_view
)) {
164 consumed_size
+= indexes_view
.buffer
.size
;
165 action_path
= lttng_action_path_create(
166 (const uint64_t *) indexes_view
.buffer
.data
,
167 header
->index_count
);
172 action_path
= lttng_action_path_create(NULL
, 0);
179 *_action_path
= action_path
;
184 int lttng_action_path_serialize(const struct lttng_action_path
*action_path
,
185 struct lttng_payload
*payload
)
188 size_t index_count
, i
;
189 enum lttng_action_path_status status
;
190 lttng_action_path_comm comm
;
192 status
= lttng_action_path_get_index_count(action_path
, &index_count
);
193 if (status
!= LTTNG_ACTION_PATH_STATUS_OK
) {
199 .index_count
= (uint32_t) index_count
,
201 ret
= lttng_dynamic_buffer_append(&payload
->buffer
,
203 sizeof(struct lttng_action_path_comm
));
205 for (i
= 0; i
< index_count
; i
++) {
208 status
= lttng_action_path_get_index_at_index(
209 action_path
, i
, &path_index
);
210 if (status
!= LTTNG_ACTION_PATH_STATUS_OK
) {
215 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, &path_index
,