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