2 * Copyright (C) 2020 Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
4 * SPDX-License-Identifier: LGPL-2.1-only
8 #include <common/error.hpp>
9 #include <common/macros.hpp>
10 #include <common/mi-lttng.hpp>
13 #include <lttng/condition/condition-internal.hpp>
14 #include <lttng/condition/event-rule-matches-internal.hpp>
15 #include <lttng/condition/event-rule-matches.h>
16 #include <lttng/event-expr-internal.hpp>
17 #include <lttng/event-expr.h>
18 #include <lttng/event-field-value-internal.hpp>
19 #include <lttng/event-rule/event-rule-internal.hpp>
20 #include <lttng/lttng-error.h>
23 #include <vendor/msgpack/msgpack.h>
25 #define IS_EVENT_RULE_MATCHES_CONDITION(condition) \
26 (lttng_condition_get_type(condition) == \
27 LTTNG_CONDITION_TYPE_EVENT_RULE_MATCHES)
29 static bool is_event_rule_matches_evaluation(
30 const struct lttng_evaluation
*evaluation
)
32 enum lttng_condition_type type
= lttng_evaluation_get_type(evaluation
);
34 return type
== LTTNG_CONDITION_TYPE_EVENT_RULE_MATCHES
;
37 static bool lttng_condition_event_rule_matches_validate(
38 const struct lttng_condition
*condition
);
39 static int lttng_condition_event_rule_matches_serialize(
40 const struct lttng_condition
*condition
,
41 struct lttng_payload
*payload
);
42 static bool lttng_condition_event_rule_matches_is_equal(
43 const struct lttng_condition
*_a
,
44 const struct lttng_condition
*_b
);
45 static void lttng_condition_event_rule_matches_destroy(
46 struct lttng_condition
*condition
);
48 static bool lttng_condition_event_rule_matches_validate(
49 const struct lttng_condition
*condition
)
52 struct lttng_condition_event_rule_matches
*event_rule
;
58 event_rule
= lttng::utils::container_of(condition
,
59 <tng_condition_event_rule_matches::parent
);
60 if (!event_rule
->rule
) {
61 ERR("Invalid on event condition: a rule must be set");
65 valid
= lttng_event_rule_validate(event_rule
->rule
);
70 static const char *msgpack_object_type_str(msgpack_object_type type
)
75 case MSGPACK_OBJECT_NIL
:
76 name
= "MSGPACK_OBJECT_NIL";
78 case MSGPACK_OBJECT_BOOLEAN
:
79 name
= "MSGPACK_OBJECT_BOOLEAN";
81 case MSGPACK_OBJECT_POSITIVE_INTEGER
:
82 name
= "MSGPACK_OBJECT_POSITIVE_INTEGER";
84 case MSGPACK_OBJECT_NEGATIVE_INTEGER
:
85 name
= "MSGPACK_OBJECT_NEGATIVE_INTEGER";
87 case MSGPACK_OBJECT_FLOAT32
:
88 name
= "MSGPACK_OBJECT_FLOAT32";
90 case MSGPACK_OBJECT_FLOAT
:
91 /* Same value as MSGPACK_OBJECT_FLOAT64 */
92 name
= "MSGPACK_OBJECT_FLOAT(64)";
94 case MSGPACK_OBJECT_STR
:
95 name
= "MSGPACK_OBJECT_STR";
97 case MSGPACK_OBJECT_ARRAY
:
98 name
= "MSGPACK_OBJECT_ARRAY";
100 case MSGPACK_OBJECT_MAP
:
101 name
= "MSGPACK_OBJECT_MAP";
103 case MSGPACK_OBJECT_BIN
:
104 name
= "MSGPACK_OBJECT_BIN";
106 case MSGPACK_OBJECT_EXT
:
107 name
= "MSGPACK_OBJECT_EXT";
117 * Serializes the C string `str` into `buf`.
119 * Encoding is the length of `str` plus one (for the null character),
120 * and then the string, including its null terminator.
123 int serialize_cstr(const char *str
, struct lttng_dynamic_buffer
*buf
)
126 const uint32_t len
= strlen(str
) + 1;
128 /* Serialize the length, including the null terminator. */
129 DBG("Serializing C string's length (including null terminator): "
131 ret
= lttng_dynamic_buffer_append(buf
, &len
, sizeof(len
));
136 /* Serialize the string. */
137 DBG("Serializing C string: '%s'", str
);
138 ret
= lttng_dynamic_buffer_append(buf
, str
, len
);
148 * Serializes the event expression `expr` into `buf`.
151 int serialize_event_expr(const struct lttng_event_expr
*expr
,
152 struct lttng_payload
*payload
)
154 const uint8_t type
= expr
->type
;
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
));
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
:
169 const struct lttng_event_expr_field
*field_expr
=
170 lttng::utils::container_of(expr
,
171 <tng_event_expr_field::parent
);
173 /* Serialize the field name. */
174 DBG("Serializing field event expression's field name: '%s'",
176 ret
= serialize_cstr(field_expr
->name
, &payload
->buffer
);
183 case LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD
:
185 const struct lttng_event_expr_app_specific_context_field
*field_expr
=
186 lttng::utils::container_of(expr
,
187 <tng_event_expr_app_specific_context_field::parent
);
189 /* Serialize the provider name. */
190 DBG("Serializing app-specific context field event expression's "
191 "provider name: '%s'",
192 field_expr
->provider_name
);
193 ret
= serialize_cstr(field_expr
->provider_name
, &payload
->buffer
);
198 /* Serialize the type name. */
199 DBG("Serializing app-specific context field event expression's "
201 field_expr
->provider_name
);
202 ret
= serialize_cstr(field_expr
->type_name
, &payload
->buffer
);
209 case LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT
:
211 const struct lttng_event_expr_array_field_element
*elem_expr
=
212 lttng::utils::container_of(expr
,
213 <tng_event_expr_array_field_element::parent
);
214 const uint32_t index
= elem_expr
->index
;
216 /* Serialize the index. */
217 DBG("Serializing array field element event expression's "
218 "index: %u", elem_expr
->index
);
219 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, &index
, sizeof(index
));
224 /* Serialize the parent array field expression. */
225 DBG("Serializing array field element event expression's "
226 "parent array field event expression");
227 ret
= serialize_event_expr(elem_expr
->array_field_expr
, payload
);
242 static struct lttng_capture_descriptor
*
243 lttng_condition_event_rule_matches_get_internal_capture_descriptor_at_index(
244 const struct lttng_condition
*condition
, unsigned int index
)
246 const struct lttng_condition_event_rule_matches
247 *event_rule_matches_cond
= lttng::utils::container_of(condition
,
248 <tng_condition_event_rule_matches::parent
);
249 struct lttng_capture_descriptor
*desc
= NULL
;
251 enum lttng_condition_status status
;
253 if (!condition
|| !IS_EVENT_RULE_MATCHES_CONDITION(condition
)) {
257 status
= lttng_condition_event_rule_matches_get_capture_descriptor_count(
259 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
263 if (index
>= count
) {
267 desc
= (lttng_capture_descriptor
*) lttng_dynamic_pointer_array_get_pointer(
268 &event_rule_matches_cond
->capture_descriptors
, index
);
273 static int lttng_condition_event_rule_matches_serialize(
274 const struct lttng_condition
*condition
,
275 struct lttng_payload
*payload
)
278 struct lttng_condition_event_rule_matches
*event_rule_matches_condition
;
279 enum lttng_condition_status status
;
280 /* Used for iteration and communication (size matters). */
281 uint32_t i
, capture_descr_count
;
283 if (!condition
|| !IS_EVENT_RULE_MATCHES_CONDITION(condition
)) {
288 DBG("Serializing on event condition");
289 event_rule_matches_condition
= lttng::utils::container_of(condition
,
290 <tng_condition_event_rule_matches::parent
);
292 DBG("Serializing on event condition's event rule");
293 ret
= lttng_event_rule_serialize(
294 event_rule_matches_condition
->rule
, payload
);
299 status
= lttng_condition_event_rule_matches_get_capture_descriptor_count(
300 condition
, &capture_descr_count
);
301 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
306 DBG("Serializing on event condition's capture descriptor count: %" PRIu32
,
307 capture_descr_count
);
308 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, &capture_descr_count
,
309 sizeof(capture_descr_count
));
314 for (i
= 0; i
< capture_descr_count
; i
++) {
315 const struct lttng_capture_descriptor
*desc
=
316 lttng_condition_event_rule_matches_get_internal_capture_descriptor_at_index(
319 DBG("Serializing on event condition's capture descriptor %" PRIu32
,
321 ret
= serialize_event_expr(desc
->event_expression
, payload
);
332 bool capture_descriptors_are_equal(
333 const struct lttng_condition
*condition_a
,
334 const struct lttng_condition
*condition_b
)
336 bool is_equal
= true;
337 unsigned int capture_descr_count_a
;
338 unsigned int capture_descr_count_b
;
340 enum lttng_condition_status status
;
342 status
= lttng_condition_event_rule_matches_get_capture_descriptor_count(
343 condition_a
, &capture_descr_count_a
);
344 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
348 status
= lttng_condition_event_rule_matches_get_capture_descriptor_count(
349 condition_b
, &capture_descr_count_b
);
350 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
354 if (capture_descr_count_a
!= capture_descr_count_b
) {
358 for (i
= 0; i
< capture_descr_count_a
; i
++) {
359 const struct lttng_event_expr
*expr_a
=
360 lttng_condition_event_rule_matches_get_capture_descriptor_at_index(
362 const struct lttng_event_expr
*expr_b
=
363 lttng_condition_event_rule_matches_get_capture_descriptor_at_index(
366 if (!lttng_event_expr_is_equal(expr_a
, expr_b
)) {
380 static bool lttng_condition_event_rule_matches_is_equal(
381 const struct lttng_condition
*_a
,
382 const struct lttng_condition
*_b
)
384 bool is_equal
= false;
385 struct lttng_condition_event_rule_matches
*a
, *b
;
387 a
= lttng::utils::container_of(_a
, <tng_condition_event_rule_matches::parent
);
388 b
= lttng::utils::container_of(_b
, <tng_condition_event_rule_matches::parent
);
390 /* Both event rules must be set or both must be unset. */
391 if ((a
->rule
&& !b
->rule
) || (!a
->rule
&& b
->rule
)) {
392 WARN("Comparing event_rule conditions with uninitialized rule");
396 is_equal
= lttng_event_rule_is_equal(a
->rule
, b
->rule
);
401 is_equal
= capture_descriptors_are_equal(_a
, _b
);
407 static void lttng_condition_event_rule_matches_destroy(
408 struct lttng_condition
*condition
)
410 struct lttng_condition_event_rule_matches
*event_rule_matches_condition
;
412 event_rule_matches_condition
= lttng::utils::container_of(condition
,
413 <tng_condition_event_rule_matches::parent
);
415 lttng_event_rule_put(event_rule_matches_condition
->rule
);
416 lttng_dynamic_pointer_array_reset(
417 &event_rule_matches_condition
->capture_descriptors
);
418 free(event_rule_matches_condition
);
422 void destroy_capture_descriptor(void *ptr
)
424 struct lttng_capture_descriptor
*desc
=
425 (struct lttng_capture_descriptor
*) ptr
;
427 lttng_event_expr_destroy(desc
->event_expression
);
428 free(desc
->bytecode
);
432 static enum lttng_error_code
lttng_condition_event_rule_matches_mi_serialize(
433 const struct lttng_condition
*condition
,
434 struct mi_writer
*writer
)
437 enum lttng_error_code ret_code
;
438 enum lttng_condition_status status
;
439 const struct lttng_event_rule
*rule
= NULL
;
440 unsigned int capture_descriptor_count
, i
;
442 LTTNG_ASSERT(condition
);
443 LTTNG_ASSERT(writer
);
444 LTTNG_ASSERT(IS_EVENT_RULE_MATCHES_CONDITION(condition
));
446 status
= lttng_condition_event_rule_matches_get_rule(condition
, &rule
);
447 LTTNG_ASSERT(status
== LTTNG_CONDITION_STATUS_OK
);
448 LTTNG_ASSERT(rule
!= NULL
);
450 status
= lttng_condition_event_rule_matches_get_capture_descriptor_count(
451 condition
, &capture_descriptor_count
);
452 LTTNG_ASSERT(status
== LTTNG_CONDITION_STATUS_OK
);
454 /* Open condition event rule matches element. */
455 ret
= mi_lttng_writer_open_element(
456 writer
, mi_lttng_element_condition_event_rule_matches
);
461 /* Serialize the event rule. */
462 ret_code
= lttng_event_rule_mi_serialize(rule
, writer
);
463 if (ret_code
!= LTTNG_OK
) {
467 /* Open the capture descriptors element. */
468 ret
= mi_lttng_writer_open_element(
469 writer
, mi_lttng_element_capture_descriptors
);
474 for (i
= 0; i
< capture_descriptor_count
; i
++) {
475 const struct lttng_event_expr
*descriptor
= NULL
;
477 descriptor
= lttng_condition_event_rule_matches_get_capture_descriptor_at_index(
479 LTTNG_ASSERT(descriptor
);
481 ret_code
= lttng_event_expr_mi_serialize(descriptor
, writer
);
482 if (ret_code
!= LTTNG_OK
) {
487 /* Close capture descriptors element. */
488 ret
= mi_lttng_writer_close_element(writer
);
493 /* Close condition_event_rule_matches. */
494 ret
= mi_lttng_writer_close_element(writer
);
502 ret_code
= LTTNG_ERR_MI_IO_FAIL
;
507 struct lttng_condition
*lttng_condition_event_rule_matches_create(
508 struct lttng_event_rule
*rule
)
510 struct lttng_condition
*parent
= NULL
;
511 struct lttng_condition_event_rule_matches
*condition
= NULL
;
517 condition
= zmalloc
<lttng_condition_event_rule_matches
>();
522 lttng_condition_init(&condition
->parent
,
523 LTTNG_CONDITION_TYPE_EVENT_RULE_MATCHES
);
524 condition
->parent
.validate
=
525 lttng_condition_event_rule_matches_validate
,
526 condition
->parent
.serialize
=
527 lttng_condition_event_rule_matches_serialize
,
528 condition
->parent
.equal
= lttng_condition_event_rule_matches_is_equal
,
529 condition
->parent
.destroy
= lttng_condition_event_rule_matches_destroy
,
530 condition
->parent
.mi_serialize
= lttng_condition_event_rule_matches_mi_serialize
,
532 lttng_event_rule_get(rule
);
533 condition
->rule
= rule
;
536 lttng_dynamic_pointer_array_init(&condition
->capture_descriptors
,
537 destroy_capture_descriptor
);
539 parent
= &condition
->parent
;
545 uint64_t uint_from_buffer(const struct lttng_buffer_view
*view
, size_t size
,
549 const struct lttng_buffer_view uint_view
=
550 lttng_buffer_view_from_view(view
, *offset
, size
);
552 if (!lttng_buffer_view_is_valid(&uint_view
)) {
559 ret
= (uint64_t) *uint_view
.data
;
561 case sizeof(uint32_t):
565 memcpy(&u32
, uint_view
.data
, sizeof(u32
));
566 ret
= (uint64_t) u32
;
570 memcpy(&ret
, uint_view
.data
, sizeof(ret
));
583 const char *str_from_buffer(const struct lttng_buffer_view
*view
,
589 len
= uint_from_buffer(view
, sizeof(uint32_t), offset
);
590 if (len
== UINT64_C(-1)) {
594 ret
= &view
->data
[*offset
];
596 if (!lttng_buffer_view_contains_string(view
, ret
, len
)) {
611 struct lttng_event_expr
*event_expr_from_payload(
612 struct lttng_payload_view
*view
, size_t *offset
)
614 struct lttng_event_expr
*expr
= NULL
;
618 type
= uint_from_buffer(&view
->buffer
, sizeof(uint8_t), offset
);
619 if (type
== UINT64_C(-1)) {
624 case LTTNG_EVENT_EXPR_TYPE_EVENT_PAYLOAD_FIELD
:
625 str
= str_from_buffer(&view
->buffer
, offset
);
630 expr
= lttng_event_expr_event_payload_field_create(str
);
632 case LTTNG_EVENT_EXPR_TYPE_CHANNEL_CONTEXT_FIELD
:
633 str
= str_from_buffer(&view
->buffer
, offset
);
638 expr
= lttng_event_expr_channel_context_field_create(str
);
640 case LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD
:
642 const char *provider_name
;
643 const char *type_name
;
645 provider_name
= str_from_buffer(&view
->buffer
, offset
);
646 if (!provider_name
) {
650 type_name
= str_from_buffer(&view
->buffer
, offset
);
655 expr
= lttng_event_expr_app_specific_context_field_create(
656 provider_name
, type_name
);
659 case LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT
:
661 struct lttng_event_expr
*array_field_expr
;
662 const uint64_t index
= uint_from_buffer(
663 &view
->buffer
, sizeof(uint32_t), offset
);
665 if (index
== UINT64_C(-1)) {
669 /* Array field expression is the encoded after this. */
670 array_field_expr
= event_expr_from_payload(view
, offset
);
671 if (!array_field_expr
) {
675 /* Move ownership of `array_field_expr` to new expression. */
676 expr
= lttng_event_expr_array_field_element_create(
677 array_field_expr
, (unsigned int) index
);
679 /* `array_field_expr` not moved: destroy it. */
680 lttng_event_expr_destroy(array_field_expr
);
686 ERR("Invalid event expression type encoutered while deserializing event expression: type = %" PRIu64
,
694 lttng_event_expr_destroy(expr
);
701 ssize_t
lttng_condition_event_rule_matches_create_from_payload(
702 struct lttng_payload_view
*view
,
703 struct lttng_condition
**_condition
)
705 ssize_t consumed_length
;
707 ssize_t event_rule_length
;
708 uint32_t i
, capture_descr_count
;
709 struct lttng_condition
*condition
= NULL
;
710 struct lttng_event_rule
*event_rule
= NULL
;
712 if (!view
|| !_condition
) {
716 /* Struct lttng_event_rule. */
718 struct lttng_payload_view event_rule_view
=
719 lttng_payload_view_from_view(view
, offset
, -1);
721 event_rule_length
= lttng_event_rule_create_from_payload(
722 &event_rule_view
, &event_rule
);
725 if (event_rule_length
< 0 || !event_rule
) {
729 offset
+= event_rule_length
;
731 /* Create condition (no capture descriptors yet) at this point */
732 condition
= lttng_condition_event_rule_matches_create(event_rule
);
737 /* Capture descriptor count. */
738 LTTNG_ASSERT(event_rule_length
>= 0);
739 capture_descr_count
= uint_from_buffer(&view
->buffer
, sizeof(uint32_t), &offset
);
740 if (capture_descr_count
== UINT32_C(-1)) {
744 /* Capture descriptors. */
745 for (i
= 0; i
< capture_descr_count
; i
++) {
746 enum lttng_condition_status status
;
747 struct lttng_event_expr
*expr
= event_expr_from_payload(
754 /* Move ownership of `expr` to `condition`. */
755 status
= lttng_condition_event_rule_matches_append_capture_descriptor(
757 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
758 /* `expr` not moved: destroy it. */
759 lttng_event_expr_destroy(expr
);
764 consumed_length
= (ssize_t
) offset
;
765 *_condition
= condition
;
770 consumed_length
= -1;
773 lttng_event_rule_put(event_rule
);
774 lttng_condition_put(condition
);
775 return consumed_length
;
778 enum lttng_condition_status
779 lttng_condition_event_rule_matches_borrow_rule_mutable(
780 const struct lttng_condition
*condition
,
781 struct lttng_event_rule
**rule
)
783 struct lttng_condition_event_rule_matches
*event_rule
;
784 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
786 if (!condition
|| !IS_EVENT_RULE_MATCHES_CONDITION(condition
) ||
788 status
= LTTNG_CONDITION_STATUS_INVALID
;
792 event_rule
= lttng::utils::container_of(condition
,
793 <tng_condition_event_rule_matches::parent
);
794 if (!event_rule
->rule
) {
795 status
= LTTNG_CONDITION_STATUS_UNSET
;
799 *rule
= event_rule
->rule
;
804 enum lttng_condition_status
lttng_condition_event_rule_matches_get_rule(
805 const struct lttng_condition
*condition
,
806 const struct lttng_event_rule
**rule
)
808 struct lttng_event_rule
*mutable_rule
= NULL
;
809 const enum lttng_condition_status status
=
810 lttng_condition_event_rule_matches_borrow_rule_mutable(
811 condition
, &mutable_rule
);
813 *rule
= mutable_rule
;
817 void lttng_condition_event_rule_matches_set_error_counter_index(
818 struct lttng_condition
*condition
, uint64_t error_counter_index
)
820 struct lttng_condition_event_rule_matches
*event_rule_matches_cond
=
821 lttng::utils::container_of(condition
,
822 <tng_condition_event_rule_matches::parent
);
824 LTTNG_OPTIONAL_SET(&event_rule_matches_cond
->error_counter_index
,
825 error_counter_index
);
828 uint64_t lttng_condition_event_rule_matches_get_error_counter_index(
829 const struct lttng_condition
*condition
)
831 const struct lttng_condition_event_rule_matches
832 *event_rule_matches_cond
= lttng::utils::container_of(condition
,
833 <tng_condition_event_rule_matches::parent
);
835 return LTTNG_OPTIONAL_GET(event_rule_matches_cond
->error_counter_index
);
838 enum lttng_condition_status
839 lttng_condition_event_rule_matches_append_capture_descriptor(
840 struct lttng_condition
*condition
,
841 struct lttng_event_expr
*expr
)
844 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
845 struct lttng_condition_event_rule_matches
*event_rule_matches_cond
=
846 lttng::utils::container_of(condition
,
847 <tng_condition_event_rule_matches::parent
);
848 struct lttng_capture_descriptor
*descriptor
= NULL
;
849 const struct lttng_event_rule
*rule
= NULL
;
851 /* Only accept l-values. */
852 if (!condition
|| !IS_EVENT_RULE_MATCHES_CONDITION(condition
) ||
853 !expr
|| !lttng_event_expr_is_lvalue(expr
)) {
854 status
= LTTNG_CONDITION_STATUS_INVALID
;
858 status
= lttng_condition_event_rule_matches_get_rule(condition
, &rule
);
859 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
863 switch(lttng_event_rule_get_type(rule
)) {
864 case LTTNG_EVENT_RULE_TYPE_USER_TRACEPOINT
:
865 case LTTNG_EVENT_RULE_TYPE_KERNEL_TRACEPOINT
:
866 case LTTNG_EVENT_RULE_TYPE_JUL_LOGGING
:
867 case LTTNG_EVENT_RULE_TYPE_LOG4J_LOGGING
:
868 case LTTNG_EVENT_RULE_TYPE_PYTHON_LOGGING
:
869 case LTTNG_EVENT_RULE_TYPE_KERNEL_SYSCALL
:
871 status
= LTTNG_CONDITION_STATUS_OK
;
873 case LTTNG_EVENT_RULE_TYPE_UNKNOWN
:
874 status
= LTTNG_CONDITION_STATUS_INVALID
;
877 status
= LTTNG_CONDITION_STATUS_UNSUPPORTED
;
881 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
885 descriptor
= malloc
<lttng_capture_descriptor
>();
886 if (descriptor
== NULL
) {
887 status
= LTTNG_CONDITION_STATUS_ERROR
;
891 descriptor
->event_expression
= expr
;
892 descriptor
->bytecode
= NULL
;
894 ret
= lttng_dynamic_pointer_array_add_pointer(
895 &event_rule_matches_cond
->capture_descriptors
,
898 status
= LTTNG_CONDITION_STATUS_ERROR
;
902 /* Ownership is transfered to the internal capture_descriptors array */
909 enum lttng_condition_status
910 lttng_condition_event_rule_matches_get_capture_descriptor_count(
911 const struct lttng_condition
*condition
, unsigned int *count
)
913 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
914 const struct lttng_condition_event_rule_matches
915 *event_rule_matches_condition
= lttng::utils::container_of(condition
,
916 <tng_condition_event_rule_matches::parent
);
918 if (!condition
|| !IS_EVENT_RULE_MATCHES_CONDITION(condition
) ||
920 status
= LTTNG_CONDITION_STATUS_INVALID
;
924 *count
= lttng_dynamic_pointer_array_get_count(
925 &event_rule_matches_condition
->capture_descriptors
);
931 const struct lttng_event_expr
*
932 lttng_condition_event_rule_matches_get_capture_descriptor_at_index(
933 const struct lttng_condition
*condition
, unsigned int index
)
935 const struct lttng_event_expr
*expr
= NULL
;
936 const struct lttng_capture_descriptor
*desc
= NULL
;
938 desc
= lttng_condition_event_rule_matches_get_internal_capture_descriptor_at_index(
943 expr
= desc
->event_expression
;
949 ssize_t
lttng_evaluation_event_rule_matches_create_from_payload(
950 const struct lttng_condition_event_rule_matches
*condition
,
951 struct lttng_payload_view
*view
,
952 struct lttng_evaluation
**_evaluation
)
954 ssize_t ret
, offset
= 0;
955 struct lttng_evaluation
*evaluation
= NULL
;
956 uint32_t capture_payload_size
;
957 const char *capture_payload
= NULL
;
965 const struct lttng_payload_view current_view
=
966 lttng_payload_view_from_view(view
, offset
, -1);
968 if (current_view
.buffer
.size
< sizeof(capture_payload_size
)) {
973 memcpy(&capture_payload_size
, current_view
.buffer
.data
,
974 sizeof(capture_payload_size
));
976 offset
+= sizeof(capture_payload_size
);
978 if (capture_payload_size
> 0) {
979 const struct lttng_payload_view current_view
=
980 lttng_payload_view_from_view(view
, offset
, -1);
982 if (current_view
.buffer
.size
< capture_payload_size
) {
987 capture_payload
= current_view
.buffer
.data
;
990 evaluation
= lttng_evaluation_event_rule_matches_create(
991 condition
, capture_payload
, capture_payload_size
, true);
997 offset
+= capture_payload_size
;
998 *_evaluation
= evaluation
;
1003 lttng_evaluation_destroy(evaluation
);
1007 static int lttng_evaluation_event_rule_matches_serialize(
1008 const struct lttng_evaluation
*evaluation
,
1009 struct lttng_payload
*payload
)
1012 struct lttng_evaluation_event_rule_matches
*hit
;
1013 uint32_t capture_payload_size
;
1015 hit
= lttng::utils::container_of(evaluation
,
1016 <tng_evaluation_event_rule_matches::parent
);
1018 capture_payload_size
= (uint32_t) hit
->capture_payload
.size
;
1019 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, &capture_payload_size
,
1020 sizeof(capture_payload_size
));
1025 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, hit
->capture_payload
.data
,
1026 hit
->capture_payload
.size
);
1036 bool msgpack_str_is_equal(const struct msgpack_object
*obj
, const char *str
)
1038 bool is_equal
= true;
1040 LTTNG_ASSERT(obj
->type
== MSGPACK_OBJECT_STR
);
1042 if (obj
->via
.str
.size
!= strlen(str
)) {
1047 if (strncmp(obj
->via
.str
.ptr
, str
, obj
->via
.str
.size
) != 0) {
1057 const msgpack_object
*get_msgpack_map_obj(const struct msgpack_object
*map_obj
,
1060 const msgpack_object
*ret
= NULL
;
1063 LTTNG_ASSERT(map_obj
->type
== MSGPACK_OBJECT_MAP
);
1065 for (i
= 0; i
< map_obj
->via
.map
.size
; i
++) {
1066 const struct msgpack_object_kv
*kv
= &map_obj
->via
.map
.ptr
[i
];
1068 LTTNG_ASSERT(kv
->key
.type
== MSGPACK_OBJECT_STR
);
1070 if (msgpack_str_is_equal(&kv
->key
, name
)) {
1080 static void lttng_evaluation_event_rule_matches_destroy(
1081 struct lttng_evaluation
*evaluation
)
1083 struct lttng_evaluation_event_rule_matches
*hit
;
1085 hit
= lttng::utils::container_of(evaluation
,
1086 <tng_evaluation_event_rule_matches::parent
);
1087 lttng_dynamic_buffer_reset(&hit
->capture_payload
);
1088 lttng_event_field_value_destroy(hit
->captured_values
);
1093 int event_field_value_from_obj(const msgpack_object
*obj
,
1094 struct lttng_event_field_value
**field_val
)
1099 LTTNG_ASSERT(field_val
);
1101 switch (obj
->type
) {
1102 case MSGPACK_OBJECT_NIL
:
1106 case MSGPACK_OBJECT_POSITIVE_INTEGER
:
1107 *field_val
= lttng_event_field_value_uint_create(
1110 case MSGPACK_OBJECT_NEGATIVE_INTEGER
:
1111 *field_val
= lttng_event_field_value_int_create(
1114 case MSGPACK_OBJECT_FLOAT32
:
1115 case MSGPACK_OBJECT_FLOAT64
:
1116 *field_val
= lttng_event_field_value_real_create(
1119 case MSGPACK_OBJECT_STR
:
1120 *field_val
= lttng_event_field_value_string_create_with_size(
1121 obj
->via
.str
.ptr
, obj
->via
.str
.size
);
1123 case MSGPACK_OBJECT_ARRAY
:
1127 *field_val
= lttng_event_field_value_array_create();
1132 for (i
= 0; i
< obj
->via
.array
.size
; i
++) {
1133 const msgpack_object
*elem_obj
= &obj
->via
.array
.ptr
[i
];
1134 struct lttng_event_field_value
*elem_field_val
;
1136 ret
= event_field_value_from_obj(elem_obj
,
1142 if (elem_field_val
) {
1143 ret
= lttng_event_field_value_array_append(
1144 *field_val
, elem_field_val
);
1146 ret
= lttng_event_field_value_array_append_unavailable(
1151 lttng_event_field_value_destroy(elem_field_val
);
1158 case MSGPACK_OBJECT_MAP
:
1161 * As of this version, the only valid map object is
1162 * for an enumeration value, for example:
1169 * - Carling Black Label
1171 const msgpack_object
*inner_obj
;
1174 inner_obj
= get_msgpack_map_obj(obj
, "type");
1176 ERR("Missing `type` entry in map object");
1180 if (inner_obj
->type
!= MSGPACK_OBJECT_STR
) {
1181 ERR("Map object's `type` entry is not a string: type = %s",
1182 msgpack_object_type_str(inner_obj
->type
));
1186 if (!msgpack_str_is_equal(inner_obj
, "enum")) {
1187 ERR("Map object's `type` entry: expecting `enum`");
1191 inner_obj
= get_msgpack_map_obj(obj
, "value");
1193 ERR("Missing `value` entry in map object");
1197 if (inner_obj
->type
== MSGPACK_OBJECT_POSITIVE_INTEGER
) {
1198 *field_val
= lttng_event_field_value_enum_uint_create(
1199 inner_obj
->via
.u64
);
1200 } else if (inner_obj
->type
== MSGPACK_OBJECT_NEGATIVE_INTEGER
) {
1201 *field_val
= lttng_event_field_value_enum_int_create(
1202 inner_obj
->via
.i64
);
1204 ERR("Map object's `value` entry is not an integer: type = %s",
1205 msgpack_object_type_str(inner_obj
->type
));
1213 inner_obj
= get_msgpack_map_obj(obj
, "labels");
1219 if (inner_obj
->type
!= MSGPACK_OBJECT_ARRAY
) {
1220 ERR("Map object's `labels` entry is not an array: type = %s",
1221 msgpack_object_type_str(inner_obj
->type
));
1225 for (label_i
= 0; label_i
< inner_obj
->via
.array
.size
;
1228 const msgpack_object
*elem_obj
=
1229 &inner_obj
->via
.array
.ptr
[label_i
];
1231 if (elem_obj
->type
!= MSGPACK_OBJECT_STR
) {
1232 ERR("Map object's `labels` entry's type is not a string: type = %s",
1233 msgpack_object_type_str(elem_obj
->type
));
1237 iret
= lttng_event_field_value_enum_append_label_with_size(
1238 *field_val
, elem_obj
->via
.str
.ptr
,
1239 elem_obj
->via
.str
.size
);
1248 ERR("Unexpected object type: type = %s",
1249 msgpack_object_type_str(obj
->type
));
1260 lttng_event_field_value_destroy(*field_val
);
1268 static struct lttng_event_field_value
*event_field_value_from_capture_payload(
1269 const struct lttng_condition_event_rule_matches
*condition
,
1270 const char *capture_payload
,
1271 size_t capture_payload_size
)
1273 struct lttng_event_field_value
*ret
= NULL
;
1274 msgpack_unpacked unpacked
;
1275 msgpack_unpack_return unpack_return
;
1276 const msgpack_object
*root_obj
;
1277 const msgpack_object_array
*root_array_obj
;
1281 LTTNG_ASSERT(condition
);
1282 LTTNG_ASSERT(capture_payload
);
1284 /* Initialize value. */
1285 msgpack_unpacked_init(&unpacked
);
1288 unpack_return
= msgpack_unpack_next(&unpacked
, capture_payload
,
1289 capture_payload_size
, NULL
);
1290 if (unpack_return
!= MSGPACK_UNPACK_SUCCESS
) {
1291 ERR("msgpack_unpack_next() failed to decode the "
1292 "MessagePack-encoded capture payload: "
1293 "size = %zu, ret = %d",
1294 capture_payload_size
, unpack_return
);
1298 /* Get root array. */
1299 root_obj
= &unpacked
.data
;
1301 if (root_obj
->type
!= MSGPACK_OBJECT_ARRAY
) {
1302 ERR("Expecting an array as the root object: type = %s",
1303 msgpack_object_type_str(root_obj
->type
));
1307 root_array_obj
= &root_obj
->via
.array
;
1309 /* Create an empty root array event field value. */
1310 ret
= lttng_event_field_value_array_create();
1316 * For each capture descriptor in the condition object:
1318 * 1. Get its corresponding captured field value MessagePack
1321 * 2. Create a corresponding event field value.
1323 * 3. Append it to `ret` (the root array event field value).
1325 count
= lttng_dynamic_pointer_array_get_count(
1326 &condition
->capture_descriptors
);
1327 LTTNG_ASSERT(count
> 0);
1329 for (i
= 0; i
< count
; i
++) {
1330 const struct lttng_capture_descriptor
*capture_descriptor
=
1331 lttng_condition_event_rule_matches_get_internal_capture_descriptor_at_index(
1332 &condition
->parent
, i
);
1333 const msgpack_object
*elem_obj
;
1334 struct lttng_event_field_value
*elem_field_val
;
1337 LTTNG_ASSERT(capture_descriptor
);
1339 elem_obj
= &root_array_obj
->ptr
[i
];
1340 iret
= event_field_value_from_obj(elem_obj
,
1346 if (elem_field_val
) {
1347 iret
= lttng_event_field_value_array_append(ret
,
1350 iret
= lttng_event_field_value_array_append_unavailable(
1355 lttng_event_field_value_destroy(elem_field_val
);
1363 lttng_event_field_value_destroy(ret
);
1367 msgpack_unpacked_destroy(&unpacked
);
1371 struct lttng_evaluation
*lttng_evaluation_event_rule_matches_create(
1372 const struct lttng_condition_event_rule_matches
*condition
,
1373 const char *capture_payload
,
1374 size_t capture_payload_size
,
1375 bool decode_capture_payload
)
1377 struct lttng_evaluation_event_rule_matches
*hit
;
1378 struct lttng_evaluation
*evaluation
= NULL
;
1380 hit
= zmalloc
<lttng_evaluation_event_rule_matches
>();
1385 lttng_dynamic_buffer_init(&hit
->capture_payload
);
1387 if (capture_payload
) {
1388 const int ret
= lttng_dynamic_buffer_append(
1389 &hit
->capture_payload
, capture_payload
,
1390 capture_payload_size
);
1392 ERR("Failed to initialize capture payload of event rule evaluation");
1396 if (decode_capture_payload
) {
1397 hit
->captured_values
=
1398 event_field_value_from_capture_payload(
1401 capture_payload_size
);
1402 if (!hit
->captured_values
) {
1403 ERR("Failed to decode the capture payload: size = %zu",
1404 capture_payload_size
);
1410 hit
->parent
.type
= LTTNG_CONDITION_TYPE_EVENT_RULE_MATCHES
;
1411 hit
->parent
.serialize
= lttng_evaluation_event_rule_matches_serialize
;
1412 hit
->parent
.destroy
= lttng_evaluation_event_rule_matches_destroy
;
1414 evaluation
= &hit
->parent
;
1419 lttng_evaluation_event_rule_matches_destroy(&hit
->parent
);
1425 enum lttng_evaluation_event_rule_matches_status
1426 lttng_evaluation_event_rule_matches_get_captured_values(
1427 const struct lttng_evaluation
*evaluation
,
1428 const struct lttng_event_field_value
**field_val
)
1430 struct lttng_evaluation_event_rule_matches
*hit
;
1431 enum lttng_evaluation_event_rule_matches_status status
=
1432 LTTNG_EVALUATION_EVENT_RULE_MATCHES_STATUS_OK
;
1434 if (!evaluation
|| !is_event_rule_matches_evaluation(evaluation
) ||
1436 status
= LTTNG_EVALUATION_EVENT_RULE_MATCHES_STATUS_INVALID
;
1440 hit
= lttng::utils::container_of(evaluation
,
1441 <tng_evaluation_event_rule_matches::parent
);
1442 if (!hit
->captured_values
) {
1443 status
= LTTNG_EVALUATION_EVENT_RULE_MATCHES_STATUS_NONE
;
1447 *field_val
= hit
->captured_values
;
1453 enum lttng_error_code
1454 lttng_condition_event_rule_matches_generate_capture_descriptor_bytecode(
1455 struct lttng_condition
*condition
)
1457 enum lttng_error_code ret
;
1458 enum lttng_condition_status status
;
1459 unsigned int capture_count
, i
;
1461 if (!condition
|| !IS_EVENT_RULE_MATCHES_CONDITION(condition
)) {
1462 ret
= LTTNG_ERR_FATAL
;
1466 status
= lttng_condition_event_rule_matches_get_capture_descriptor_count(
1467 condition
, &capture_count
);
1468 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
1469 ret
= LTTNG_ERR_FATAL
;
1473 for (i
= 0; i
< capture_count
; i
++) {
1474 struct lttng_capture_descriptor
*local_capture_desc
=
1475 lttng_condition_event_rule_matches_get_internal_capture_descriptor_at_index(
1479 if (local_capture_desc
== NULL
) {
1480 ret
= LTTNG_ERR_FATAL
;
1484 /* Generate the bytecode. */
1485 bytecode_ret
= lttng_event_expr_to_bytecode(
1486 local_capture_desc
->event_expression
,
1487 &local_capture_desc
->bytecode
);
1488 if (bytecode_ret
< 0 || local_capture_desc
->bytecode
== NULL
) {
1489 ret
= LTTNG_ERR_INVALID_CAPTURE_EXPRESSION
;
1494 /* Everything went better than expected */
1501 const struct lttng_bytecode
*
1502 lttng_condition_event_rule_matches_get_capture_bytecode_at_index(
1503 const struct lttng_condition
*condition
, unsigned int index
)
1505 const struct lttng_condition_event_rule_matches
1506 *event_rule_matches_cond
= lttng::utils::container_of(condition
,
1507 <tng_condition_event_rule_matches::parent
);
1508 struct lttng_capture_descriptor
*desc
= NULL
;
1509 struct lttng_bytecode
*bytecode
= NULL
;
1511 enum lttng_condition_status status
;
1513 if (!condition
|| !IS_EVENT_RULE_MATCHES_CONDITION(condition
)) {
1517 status
= lttng_condition_event_rule_matches_get_capture_descriptor_count(
1519 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
1523 if (index
>= count
) {
1527 desc
= (lttng_capture_descriptor
*) lttng_dynamic_pointer_array_get_pointer(
1528 &event_rule_matches_cond
->capture_descriptors
, index
);
1533 bytecode
= desc
->bytecode
;