Fix: file-descriptor: missing include guards
[lttng-tools.git] / src / common / conditions / event-rule-matches.cpp
CommitLineData
683d081a
JR
1/*
2 * Copyright (C) 2020 Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
5 *
6 */
7
c9e313bc
SM
8#include <common/error.hpp>
9#include <common/macros.hpp>
10#include <common/mi-lttng.hpp>
28ab034a 11
c9e313bc
SM
12#include <lttng/condition/condition-internal.hpp>
13#include <lttng/condition/event-rule-matches-internal.hpp>
670a26e4 14#include <lttng/condition/event-rule-matches.h>
c9e313bc 15#include <lttng/event-expr-internal.hpp>
38114013 16#include <lttng/event-expr.h>
c9e313bc
SM
17#include <lttng/event-field-value-internal.hpp>
18#include <lttng/event-rule/event-rule-internal.hpp>
834966af 19#include <lttng/lttng-error.h>
28ab034a
JG
20
21#include <vendor/msgpack/msgpack.h>
22
23#include <inttypes.h>
24#include <limits.h>
683d081a 25#include <stdbool.h>
38114013 26#include <stdint.h>
683d081a 27
8dbb86b8 28#define IS_EVENT_RULE_MATCHES_CONDITION(condition) \
28ab034a 29 (lttng_condition_get_type(condition) == LTTNG_CONDITION_TYPE_EVENT_RULE_MATCHES)
683d081a 30
28ab034a 31static bool is_event_rule_matches_evaluation(const struct lttng_evaluation *evaluation)
683d081a
JR
32{
33 enum lttng_condition_type type = lttng_evaluation_get_type(evaluation);
34
8dbb86b8 35 return type == LTTNG_CONDITION_TYPE_EVENT_RULE_MATCHES;
683d081a
JR
36}
37
28ab034a
JG
38static bool lttng_condition_event_rule_matches_validate(const struct lttng_condition *condition);
39static int lttng_condition_event_rule_matches_serialize(const struct lttng_condition *condition,
40 struct lttng_payload *payload);
41static bool lttng_condition_event_rule_matches_is_equal(const struct lttng_condition *_a,
42 const struct lttng_condition *_b);
43static void lttng_condition_event_rule_matches_destroy(struct lttng_condition *condition);
44
45static bool lttng_condition_event_rule_matches_validate(const struct lttng_condition *condition)
683d081a
JR
46{
47 bool valid = false;
8dbb86b8 48 struct lttng_condition_event_rule_matches *event_rule;
683d081a
JR
49
50 if (!condition) {
51 goto end;
52 }
53
28ab034a
JG
54 event_rule =
55 lttng::utils::container_of(condition, &lttng_condition_event_rule_matches::parent);
683d081a 56 if (!event_rule->rule) {
d602bd6a 57 ERR("Invalid on event condition: a rule must be set");
683d081a
JR
58 goto end;
59 }
60
61 valid = lttng_event_rule_validate(event_rule->rule);
62end:
63 return valid;
64}
65
7c920b63
PP
66static const char *msgpack_object_type_str(msgpack_object_type type)
67{
68 const char *name;
69
70 switch (type) {
71 case MSGPACK_OBJECT_NIL:
72 name = "MSGPACK_OBJECT_NIL";
73 break;
74 case MSGPACK_OBJECT_BOOLEAN:
75 name = "MSGPACK_OBJECT_BOOLEAN";
76 break;
77 case MSGPACK_OBJECT_POSITIVE_INTEGER:
78 name = "MSGPACK_OBJECT_POSITIVE_INTEGER";
79 break;
80 case MSGPACK_OBJECT_NEGATIVE_INTEGER:
81 name = "MSGPACK_OBJECT_NEGATIVE_INTEGER";
82 break;
83 case MSGPACK_OBJECT_FLOAT32:
84 name = "MSGPACK_OBJECT_FLOAT32";
85 break;
86 case MSGPACK_OBJECT_FLOAT:
87 /* Same value as MSGPACK_OBJECT_FLOAT64 */
88 name = "MSGPACK_OBJECT_FLOAT(64)";
89 break;
90 case MSGPACK_OBJECT_STR:
91 name = "MSGPACK_OBJECT_STR";
92 break;
93 case MSGPACK_OBJECT_ARRAY:
94 name = "MSGPACK_OBJECT_ARRAY";
95 break;
96 case MSGPACK_OBJECT_MAP:
97 name = "MSGPACK_OBJECT_MAP";
98 break;
99 case MSGPACK_OBJECT_BIN:
100 name = "MSGPACK_OBJECT_BIN";
101 break;
102 case MSGPACK_OBJECT_EXT:
103 name = "MSGPACK_OBJECT_EXT";
104 break;
105 default:
106 abort();
107 }
108
109 return name;
110}
111
38114013
PP
112/*
113 * Serializes the C string `str` into `buf`.
114 *
115 * Encoding is the length of `str` plus one (for the null character),
116 * and then the string, including its null terminator.
117 */
28ab034a 118static int serialize_cstr(const char *str, struct lttng_dynamic_buffer *buf)
38114013
PP
119{
120 int ret;
121 const uint32_t len = strlen(str) + 1;
122
123 /* Serialize the length, including the null terminator. */
124 DBG("Serializing C string's length (including null terminator): "
28ab034a
JG
125 "%" PRIu32,
126 len);
38114013
PP
127 ret = lttng_dynamic_buffer_append(buf, &len, sizeof(len));
128 if (ret) {
129 goto end;
130 }
131
132 /* Serialize the string. */
133 DBG("Serializing C string: '%s'", str);
134 ret = lttng_dynamic_buffer_append(buf, str, len);
135 if (ret) {
136 goto end;
137 }
138
139end:
140 return ret;
141}
142
143/*
144 * Serializes the event expression `expr` into `buf`.
145 */
28ab034a 146static int serialize_event_expr(const struct lttng_event_expr *expr, struct lttng_payload *payload)
38114013
PP
147{
148 const uint8_t type = expr->type;
149 int ret;
150
151 /* Serialize the expression's type. */
152 DBG("Serializing event expression's type: %d", expr->type);
153 ret = lttng_dynamic_buffer_append(&payload->buffer, &type, sizeof(type));
154 if (ret) {
155 goto end;
156 }
157
158 /* Serialize the expression */
159 switch (expr->type) {
160 case LTTNG_EVENT_EXPR_TYPE_EVENT_PAYLOAD_FIELD:
161 case LTTNG_EVENT_EXPR_TYPE_CHANNEL_CONTEXT_FIELD:
162 {
163 const struct lttng_event_expr_field *field_expr =
28ab034a 164 lttng::utils::container_of(expr, &lttng_event_expr_field::parent);
38114013
PP
165
166 /* Serialize the field name. */
28ab034a 167 DBG("Serializing field event expression's field name: '%s'", field_expr->name);
38114013
PP
168 ret = serialize_cstr(field_expr->name, &payload->buffer);
169 if (ret) {
170 goto end;
171 }
172
173 break;
174 }
175 case LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD:
176 {
177 const struct lttng_event_expr_app_specific_context_field *field_expr =
28ab034a
JG
178 lttng::utils::container_of(
179 expr, &lttng_event_expr_app_specific_context_field::parent);
38114013
PP
180
181 /* Serialize the provider name. */
182 DBG("Serializing app-specific context field event expression's "
28ab034a
JG
183 "provider name: '%s'",
184 field_expr->provider_name);
38114013
PP
185 ret = serialize_cstr(field_expr->provider_name, &payload->buffer);
186 if (ret) {
187 goto end;
188 }
189
190 /* Serialize the type name. */
191 DBG("Serializing app-specific context field event expression's "
28ab034a
JG
192 "type name: '%s'",
193 field_expr->provider_name);
38114013
PP
194 ret = serialize_cstr(field_expr->type_name, &payload->buffer);
195 if (ret) {
196 goto end;
197 }
198
199 break;
200 }
201 case LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT:
202 {
203 const struct lttng_event_expr_array_field_element *elem_expr =
28ab034a
JG
204 lttng::utils::container_of(expr,
205 &lttng_event_expr_array_field_element::parent);
38114013
PP
206 const uint32_t index = elem_expr->index;
207
208 /* Serialize the index. */
209 DBG("Serializing array field element event expression's "
28ab034a
JG
210 "index: %u",
211 elem_expr->index);
38114013
PP
212 ret = lttng_dynamic_buffer_append(&payload->buffer, &index, sizeof(index));
213 if (ret) {
214 goto end;
215 }
216
217 /* Serialize the parent array field expression. */
218 DBG("Serializing array field element event expression's "
28ab034a 219 "parent array field event expression");
38114013
PP
220 ret = serialize_event_expr(elem_expr->array_field_expr, payload);
221 if (ret) {
222 goto end;
223 }
224
225 break;
226 }
227 default:
228 break;
229 }
230
231end:
232 return ret;
233}
234
8dbb86b8
JR
235static struct lttng_capture_descriptor *
236lttng_condition_event_rule_matches_get_internal_capture_descriptor_at_index(
28ab034a 237 const struct lttng_condition *condition, unsigned int index)
6fb7c690 238{
28ab034a
JG
239 const struct lttng_condition_event_rule_matches *event_rule_matches_cond =
240 lttng::utils::container_of(condition, &lttng_condition_event_rule_matches::parent);
cd9adb8b 241 struct lttng_capture_descriptor *desc = nullptr;
6fb7c690
JR
242 unsigned int count;
243 enum lttng_condition_status status;
244
8dbb86b8 245 if (!condition || !IS_EVENT_RULE_MATCHES_CONDITION(condition)) {
6fb7c690
JR
246 goto end;
247 }
248
28ab034a 249 status = lttng_condition_event_rule_matches_get_capture_descriptor_count(condition, &count);
6fb7c690
JR
250 if (status != LTTNG_CONDITION_STATUS_OK) {
251 goto end;
252 }
253
254 if (index >= count) {
255 goto end;
256 }
257
a6bc4ca9 258 desc = (lttng_capture_descriptor *) lttng_dynamic_pointer_array_get_pointer(
28ab034a 259 &event_rule_matches_cond->capture_descriptors, index);
6fb7c690
JR
260end:
261 return desc;
262}
263
28ab034a
JG
264static int lttng_condition_event_rule_matches_serialize(const struct lttng_condition *condition,
265 struct lttng_payload *payload)
683d081a
JR
266{
267 int ret;
8dbb86b8 268 struct lttng_condition_event_rule_matches *event_rule_matches_condition;
0912b5ea 269 enum lttng_condition_status status;
38114013
PP
270 /* Used for iteration and communication (size matters). */
271 uint32_t i, capture_descr_count;
683d081a 272
8dbb86b8 273 if (!condition || !IS_EVENT_RULE_MATCHES_CONDITION(condition)) {
683d081a
JR
274 ret = -1;
275 goto end;
276 }
277
d602bd6a 278 DBG("Serializing on event condition");
28ab034a
JG
279 event_rule_matches_condition =
280 lttng::utils::container_of(condition, &lttng_condition_event_rule_matches::parent);
683d081a 281
d602bd6a 282 DBG("Serializing on event condition's event rule");
28ab034a 283 ret = lttng_event_rule_serialize(event_rule_matches_condition->rule, payload);
683d081a
JR
284 if (ret) {
285 goto end;
286 }
287
8dbb86b8 288 status = lttng_condition_event_rule_matches_get_capture_descriptor_count(
28ab034a 289 condition, &capture_descr_count);
0912b5ea
JR
290 if (status != LTTNG_CONDITION_STATUS_OK) {
291 ret = -1;
292 goto end;
293 };
294
d602bd6a 295 DBG("Serializing on event condition's capture descriptor count: %" PRIu32,
28ab034a
JG
296 capture_descr_count);
297 ret = lttng_dynamic_buffer_append(
298 &payload->buffer, &capture_descr_count, sizeof(capture_descr_count));
683d081a
JR
299 if (ret) {
300 goto end;
301 }
302
38114013 303 for (i = 0; i < capture_descr_count; i++) {
6fb7c690 304 const struct lttng_capture_descriptor *desc =
28ab034a
JG
305 lttng_condition_event_rule_matches_get_internal_capture_descriptor_at_index(
306 condition, i);
38114013 307
28ab034a 308 DBG("Serializing on event condition's capture descriptor %" PRIu32, i);
6fb7c690 309 ret = serialize_event_expr(desc->event_expression, payload);
38114013
PP
310 if (ret) {
311 goto end;
312 }
313 }
683d081a
JR
314
315end:
316 return ret;
317}
318
28ab034a
JG
319static bool capture_descriptors_are_equal(const struct lttng_condition *condition_a,
320 const struct lttng_condition *condition_b)
38114013
PP
321{
322 bool is_equal = true;
0912b5ea
JR
323 unsigned int capture_descr_count_a;
324 unsigned int capture_descr_count_b;
38114013 325 size_t i;
0912b5ea 326 enum lttng_condition_status status;
38114013 327
8dbb86b8 328 status = lttng_condition_event_rule_matches_get_capture_descriptor_count(
28ab034a 329 condition_a, &capture_descr_count_a);
0912b5ea
JR
330 if (status != LTTNG_CONDITION_STATUS_OK) {
331 goto not_equal;
332 }
333
8dbb86b8 334 status = lttng_condition_event_rule_matches_get_capture_descriptor_count(
28ab034a 335 condition_b, &capture_descr_count_b);
0912b5ea
JR
336 if (status != LTTNG_CONDITION_STATUS_OK) {
337 goto not_equal;
338 }
38114013
PP
339
340 if (capture_descr_count_a != capture_descr_count_b) {
341 goto not_equal;
342 }
343
344 for (i = 0; i < capture_descr_count_a; i++) {
345 const struct lttng_event_expr *expr_a =
28ab034a
JG
346 lttng_condition_event_rule_matches_get_capture_descriptor_at_index(
347 condition_a, i);
38114013 348 const struct lttng_event_expr *expr_b =
28ab034a
JG
349 lttng_condition_event_rule_matches_get_capture_descriptor_at_index(
350 condition_b, i);
38114013
PP
351
352 if (!lttng_event_expr_is_equal(expr_a, expr_b)) {
353 goto not_equal;
354 }
355 }
356
357 goto end;
358
359not_equal:
360 is_equal = false;
361
362end:
363 return is_equal;
364}
365
28ab034a
JG
366static bool lttng_condition_event_rule_matches_is_equal(const struct lttng_condition *_a,
367 const struct lttng_condition *_b)
683d081a
JR
368{
369 bool is_equal = false;
8dbb86b8 370 struct lttng_condition_event_rule_matches *a, *b;
683d081a 371
0114db0e
JG
372 a = lttng::utils::container_of(_a, &lttng_condition_event_rule_matches::parent);
373 b = lttng::utils::container_of(_b, &lttng_condition_event_rule_matches::parent);
683d081a
JR
374
375 /* Both event rules must be set or both must be unset. */
376 if ((a->rule && !b->rule) || (!a->rule && b->rule)) {
377 WARN("Comparing event_rule conditions with uninitialized rule");
378 goto end;
379 }
380
381 is_equal = lttng_event_rule_is_equal(a->rule, b->rule);
38114013
PP
382 if (!is_equal) {
383 goto end;
384 }
385
0912b5ea 386 is_equal = capture_descriptors_are_equal(_a, _b);
38114013 387
683d081a
JR
388end:
389 return is_equal;
390}
391
28ab034a 392static void lttng_condition_event_rule_matches_destroy(struct lttng_condition *condition)
683d081a 393{
8dbb86b8 394 struct lttng_condition_event_rule_matches *event_rule_matches_condition;
683d081a 395
28ab034a
JG
396 event_rule_matches_condition =
397 lttng::utils::container_of(condition, &lttng_condition_event_rule_matches::parent);
683d081a 398
8dbb86b8 399 lttng_event_rule_put(event_rule_matches_condition->rule);
28ab034a 400 lttng_dynamic_pointer_array_reset(&event_rule_matches_condition->capture_descriptors);
8dbb86b8 401 free(event_rule_matches_condition);
683d081a
JR
402}
403
28ab034a 404static void destroy_capture_descriptor(void *ptr)
38114013 405{
28ab034a 406 struct lttng_capture_descriptor *desc = (struct lttng_capture_descriptor *) ptr;
0912b5ea
JR
407
408 lttng_event_expr_destroy(desc->event_expression);
409 free(desc->bytecode);
410 free(desc);
38114013
PP
411}
412
28ab034a
JG
413static enum lttng_error_code
414lttng_condition_event_rule_matches_mi_serialize(const struct lttng_condition *condition,
415 struct mi_writer *writer)
6a751b95
JR
416{
417 int ret;
418 enum lttng_error_code ret_code;
419 enum lttng_condition_status status;
cd9adb8b 420 const struct lttng_event_rule *rule = nullptr;
6a751b95
JR
421 unsigned int capture_descriptor_count, i;
422
a0377dfe
FD
423 LTTNG_ASSERT(condition);
424 LTTNG_ASSERT(writer);
425 LTTNG_ASSERT(IS_EVENT_RULE_MATCHES_CONDITION(condition));
6a751b95
JR
426
427 status = lttng_condition_event_rule_matches_get_rule(condition, &rule);
a0377dfe 428 LTTNG_ASSERT(status == LTTNG_CONDITION_STATUS_OK);
cd9adb8b 429 LTTNG_ASSERT(rule != nullptr);
6a751b95
JR
430
431 status = lttng_condition_event_rule_matches_get_capture_descriptor_count(
28ab034a 432 condition, &capture_descriptor_count);
a0377dfe 433 LTTNG_ASSERT(status == LTTNG_CONDITION_STATUS_OK);
6a751b95
JR
434
435 /* Open condition event rule matches element. */
28ab034a 436 ret = mi_lttng_writer_open_element(writer, mi_lttng_element_condition_event_rule_matches);
6a751b95
JR
437 if (ret) {
438 goto mi_error;
439 }
440
441 /* Serialize the event rule. */
442 ret_code = lttng_event_rule_mi_serialize(rule, writer);
443 if (ret_code != LTTNG_OK) {
444 goto end;
445 }
446
447 /* Open the capture descriptors element. */
28ab034a 448 ret = mi_lttng_writer_open_element(writer, mi_lttng_element_capture_descriptors);
6a751b95
JR
449 if (ret) {
450 goto mi_error;
451 }
452
453 for (i = 0; i < capture_descriptor_count; i++) {
cd9adb8b 454 const struct lttng_event_expr *descriptor = nullptr;
6a751b95
JR
455
456 descriptor = lttng_condition_event_rule_matches_get_capture_descriptor_at_index(
28ab034a 457 condition, i);
a0377dfe 458 LTTNG_ASSERT(descriptor);
6a751b95
JR
459
460 ret_code = lttng_event_expr_mi_serialize(descriptor, writer);
461 if (ret_code != LTTNG_OK) {
462 goto end;
463 }
464 }
465
466 /* Close capture descriptors element. */
467 ret = mi_lttng_writer_close_element(writer);
468 if (ret) {
469 goto mi_error;
470 }
471
472 /* Close condition_event_rule_matches. */
473 ret = mi_lttng_writer_close_element(writer);
474 if (ret) {
475 goto mi_error;
476 }
477 ret_code = LTTNG_OK;
478 goto end;
479
480mi_error:
481 ret_code = LTTNG_ERR_MI_IO_FAIL;
482end:
483 return ret_code;
484}
485
28ab034a 486struct lttng_condition *lttng_condition_event_rule_matches_create(struct lttng_event_rule *rule)
683d081a 487{
cd9adb8b
JG
488 struct lttng_condition *parent = nullptr;
489 struct lttng_condition_event_rule_matches *condition = nullptr;
683d081a
JR
490
491 if (!rule) {
492 goto end;
493 }
494
64803277 495 condition = zmalloc<lttng_condition_event_rule_matches>();
683d081a 496 if (!condition) {
cd9adb8b 497 return nullptr;
683d081a
JR
498 }
499
28ab034a
JG
500 lttng_condition_init(&condition->parent, LTTNG_CONDITION_TYPE_EVENT_RULE_MATCHES);
501 condition->parent.validate = lttng_condition_event_rule_matches_validate,
502 condition->parent.serialize = lttng_condition_event_rule_matches_serialize,
8dbb86b8
JR
503 condition->parent.equal = lttng_condition_event_rule_matches_is_equal,
504 condition->parent.destroy = lttng_condition_event_rule_matches_destroy,
6a751b95 505 condition->parent.mi_serialize = lttng_condition_event_rule_matches_mi_serialize,
683d081a
JR
506
507 lttng_event_rule_get(rule);
508 condition->rule = rule;
cd9adb8b 509 rule = nullptr;
683d081a 510
38114013 511 lttng_dynamic_pointer_array_init(&condition->capture_descriptors,
28ab034a 512 destroy_capture_descriptor);
38114013 513
683d081a
JR
514 parent = &condition->parent;
515end:
516 return parent;
517}
518
28ab034a 519static uint64_t uint_from_buffer(const struct lttng_buffer_view *view, size_t size, size_t *offset)
38114013
PP
520{
521 uint64_t ret;
28ab034a 522 const struct lttng_buffer_view uint_view = lttng_buffer_view_from_view(view, *offset, size);
38114013
PP
523
524 if (!lttng_buffer_view_is_valid(&uint_view)) {
525 ret = UINT64_C(-1);
526 goto end;
527 }
528
529 switch (size) {
530 case 1:
5c7248cd 531 ret = (unsigned char) *uint_view.data;
38114013
PP
532 break;
533 case sizeof(uint32_t):
534 {
535 uint32_t u32;
536
537 memcpy(&u32, uint_view.data, sizeof(u32));
538 ret = (uint64_t) u32;
539 break;
540 }
541 case sizeof(ret):
542 memcpy(&ret, uint_view.data, sizeof(ret));
543 break;
544 default:
545 abort();
546 }
547
548 *offset += size;
549
550end:
551 return ret;
552}
553
28ab034a 554static const char *str_from_buffer(const struct lttng_buffer_view *view, size_t *offset)
38114013
PP
555{
556 uint64_t len;
557 const char *ret;
558
559 len = uint_from_buffer(view, sizeof(uint32_t), offset);
560 if (len == UINT64_C(-1)) {
561 goto error;
562 }
563
564 ret = &view->data[*offset];
565
566 if (!lttng_buffer_view_contains_string(view, ret, len)) {
567 goto error;
568 }
569
570 *offset += len;
571 goto end;
572
573error:
cd9adb8b 574 ret = nullptr;
38114013
PP
575
576end:
577 return ret;
578}
579
28ab034a
JG
580static struct lttng_event_expr *event_expr_from_payload(struct lttng_payload_view *view,
581 size_t *offset)
38114013 582{
cd9adb8b 583 struct lttng_event_expr *expr = nullptr;
38114013
PP
584 const char *str;
585 uint64_t type;
586
587 type = uint_from_buffer(&view->buffer, sizeof(uint8_t), offset);
588 if (type == UINT64_C(-1)) {
589 goto error;
590 }
591
592 switch (type) {
593 case LTTNG_EVENT_EXPR_TYPE_EVENT_PAYLOAD_FIELD:
594 str = str_from_buffer(&view->buffer, offset);
595 if (!str) {
596 goto error;
597 }
598
599 expr = lttng_event_expr_event_payload_field_create(str);
600 break;
601 case LTTNG_EVENT_EXPR_TYPE_CHANNEL_CONTEXT_FIELD:
602 str = str_from_buffer(&view->buffer, offset);
603 if (!str) {
604 goto error;
605 }
606
607 expr = lttng_event_expr_channel_context_field_create(str);
608 break;
609 case LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD:
610 {
611 const char *provider_name;
612 const char *type_name;
613
614 provider_name = str_from_buffer(&view->buffer, offset);
615 if (!provider_name) {
616 goto error;
617 }
618
619 type_name = str_from_buffer(&view->buffer, offset);
620 if (!type_name) {
621 goto error;
622 }
623
28ab034a 624 expr = lttng_event_expr_app_specific_context_field_create(provider_name, type_name);
38114013
PP
625 break;
626 }
627 case LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT:
628 {
629 struct lttng_event_expr *array_field_expr;
28ab034a 630 const uint64_t index = uint_from_buffer(&view->buffer, sizeof(uint32_t), offset);
38114013
PP
631
632 if (index == UINT64_C(-1)) {
633 goto error;
634 }
635
636 /* Array field expression is the encoded after this. */
637 array_field_expr = event_expr_from_payload(view, offset);
638 if (!array_field_expr) {
639 goto error;
640 }
641
642 /* Move ownership of `array_field_expr` to new expression. */
28ab034a
JG
643 expr = lttng_event_expr_array_field_element_create(array_field_expr,
644 (unsigned int) index);
38114013
PP
645 if (!expr) {
646 /* `array_field_expr` not moved: destroy it. */
647 lttng_event_expr_destroy(array_field_expr);
648 }
649
650 break;
651 }
652 default:
52894180 653 ERR("Invalid event expression type encoutered while deserializing event expression: type = %" PRIu64,
28ab034a 654 type);
52894180 655 goto error;
38114013
PP
656 }
657
658 goto end;
659
660error:
661 lttng_event_expr_destroy(expr);
cd9adb8b 662 expr = nullptr;
38114013
PP
663
664end:
665 return expr;
666}
667
28ab034a
JG
668ssize_t lttng_condition_event_rule_matches_create_from_payload(struct lttng_payload_view *view,
669 struct lttng_condition **_condition)
683d081a 670{
38114013
PP
671 ssize_t consumed_length;
672 size_t offset = 0;
673 ssize_t event_rule_length;
674 uint32_t i, capture_descr_count;
cd9adb8b
JG
675 struct lttng_condition *condition = nullptr;
676 struct lttng_event_rule *event_rule = nullptr;
683d081a
JR
677
678 if (!view || !_condition) {
679 goto error;
680 }
681
38114013 682 /* Struct lttng_event_rule. */
683d081a
JR
683 {
684 struct lttng_payload_view event_rule_view =
28ab034a 685 lttng_payload_view_from_view(view, offset, -1);
683d081a 686
28ab034a
JG
687 event_rule_length =
688 lttng_event_rule_create_from_payload(&event_rule_view, &event_rule);
683d081a
JR
689 }
690
691 if (event_rule_length < 0 || !event_rule) {
692 goto error;
693 }
694
35a9ac41
FD
695 offset += event_rule_length;
696
d602bd6a 697 /* Create condition (no capture descriptors yet) at this point */
8dbb86b8 698 condition = lttng_condition_event_rule_matches_create(event_rule);
38114013 699 if (!condition) {
683d081a
JR
700 goto error;
701 }
702
38114013 703 /* Capture descriptor count. */
a0377dfe 704 LTTNG_ASSERT(event_rule_length >= 0);
38114013
PP
705 capture_descr_count = uint_from_buffer(&view->buffer, sizeof(uint32_t), &offset);
706 if (capture_descr_count == UINT32_C(-1)) {
683d081a
JR
707 goto error;
708 }
709
38114013
PP
710 /* Capture descriptors. */
711 for (i = 0; i < capture_descr_count; i++) {
6fb7c690 712 enum lttng_condition_status status;
28ab034a 713 struct lttng_event_expr *expr = event_expr_from_payload(view, &offset);
38114013
PP
714
715 if (!expr) {
716 goto error;
717 }
718
719 /* Move ownership of `expr` to `condition`. */
28ab034a
JG
720 status = lttng_condition_event_rule_matches_append_capture_descriptor(condition,
721 expr);
38114013
PP
722 if (status != LTTNG_CONDITION_STATUS_OK) {
723 /* `expr` not moved: destroy it. */
724 lttng_event_expr_destroy(expr);
725 goto error;
726 }
727 }
728
729 consumed_length = (ssize_t) offset;
683d081a 730 *_condition = condition;
cd9adb8b 731 condition = nullptr;
683d081a
JR
732 goto end;
733
734error:
38114013 735 consumed_length = -1;
683d081a
JR
736
737end:
738 lttng_event_rule_put(event_rule);
739 lttng_condition_put(condition);
38114013 740 return consumed_length;
683d081a
JR
741}
742
8dbb86b8 743enum lttng_condition_status
28ab034a
JG
744lttng_condition_event_rule_matches_borrow_rule_mutable(const struct lttng_condition *condition,
745 struct lttng_event_rule **rule)
683d081a 746{
8dbb86b8 747 struct lttng_condition_event_rule_matches *event_rule;
683d081a
JR
748 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
749
28ab034a 750 if (!condition || !IS_EVENT_RULE_MATCHES_CONDITION(condition) || !rule) {
683d081a
JR
751 status = LTTNG_CONDITION_STATUS_INVALID;
752 goto end;
753 }
754
28ab034a
JG
755 event_rule =
756 lttng::utils::container_of(condition, &lttng_condition_event_rule_matches::parent);
683d081a
JR
757 if (!event_rule->rule) {
758 status = LTTNG_CONDITION_STATUS_UNSET;
759 goto end;
760 }
761
762 *rule = event_rule->rule;
763end:
764 return status;
765}
766
28ab034a
JG
767enum lttng_condition_status
768lttng_condition_event_rule_matches_get_rule(const struct lttng_condition *condition,
769 const struct lttng_event_rule **rule)
683d081a 770{
cd9adb8b 771 struct lttng_event_rule *mutable_rule = nullptr;
683d081a 772 const enum lttng_condition_status status =
28ab034a 773 lttng_condition_event_rule_matches_borrow_rule_mutable(condition, &mutable_rule);
683d081a
JR
774
775 *rule = mutable_rule;
776 return status;
777}
778
28ab034a
JG
779void lttng_condition_event_rule_matches_set_error_counter_index(struct lttng_condition *condition,
780 uint64_t error_counter_index)
35a9ac41 781{
8dbb86b8 782 struct lttng_condition_event_rule_matches *event_rule_matches_cond =
28ab034a 783 lttng::utils::container_of(condition, &lttng_condition_event_rule_matches::parent);
35a9ac41 784
28ab034a 785 LTTNG_OPTIONAL_SET(&event_rule_matches_cond->error_counter_index, error_counter_index);
35a9ac41
FD
786}
787
28ab034a
JG
788uint64_t
789lttng_condition_event_rule_matches_get_error_counter_index(const struct lttng_condition *condition)
35a9ac41 790{
28ab034a
JG
791 const struct lttng_condition_event_rule_matches *event_rule_matches_cond =
792 lttng::utils::container_of(condition, &lttng_condition_event_rule_matches::parent);
35a9ac41 793
8dbb86b8 794 return LTTNG_OPTIONAL_GET(event_rule_matches_cond->error_counter_index);
35a9ac41
FD
795}
796
38114013 797enum lttng_condition_status
28ab034a
JG
798lttng_condition_event_rule_matches_append_capture_descriptor(struct lttng_condition *condition,
799 struct lttng_event_expr *expr)
38114013
PP
800{
801 int ret;
802 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
8dbb86b8 803 struct lttng_condition_event_rule_matches *event_rule_matches_cond =
28ab034a 804 lttng::utils::container_of(condition, &lttng_condition_event_rule_matches::parent);
cd9adb8b
JG
805 struct lttng_capture_descriptor *descriptor = nullptr;
806 const struct lttng_event_rule *rule = nullptr;
38114013
PP
807
808 /* Only accept l-values. */
28ab034a
JG
809 if (!condition || !IS_EVENT_RULE_MATCHES_CONDITION(condition) || !expr ||
810 !lttng_event_expr_is_lvalue(expr)) {
38114013 811 status = LTTNG_CONDITION_STATUS_INVALID;
81d566c9
JR
812 goto end;
813 }
814
8dbb86b8 815 status = lttng_condition_event_rule_matches_get_rule(condition, &rule);
81d566c9
JR
816 if (status != LTTNG_CONDITION_STATUS_OK) {
817 goto end;
818 }
819
28ab034a 820 switch (lttng_event_rule_get_type(rule)) {
695f7044
JR
821 case LTTNG_EVENT_RULE_TYPE_USER_TRACEPOINT:
822 case LTTNG_EVENT_RULE_TYPE_KERNEL_TRACEPOINT:
823 case LTTNG_EVENT_RULE_TYPE_JUL_LOGGING:
824 case LTTNG_EVENT_RULE_TYPE_LOG4J_LOGGING:
825 case LTTNG_EVENT_RULE_TYPE_PYTHON_LOGGING:
4f7da553 826 case LTTNG_EVENT_RULE_TYPE_KERNEL_SYSCALL:
81d566c9
JR
827 /* Supported. */
828 status = LTTNG_CONDITION_STATUS_OK;
829 break;
830 case LTTNG_EVENT_RULE_TYPE_UNKNOWN:
831 status = LTTNG_CONDITION_STATUS_INVALID;
832 break;
833 default:
834 status = LTTNG_CONDITION_STATUS_UNSUPPORTED;
835 break;
836 }
837
838 if (status != LTTNG_CONDITION_STATUS_OK) {
38114013
PP
839 goto end;
840 }
841
64803277 842 descriptor = malloc<lttng_capture_descriptor>();
cd9adb8b 843 if (descriptor == nullptr) {
0912b5ea
JR
844 status = LTTNG_CONDITION_STATUS_ERROR;
845 goto end;
846 }
847
848 descriptor->event_expression = expr;
cd9adb8b 849 descriptor->bytecode = nullptr;
0912b5ea 850
28ab034a
JG
851 ret = lttng_dynamic_pointer_array_add_pointer(&event_rule_matches_cond->capture_descriptors,
852 descriptor);
38114013
PP
853 if (ret) {
854 status = LTTNG_CONDITION_STATUS_ERROR;
855 goto end;
856 }
857
0912b5ea 858 /* Ownership is transfered to the internal capture_descriptors array */
cd9adb8b 859 descriptor = nullptr;
38114013 860end:
0912b5ea 861 free(descriptor);
38114013
PP
862 return status;
863}
864
28ab034a
JG
865enum lttng_condition_status lttng_condition_event_rule_matches_get_capture_descriptor_count(
866 const struct lttng_condition *condition, unsigned int *count)
38114013
PP
867{
868 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
28ab034a
JG
869 const struct lttng_condition_event_rule_matches *event_rule_matches_condition =
870 lttng::utils::container_of(condition, &lttng_condition_event_rule_matches::parent);
38114013 871
28ab034a 872 if (!condition || !IS_EVENT_RULE_MATCHES_CONDITION(condition) || !count) {
38114013
PP
873 status = LTTNG_CONDITION_STATUS_INVALID;
874 goto end;
875 }
876
877 *count = lttng_dynamic_pointer_array_get_count(
28ab034a 878 &event_rule_matches_condition->capture_descriptors);
38114013
PP
879
880end:
881 return status;
882}
883
28ab034a
JG
884const struct lttng_event_expr *lttng_condition_event_rule_matches_get_capture_descriptor_at_index(
885 const struct lttng_condition *condition, unsigned int index)
38114013 886{
cd9adb8b
JG
887 const struct lttng_event_expr *expr = nullptr;
888 const struct lttng_capture_descriptor *desc = nullptr;
0912b5ea 889
8dbb86b8 890 desc = lttng_condition_event_rule_matches_get_internal_capture_descriptor_at_index(
28ab034a 891 condition, index);
cd9adb8b 892 if (desc == nullptr) {
38114013
PP
893 goto end;
894 }
0912b5ea 895 expr = desc->event_expression;
38114013
PP
896
897end:
898 return expr;
899}
900
8dbb86b8 901ssize_t lttng_evaluation_event_rule_matches_create_from_payload(
28ab034a
JG
902 const struct lttng_condition_event_rule_matches *condition,
903 struct lttng_payload_view *view,
904 struct lttng_evaluation **_evaluation)
683d081a
JR
905{
906 ssize_t ret, offset = 0;
cd9adb8b 907 struct lttng_evaluation *evaluation = nullptr;
7c920b63 908 uint32_t capture_payload_size;
cd9adb8b 909 const char *capture_payload = nullptr;
683d081a
JR
910
911 if (!_evaluation) {
912 ret = -1;
913 goto error;
914 }
915
7c920b63
PP
916 {
917 const struct lttng_payload_view current_view =
28ab034a 918 lttng_payload_view_from_view(view, offset, -1);
7c920b63
PP
919
920 if (current_view.buffer.size < sizeof(capture_payload_size)) {
921 ret = -1;
922 goto error;
923 }
683d081a 924
28ab034a
JG
925 memcpy(&capture_payload_size,
926 current_view.buffer.data,
927 sizeof(capture_payload_size));
7c920b63
PP
928 }
929 offset += sizeof(capture_payload_size);
930
931 if (capture_payload_size > 0) {
932 const struct lttng_payload_view current_view =
28ab034a 933 lttng_payload_view_from_view(view, offset, -1);
7c920b63
PP
934
935 if (current_view.buffer.size < capture_payload_size) {
936 ret = -1;
937 goto error;
938 }
939
940 capture_payload = current_view.buffer.data;
941 }
942
8dbb86b8 943 evaluation = lttng_evaluation_event_rule_matches_create(
28ab034a 944 condition, capture_payload, capture_payload_size, true);
683d081a
JR
945 if (!evaluation) {
946 ret = -1;
947 goto error;
948 }
949
7c920b63 950 offset += capture_payload_size;
683d081a 951 *_evaluation = evaluation;
cd9adb8b 952 evaluation = nullptr;
683d081a
JR
953 ret = offset;
954
955error:
956 lttng_evaluation_destroy(evaluation);
957 return ret;
958}
959
28ab034a
JG
960static int lttng_evaluation_event_rule_matches_serialize(const struct lttng_evaluation *evaluation,
961 struct lttng_payload *payload)
683d081a
JR
962{
963 int ret = 0;
8dbb86b8 964 struct lttng_evaluation_event_rule_matches *hit;
7c920b63 965 uint32_t capture_payload_size;
683d081a 966
28ab034a 967 hit = lttng::utils::container_of(evaluation, &lttng_evaluation_event_rule_matches::parent);
683d081a 968
7c920b63 969 capture_payload_size = (uint32_t) hit->capture_payload.size;
28ab034a
JG
970 ret = lttng_dynamic_buffer_append(
971 &payload->buffer, &capture_payload_size, sizeof(capture_payload_size));
7c920b63
PP
972 if (ret) {
973 goto end;
974 }
975
28ab034a
JG
976 ret = lttng_dynamic_buffer_append(
977 &payload->buffer, hit->capture_payload.data, hit->capture_payload.size);
7c920b63
PP
978 if (ret) {
979 goto end;
980 }
981
982end:
983 return ret;
984}
985
28ab034a 986static bool msgpack_str_is_equal(const struct msgpack_object *obj, const char *str)
7c920b63
PP
987{
988 bool is_equal = true;
989
a0377dfe 990 LTTNG_ASSERT(obj->type == MSGPACK_OBJECT_STR);
7c920b63
PP
991
992 if (obj->via.str.size != strlen(str)) {
993 is_equal = false;
994 goto end;
995 }
996
997 if (strncmp(obj->via.str.ptr, str, obj->via.str.size) != 0) {
998 is_equal = false;
999 goto end;
1000 }
1001
1002end:
1003 return is_equal;
1004}
1005
28ab034a
JG
1006static const msgpack_object *get_msgpack_map_obj(const struct msgpack_object *map_obj,
1007 const char *name)
7c920b63 1008{
cd9adb8b 1009 const msgpack_object *ret = nullptr;
7c920b63
PP
1010 size_t i;
1011
a0377dfe 1012 LTTNG_ASSERT(map_obj->type == MSGPACK_OBJECT_MAP);
7c920b63
PP
1013
1014 for (i = 0; i < map_obj->via.map.size; i++) {
1015 const struct msgpack_object_kv *kv = &map_obj->via.map.ptr[i];
1016
a0377dfe 1017 LTTNG_ASSERT(kv->key.type == MSGPACK_OBJECT_STR);
7c920b63
PP
1018
1019 if (msgpack_str_is_equal(&kv->key, name)) {
1020 ret = &kv->val;
1021 goto end;
1022 }
1023 }
1024
683d081a
JR
1025end:
1026 return ret;
1027}
1028
28ab034a 1029static void lttng_evaluation_event_rule_matches_destroy(struct lttng_evaluation *evaluation)
683d081a 1030{
8dbb86b8 1031 struct lttng_evaluation_event_rule_matches *hit;
683d081a 1032
28ab034a 1033 hit = lttng::utils::container_of(evaluation, &lttng_evaluation_event_rule_matches::parent);
7c920b63
PP
1034 lttng_dynamic_buffer_reset(&hit->capture_payload);
1035 lttng_event_field_value_destroy(hit->captured_values);
683d081a
JR
1036 free(hit);
1037}
1038
28ab034a
JG
1039static int event_field_value_from_obj(const msgpack_object *obj,
1040 struct lttng_event_field_value **field_val)
7c920b63
PP
1041{
1042 int ret = 0;
1043
a0377dfe
FD
1044 LTTNG_ASSERT(obj);
1045 LTTNG_ASSERT(field_val);
7c920b63
PP
1046
1047 switch (obj->type) {
1048 case MSGPACK_OBJECT_NIL:
1049 /* Unavailable. */
cd9adb8b 1050 *field_val = nullptr;
7c920b63
PP
1051 goto end;
1052 case MSGPACK_OBJECT_POSITIVE_INTEGER:
28ab034a 1053 *field_val = lttng_event_field_value_uint_create(obj->via.u64);
7c920b63
PP
1054 break;
1055 case MSGPACK_OBJECT_NEGATIVE_INTEGER:
28ab034a 1056 *field_val = lttng_event_field_value_int_create(obj->via.i64);
7c920b63
PP
1057 break;
1058 case MSGPACK_OBJECT_FLOAT32:
1059 case MSGPACK_OBJECT_FLOAT64:
28ab034a 1060 *field_val = lttng_event_field_value_real_create(obj->via.f64);
7c920b63
PP
1061 break;
1062 case MSGPACK_OBJECT_STR:
28ab034a
JG
1063 *field_val = lttng_event_field_value_string_create_with_size(obj->via.str.ptr,
1064 obj->via.str.size);
7c920b63
PP
1065 break;
1066 case MSGPACK_OBJECT_ARRAY:
1067 {
1068 size_t i;
1069
1070 *field_val = lttng_event_field_value_array_create();
1071 if (!*field_val) {
1072 goto error;
1073 }
1074
1075 for (i = 0; i < obj->via.array.size; i++) {
1076 const msgpack_object *elem_obj = &obj->via.array.ptr[i];
1077 struct lttng_event_field_value *elem_field_val;
1078
28ab034a 1079 ret = event_field_value_from_obj(elem_obj, &elem_field_val);
7c920b63
PP
1080 if (ret) {
1081 goto error;
1082 }
1083
1084 if (elem_field_val) {
28ab034a
JG
1085 ret = lttng_event_field_value_array_append(*field_val,
1086 elem_field_val);
7c920b63 1087 } else {
28ab034a 1088 ret = lttng_event_field_value_array_append_unavailable(*field_val);
7c920b63
PP
1089 }
1090
1091 if (ret) {
1092 lttng_event_field_value_destroy(elem_field_val);
1093 goto error;
1094 }
1095 }
1096
1097 break;
1098 }
1099 case MSGPACK_OBJECT_MAP:
1100 {
1101 /*
1102 * As of this version, the only valid map object is
1103 * for an enumeration value, for example:
1104 *
1105 * type: enum
1106 * value: 177
1107 * labels:
1108 * - Labatt 50
1109 * - Molson Dry
1110 * - Carling Black Label
1111 */
1112 const msgpack_object *inner_obj;
1113 size_t label_i;
1114
1115 inner_obj = get_msgpack_map_obj(obj, "type");
1116 if (!inner_obj) {
1117 ERR("Missing `type` entry in map object");
1118 goto error;
1119 }
1120
1121 if (inner_obj->type != MSGPACK_OBJECT_STR) {
1122 ERR("Map object's `type` entry is not a string: type = %s",
28ab034a 1123 msgpack_object_type_str(inner_obj->type));
7c920b63
PP
1124 goto error;
1125 }
1126
1127 if (!msgpack_str_is_equal(inner_obj, "enum")) {
1128 ERR("Map object's `type` entry: expecting `enum`");
1129 goto error;
1130 }
1131
1132 inner_obj = get_msgpack_map_obj(obj, "value");
1133 if (!inner_obj) {
1134 ERR("Missing `value` entry in map object");
1135 goto error;
1136 }
1137
1138 if (inner_obj->type == MSGPACK_OBJECT_POSITIVE_INTEGER) {
28ab034a 1139 *field_val = lttng_event_field_value_enum_uint_create(inner_obj->via.u64);
7c920b63 1140 } else if (inner_obj->type == MSGPACK_OBJECT_NEGATIVE_INTEGER) {
28ab034a 1141 *field_val = lttng_event_field_value_enum_int_create(inner_obj->via.i64);
7c920b63
PP
1142 } else {
1143 ERR("Map object's `value` entry is not an integer: type = %s",
28ab034a 1144 msgpack_object_type_str(inner_obj->type));
7c920b63
PP
1145 goto error;
1146 }
1147
1148 if (!*field_val) {
1149 goto error;
1150 }
1151
1152 inner_obj = get_msgpack_map_obj(obj, "labels");
1153 if (!inner_obj) {
1154 /* No labels */
1155 goto end;
1156 }
1157
1158 if (inner_obj->type != MSGPACK_OBJECT_ARRAY) {
1159 ERR("Map object's `labels` entry is not an array: type = %s",
28ab034a 1160 msgpack_object_type_str(inner_obj->type));
7c920b63
PP
1161 goto error;
1162 }
1163
28ab034a 1164 for (label_i = 0; label_i < inner_obj->via.array.size; label_i++) {
7c920b63 1165 int iret;
28ab034a 1166 const msgpack_object *elem_obj = &inner_obj->via.array.ptr[label_i];
7c920b63
PP
1167
1168 if (elem_obj->type != MSGPACK_OBJECT_STR) {
1169 ERR("Map object's `labels` entry's type is not a string: type = %s",
28ab034a 1170 msgpack_object_type_str(elem_obj->type));
7c920b63
PP
1171 goto error;
1172 }
1173
1174 iret = lttng_event_field_value_enum_append_label_with_size(
28ab034a 1175 *field_val, elem_obj->via.str.ptr, elem_obj->via.str.size);
7c920b63
PP
1176 if (iret) {
1177 goto error;
1178 }
1179 }
1180
1181 break;
1182 }
1183 default:
28ab034a 1184 ERR("Unexpected object type: type = %s", msgpack_object_type_str(obj->type));
7c920b63
PP
1185 goto error;
1186 }
1187
1188 if (!*field_val) {
1189 goto error;
1190 }
1191
1192 goto end;
1193
1194error:
1195 lttng_event_field_value_destroy(*field_val);
cd9adb8b 1196 *field_val = nullptr;
7c920b63
PP
1197 ret = -1;
1198
1199end:
1200 return ret;
1201}
1202
28ab034a
JG
1203static struct lttng_event_field_value *
1204event_field_value_from_capture_payload(const struct lttng_condition_event_rule_matches *condition,
1205 const char *capture_payload,
1206 size_t capture_payload_size)
7c920b63 1207{
cd9adb8b 1208 struct lttng_event_field_value *ret = nullptr;
7c920b63
PP
1209 msgpack_unpacked unpacked;
1210 msgpack_unpack_return unpack_return;
1211 const msgpack_object *root_obj;
1212 const msgpack_object_array *root_array_obj;
1213 size_t i;
1214 size_t count;
1215
a0377dfe
FD
1216 LTTNG_ASSERT(condition);
1217 LTTNG_ASSERT(capture_payload);
7c920b63
PP
1218
1219 /* Initialize value. */
1220 msgpack_unpacked_init(&unpacked);
1221
1222 /* Decode. */
cd9adb8b
JG
1223 unpack_return =
1224 msgpack_unpack_next(&unpacked, capture_payload, capture_payload_size, nullptr);
7c920b63
PP
1225 if (unpack_return != MSGPACK_UNPACK_SUCCESS) {
1226 ERR("msgpack_unpack_next() failed to decode the "
28ab034a
JG
1227 "MessagePack-encoded capture payload: "
1228 "size = %zu, ret = %d",
1229 capture_payload_size,
1230 unpack_return);
7c920b63
PP
1231 goto error;
1232 }
1233
1234 /* Get root array. */
1235 root_obj = &unpacked.data;
1236
1237 if (root_obj->type != MSGPACK_OBJECT_ARRAY) {
1238 ERR("Expecting an array as the root object: type = %s",
28ab034a 1239 msgpack_object_type_str(root_obj->type));
7c920b63
PP
1240 goto error;
1241 }
1242
1243 root_array_obj = &root_obj->via.array;
1244
1245 /* Create an empty root array event field value. */
1246 ret = lttng_event_field_value_array_create();
1247 if (!ret) {
1248 goto error;
1249 }
1250
1251 /*
1252 * For each capture descriptor in the condition object:
1253 *
1254 * 1. Get its corresponding captured field value MessagePack
1255 * object.
1256 *
1257 * 2. Create a corresponding event field value.
1258 *
1259 * 3. Append it to `ret` (the root array event field value).
1260 */
28ab034a 1261 count = lttng_dynamic_pointer_array_get_count(&condition->capture_descriptors);
a0377dfe 1262 LTTNG_ASSERT(count > 0);
7c920b63
PP
1263
1264 for (i = 0; i < count; i++) {
1265 const struct lttng_capture_descriptor *capture_descriptor =
28ab034a
JG
1266 lttng_condition_event_rule_matches_get_internal_capture_descriptor_at_index(
1267 &condition->parent, i);
7c920b63
PP
1268 const msgpack_object *elem_obj;
1269 struct lttng_event_field_value *elem_field_val;
1270 int iret;
1271
a0377dfe 1272 LTTNG_ASSERT(capture_descriptor);
7c920b63
PP
1273
1274 elem_obj = &root_array_obj->ptr[i];
28ab034a 1275 iret = event_field_value_from_obj(elem_obj, &elem_field_val);
7c920b63
PP
1276 if (iret) {
1277 goto error;
1278 }
1279
1280 if (elem_field_val) {
28ab034a 1281 iret = lttng_event_field_value_array_append(ret, elem_field_val);
7c920b63 1282 } else {
28ab034a 1283 iret = lttng_event_field_value_array_append_unavailable(ret);
7c920b63
PP
1284 }
1285
1286 if (iret) {
1287 lttng_event_field_value_destroy(elem_field_val);
1288 goto error;
1289 }
1290 }
1291
1292 goto end;
1293
1294error:
1295 lttng_event_field_value_destroy(ret);
cd9adb8b 1296 ret = nullptr;
7c920b63
PP
1297
1298end:
1299 msgpack_unpacked_destroy(&unpacked);
1300 return ret;
1301}
1302
8dbb86b8 1303struct lttng_evaluation *lttng_evaluation_event_rule_matches_create(
28ab034a
JG
1304 const struct lttng_condition_event_rule_matches *condition,
1305 const char *capture_payload,
1306 size_t capture_payload_size,
1307 bool decode_capture_payload)
683d081a 1308{
8dbb86b8 1309 struct lttng_evaluation_event_rule_matches *hit;
cd9adb8b 1310 struct lttng_evaluation *evaluation = nullptr;
683d081a 1311
64803277 1312 hit = zmalloc<lttng_evaluation_event_rule_matches>();
683d081a 1313 if (!hit) {
7c920b63 1314 goto error;
683d081a
JR
1315 }
1316
7c920b63
PP
1317 lttng_dynamic_buffer_init(&hit->capture_payload);
1318
1319 if (capture_payload) {
1320 const int ret = lttng_dynamic_buffer_append(
28ab034a 1321 &hit->capture_payload, capture_payload, capture_payload_size);
7c920b63
PP
1322 if (ret) {
1323 ERR("Failed to initialize capture payload of event rule evaluation");
1324 goto error;
1325 }
1326
1327 if (decode_capture_payload) {
28ab034a
JG
1328 hit->captured_values = event_field_value_from_capture_payload(
1329 condition, capture_payload, capture_payload_size);
7c920b63
PP
1330 if (!hit->captured_values) {
1331 ERR("Failed to decode the capture payload: size = %zu",
28ab034a 1332 capture_payload_size);
7c920b63
PP
1333 goto error;
1334 }
1335 }
683d081a
JR
1336 }
1337
8dbb86b8
JR
1338 hit->parent.type = LTTNG_CONDITION_TYPE_EVENT_RULE_MATCHES;
1339 hit->parent.serialize = lttng_evaluation_event_rule_matches_serialize;
1340 hit->parent.destroy = lttng_evaluation_event_rule_matches_destroy;
683d081a
JR
1341
1342 evaluation = &hit->parent;
cd9adb8b 1343 hit = nullptr;
683d081a 1344
7c920b63 1345error:
683d081a 1346 if (hit) {
8dbb86b8 1347 lttng_evaluation_event_rule_matches_destroy(&hit->parent);
683d081a
JR
1348 }
1349
1350 return evaluation;
1351}
1352
8dbb86b8
JR
1353enum lttng_evaluation_event_rule_matches_status
1354lttng_evaluation_event_rule_matches_get_captured_values(
28ab034a 1355 const struct lttng_evaluation *evaluation, const struct lttng_event_field_value **field_val)
7c920b63 1356{
8dbb86b8
JR
1357 struct lttng_evaluation_event_rule_matches *hit;
1358 enum lttng_evaluation_event_rule_matches_status status =
28ab034a 1359 LTTNG_EVALUATION_EVENT_RULE_MATCHES_STATUS_OK;
7c920b63 1360
28ab034a 1361 if (!evaluation || !is_event_rule_matches_evaluation(evaluation) || !field_val) {
8dbb86b8 1362 status = LTTNG_EVALUATION_EVENT_RULE_MATCHES_STATUS_INVALID;
7c920b63
PP
1363 goto end;
1364 }
1365
28ab034a 1366 hit = lttng::utils::container_of(evaluation, &lttng_evaluation_event_rule_matches::parent);
7c920b63 1367 if (!hit->captured_values) {
8dbb86b8 1368 status = LTTNG_EVALUATION_EVENT_RULE_MATCHES_STATUS_NONE;
7c920b63
PP
1369 goto end;
1370 }
1371
1372 *field_val = hit->captured_values;
1373
1374end:
1375 return status;
683d081a 1376}
834966af 1377
28ab034a
JG
1378enum lttng_error_code lttng_condition_event_rule_matches_generate_capture_descriptor_bytecode(
1379 struct lttng_condition *condition)
834966af
JR
1380{
1381 enum lttng_error_code ret;
1382 enum lttng_condition_status status;
1383 unsigned int capture_count, i;
1384
8dbb86b8 1385 if (!condition || !IS_EVENT_RULE_MATCHES_CONDITION(condition)) {
834966af
JR
1386 ret = LTTNG_ERR_FATAL;
1387 goto end;
1388 }
1389
28ab034a
JG
1390 status = lttng_condition_event_rule_matches_get_capture_descriptor_count(condition,
1391 &capture_count);
834966af
JR
1392 if (status != LTTNG_CONDITION_STATUS_OK) {
1393 ret = LTTNG_ERR_FATAL;
1394 goto end;
1395 }
1396
1397 for (i = 0; i < capture_count; i++) {
1398 struct lttng_capture_descriptor *local_capture_desc =
28ab034a
JG
1399 lttng_condition_event_rule_matches_get_internal_capture_descriptor_at_index(
1400 condition, i);
a6bc4ca9 1401 int bytecode_ret;
834966af 1402
cd9adb8b 1403 if (local_capture_desc == nullptr) {
834966af
JR
1404 ret = LTTNG_ERR_FATAL;
1405 goto end;
1406 }
1407
1408 /* Generate the bytecode. */
28ab034a
JG
1409 bytecode_ret = lttng_event_expr_to_bytecode(local_capture_desc->event_expression,
1410 &local_capture_desc->bytecode);
cd9adb8b 1411 if (bytecode_ret < 0 || local_capture_desc->bytecode == nullptr) {
834966af
JR
1412 ret = LTTNG_ERR_INVALID_CAPTURE_EXPRESSION;
1413 goto end;
1414 }
1415 }
1416
1417 /* Everything went better than expected */
1418 ret = LTTNG_OK;
1419
1420end:
1421 return ret;
1422}
51dbe985 1423
28ab034a
JG
1424const struct lttng_bytecode *lttng_condition_event_rule_matches_get_capture_bytecode_at_index(
1425 const struct lttng_condition *condition, unsigned int index)
51dbe985 1426{
28ab034a
JG
1427 const struct lttng_condition_event_rule_matches *event_rule_matches_cond =
1428 lttng::utils::container_of(condition, &lttng_condition_event_rule_matches::parent);
cd9adb8b
JG
1429 struct lttng_capture_descriptor *desc = nullptr;
1430 struct lttng_bytecode *bytecode = nullptr;
51dbe985
JR
1431 unsigned int count;
1432 enum lttng_condition_status status;
1433
8dbb86b8 1434 if (!condition || !IS_EVENT_RULE_MATCHES_CONDITION(condition)) {
51dbe985
JR
1435 goto end;
1436 }
1437
28ab034a 1438 status = lttng_condition_event_rule_matches_get_capture_descriptor_count(condition, &count);
51dbe985
JR
1439 if (status != LTTNG_CONDITION_STATUS_OK) {
1440 goto end;
1441 }
1442
1443 if (index >= count) {
1444 goto end;
1445 }
1446
a6bc4ca9 1447 desc = (lttng_capture_descriptor *) lttng_dynamic_pointer_array_get_pointer(
28ab034a 1448 &event_rule_matches_cond->capture_descriptors, index);
cd9adb8b 1449 if (desc == nullptr) {
51dbe985
JR
1450 goto end;
1451 }
1452
1453 bytecode = desc->bytecode;
1454end:
1455 return bytecode;
1456}
This page took 0.121029 seconds and 4 git commands to generate.