Commit | Line | Data |
---|---|---|
27993cc2 JG |
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 | ||
c9e313bc | 8 | #include <lttng/action/path-internal.hpp> |
27993cc2 | 9 | |
f1494934 | 10 | namespace { |
27993cc2 JG |
11 | struct lttng_action_path_comm { |
12 | uint32_t index_count; | |
13 | uint64_t indexes[]; | |
14 | } LTTNG_PACKED; | |
f1494934 | 15 | } /* namespace */ |
27993cc2 | 16 | |
28ab034a | 17 | struct lttng_action_path *lttng_action_path_create(const uint64_t *indexes, size_t index_count) |
27993cc2 JG |
18 | { |
19 | int ret; | |
20 | size_t i; | |
cd9adb8b | 21 | struct lttng_action_path *path = nullptr; |
27993cc2 JG |
22 | |
23 | if (!indexes && index_count > 0) { | |
24 | goto error; | |
25 | } | |
26 | ||
64803277 | 27 | path = zmalloc<lttng_action_path>(); |
27993cc2 JG |
28 | if (!path) { |
29 | goto error; | |
30 | } | |
31 | ||
cd9adb8b | 32 | lttng_dynamic_array_init(&path->indexes, sizeof(uint64_t), nullptr); |
27993cc2 JG |
33 | |
34 | for (i = 0; i < index_count; i++) { | |
28ab034a | 35 | ret = lttng_dynamic_array_add_element(&path->indexes, &indexes[i]); |
27993cc2 JG |
36 | if (ret) { |
37 | goto error; | |
38 | } | |
39 | } | |
40 | ||
41 | goto end; | |
42 | error: | |
43 | lttng_action_path_destroy(path); | |
cd9adb8b | 44 | path = nullptr; |
27993cc2 JG |
45 | end: |
46 | return path; | |
47 | } | |
48 | ||
28ab034a JG |
49 | enum lttng_action_path_status |
50 | lttng_action_path_get_index_count(const struct lttng_action_path *path, size_t *index_count) | |
27993cc2 JG |
51 | { |
52 | enum lttng_action_path_status status; | |
53 | ||
54 | if (!path || !index_count) { | |
55 | status = LTTNG_ACTION_PATH_STATUS_INVALID; | |
56 | goto end; | |
57 | } | |
58 | ||
59 | *index_count = lttng_dynamic_array_get_count(&path->indexes); | |
60 | status = LTTNG_ACTION_PATH_STATUS_OK; | |
61 | end: | |
62 | return status; | |
63 | } | |
64 | ||
65 | enum lttng_action_path_status lttng_action_path_get_index_at_index( | |
28ab034a | 66 | const struct lttng_action_path *path, size_t path_index, uint64_t *out_index) |
27993cc2 JG |
67 | { |
68 | enum lttng_action_path_status status; | |
69 | ||
28ab034a | 70 | if (!path || !out_index || path_index >= lttng_dynamic_array_get_count(&path->indexes)) { |
27993cc2 JG |
71 | status = LTTNG_ACTION_PATH_STATUS_INVALID; |
72 | goto end; | |
73 | } | |
74 | ||
28ab034a JG |
75 | *out_index = |
76 | *((typeof(out_index)) lttng_dynamic_array_get_element(&path->indexes, path_index)); | |
27993cc2 JG |
77 | status = LTTNG_ACTION_PATH_STATUS_OK; |
78 | end: | |
79 | return status; | |
80 | } | |
81 | ||
82 | void lttng_action_path_destroy(struct lttng_action_path *action_path) | |
83 | { | |
84 | if (!action_path) { | |
85 | goto end; | |
86 | } | |
87 | ||
88 | lttng_dynamic_array_reset(&action_path->indexes); | |
89 | free(action_path); | |
90 | end: | |
91 | return; | |
92 | } | |
93 | ||
28ab034a | 94 | int lttng_action_path_copy(const struct lttng_action_path *src, struct lttng_action_path **dst) |
27993cc2 JG |
95 | { |
96 | int ret; | |
1ad48d96 | 97 | struct lttng_action_path *new_path; |
27993cc2 | 98 | |
a0377dfe FD |
99 | LTTNG_ASSERT(src); |
100 | LTTNG_ASSERT(dst); | |
27993cc2 | 101 | |
1ad48d96 | 102 | new_path = lttng_action_path_create( |
28ab034a JG |
103 | (uint64_t *) lttng_dynamic_array_get_element(&src->indexes, 0), |
104 | lttng_dynamic_array_get_count(&src->indexes)); | |
1ad48d96 JG |
105 | if (!new_path) { |
106 | ret = -1; | |
107 | } else { | |
108 | ret = 0; | |
109 | *dst = new_path; | |
27993cc2 JG |
110 | } |
111 | ||
27993cc2 JG |
112 | return ret; |
113 | } | |
114 | ||
28ab034a JG |
115 | ssize_t lttng_action_path_create_from_payload(struct lttng_payload_view *view, |
116 | struct lttng_action_path **_action_path) | |
27993cc2 JG |
117 | { |
118 | ssize_t consumed_size = 0, ret = -1; | |
119 | const struct lttng_action_path_comm *header; | |
cd9adb8b | 120 | struct lttng_action_path *action_path = nullptr; |
27993cc2 | 121 | const struct lttng_payload_view header_view = |
28ab034a | 122 | lttng_payload_view_from_view(view, 0, sizeof(*header)); |
27993cc2 JG |
123 | |
124 | if (!lttng_payload_view_is_valid(&header_view)) { | |
125 | goto end; | |
126 | } | |
127 | ||
128 | header = (typeof(header)) header_view.buffer.data; | |
129 | consumed_size += header_view.buffer.size; | |
7afaf43b JR |
130 | |
131 | /* | |
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. | |
135 | */ | |
28ab034a JG |
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)); | |
27993cc2 JG |
139 | |
140 | if (!lttng_payload_view_is_valid(&indexes_view)) { | |
141 | goto end; | |
142 | } | |
143 | ||
144 | consumed_size += indexes_view.buffer.size; | |
28ab034a JG |
145 | action_path = lttng_action_path_create((const uint64_t *) indexes_view.buffer.data, |
146 | header->index_count); | |
27993cc2 JG |
147 | if (!action_path) { |
148 | goto end; | |
149 | } | |
7afaf43b | 150 | } else { |
cd9adb8b | 151 | action_path = lttng_action_path_create(nullptr, 0); |
7afaf43b JR |
152 | if (!action_path) { |
153 | goto end; | |
154 | } | |
27993cc2 JG |
155 | } |
156 | ||
157 | ret = consumed_size; | |
cb9222ff | 158 | *_action_path = action_path; |
27993cc2 JG |
159 | end: |
160 | return ret; | |
161 | } | |
162 | ||
27993cc2 | 163 | int lttng_action_path_serialize(const struct lttng_action_path *action_path, |
28ab034a | 164 | struct lttng_payload *payload) |
27993cc2 JG |
165 | { |
166 | int ret; | |
167 | size_t index_count, i; | |
168 | enum lttng_action_path_status status; | |
a6bc4ca9 | 169 | lttng_action_path_comm comm; |
27993cc2 JG |
170 | |
171 | status = lttng_action_path_get_index_count(action_path, &index_count); | |
172 | if (status != LTTNG_ACTION_PATH_STATUS_OK) { | |
173 | ret = -1; | |
174 | goto end; | |
175 | } | |
176 | ||
5611a81d | 177 | comm.index_count = (uint32_t) index_count; |
28ab034a JG |
178 | ret = lttng_dynamic_buffer_append( |
179 | &payload->buffer, &comm, sizeof(struct lttng_action_path_comm)); | |
27993cc2 JG |
180 | |
181 | for (i = 0; i < index_count; i++) { | |
182 | uint64_t path_index; | |
183 | ||
28ab034a | 184 | status = lttng_action_path_get_index_at_index(action_path, i, &path_index); |
27993cc2 JG |
185 | if (status != LTTNG_ACTION_PATH_STATUS_OK) { |
186 | ret = -1; | |
187 | goto end; | |
188 | } | |
189 | ||
28ab034a JG |
190 | ret = lttng_dynamic_buffer_append( |
191 | &payload->buffer, &path_index, sizeof(path_index)); | |
27993cc2 JG |
192 | if (ret) { |
193 | goto end; | |
194 | } | |
195 | } | |
196 | ||
197 | ret = 0; | |
198 | end: | |
199 | return ret; | |
200 | } |