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