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