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