Commit | Line | Data |
---|---|---|
a58c490f | 1 | /* |
ab5be9fa | 2 | * Copyright (C) 2017 Jérémie Galarneau <jeremie.galarneau@efficios.com> |
a58c490f | 3 | * |
ab5be9fa | 4 | * SPDX-License-Identifier: LGPL-2.1-only |
a58c490f | 5 | * |
a58c490f JG |
6 | */ |
7 | ||
c9e313bc SM |
8 | #include <common/buffer-view.hpp> |
9 | #include <common/dynamic-buffer.hpp> | |
10 | #include <common/error.hpp> | |
11 | #include <common/macros.hpp> | |
12 | #include <common/mi-lttng.hpp> | |
28ab034a | 13 | |
c9e313bc SM |
14 | #include <lttng/condition/buffer-usage-internal.hpp> |
15 | #include <lttng/condition/condition-internal.hpp> | |
16 | #include <lttng/condition/event-rule-matches-internal.hpp> | |
17 | #include <lttng/condition/session-consumed-size-internal.hpp> | |
18 | #include <lttng/condition/session-rotation-internal.hpp> | |
19 | #include <lttng/error-query-internal.hpp> | |
28ab034a | 20 | |
a58c490f | 21 | #include <stdbool.h> |
a58c490f | 22 | |
28ab034a | 23 | enum lttng_condition_type lttng_condition_get_type(const struct lttng_condition *condition) |
a58c490f JG |
24 | { |
25 | return condition ? condition->type : LTTNG_CONDITION_TYPE_UNKNOWN; | |
26 | } | |
27 | ||
28 | void lttng_condition_destroy(struct lttng_condition *condition) | |
4655b864 JR |
29 | { |
30 | lttng_condition_put(condition); | |
31 | } | |
32 | ||
33 | static void condition_destroy_ref(struct urcu_ref *ref) | |
34 | { | |
28ab034a | 35 | struct lttng_condition *condition = lttng::utils::container_of(ref, <tng_condition::ref); |
4655b864 JR |
36 | |
37 | condition->destroy(condition); | |
38 | } | |
39 | ||
4655b864 JR |
40 | void lttng_condition_get(struct lttng_condition *condition) |
41 | { | |
42 | urcu_ref_get(&condition->ref); | |
43 | } | |
44 | ||
4655b864 | 45 | void lttng_condition_put(struct lttng_condition *condition) |
a58c490f JG |
46 | { |
47 | if (!condition) { | |
48 | return; | |
49 | } | |
50 | ||
a0377dfe | 51 | LTTNG_ASSERT(condition->destroy); |
4655b864 | 52 | urcu_ref_put(&condition->ref, condition_destroy_ref); |
a58c490f JG |
53 | } |
54 | ||
a58c490f JG |
55 | bool lttng_condition_validate(const struct lttng_condition *condition) |
56 | { | |
57 | bool valid; | |
58 | ||
59 | if (!condition) { | |
60 | valid = false; | |
61 | goto end; | |
62 | } | |
63 | ||
64 | if (!condition->validate) { | |
65 | /* Sub-class guarantees that it can never be invalid. */ | |
66 | valid = true; | |
67 | goto end; | |
68 | } | |
69 | ||
70 | valid = condition->validate(condition); | |
71 | end: | |
72 | return valid; | |
73 | } | |
74 | ||
3647288f | 75 | int lttng_condition_serialize(const struct lttng_condition *condition, |
28ab034a | 76 | struct lttng_payload *payload) |
a58c490f | 77 | { |
3647288f | 78 | int ret; |
c0a66c84 | 79 | struct lttng_condition_comm condition_comm = {}; |
a58c490f JG |
80 | |
81 | if (!condition) { | |
82 | ret = -1; | |
83 | goto end; | |
84 | } | |
85 | ||
3647288f JG |
86 | condition_comm.condition_type = (int8_t) condition->type; |
87 | ||
28ab034a JG |
88 | ret = lttng_dynamic_buffer_append( |
89 | &payload->buffer, &condition_comm, sizeof(condition_comm)); | |
3647288f JG |
90 | if (ret) { |
91 | goto end; | |
a58c490f JG |
92 | } |
93 | ||
c0a66c84 | 94 | ret = condition->serialize(condition, payload); |
3647288f | 95 | if (ret) { |
a58c490f JG |
96 | goto end; |
97 | } | |
a58c490f JG |
98 | end: |
99 | return ret; | |
100 | } | |
101 | ||
28ab034a | 102 | bool lttng_condition_is_equal(const struct lttng_condition *a, const struct lttng_condition *b) |
a58c490f JG |
103 | { |
104 | bool is_equal = false; | |
105 | ||
106 | if (!a || !b) { | |
107 | goto end; | |
108 | } | |
109 | ||
110 | if (a->type != b->type) { | |
111 | goto end; | |
112 | } | |
113 | ||
6c2fe319 JG |
114 | if (a == b) { |
115 | is_equal = true; | |
116 | goto end; | |
117 | } | |
118 | ||
a58c490f JG |
119 | is_equal = a->equal ? a->equal(a, b) : true; |
120 | end: | |
121 | return is_equal; | |
122 | } | |
123 | ||
28ab034a JG |
124 | ssize_t lttng_condition_create_from_payload(struct lttng_payload_view *view, |
125 | struct lttng_condition **condition) | |
a58c490f JG |
126 | { |
127 | ssize_t ret, condition_size = 0; | |
cd9adb8b | 128 | condition_create_from_payload_cb create_from_payload = nullptr; |
3e6e0df2 JG |
129 | const struct lttng_condition_comm *condition_comm; |
130 | const struct lttng_payload_view condition_comm_view = | |
28ab034a | 131 | lttng_payload_view_from_view(view, 0, sizeof(*condition_comm)); |
a58c490f | 132 | |
c0a66c84 | 133 | if (!view || !condition) { |
a58c490f JG |
134 | ret = -1; |
135 | goto end; | |
136 | } | |
137 | ||
3e6e0df2 JG |
138 | if (!lttng_payload_view_is_valid(&condition_comm_view)) { |
139 | /* Payload not large enough to contain the header. */ | |
140 | ret = -1; | |
141 | goto end; | |
142 | } | |
143 | ||
a58c490f | 144 | DBG("Deserializing condition from buffer"); |
3e6e0df2 | 145 | condition_comm = (typeof(condition_comm)) condition_comm_view.buffer.data; |
a58c490f JG |
146 | condition_size += sizeof(*condition_comm); |
147 | ||
148 | switch ((enum lttng_condition_type) condition_comm->condition_type) { | |
149 | case LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW: | |
c0a66c84 | 150 | create_from_payload = lttng_condition_buffer_usage_low_create_from_payload; |
a58c490f JG |
151 | break; |
152 | case LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH: | |
c0a66c84 | 153 | create_from_payload = lttng_condition_buffer_usage_high_create_from_payload; |
a58c490f | 154 | break; |
e8360425 | 155 | case LTTNG_CONDITION_TYPE_SESSION_CONSUMED_SIZE: |
c0a66c84 | 156 | create_from_payload = lttng_condition_session_consumed_size_create_from_payload; |
e8360425 | 157 | break; |
c19092cd | 158 | case LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING: |
c0a66c84 | 159 | create_from_payload = lttng_condition_session_rotation_ongoing_create_from_payload; |
c19092cd JG |
160 | break; |
161 | case LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED: | |
28ab034a JG |
162 | create_from_payload = |
163 | lttng_condition_session_rotation_completed_create_from_payload; | |
c19092cd | 164 | break; |
8dbb86b8 | 165 | case LTTNG_CONDITION_TYPE_EVENT_RULE_MATCHES: |
28ab034a | 166 | create_from_payload = lttng_condition_event_rule_matches_create_from_payload; |
683d081a | 167 | break; |
a58c490f JG |
168 | default: |
169 | ERR("Attempted to create condition of unknown type (%i)", | |
28ab034a | 170 | (int) condition_comm->condition_type); |
a58c490f JG |
171 | ret = -1; |
172 | goto end; | |
173 | } | |
174 | ||
c0a66c84 JG |
175 | if (create_from_payload) { |
176 | struct lttng_payload_view condition_view = | |
28ab034a | 177 | lttng_payload_view_from_view(view, sizeof(*condition_comm), -1); |
a58c490f | 178 | |
c0a66c84 | 179 | ret = create_from_payload(&condition_view, condition); |
a58c490f JG |
180 | if (ret < 0) { |
181 | goto end; | |
182 | } | |
183 | condition_size += ret; | |
184 | ||
185 | } else { | |
186 | abort(); | |
187 | } | |
188 | ||
189 | ret = condition_size; | |
190 | end: | |
191 | return ret; | |
192 | } | |
193 | ||
28ab034a | 194 | void lttng_condition_init(struct lttng_condition *condition, enum lttng_condition_type type) |
a58c490f JG |
195 | { |
196 | condition->type = type; | |
4655b864 | 197 | urcu_ref_init(&condition->ref); |
a58c490f | 198 | } |
0de2479d | 199 | |
0de2479d SM |
200 | const char *lttng_condition_type_str(enum lttng_condition_type type) |
201 | { | |
202 | switch (type) { | |
203 | case LTTNG_CONDITION_TYPE_UNKNOWN: | |
204 | return "unknown"; | |
205 | ||
206 | case LTTNG_CONDITION_TYPE_SESSION_CONSUMED_SIZE: | |
207 | return "session consumed size"; | |
208 | ||
209 | case LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH: | |
210 | return "buffer usage high"; | |
211 | ||
212 | case LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW: | |
213 | return "buffer usage low"; | |
214 | ||
215 | case LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING: | |
216 | return "session rotation ongoing"; | |
217 | ||
218 | case LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED: | |
219 | return "session rotation completed"; | |
220 | ||
8dbb86b8 | 221 | case LTTNG_CONDITION_TYPE_EVENT_RULE_MATCHES: |
8c1d25ff | 222 | return "event rule matches"; |
0de2479d SM |
223 | |
224 | default: | |
225 | return "???"; | |
226 | } | |
227 | } | |
6a751b95 | 228 | |
28ab034a JG |
229 | enum lttng_error_code |
230 | lttng_condition_mi_serialize(const struct lttng_trigger *trigger, | |
231 | const struct lttng_condition *condition, | |
232 | struct mi_writer *writer, | |
233 | const struct mi_lttng_error_query_callbacks *error_query_callbacks) | |
6a751b95 JR |
234 | { |
235 | int ret; | |
236 | enum lttng_error_code ret_code; | |
cd9adb8b | 237 | struct lttng_error_query_results *error_query_results = nullptr; |
6a751b95 | 238 | |
a0377dfe FD |
239 | LTTNG_ASSERT(condition); |
240 | LTTNG_ASSERT(writer); | |
241 | LTTNG_ASSERT(condition->mi_serialize); | |
6a751b95 JR |
242 | |
243 | /* Open condition element. */ | |
244 | ret = mi_lttng_writer_open_element(writer, mi_lttng_element_condition); | |
245 | if (ret) { | |
246 | goto mi_error; | |
247 | } | |
248 | ||
249 | /* Serialize underlying condition. */ | |
250 | ret_code = condition->mi_serialize(condition, writer); | |
251 | if (ret_code != LTTNG_OK) { | |
252 | goto end; | |
253 | } | |
254 | ||
255 | /* Serialize error query results for the action. */ | |
256 | if (error_query_callbacks && error_query_callbacks->action_cb) { | |
28ab034a | 257 | ret_code = error_query_callbacks->condition_cb(trigger, &error_query_results); |
6a751b95 JR |
258 | if (ret_code != LTTNG_OK) { |
259 | goto end; | |
260 | } | |
261 | ||
28ab034a | 262 | ret_code = lttng_error_query_results_mi_serialize(error_query_results, writer); |
6a751b95 JR |
263 | if (ret_code != LTTNG_OK) { |
264 | goto end; | |
265 | } | |
266 | } | |
267 | ||
268 | /* Close condition element. */ | |
269 | ret = mi_lttng_writer_close_element(writer); | |
270 | if (ret) { | |
271 | goto mi_error; | |
272 | } | |
273 | ||
274 | ret_code = LTTNG_OK; | |
275 | goto end; | |
276 | ||
277 | mi_error: | |
278 | ret_code = LTTNG_ERR_MI_IO_FAIL; | |
279 | end: | |
280 | lttng_error_query_results_destroy(error_query_results); | |
281 | return ret_code; | |
282 | } |