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