41fb92e27bddfc2e599a72807e9de7feefaeb216
[lttng-tools.git] / src / common / actions / path.cpp
1 /*
2 * Copyright (C) 2021 Jérémie Galarneau <jeremie.galarneau@efficios.com>
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
5 *
6 */
7
8 #include <lttng/action/path-internal.hpp>
9
10 namespace {
11 struct lttng_action_path_comm {
12 uint32_t index_count;
13 uint64_t indexes[];
14 } LTTNG_PACKED;
15 } /* namespace */
16
17 struct lttng_action_path *lttng_action_path_create(
18 const uint64_t *indexes, size_t index_count)
19 {
20 int ret;
21 size_t i;
22 struct lttng_action_path *path = NULL;
23
24 if (!indexes && index_count > 0) {
25 goto error;
26 }
27
28 path = zmalloc<lttng_action_path>();
29 if (!path) {
30 goto error;
31 }
32
33 lttng_dynamic_array_init(&path->indexes, sizeof(uint64_t), NULL);
34
35 for (i = 0; i < index_count; i++) {
36 ret = lttng_dynamic_array_add_element(
37 &path->indexes, &indexes[i]);
38 if (ret) {
39 goto error;
40 }
41 }
42
43 goto end;
44 error:
45 lttng_action_path_destroy(path);
46 path = NULL;
47 end:
48 return path;
49 }
50
51 enum lttng_action_path_status lttng_action_path_get_index_count(
52 const struct lttng_action_path *path, size_t *index_count)
53 {
54 enum lttng_action_path_status status;
55
56 if (!path || !index_count) {
57 status = LTTNG_ACTION_PATH_STATUS_INVALID;
58 goto end;
59 }
60
61 *index_count = lttng_dynamic_array_get_count(&path->indexes);
62 status = LTTNG_ACTION_PATH_STATUS_OK;
63 end:
64 return status;
65 }
66
67 enum lttng_action_path_status lttng_action_path_get_index_at_index(
68 const struct lttng_action_path *path,
69 size_t path_index,
70 uint64_t *out_index)
71 {
72 enum lttng_action_path_status status;
73
74 if (!path || !out_index ||
75 path_index >= lttng_dynamic_array_get_count(
76 &path->indexes)) {
77 status = LTTNG_ACTION_PATH_STATUS_INVALID;
78 goto end;
79 }
80
81 *out_index = *((typeof(out_index)) lttng_dynamic_array_get_element(
82 &path->indexes, path_index));
83 status = LTTNG_ACTION_PATH_STATUS_OK;
84 end:
85 return status;
86 }
87
88 void lttng_action_path_destroy(struct lttng_action_path *action_path)
89 {
90 if (!action_path) {
91 goto end;
92 }
93
94 lttng_dynamic_array_reset(&action_path->indexes);
95 free(action_path);
96 end:
97 return;
98 }
99
100 int lttng_action_path_copy(const struct lttng_action_path *src,
101 struct lttng_action_path **dst)
102 {
103 int ret;
104 struct lttng_action_path *new_path;
105
106 LTTNG_ASSERT(src);
107 LTTNG_ASSERT(dst);
108
109 new_path = lttng_action_path_create(
110 (uint64_t *) lttng_dynamic_array_get_element(
111 &src->indexes, 0),
112 lttng_dynamic_array_get_count(&src->indexes));
113 if (!new_path) {
114 ret = -1;
115 } else {
116 ret = 0;
117 *dst = new_path;
118 }
119
120 return ret;
121 }
122
123 ssize_t lttng_action_path_create_from_payload(
124 struct lttng_payload_view *view,
125 struct lttng_action_path **_action_path)
126 {
127 ssize_t consumed_size = 0, ret = -1;
128 const struct lttng_action_path_comm *header;
129 struct lttng_action_path *action_path = NULL;
130 const struct lttng_payload_view header_view =
131 lttng_payload_view_from_view(view, 0, sizeof(*header));
132
133 if (!lttng_payload_view_is_valid(&header_view)) {
134 goto end;
135 }
136
137 header = (typeof(header)) header_view.buffer.data;
138 consumed_size += header_view.buffer.size;
139
140 /*
141 * An action path of size 0 can exist and represents a trigger with a
142 * single non-list action. Handle it differently since a payload view of
143 * size 0 is considered invalid.
144 */
145 if (header->index_count != 0)
146 {
147 const struct lttng_payload_view indexes_view =
148 lttng_payload_view_from_view(view,
149 consumed_size,
150 header->index_count *
151 sizeof(uint64_t));
152
153 if (!lttng_payload_view_is_valid(&indexes_view)) {
154 goto end;
155 }
156
157 consumed_size += indexes_view.buffer.size;
158 action_path = lttng_action_path_create(
159 (const uint64_t *) indexes_view.buffer.data,
160 header->index_count);
161 if (!action_path) {
162 goto end;
163 }
164 } else {
165 action_path = lttng_action_path_create(NULL, 0);
166 if (!action_path) {
167 goto end;
168 }
169 }
170
171 ret = consumed_size;
172 *_action_path = action_path;
173 end:
174 return ret;
175 }
176
177 int lttng_action_path_serialize(const struct lttng_action_path *action_path,
178 struct lttng_payload *payload)
179 {
180 int ret;
181 size_t index_count, i;
182 enum lttng_action_path_status status;
183 lttng_action_path_comm comm;
184
185 status = lttng_action_path_get_index_count(action_path, &index_count);
186 if (status != LTTNG_ACTION_PATH_STATUS_OK) {
187 ret = -1;
188 goto end;
189 }
190
191 comm = {
192 .index_count = (uint32_t) index_count,
193 };
194 ret = lttng_dynamic_buffer_append(&payload->buffer,
195 &comm,
196 sizeof(struct lttng_action_path_comm));
197
198 for (i = 0; i < index_count; i++) {
199 uint64_t path_index;
200
201 status = lttng_action_path_get_index_at_index(
202 action_path, i, &path_index);
203 if (status != LTTNG_ACTION_PATH_STATUS_OK) {
204 ret = -1;
205 goto end;
206 }
207
208 ret = lttng_dynamic_buffer_append(&payload->buffer, &path_index,
209 sizeof(path_index));
210 if (ret) {
211 goto end;
212 }
213 }
214
215 ret = 0;
216 end:
217 return ret;
218 }
This page took 0.03291 seconds and 3 git commands to generate.