Move event-expr-to-bytecode to event-expr
[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>
38114013 11#include <inttypes.h>
7c920b63 12#include <limits.h>
683d081a 13#include <lttng/condition/condition-internal.h>
670a26e4
JR
14#include <lttng/condition/event-rule-matches-internal.h>
15#include <lttng/condition/event-rule-matches.h>
38114013
PP
16#include <lttng/event-expr-internal.h>
17#include <lttng/event-expr.h>
7c920b63
PP
18#include <lttng/event-field-value-internal.h>
19#include <lttng/event-rule/event-rule-internal.h>
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
271 desc = 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
8dbb86b8 436struct lttng_condition *lttng_condition_event_rule_matches_create(
683d081a
JR
437 struct lttng_event_rule *rule)
438{
439 struct lttng_condition *parent = NULL;
8dbb86b8 440 struct lttng_condition_event_rule_matches *condition = NULL;
683d081a
JR
441
442 if (!rule) {
443 goto end;
444 }
445
8dbb86b8 446 condition = zmalloc(sizeof(struct lttng_condition_event_rule_matches));
683d081a
JR
447 if (!condition) {
448 return NULL;
449 }
450
451 lttng_condition_init(&condition->parent,
8dbb86b8
JR
452 LTTNG_CONDITION_TYPE_EVENT_RULE_MATCHES);
453 condition->parent.validate =
454 lttng_condition_event_rule_matches_validate,
455 condition->parent.serialize =
456 lttng_condition_event_rule_matches_serialize,
457 condition->parent.equal = lttng_condition_event_rule_matches_is_equal,
458 condition->parent.destroy = lttng_condition_event_rule_matches_destroy,
683d081a
JR
459
460 lttng_event_rule_get(rule);
461 condition->rule = rule;
462 rule = NULL;
463
38114013 464 lttng_dynamic_pointer_array_init(&condition->capture_descriptors,
0912b5ea 465 destroy_capture_descriptor);
38114013 466
683d081a
JR
467 parent = &condition->parent;
468end:
469 return parent;
470}
471
38114013
PP
472static
473uint64_t uint_from_buffer(const struct lttng_buffer_view *view, size_t size,
474 size_t *offset)
475{
476 uint64_t ret;
477 const struct lttng_buffer_view uint_view =
478 lttng_buffer_view_from_view(view, *offset, size);
479
480 if (!lttng_buffer_view_is_valid(&uint_view)) {
481 ret = UINT64_C(-1);
482 goto end;
483 }
484
485 switch (size) {
486 case 1:
487 ret = (uint64_t) *uint_view.data;
488 break;
489 case sizeof(uint32_t):
490 {
491 uint32_t u32;
492
493 memcpy(&u32, uint_view.data, sizeof(u32));
494 ret = (uint64_t) u32;
495 break;
496 }
497 case sizeof(ret):
498 memcpy(&ret, uint_view.data, sizeof(ret));
499 break;
500 default:
501 abort();
502 }
503
504 *offset += size;
505
506end:
507 return ret;
508}
509
510static
511const char *str_from_buffer(const struct lttng_buffer_view *view,
512 size_t *offset)
513{
514 uint64_t len;
515 const char *ret;
516
517 len = uint_from_buffer(view, sizeof(uint32_t), offset);
518 if (len == UINT64_C(-1)) {
519 goto error;
520 }
521
522 ret = &view->data[*offset];
523
524 if (!lttng_buffer_view_contains_string(view, ret, len)) {
525 goto error;
526 }
527
528 *offset += len;
529 goto end;
530
531error:
532 ret = NULL;
533
534end:
535 return ret;
536}
537
538static
539struct lttng_event_expr *event_expr_from_payload(
540 struct lttng_payload_view *view, size_t *offset)
541{
542 struct lttng_event_expr *expr = NULL;
543 const char *str;
544 uint64_t type;
545
546 type = uint_from_buffer(&view->buffer, sizeof(uint8_t), offset);
547 if (type == UINT64_C(-1)) {
548 goto error;
549 }
550
551 switch (type) {
552 case LTTNG_EVENT_EXPR_TYPE_EVENT_PAYLOAD_FIELD:
553 str = str_from_buffer(&view->buffer, offset);
554 if (!str) {
555 goto error;
556 }
557
558 expr = lttng_event_expr_event_payload_field_create(str);
559 break;
560 case LTTNG_EVENT_EXPR_TYPE_CHANNEL_CONTEXT_FIELD:
561 str = str_from_buffer(&view->buffer, offset);
562 if (!str) {
563 goto error;
564 }
565
566 expr = lttng_event_expr_channel_context_field_create(str);
567 break;
568 case LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD:
569 {
570 const char *provider_name;
571 const char *type_name;
572
573 provider_name = str_from_buffer(&view->buffer, offset);
574 if (!provider_name) {
575 goto error;
576 }
577
578 type_name = str_from_buffer(&view->buffer, offset);
579 if (!type_name) {
580 goto error;
581 }
582
583 expr = lttng_event_expr_app_specific_context_field_create(
584 provider_name, type_name);
585 break;
586 }
587 case LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT:
588 {
589 struct lttng_event_expr *array_field_expr;
590 const uint64_t index = uint_from_buffer(
591 &view->buffer, sizeof(uint32_t), offset);
592
593 if (index == UINT64_C(-1)) {
594 goto error;
595 }
596
597 /* Array field expression is the encoded after this. */
598 array_field_expr = event_expr_from_payload(view, offset);
599 if (!array_field_expr) {
600 goto error;
601 }
602
603 /* Move ownership of `array_field_expr` to new expression. */
604 expr = lttng_event_expr_array_field_element_create(
605 array_field_expr, (unsigned int) index);
606 if (!expr) {
607 /* `array_field_expr` not moved: destroy it. */
608 lttng_event_expr_destroy(array_field_expr);
609 }
610
611 break;
612 }
613 default:
52894180
JG
614 ERR("Invalid event expression type encoutered while deserializing event expression: type = %" PRIu64,
615 type);
616 goto error;
38114013
PP
617 }
618
619 goto end;
620
621error:
622 lttng_event_expr_destroy(expr);
623 expr = NULL;
624
625end:
626 return expr;
627}
628
683d081a 629LTTNG_HIDDEN
8dbb86b8 630ssize_t lttng_condition_event_rule_matches_create_from_payload(
683d081a
JR
631 struct lttng_payload_view *view,
632 struct lttng_condition **_condition)
633{
38114013
PP
634 ssize_t consumed_length;
635 size_t offset = 0;
636 ssize_t event_rule_length;
637 uint32_t i, capture_descr_count;
683d081a
JR
638 struct lttng_condition *condition = NULL;
639 struct lttng_event_rule *event_rule = NULL;
683d081a
JR
640
641 if (!view || !_condition) {
642 goto error;
643 }
644
38114013 645 /* Struct lttng_event_rule. */
683d081a
JR
646 {
647 struct lttng_payload_view event_rule_view =
648 lttng_payload_view_from_view(view, offset, -1);
649
650 event_rule_length = lttng_event_rule_create_from_payload(
651 &event_rule_view, &event_rule);
652 }
653
654 if (event_rule_length < 0 || !event_rule) {
655 goto error;
656 }
657
35a9ac41
FD
658 offset += event_rule_length;
659
d602bd6a 660 /* Create condition (no capture descriptors yet) at this point */
8dbb86b8 661 condition = lttng_condition_event_rule_matches_create(event_rule);
38114013 662 if (!condition) {
683d081a
JR
663 goto error;
664 }
665
38114013
PP
666 /* Capture descriptor count. */
667 assert(event_rule_length >= 0);
38114013
PP
668 capture_descr_count = uint_from_buffer(&view->buffer, sizeof(uint32_t), &offset);
669 if (capture_descr_count == UINT32_C(-1)) {
683d081a
JR
670 goto error;
671 }
672
38114013
PP
673 /* Capture descriptors. */
674 for (i = 0; i < capture_descr_count; i++) {
6fb7c690 675 enum lttng_condition_status status;
38114013
PP
676 struct lttng_event_expr *expr = event_expr_from_payload(
677 view, &offset);
38114013
PP
678
679 if (!expr) {
680 goto error;
681 }
682
683 /* Move ownership of `expr` to `condition`. */
8dbb86b8 684 status = lttng_condition_event_rule_matches_append_capture_descriptor(
38114013
PP
685 condition, expr);
686 if (status != LTTNG_CONDITION_STATUS_OK) {
687 /* `expr` not moved: destroy it. */
688 lttng_event_expr_destroy(expr);
689 goto error;
690 }
691 }
692
693 consumed_length = (ssize_t) offset;
683d081a
JR
694 *_condition = condition;
695 condition = NULL;
696 goto end;
697
698error:
38114013 699 consumed_length = -1;
683d081a
JR
700
701end:
702 lttng_event_rule_put(event_rule);
703 lttng_condition_put(condition);
38114013 704 return consumed_length;
683d081a
JR
705}
706
707LTTNG_HIDDEN
8dbb86b8
JR
708enum lttng_condition_status
709lttng_condition_event_rule_matches_borrow_rule_mutable(
683d081a
JR
710 const struct lttng_condition *condition,
711 struct lttng_event_rule **rule)
712{
8dbb86b8 713 struct lttng_condition_event_rule_matches *event_rule;
683d081a
JR
714 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
715
8dbb86b8
JR
716 if (!condition || !IS_EVENT_RULE_MATCHES_CONDITION(condition) ||
717 !rule) {
683d081a
JR
718 status = LTTNG_CONDITION_STATUS_INVALID;
719 goto end;
720 }
721
8dbb86b8
JR
722 event_rule = container_of(condition,
723 struct lttng_condition_event_rule_matches, parent);
683d081a
JR
724 if (!event_rule->rule) {
725 status = LTTNG_CONDITION_STATUS_UNSET;
726 goto end;
727 }
728
729 *rule = event_rule->rule;
730end:
731 return status;
732}
733
8dbb86b8 734enum lttng_condition_status lttng_condition_event_rule_matches_get_rule(
683d081a
JR
735 const struct lttng_condition *condition,
736 const struct lttng_event_rule **rule)
737{
738 struct lttng_event_rule *mutable_rule = NULL;
739 const enum lttng_condition_status status =
8dbb86b8
JR
740 lttng_condition_event_rule_matches_borrow_rule_mutable(
741 condition, &mutable_rule);
683d081a
JR
742
743 *rule = mutable_rule;
744 return status;
745}
746
35a9ac41 747LTTNG_HIDDEN
8dbb86b8 748void lttng_condition_event_rule_matches_set_error_counter_index(
35a9ac41
FD
749 struct lttng_condition *condition, uint64_t error_counter_index)
750{
8dbb86b8 751 struct lttng_condition_event_rule_matches *event_rule_matches_cond =
35a9ac41 752 container_of(condition,
8dbb86b8
JR
753 struct lttng_condition_event_rule_matches,
754 parent);
35a9ac41 755
8dbb86b8
JR
756 LTTNG_OPTIONAL_SET(&event_rule_matches_cond->error_counter_index,
757 error_counter_index);
35a9ac41
FD
758}
759
760LTTNG_HIDDEN
8dbb86b8 761uint64_t lttng_condition_event_rule_matches_get_error_counter_index(
35a9ac41
FD
762 const struct lttng_condition *condition)
763{
8dbb86b8
JR
764 const struct lttng_condition_event_rule_matches
765 *event_rule_matches_cond = container_of(condition,
766 const struct lttng_condition_event_rule_matches,
767 parent);
35a9ac41 768
8dbb86b8 769 return LTTNG_OPTIONAL_GET(event_rule_matches_cond->error_counter_index);
35a9ac41
FD
770}
771
38114013 772enum lttng_condition_status
8dbb86b8 773lttng_condition_event_rule_matches_append_capture_descriptor(
38114013
PP
774 struct lttng_condition *condition,
775 struct lttng_event_expr *expr)
776{
777 int ret;
778 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
8dbb86b8 779 struct lttng_condition_event_rule_matches *event_rule_matches_cond =
38114013 780 container_of(condition,
8dbb86b8
JR
781 struct lttng_condition_event_rule_matches,
782 parent);
0912b5ea 783 struct lttng_capture_descriptor *descriptor = NULL;
81d566c9 784 const struct lttng_event_rule *rule = NULL;
38114013
PP
785
786 /* Only accept l-values. */
8dbb86b8
JR
787 if (!condition || !IS_EVENT_RULE_MATCHES_CONDITION(condition) ||
788 !expr || !lttng_event_expr_is_lvalue(expr)) {
38114013 789 status = LTTNG_CONDITION_STATUS_INVALID;
81d566c9
JR
790 goto end;
791 }
792
8dbb86b8 793 status = lttng_condition_event_rule_matches_get_rule(condition, &rule);
81d566c9
JR
794 if (status != LTTNG_CONDITION_STATUS_OK) {
795 goto end;
796 }
797
798 switch(lttng_event_rule_get_type(rule)) {
695f7044
JR
799 case LTTNG_EVENT_RULE_TYPE_USER_TRACEPOINT:
800 case LTTNG_EVENT_RULE_TYPE_KERNEL_TRACEPOINT:
801 case LTTNG_EVENT_RULE_TYPE_JUL_LOGGING:
802 case LTTNG_EVENT_RULE_TYPE_LOG4J_LOGGING:
803 case LTTNG_EVENT_RULE_TYPE_PYTHON_LOGGING:
4f7da553 804 case LTTNG_EVENT_RULE_TYPE_KERNEL_SYSCALL:
81d566c9
JR
805 /* Supported. */
806 status = LTTNG_CONDITION_STATUS_OK;
807 break;
808 case LTTNG_EVENT_RULE_TYPE_UNKNOWN:
809 status = LTTNG_CONDITION_STATUS_INVALID;
810 break;
811 default:
812 status = LTTNG_CONDITION_STATUS_UNSUPPORTED;
813 break;
814 }
815
816 if (status != LTTNG_CONDITION_STATUS_OK) {
38114013
PP
817 goto end;
818 }
819
0912b5ea
JR
820 descriptor = malloc(sizeof(*descriptor));
821 if (descriptor == NULL) {
822 status = LTTNG_CONDITION_STATUS_ERROR;
823 goto end;
824 }
825
826 descriptor->event_expression = expr;
827 descriptor->bytecode = NULL;
828
38114013 829 ret = lttng_dynamic_pointer_array_add_pointer(
8dbb86b8
JR
830 &event_rule_matches_cond->capture_descriptors,
831 descriptor);
38114013
PP
832 if (ret) {
833 status = LTTNG_CONDITION_STATUS_ERROR;
834 goto end;
835 }
836
0912b5ea
JR
837 /* Ownership is transfered to the internal capture_descriptors array */
838 descriptor = NULL;
38114013 839end:
0912b5ea 840 free(descriptor);
38114013
PP
841 return status;
842}
843
844enum lttng_condition_status
8dbb86b8 845lttng_condition_event_rule_matches_get_capture_descriptor_count(
38114013
PP
846 const struct lttng_condition *condition, unsigned int *count)
847{
848 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
8dbb86b8
JR
849 const struct lttng_condition_event_rule_matches
850 *event_rule_matches_condition = container_of(condition,
851 const struct lttng_condition_event_rule_matches,
852 parent);
38114013 853
8dbb86b8
JR
854 if (!condition || !IS_EVENT_RULE_MATCHES_CONDITION(condition) ||
855 !count) {
38114013
PP
856 status = LTTNG_CONDITION_STATUS_INVALID;
857 goto end;
858 }
859
860 *count = lttng_dynamic_pointer_array_get_count(
8dbb86b8 861 &event_rule_matches_condition->capture_descriptors);
38114013
PP
862
863end:
864 return status;
865}
866
867const struct lttng_event_expr *
8dbb86b8 868lttng_condition_event_rule_matches_get_capture_descriptor_at_index(
38114013
PP
869 const struct lttng_condition *condition, unsigned int index)
870{
38114013 871 const struct lttng_event_expr *expr = NULL;
6fb7c690 872 const struct lttng_capture_descriptor *desc = NULL;
0912b5ea 873
8dbb86b8 874 desc = lttng_condition_event_rule_matches_get_internal_capture_descriptor_at_index(
6fb7c690
JR
875 condition, index);
876 if (desc == NULL) {
38114013
PP
877 goto end;
878 }
0912b5ea 879 expr = desc->event_expression;
38114013
PP
880
881end:
882 return expr;
883}
884
683d081a 885LTTNG_HIDDEN
8dbb86b8
JR
886ssize_t lttng_evaluation_event_rule_matches_create_from_payload(
887 const struct lttng_condition_event_rule_matches *condition,
683d081a
JR
888 struct lttng_payload_view *view,
889 struct lttng_evaluation **_evaluation)
890{
891 ssize_t ret, offset = 0;
683d081a 892 struct lttng_evaluation *evaluation = NULL;
7c920b63
PP
893 uint32_t capture_payload_size;
894 const char *capture_payload = NULL;
683d081a
JR
895
896 if (!_evaluation) {
897 ret = -1;
898 goto error;
899 }
900
7c920b63
PP
901 {
902 const struct lttng_payload_view current_view =
903 lttng_payload_view_from_view(view, offset, -1);
904
905 if (current_view.buffer.size < sizeof(capture_payload_size)) {
906 ret = -1;
907 goto error;
908 }
683d081a 909
7c920b63
PP
910 memcpy(&capture_payload_size, current_view.buffer.data,
911 sizeof(capture_payload_size));
912 }
913 offset += sizeof(capture_payload_size);
914
915 if (capture_payload_size > 0) {
916 const struct lttng_payload_view current_view =
917 lttng_payload_view_from_view(view, offset, -1);
918
919 if (current_view.buffer.size < capture_payload_size) {
920 ret = -1;
921 goto error;
922 }
923
924 capture_payload = current_view.buffer.data;
925 }
926
8dbb86b8
JR
927 evaluation = lttng_evaluation_event_rule_matches_create(
928 condition, capture_payload, capture_payload_size, true);
683d081a
JR
929 if (!evaluation) {
930 ret = -1;
931 goto error;
932 }
933
7c920b63 934 offset += capture_payload_size;
683d081a
JR
935 *_evaluation = evaluation;
936 evaluation = NULL;
937 ret = offset;
938
939error:
940 lttng_evaluation_destroy(evaluation);
941 return ret;
942}
943
8dbb86b8 944static int lttng_evaluation_event_rule_matches_serialize(
683d081a
JR
945 const struct lttng_evaluation *evaluation,
946 struct lttng_payload *payload)
947{
948 int ret = 0;
8dbb86b8 949 struct lttng_evaluation_event_rule_matches *hit;
7c920b63 950 uint32_t capture_payload_size;
683d081a 951
8dbb86b8
JR
952 hit = container_of(evaluation,
953 struct lttng_evaluation_event_rule_matches, parent);
683d081a 954
7c920b63
PP
955 capture_payload_size = (uint32_t) hit->capture_payload.size;
956 ret = lttng_dynamic_buffer_append(&payload->buffer, &capture_payload_size,
957 sizeof(capture_payload_size));
958 if (ret) {
959 goto end;
960 }
961
962 ret = lttng_dynamic_buffer_append(&payload->buffer, hit->capture_payload.data,
963 hit->capture_payload.size);
964 if (ret) {
965 goto end;
966 }
967
968end:
969 return ret;
970}
971
972static
973bool msgpack_str_is_equal(const struct msgpack_object *obj, const char *str)
974{
975 bool is_equal = true;
976
977 assert(obj->type == MSGPACK_OBJECT_STR);
978
979 if (obj->via.str.size != strlen(str)) {
980 is_equal = false;
981 goto end;
982 }
983
984 if (strncmp(obj->via.str.ptr, str, obj->via.str.size) != 0) {
985 is_equal = false;
986 goto end;
987 }
988
989end:
990 return is_equal;
991}
992
993static
994const msgpack_object *get_msgpack_map_obj(const struct msgpack_object *map_obj,
995 const char *name)
996{
997 const msgpack_object *ret = NULL;
998 size_t i;
999
1000 assert(map_obj->type == MSGPACK_OBJECT_MAP);
1001
1002 for (i = 0; i < map_obj->via.map.size; i++) {
1003 const struct msgpack_object_kv *kv = &map_obj->via.map.ptr[i];
1004
1005 assert(kv->key.type == MSGPACK_OBJECT_STR);
1006
1007 if (msgpack_str_is_equal(&kv->key, name)) {
1008 ret = &kv->val;
1009 goto end;
1010 }
1011 }
1012
683d081a
JR
1013end:
1014 return ret;
1015}
1016
8dbb86b8 1017static void lttng_evaluation_event_rule_matches_destroy(
683d081a
JR
1018 struct lttng_evaluation *evaluation)
1019{
8dbb86b8 1020 struct lttng_evaluation_event_rule_matches *hit;
683d081a 1021
8dbb86b8
JR
1022 hit = container_of(evaluation,
1023 struct lttng_evaluation_event_rule_matches, parent);
7c920b63
PP
1024 lttng_dynamic_buffer_reset(&hit->capture_payload);
1025 lttng_event_field_value_destroy(hit->captured_values);
683d081a
JR
1026 free(hit);
1027}
1028
7c920b63
PP
1029static
1030int event_field_value_from_obj(const msgpack_object *obj,
1031 struct lttng_event_field_value **field_val)
1032{
1033 int ret = 0;
1034
1035 assert(obj);
1036 assert(field_val);
1037
1038 switch (obj->type) {
1039 case MSGPACK_OBJECT_NIL:
1040 /* Unavailable. */
1041 *field_val = NULL;
1042 goto end;
1043 case MSGPACK_OBJECT_POSITIVE_INTEGER:
1044 *field_val = lttng_event_field_value_uint_create(
1045 obj->via.u64);
1046 break;
1047 case MSGPACK_OBJECT_NEGATIVE_INTEGER:
1048 *field_val = lttng_event_field_value_int_create(
1049 obj->via.i64);
1050 break;
1051 case MSGPACK_OBJECT_FLOAT32:
1052 case MSGPACK_OBJECT_FLOAT64:
1053 *field_val = lttng_event_field_value_real_create(
1054 obj->via.f64);
1055 break;
1056 case MSGPACK_OBJECT_STR:
1057 *field_val = lttng_event_field_value_string_create_with_size(
1058 obj->via.str.ptr, obj->via.str.size);
1059 break;
1060 case MSGPACK_OBJECT_ARRAY:
1061 {
1062 size_t i;
1063
1064 *field_val = lttng_event_field_value_array_create();
1065 if (!*field_val) {
1066 goto error;
1067 }
1068
1069 for (i = 0; i < obj->via.array.size; i++) {
1070 const msgpack_object *elem_obj = &obj->via.array.ptr[i];
1071 struct lttng_event_field_value *elem_field_val;
1072
1073 ret = event_field_value_from_obj(elem_obj,
1074 &elem_field_val);
1075 if (ret) {
1076 goto error;
1077 }
1078
1079 if (elem_field_val) {
1080 ret = lttng_event_field_value_array_append(
1081 *field_val, elem_field_val);
1082 } else {
1083 ret = lttng_event_field_value_array_append_unavailable(
1084 *field_val);
1085 }
1086
1087 if (ret) {
1088 lttng_event_field_value_destroy(elem_field_val);
1089 goto error;
1090 }
1091 }
1092
1093 break;
1094 }
1095 case MSGPACK_OBJECT_MAP:
1096 {
1097 /*
1098 * As of this version, the only valid map object is
1099 * for an enumeration value, for example:
1100 *
1101 * type: enum
1102 * value: 177
1103 * labels:
1104 * - Labatt 50
1105 * - Molson Dry
1106 * - Carling Black Label
1107 */
1108 const msgpack_object *inner_obj;
1109 size_t label_i;
1110
1111 inner_obj = get_msgpack_map_obj(obj, "type");
1112 if (!inner_obj) {
1113 ERR("Missing `type` entry in map object");
1114 goto error;
1115 }
1116
1117 if (inner_obj->type != MSGPACK_OBJECT_STR) {
1118 ERR("Map object's `type` entry is not a string: type = %s",
1119 msgpack_object_type_str(inner_obj->type));
1120 goto error;
1121 }
1122
1123 if (!msgpack_str_is_equal(inner_obj, "enum")) {
1124 ERR("Map object's `type` entry: expecting `enum`");
1125 goto error;
1126 }
1127
1128 inner_obj = get_msgpack_map_obj(obj, "value");
1129 if (!inner_obj) {
1130 ERR("Missing `value` entry in map object");
1131 goto error;
1132 }
1133
1134 if (inner_obj->type == MSGPACK_OBJECT_POSITIVE_INTEGER) {
1135 *field_val = lttng_event_field_value_enum_uint_create(
1136 inner_obj->via.u64);
1137 } else if (inner_obj->type == MSGPACK_OBJECT_NEGATIVE_INTEGER) {
1138 *field_val = lttng_event_field_value_enum_int_create(
1139 inner_obj->via.i64);
1140 } else {
1141 ERR("Map object's `value` entry is not an integer: type = %s",
1142 msgpack_object_type_str(inner_obj->type));
1143 goto error;
1144 }
1145
1146 if (!*field_val) {
1147 goto error;
1148 }
1149
1150 inner_obj = get_msgpack_map_obj(obj, "labels");
1151 if (!inner_obj) {
1152 /* No labels */
1153 goto end;
1154 }
1155
1156 if (inner_obj->type != MSGPACK_OBJECT_ARRAY) {
1157 ERR("Map object's `labels` entry is not an array: type = %s",
1158 msgpack_object_type_str(inner_obj->type));
1159 goto error;
1160 }
1161
1162 for (label_i = 0; label_i < inner_obj->via.array.size;
1163 label_i++) {
1164 int iret;
1165 const msgpack_object *elem_obj =
1166 &inner_obj->via.array.ptr[label_i];
1167
1168 if (elem_obj->type != MSGPACK_OBJECT_STR) {
1169 ERR("Map object's `labels` entry's type is not a string: type = %s",
1170 msgpack_object_type_str(elem_obj->type));
1171 goto error;
1172 }
1173
1174 iret = lttng_event_field_value_enum_append_label_with_size(
1175 *field_val, elem_obj->via.str.ptr,
1176 elem_obj->via.str.size);
1177 if (iret) {
1178 goto error;
1179 }
1180 }
1181
1182 break;
1183 }
1184 default:
1185 ERR("Unexpected object type: type = %s",
1186 msgpack_object_type_str(obj->type));
1187 goto error;
1188 }
1189
1190 if (!*field_val) {
1191 goto error;
1192 }
1193
1194 goto end;
1195
1196error:
1197 lttng_event_field_value_destroy(*field_val);
1198 *field_val = NULL;
1199 ret = -1;
1200
1201end:
1202 return ret;
1203}
1204
8dbb86b8
JR
1205static struct lttng_event_field_value *event_field_value_from_capture_payload(
1206 const struct lttng_condition_event_rule_matches *condition,
1207 const char *capture_payload,
1208 size_t capture_payload_size)
7c920b63
PP
1209{
1210 struct lttng_event_field_value *ret = NULL;
1211 msgpack_unpacked unpacked;
1212 msgpack_unpack_return unpack_return;
1213 const msgpack_object *root_obj;
1214 const msgpack_object_array *root_array_obj;
1215 size_t i;
1216 size_t count;
1217
1218 assert(condition);
1219 assert(capture_payload);
1220
1221 /* Initialize value. */
1222 msgpack_unpacked_init(&unpacked);
1223
1224 /* Decode. */
1225 unpack_return = msgpack_unpack_next(&unpacked, capture_payload,
1226 capture_payload_size, NULL);
1227 if (unpack_return != MSGPACK_UNPACK_SUCCESS) {
1228 ERR("msgpack_unpack_next() failed to decode the "
1229 "MessagePack-encoded capture payload: "
1230 "size = %zu, ret = %d",
1231 capture_payload_size, unpack_return);
1232 goto error;
1233 }
1234
1235 /* Get root array. */
1236 root_obj = &unpacked.data;
1237
1238 if (root_obj->type != MSGPACK_OBJECT_ARRAY) {
1239 ERR("Expecting an array as the root object: type = %s",
1240 msgpack_object_type_str(root_obj->type));
1241 goto error;
1242 }
1243
1244 root_array_obj = &root_obj->via.array;
1245
1246 /* Create an empty root array event field value. */
1247 ret = lttng_event_field_value_array_create();
1248 if (!ret) {
1249 goto error;
1250 }
1251
1252 /*
1253 * For each capture descriptor in the condition object:
1254 *
1255 * 1. Get its corresponding captured field value MessagePack
1256 * object.
1257 *
1258 * 2. Create a corresponding event field value.
1259 *
1260 * 3. Append it to `ret` (the root array event field value).
1261 */
1262 count = lttng_dynamic_pointer_array_get_count(
1263 &condition->capture_descriptors);
1264 assert(count > 0);
1265
1266 for (i = 0; i < count; i++) {
1267 const struct lttng_capture_descriptor *capture_descriptor =
8dbb86b8 1268 lttng_condition_event_rule_matches_get_internal_capture_descriptor_at_index(
7c920b63
PP
1269 &condition->parent, i);
1270 const msgpack_object *elem_obj;
1271 struct lttng_event_field_value *elem_field_val;
1272 int iret;
1273
1274 assert(capture_descriptor);
1275
1276 elem_obj = &root_array_obj->ptr[i];
1277 iret = event_field_value_from_obj(elem_obj,
1278 &elem_field_val);
1279 if (iret) {
1280 goto error;
1281 }
1282
1283 if (elem_field_val) {
1284 iret = lttng_event_field_value_array_append(ret,
1285 elem_field_val);
1286 } else {
1287 iret = lttng_event_field_value_array_append_unavailable(
1288 ret);
1289 }
1290
1291 if (iret) {
1292 lttng_event_field_value_destroy(elem_field_val);
1293 goto error;
1294 }
1295 }
1296
1297 goto end;
1298
1299error:
1300 lttng_event_field_value_destroy(ret);
1301 ret = NULL;
1302
1303end:
1304 msgpack_unpacked_destroy(&unpacked);
1305 return ret;
1306}
1307
683d081a 1308LTTNG_HIDDEN
8dbb86b8
JR
1309struct lttng_evaluation *lttng_evaluation_event_rule_matches_create(
1310 const struct lttng_condition_event_rule_matches *condition,
1311 const char *capture_payload,
1312 size_t capture_payload_size,
7c920b63 1313 bool decode_capture_payload)
683d081a 1314{
8dbb86b8 1315 struct lttng_evaluation_event_rule_matches *hit;
683d081a
JR
1316 struct lttng_evaluation *evaluation = NULL;
1317
8dbb86b8 1318 hit = zmalloc(sizeof(struct lttng_evaluation_event_rule_matches));
683d081a 1319 if (!hit) {
7c920b63 1320 goto error;
683d081a
JR
1321 }
1322
7c920b63
PP
1323 lttng_dynamic_buffer_init(&hit->capture_payload);
1324
1325 if (capture_payload) {
1326 const int ret = lttng_dynamic_buffer_append(
1327 &hit->capture_payload, capture_payload,
1328 capture_payload_size);
1329 if (ret) {
1330 ERR("Failed to initialize capture payload of event rule evaluation");
1331 goto error;
1332 }
1333
1334 if (decode_capture_payload) {
1335 hit->captured_values =
1336 event_field_value_from_capture_payload(
1337 condition,
1338 capture_payload,
1339 capture_payload_size);
1340 if (!hit->captured_values) {
1341 ERR("Failed to decode the capture payload: size = %zu",
1342 capture_payload_size);
1343 goto error;
1344 }
1345 }
683d081a
JR
1346 }
1347
8dbb86b8
JR
1348 hit->parent.type = LTTNG_CONDITION_TYPE_EVENT_RULE_MATCHES;
1349 hit->parent.serialize = lttng_evaluation_event_rule_matches_serialize;
1350 hit->parent.destroy = lttng_evaluation_event_rule_matches_destroy;
683d081a
JR
1351
1352 evaluation = &hit->parent;
1353 hit = NULL;
1354
7c920b63 1355error:
683d081a 1356 if (hit) {
8dbb86b8 1357 lttng_evaluation_event_rule_matches_destroy(&hit->parent);
683d081a
JR
1358 }
1359
1360 return evaluation;
1361}
1362
8dbb86b8
JR
1363enum lttng_evaluation_event_rule_matches_status
1364lttng_evaluation_event_rule_matches_get_captured_values(
7c920b63
PP
1365 const struct lttng_evaluation *evaluation,
1366 const struct lttng_event_field_value **field_val)
1367{
8dbb86b8
JR
1368 struct lttng_evaluation_event_rule_matches *hit;
1369 enum lttng_evaluation_event_rule_matches_status status =
1370 LTTNG_EVALUATION_EVENT_RULE_MATCHES_STATUS_OK;
7c920b63 1371
8dbb86b8 1372 if (!evaluation || !is_event_rule_matches_evaluation(evaluation) ||
7c920b63 1373 !field_val) {
8dbb86b8 1374 status = LTTNG_EVALUATION_EVENT_RULE_MATCHES_STATUS_INVALID;
7c920b63
PP
1375 goto end;
1376 }
1377
8dbb86b8
JR
1378 hit = container_of(evaluation,
1379 struct lttng_evaluation_event_rule_matches, parent);
7c920b63 1380 if (!hit->captured_values) {
8dbb86b8 1381 status = LTTNG_EVALUATION_EVENT_RULE_MATCHES_STATUS_NONE;
7c920b63
PP
1382 goto end;
1383 }
1384
1385 *field_val = hit->captured_values;
1386
1387end:
1388 return status;
683d081a 1389}
834966af
JR
1390
1391LTTNG_HIDDEN
1392enum lttng_error_code
8dbb86b8 1393lttng_condition_event_rule_matches_generate_capture_descriptor_bytecode(
834966af
JR
1394 struct lttng_condition *condition)
1395{
1396 enum lttng_error_code ret;
1397 enum lttng_condition_status status;
1398 unsigned int capture_count, i;
1399
8dbb86b8 1400 if (!condition || !IS_EVENT_RULE_MATCHES_CONDITION(condition)) {
834966af
JR
1401 ret = LTTNG_ERR_FATAL;
1402 goto end;
1403 }
1404
8dbb86b8 1405 status = lttng_condition_event_rule_matches_get_capture_descriptor_count(
834966af
JR
1406 condition, &capture_count);
1407 if (status != LTTNG_CONDITION_STATUS_OK) {
1408 ret = LTTNG_ERR_FATAL;
1409 goto end;
1410 }
1411
1412 for (i = 0; i < capture_count; i++) {
1413 struct lttng_capture_descriptor *local_capture_desc =
8dbb86b8 1414 lttng_condition_event_rule_matches_get_internal_capture_descriptor_at_index(
834966af
JR
1415 condition, i);
1416
1417 if (local_capture_desc == NULL) {
1418 ret = LTTNG_ERR_FATAL;
1419 goto end;
1420 }
1421
1422 /* Generate the bytecode. */
1423 status = lttng_event_expr_to_bytecode(
1424 local_capture_desc->event_expression,
1425 &local_capture_desc->bytecode);
1426 if (status < 0 || local_capture_desc->bytecode == NULL) {
1427 ret = LTTNG_ERR_INVALID_CAPTURE_EXPRESSION;
1428 goto end;
1429 }
1430 }
1431
1432 /* Everything went better than expected */
1433 ret = LTTNG_OK;
1434
1435end:
1436 return ret;
1437}
51dbe985
JR
1438
1439LTTNG_HIDDEN
1440const struct lttng_bytecode *
8dbb86b8 1441lttng_condition_event_rule_matches_get_capture_bytecode_at_index(
51dbe985
JR
1442 const struct lttng_condition *condition, unsigned int index)
1443{
8dbb86b8
JR
1444 const struct lttng_condition_event_rule_matches
1445 *event_rule_matches_cond = container_of(condition,
1446 const struct lttng_condition_event_rule_matches,
1447 parent);
51dbe985
JR
1448 struct lttng_capture_descriptor *desc = NULL;
1449 struct lttng_bytecode *bytecode = NULL;
1450 unsigned int count;
1451 enum lttng_condition_status status;
1452
8dbb86b8 1453 if (!condition || !IS_EVENT_RULE_MATCHES_CONDITION(condition)) {
51dbe985
JR
1454 goto end;
1455 }
1456
8dbb86b8 1457 status = lttng_condition_event_rule_matches_get_capture_descriptor_count(
51dbe985
JR
1458 condition, &count);
1459 if (status != LTTNG_CONDITION_STATUS_OK) {
1460 goto end;
1461 }
1462
1463 if (index >= count) {
1464 goto end;
1465 }
1466
1467 desc = lttng_dynamic_pointer_array_get_pointer(
8dbb86b8 1468 &event_rule_matches_cond->capture_descriptors, index);
51dbe985
JR
1469 if (desc == NULL) {
1470 goto end;
1471 }
1472
1473 bytecode = desc->bytecode;
1474end:
1475 return bytecode;
1476}
This page took 0.090472 seconds and 4 git commands to generate.