2 * Copyright (C) 2020 Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
4 * SPDX-License-Identifier: LGPL-2.1-only
9 #include <common/error.h>
10 #include <common/event-expr-to-bytecode.h>
11 #include <common/macros.h>
14 #include <lttng/condition/condition-internal.h>
15 #include <lttng/condition/on-event-internal.h>
16 #include <lttng/condition/on-event.h>
17 #include <lttng/event-expr-internal.h>
18 #include <lttng/event-expr.h>
19 #include <lttng/event-field-value-internal.h>
20 #include <lttng/event-rule/event-rule-internal.h>
21 #include <lttng/lttng-error.h>
24 #include <vendor/msgpack/msgpack.h>
26 #define IS_EVENT_RULE_CONDITION(condition) \
27 (lttng_condition_get_type(condition) == \
28 LTTNG_CONDITION_TYPE_ON_EVENT)
30 static bool is_event_rule_evaluation(const struct lttng_evaluation
*evaluation
)
32 enum lttng_condition_type type
= lttng_evaluation_get_type(evaluation
);
34 return type
== LTTNG_CONDITION_TYPE_ON_EVENT
;
37 static bool lttng_condition_on_event_validate(
38 const struct lttng_condition
*condition
);
39 static int lttng_condition_on_event_serialize(
40 const struct lttng_condition
*condition
,
41 struct lttng_payload
*payload
);
42 static bool lttng_condition_on_event_is_equal(
43 const struct lttng_condition
*_a
,
44 const struct lttng_condition
*_b
);
45 static void lttng_condition_on_event_destroy(
46 struct lttng_condition
*condition
);
48 static bool lttng_condition_on_event_validate(
49 const struct lttng_condition
*condition
)
52 struct lttng_condition_on_event
*event_rule
;
58 event_rule
= container_of(
59 condition
, struct lttng_condition_on_event
, parent
);
60 if (!event_rule
->rule
) {
61 ERR("Invalid event rule condition: a rule must be set.");
65 valid
= lttng_event_rule_validate(event_rule
->rule
);
71 * Serializes the C string `str` into `buf`.
73 * Encoding is the length of `str` plus one (for the null character),
74 * and then the string, including its null terminator.
77 int serialize_cstr(const char *str
, struct lttng_dynamic_buffer
*buf
)
80 const uint32_t len
= strlen(str
) + 1;
82 /* Serialize the length, including the null terminator. */
83 DBG("Serializing C string's length (including null terminator): "
85 ret
= lttng_dynamic_buffer_append(buf
, &len
, sizeof(len
));
90 /* Serialize the string. */
91 DBG("Serializing C string: '%s'", str
);
92 ret
= lttng_dynamic_buffer_append(buf
, str
, len
);
102 * Serializes the event expression `expr` into `buf`.
105 int serialize_event_expr(const struct lttng_event_expr
*expr
,
106 struct lttng_payload
*payload
)
108 const uint8_t type
= expr
->type
;
111 /* Serialize the expression's type. */
112 DBG("Serializing event expression's type: %d", expr
->type
);
113 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, &type
, sizeof(type
));
118 /* Serialize the expression */
119 switch (expr
->type
) {
120 case LTTNG_EVENT_EXPR_TYPE_EVENT_PAYLOAD_FIELD
:
121 case LTTNG_EVENT_EXPR_TYPE_CHANNEL_CONTEXT_FIELD
:
123 const struct lttng_event_expr_field
*field_expr
=
125 const struct lttng_event_expr_field
,
128 /* Serialize the field name. */
129 DBG("Serializing field event expression's field name: '%s'",
131 ret
= serialize_cstr(field_expr
->name
, &payload
->buffer
);
138 case LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD
:
140 const struct lttng_event_expr_app_specific_context_field
*field_expr
=
142 const struct lttng_event_expr_app_specific_context_field
,
145 /* Serialize the provider name. */
146 DBG("Serializing app-specific context field event expression's "
147 "provider name: '%s'",
148 field_expr
->provider_name
);
149 ret
= serialize_cstr(field_expr
->provider_name
, &payload
->buffer
);
154 /* Serialize the type name. */
155 DBG("Serializing app-specific context field event expression's "
157 field_expr
->provider_name
);
158 ret
= serialize_cstr(field_expr
->type_name
, &payload
->buffer
);
165 case LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT
:
167 const struct lttng_event_expr_array_field_element
*elem_expr
=
169 const struct lttng_event_expr_array_field_element
,
171 const uint32_t index
= elem_expr
->index
;
173 /* Serialize the index. */
174 DBG("Serializing array field element event expression's "
175 "index: %u", elem_expr
->index
);
176 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, &index
, sizeof(index
));
181 /* Serialize the parent array field expression. */
182 DBG("Serializing array field element event expression's "
183 "parent array field event expression.");
184 ret
= serialize_event_expr(elem_expr
->array_field_expr
, payload
);
200 struct lttng_capture_descriptor
*
201 lttng_condition_on_event_get_internal_capture_descriptor_at_index(
202 const struct lttng_condition
*condition
, unsigned int index
)
204 const struct lttng_condition_on_event
*event_rule_cond
=
205 container_of(condition
,
206 const struct lttng_condition_on_event
,
208 struct lttng_capture_descriptor
*desc
= NULL
;
210 enum lttng_condition_status status
;
212 if (!condition
|| !IS_EVENT_RULE_CONDITION(condition
)) {
216 status
= lttng_condition_on_event_get_capture_descriptor_count(
218 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
222 if (index
>= count
) {
226 desc
= lttng_dynamic_pointer_array_get_pointer(
227 &event_rule_cond
->capture_descriptors
, index
);
232 static int lttng_condition_on_event_serialize(
233 const struct lttng_condition
*condition
,
234 struct lttng_payload
*payload
)
237 struct lttng_condition_on_event
*event_rule
;
238 enum lttng_condition_status status
;
239 uint64_t error_count
, error_counter_index
;
240 /* Used for iteration and communication (size matters). */
241 uint32_t i
, capture_descr_count
;
243 if (!condition
|| !IS_EVENT_RULE_CONDITION(condition
)) {
248 DBG("Serializing event rule condition");
249 event_rule
= container_of(
250 condition
, struct lttng_condition_on_event
, parent
);
252 DBG("Serializing event rule condition's event rule");
253 ret
= lttng_event_rule_serialize(event_rule
->rule
, payload
);
258 error_counter_index
= lttng_condition_on_event_get_error_counter_index(
260 DBG("Serializing event rule condition's error counter index: %" PRIu64
,
261 error_counter_index
);
262 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, &error_counter_index
,
263 sizeof(error_counter_index
));
268 error_count
= lttng_condition_on_event_get_error_count(
270 DBG("Serializing event rule condition's error count: %" PRIu64
,
272 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, &error_count
,
273 sizeof(error_count
));
278 status
= lttng_condition_on_event_get_capture_descriptor_count(
279 condition
, &capture_descr_count
);
280 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
285 DBG("Serializing event rule condition's capture descriptor count: %" PRIu32
,
286 capture_descr_count
);
287 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, &capture_descr_count
,
288 sizeof(capture_descr_count
));
293 for (i
= 0; i
< capture_descr_count
; i
++) {
294 const struct lttng_capture_descriptor
*desc
=
295 lttng_condition_on_event_get_internal_capture_descriptor_at_index(
298 DBG("Serializing event rule condition's capture descriptor %" PRIu32
,
300 ret
= serialize_event_expr(desc
->event_expression
, payload
);
311 bool capture_descriptors_are_equal(
312 const struct lttng_condition
*condition_a
,
313 const struct lttng_condition
*condition_b
)
315 bool is_equal
= true;
316 unsigned int capture_descr_count_a
;
317 unsigned int capture_descr_count_b
;
319 enum lttng_condition_status status
;
321 status
= lttng_condition_on_event_get_capture_descriptor_count(
322 condition_a
, &capture_descr_count_a
);
323 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
327 status
= lttng_condition_on_event_get_capture_descriptor_count(
328 condition_b
, &capture_descr_count_b
);
329 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
333 if (capture_descr_count_a
!= capture_descr_count_b
) {
337 for (i
= 0; i
< capture_descr_count_a
; i
++) {
338 const struct lttng_event_expr
*expr_a
=
339 lttng_condition_on_event_get_capture_descriptor_at_index(
342 const struct lttng_event_expr
*expr_b
=
343 lttng_condition_on_event_get_capture_descriptor_at_index(
347 if (!lttng_event_expr_is_equal(expr_a
, expr_b
)) {
361 static bool lttng_condition_on_event_is_equal(
362 const struct lttng_condition
*_a
,
363 const struct lttng_condition
*_b
)
365 bool is_equal
= false;
366 struct lttng_condition_on_event
*a
, *b
;
368 a
= container_of(_a
, struct lttng_condition_on_event
, parent
);
369 b
= container_of(_b
, struct lttng_condition_on_event
, parent
);
371 /* Both event rules must be set or both must be unset. */
372 if ((a
->rule
&& !b
->rule
) || (!a
->rule
&& b
->rule
)) {
373 WARN("Comparing event_rule conditions with uninitialized rule");
377 is_equal
= lttng_event_rule_is_equal(a
->rule
, b
->rule
);
382 is_equal
= capture_descriptors_are_equal(_a
, _b
);
388 static void lttng_condition_on_event_destroy(
389 struct lttng_condition
*condition
)
391 struct lttng_condition_on_event
*event_rule
;
393 event_rule
= container_of(
394 condition
, struct lttng_condition_on_event
, parent
);
396 lttng_event_rule_put(event_rule
->rule
);
397 lttng_dynamic_pointer_array_reset(&event_rule
->capture_descriptors
);
402 void destroy_capture_descriptor(void *ptr
)
404 struct lttng_capture_descriptor
*desc
=
405 (struct lttng_capture_descriptor
*) ptr
;
407 lttng_event_expr_destroy(desc
->event_expression
);
408 free(desc
->bytecode
);
412 struct lttng_condition
*lttng_condition_on_event_create(
413 struct lttng_event_rule
*rule
)
415 struct lttng_condition
*parent
= NULL
;
416 struct lttng_condition_on_event
*condition
= NULL
;
422 condition
= zmalloc(sizeof(struct lttng_condition_on_event
));
427 lttng_condition_init(&condition
->parent
,
428 LTTNG_CONDITION_TYPE_ON_EVENT
);
429 condition
->parent
.validate
= lttng_condition_on_event_validate
,
430 condition
->parent
.serialize
= lttng_condition_on_event_serialize
,
431 condition
->parent
.equal
= lttng_condition_on_event_is_equal
,
432 condition
->parent
.destroy
= lttng_condition_on_event_destroy
,
434 lttng_event_rule_get(rule
);
435 condition
->rule
= rule
;
438 LTTNG_OPTIONAL_SET(&condition
->error_count
, 0);
439 LTTNG_OPTIONAL_SET(&condition
->error_counter_index
, 0);
441 lttng_dynamic_pointer_array_init(&condition
->capture_descriptors
,
442 destroy_capture_descriptor
);
444 parent
= &condition
->parent
;
450 uint64_t uint_from_buffer(const struct lttng_buffer_view
*view
, size_t size
,
454 const struct lttng_buffer_view uint_view
=
455 lttng_buffer_view_from_view(view
, *offset
, size
);
457 if (!lttng_buffer_view_is_valid(&uint_view
)) {
464 ret
= (uint64_t) *uint_view
.data
;
466 case sizeof(uint32_t):
470 memcpy(&u32
, uint_view
.data
, sizeof(u32
));
471 ret
= (uint64_t) u32
;
475 memcpy(&ret
, uint_view
.data
, sizeof(ret
));
488 const char *str_from_buffer(const struct lttng_buffer_view
*view
,
494 len
= uint_from_buffer(view
, sizeof(uint32_t), offset
);
495 if (len
== UINT64_C(-1)) {
499 ret
= &view
->data
[*offset
];
501 if (!lttng_buffer_view_contains_string(view
, ret
, len
)) {
516 struct lttng_event_expr
*event_expr_from_payload(
517 struct lttng_payload_view
*view
, size_t *offset
)
519 struct lttng_event_expr
*expr
= NULL
;
523 type
= uint_from_buffer(&view
->buffer
, sizeof(uint8_t), offset
);
524 if (type
== UINT64_C(-1)) {
529 case LTTNG_EVENT_EXPR_TYPE_EVENT_PAYLOAD_FIELD
:
530 str
= str_from_buffer(&view
->buffer
, offset
);
535 expr
= lttng_event_expr_event_payload_field_create(str
);
537 case LTTNG_EVENT_EXPR_TYPE_CHANNEL_CONTEXT_FIELD
:
538 str
= str_from_buffer(&view
->buffer
, offset
);
543 expr
= lttng_event_expr_channel_context_field_create(str
);
545 case LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD
:
547 const char *provider_name
;
548 const char *type_name
;
550 provider_name
= str_from_buffer(&view
->buffer
, offset
);
551 if (!provider_name
) {
555 type_name
= str_from_buffer(&view
->buffer
, offset
);
560 expr
= lttng_event_expr_app_specific_context_field_create(
561 provider_name
, type_name
);
564 case LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT
:
566 struct lttng_event_expr
*array_field_expr
;
567 const uint64_t index
= uint_from_buffer(
568 &view
->buffer
, sizeof(uint32_t), offset
);
570 if (index
== UINT64_C(-1)) {
574 /* Array field expression is the encoded after this. */
575 array_field_expr
= event_expr_from_payload(view
, offset
);
576 if (!array_field_expr
) {
580 /* Move ownership of `array_field_expr` to new expression. */
581 expr
= lttng_event_expr_array_field_element_create(
582 array_field_expr
, (unsigned int) index
);
584 /* `array_field_expr` not moved: destroy it. */
585 lttng_event_expr_destroy(array_field_expr
);
597 lttng_event_expr_destroy(expr
);
605 ssize_t
lttng_condition_on_event_create_from_payload(
606 struct lttng_payload_view
*view
,
607 struct lttng_condition
**_condition
)
609 ssize_t consumed_length
;
611 ssize_t event_rule_length
;
612 uint32_t i
, capture_descr_count
;
613 uint64_t error_counter_index
, error_count
;
614 struct lttng_condition
*condition
= NULL
;
615 struct lttng_event_rule
*event_rule
= NULL
;
617 if (!view
|| !_condition
) {
621 /* Struct lttng_event_rule. */
623 struct lttng_payload_view event_rule_view
=
624 lttng_payload_view_from_view(view
, offset
, -1);
626 event_rule_length
= lttng_event_rule_create_from_payload(
627 &event_rule_view
, &event_rule
);
630 if (event_rule_length
< 0 || !event_rule
) {
634 offset
+= event_rule_length
;
636 /* Error counter index. */
637 error_counter_index
= uint_from_buffer(&view
->buffer
, sizeof(uint64_t),
639 if (error_counter_index
== UINT64_C(-1)) {
644 error_count
= uint_from_buffer(&view
->buffer
, sizeof(uint64_t), &offset
);
645 if (error_count
== UINT64_C(-1)) {
649 /* Create condition (no capture descriptors yet) at this point */
650 condition
= lttng_condition_on_event_create(event_rule
);
655 lttng_condition_on_event_set_error_count(condition
, error_count
);
656 lttng_condition_on_event_set_error_counter_index(condition
,
657 error_counter_index
);
659 /* Capture descriptor count. */
660 assert(event_rule_length
>= 0);
661 capture_descr_count
= uint_from_buffer(&view
->buffer
, sizeof(uint32_t), &offset
);
662 if (capture_descr_count
== UINT32_C(-1)) {
666 /* Capture descriptors. */
667 for (i
= 0; i
< capture_descr_count
; i
++) {
668 enum lttng_condition_status status
;
669 struct lttng_event_expr
*expr
= event_expr_from_payload(
676 /* Move ownership of `expr` to `condition`. */
677 status
= lttng_condition_on_event_append_capture_descriptor(
679 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
680 /* `expr` not moved: destroy it. */
681 lttng_event_expr_destroy(expr
);
686 consumed_length
= (ssize_t
) offset
;
687 *_condition
= condition
;
692 consumed_length
= -1;
695 lttng_event_rule_put(event_rule
);
696 lttng_condition_put(condition
);
697 return consumed_length
;
701 enum lttng_condition_status
lttng_condition_on_event_borrow_rule_mutable(
702 const struct lttng_condition
*condition
,
703 struct lttng_event_rule
**rule
)
705 struct lttng_condition_on_event
*event_rule
;
706 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
708 if (!condition
|| !IS_EVENT_RULE_CONDITION(condition
) || !rule
) {
709 status
= LTTNG_CONDITION_STATUS_INVALID
;
713 event_rule
= container_of(
714 condition
, struct lttng_condition_on_event
, parent
);
715 if (!event_rule
->rule
) {
716 status
= LTTNG_CONDITION_STATUS_UNSET
;
720 *rule
= event_rule
->rule
;
725 enum lttng_condition_status
lttng_condition_on_event_get_rule(
726 const struct lttng_condition
*condition
,
727 const struct lttng_event_rule
**rule
)
729 struct lttng_event_rule
*mutable_rule
= NULL
;
730 const enum lttng_condition_status status
=
731 lttng_condition_on_event_borrow_rule_mutable(
732 condition
, &mutable_rule
);
734 *rule
= mutable_rule
;
738 void lttng_condition_on_event_set_error_counter_index(
739 struct lttng_condition
*condition
, uint64_t error_counter_index
)
741 struct lttng_condition_on_event
*on_event_cond
=
742 container_of(condition
,
743 struct lttng_condition_on_event
, parent
);
745 LTTNG_OPTIONAL_SET(&on_event_cond
->error_counter_index
, error_counter_index
);
748 uint64_t lttng_condition_on_event_get_error_counter_index(
749 const struct lttng_condition
*condition
)
751 struct lttng_condition_on_event
*on_event_cond
=
752 container_of(condition
,
753 struct lttng_condition_on_event
, parent
);
755 return LTTNG_OPTIONAL_GET(on_event_cond
->error_counter_index
);
758 void lttng_condition_on_event_set_error_count(struct lttng_condition
*condition
,
759 uint64_t error_count
)
761 struct lttng_condition_on_event
*on_event_cond
=
762 container_of(condition
,
763 struct lttng_condition_on_event
, parent
);
765 LTTNG_OPTIONAL_SET(&on_event_cond
->error_count
, error_count
);
768 uint64_t lttng_condition_on_event_get_error_count(
769 const struct lttng_condition
*condition
)
771 struct lttng_condition_on_event
*on_event_cond
=
772 container_of(condition
,
773 struct lttng_condition_on_event
, parent
);
775 return LTTNG_OPTIONAL_GET(on_event_cond
->error_count
);
778 enum lttng_condition_status
779 lttng_condition_on_event_append_capture_descriptor(
780 struct lttng_condition
*condition
,
781 struct lttng_event_expr
*expr
)
784 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
785 struct lttng_condition_on_event
*on_event_cond
=
786 container_of(condition
,
787 struct lttng_condition_on_event
, parent
);
788 struct lttng_capture_descriptor
*descriptor
= NULL
;
789 const struct lttng_event_rule
*rule
= NULL
;
791 /* Only accept l-values. */
792 if (!condition
|| !IS_EVENT_RULE_CONDITION(condition
) || !expr
||
793 !lttng_event_expr_is_lvalue(expr
)) {
794 status
= LTTNG_CONDITION_STATUS_INVALID
;
798 status
= lttng_condition_on_event_get_rule(condition
, &rule
);
799 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
803 switch(lttng_event_rule_get_type(rule
)) {
804 case LTTNG_EVENT_RULE_TYPE_TRACEPOINT
:
805 case LTTNG_EVENT_RULE_TYPE_SYSCALL
:
807 status
= LTTNG_CONDITION_STATUS_OK
;
809 case LTTNG_EVENT_RULE_TYPE_UNKNOWN
:
810 status
= LTTNG_CONDITION_STATUS_INVALID
;
813 status
= LTTNG_CONDITION_STATUS_UNSUPPORTED
;
817 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
821 descriptor
= malloc(sizeof(*descriptor
));
822 if (descriptor
== NULL
) {
823 status
= LTTNG_CONDITION_STATUS_ERROR
;
827 descriptor
->event_expression
= expr
;
828 descriptor
->bytecode
= NULL
;
830 ret
= lttng_dynamic_pointer_array_add_pointer(
831 &on_event_cond
->capture_descriptors
, descriptor
);
833 status
= LTTNG_CONDITION_STATUS_ERROR
;
837 /* Ownership is transfered to the internal capture_descriptors array */
844 enum lttng_condition_status
845 lttng_condition_on_event_get_capture_descriptor_count(
846 const struct lttng_condition
*condition
, unsigned int *count
)
848 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
849 const struct lttng_condition_on_event
*event_rule_cond
=
850 container_of(condition
,
851 const struct lttng_condition_on_event
,
854 if (!condition
|| !IS_EVENT_RULE_CONDITION(condition
) || !count
) {
855 status
= LTTNG_CONDITION_STATUS_INVALID
;
859 *count
= lttng_dynamic_pointer_array_get_count(
860 &event_rule_cond
->capture_descriptors
);
866 const struct lttng_event_expr
*
867 lttng_condition_on_event_get_capture_descriptor_at_index(
868 const struct lttng_condition
*condition
, unsigned int index
)
870 const struct lttng_event_expr
*expr
= NULL
;
871 const struct lttng_capture_descriptor
*desc
= NULL
;
873 desc
= lttng_condition_on_event_get_internal_capture_descriptor_at_index(
878 expr
= desc
->event_expression
;
885 ssize_t
lttng_evaluation_event_rule_create_from_payload(
886 const struct lttng_condition_on_event
*condition
,
887 struct lttng_payload_view
*view
,
888 struct lttng_evaluation
**_evaluation
)
890 ssize_t ret
, offset
= 0;
891 const char *trigger_name
;
892 struct lttng_evaluation
*evaluation
= NULL
;
893 const struct lttng_evaluation_event_rule_comm
*header
;
894 const struct lttng_payload_view header_view
=
895 lttng_payload_view_from_view(
896 view
, 0, sizeof(*header
));
897 uint32_t capture_payload_size
;
898 const char *capture_payload
= NULL
;
905 if (!lttng_payload_view_is_valid(&header_view
)) {
906 ERR("Failed to initialize from malformed event rule evaluation: buffer too short to contain header");
911 header
= (typeof(header
)) header_view
.buffer
.data
;
913 /* Map the originating trigger's name. */
914 offset
+= sizeof(*header
);
916 const struct lttng_payload_view current_view
=
917 lttng_payload_view_from_view(view
, offset
,
918 header
->trigger_name_length
);
920 if (!lttng_payload_view_is_valid(¤t_view
)) {
921 ERR("Failed to initialize from malformed event rule evaluation: buffer too short to contain trigger name");
926 trigger_name
= current_view
.buffer
.data
;
927 if (!lttng_buffer_view_contains_string(¤t_view
.buffer
,
928 trigger_name
, header
->trigger_name_length
)) {
929 ERR("Failed to initialize from malformed event rule evaluation: invalid trigger name");
935 offset
+= header
->trigger_name_length
;
937 const struct lttng_payload_view current_view
=
938 lttng_payload_view_from_view(view
, offset
, -1);
940 if (current_view
.buffer
.size
< sizeof(capture_payload_size
)) {
945 memcpy(&capture_payload_size
, current_view
.buffer
.data
,
946 sizeof(capture_payload_size
));
948 offset
+= sizeof(capture_payload_size
);
950 if (capture_payload_size
> 0) {
951 const struct lttng_payload_view current_view
=
952 lttng_payload_view_from_view(view
, offset
, -1);
954 if (current_view
.buffer
.size
< capture_payload_size
) {
959 capture_payload
= current_view
.buffer
.data
;
962 evaluation
= lttng_evaluation_event_rule_create(condition
, trigger_name
,
963 capture_payload
, capture_payload_size
, true);
969 offset
+= capture_payload_size
;
970 *_evaluation
= evaluation
;
975 lttng_evaluation_destroy(evaluation
);
979 static int lttng_evaluation_event_rule_serialize(
980 const struct lttng_evaluation
*evaluation
,
981 struct lttng_payload
*payload
)
984 struct lttng_evaluation_event_rule
*hit
;
985 struct lttng_evaluation_event_rule_comm comm
;
986 uint32_t capture_payload_size
;
989 evaluation
, struct lttng_evaluation_event_rule
, parent
);
992 comm
.trigger_name_length
= strlen(hit
->name
) + 1;
994 ret
= lttng_dynamic_buffer_append(
995 &payload
->buffer
, &comm
, sizeof(comm
));
1000 ret
= lttng_dynamic_buffer_append(
1001 &payload
->buffer
, hit
->name
, comm
.trigger_name_length
);
1006 capture_payload_size
= (uint32_t) hit
->capture_payload
.size
;
1007 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, &capture_payload_size
,
1008 sizeof(capture_payload_size
));
1013 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, hit
->capture_payload
.data
,
1014 hit
->capture_payload
.size
);
1024 bool msgpack_str_is_equal(const struct msgpack_object
*obj
, const char *str
)
1026 bool is_equal
= true;
1028 assert(obj
->type
== MSGPACK_OBJECT_STR
);
1030 if (obj
->via
.str
.size
!= strlen(str
)) {
1035 if (strncmp(obj
->via
.str
.ptr
, str
, obj
->via
.str
.size
) != 0) {
1045 const msgpack_object
*get_msgpack_map_obj(const struct msgpack_object
*map_obj
,
1048 const msgpack_object
*ret
= NULL
;
1051 assert(map_obj
->type
== MSGPACK_OBJECT_MAP
);
1053 for (i
= 0; i
< map_obj
->via
.map
.size
; i
++) {
1054 const struct msgpack_object_kv
*kv
= &map_obj
->via
.map
.ptr
[i
];
1056 assert(kv
->key
.type
== MSGPACK_OBJECT_STR
);
1058 if (msgpack_str_is_equal(&kv
->key
, name
)) {
1068 static void lttng_evaluation_event_rule_destroy(
1069 struct lttng_evaluation
*evaluation
)
1071 struct lttng_evaluation_event_rule
*hit
;
1074 evaluation
, struct lttng_evaluation_event_rule
, parent
);
1076 lttng_dynamic_buffer_reset(&hit
->capture_payload
);
1077 lttng_event_field_value_destroy(hit
->captured_values
);
1082 int event_field_value_from_obj(const msgpack_object
*obj
,
1083 struct lttng_event_field_value
**field_val
)
1090 switch (obj
->type
) {
1091 case MSGPACK_OBJECT_NIL
:
1095 case MSGPACK_OBJECT_POSITIVE_INTEGER
:
1096 *field_val
= lttng_event_field_value_uint_create(
1099 case MSGPACK_OBJECT_NEGATIVE_INTEGER
:
1100 *field_val
= lttng_event_field_value_int_create(
1103 case MSGPACK_OBJECT_FLOAT32
:
1104 case MSGPACK_OBJECT_FLOAT64
:
1105 *field_val
= lttng_event_field_value_real_create(
1108 case MSGPACK_OBJECT_STR
:
1109 *field_val
= lttng_event_field_value_string_create_with_size(
1110 obj
->via
.str
.ptr
, obj
->via
.str
.size
);
1112 case MSGPACK_OBJECT_ARRAY
:
1116 *field_val
= lttng_event_field_value_array_create();
1121 for (i
= 0; i
< obj
->via
.array
.size
; i
++) {
1122 const msgpack_object
*elem_obj
= &obj
->via
.array
.ptr
[i
];
1123 struct lttng_event_field_value
*elem_field_val
;
1125 ret
= event_field_value_from_obj(elem_obj
,
1131 if (elem_field_val
) {
1132 ret
= lttng_event_field_value_array_append(
1133 *field_val
, elem_field_val
);
1135 ret
= lttng_event_field_value_array_append_unavailable(
1140 lttng_event_field_value_destroy(elem_field_val
);
1147 case MSGPACK_OBJECT_MAP
:
1150 * As of this version, the only valid map object is
1151 * for an enumeration value, for example:
1158 * - Carling Black Label
1160 const msgpack_object
*inner_obj
;
1163 inner_obj
= get_msgpack_map_obj(obj
, "type");
1165 ERR("Missing `type` entry in map object.");
1169 if (inner_obj
->type
!= MSGPACK_OBJECT_STR
) {
1170 ERR("Map object's `type` entry is not a string (it's a %d).",
1175 if (!msgpack_str_is_equal(inner_obj
, "enum")) {
1176 ERR("Map object's `type` entry: expecting `enum`.");
1180 inner_obj
= get_msgpack_map_obj(obj
, "value");
1182 ERR("Missing `value` entry in map object.");
1186 if (inner_obj
->type
== MSGPACK_OBJECT_POSITIVE_INTEGER
) {
1187 *field_val
= lttng_event_field_value_enum_uint_create(
1188 inner_obj
->via
.u64
);
1189 } else if (inner_obj
->type
== MSGPACK_OBJECT_NEGATIVE_INTEGER
) {
1190 *field_val
= lttng_event_field_value_enum_int_create(
1191 inner_obj
->via
.i64
);
1193 ERR("Map object's `value` entry is not an integer (it's a %d).",
1202 inner_obj
= get_msgpack_map_obj(obj
, "labels");
1208 if (inner_obj
->type
!= MSGPACK_OBJECT_ARRAY
) {
1209 ERR("Map object's `labels` entry is not an array (it's a %d).",
1214 for (label_i
= 0; label_i
< inner_obj
->via
.array
.size
;
1217 const msgpack_object
*elem_obj
=
1218 &inner_obj
->via
.array
.ptr
[label_i
];
1220 if (elem_obj
->type
!= MSGPACK_OBJECT_STR
) {
1221 ERR("Map object's `labels` entry's type is not a string (it's a %d).",
1226 iret
= lttng_event_field_value_enum_append_label_with_size(
1227 *field_val
, elem_obj
->via
.str
.ptr
,
1228 elem_obj
->via
.str
.size
);
1237 ERR("Unexpected object type %d.", obj
->type
);
1248 lttng_event_field_value_destroy(*field_val
);
1257 struct lttng_event_field_value
*event_field_value_from_capture_payload(
1258 const struct lttng_condition_on_event
*condition
,
1259 const char *capture_payload
, size_t capture_payload_size
)
1261 struct lttng_event_field_value
*ret
= NULL
;
1262 msgpack_unpacked unpacked
;
1263 msgpack_unpack_return unpack_return
;
1264 const msgpack_object
*root_obj
;
1265 const msgpack_object_array
*root_array_obj
;
1270 assert(capture_payload
);
1272 /* Initialize value. */
1273 msgpack_unpacked_init(&unpacked
);
1276 unpack_return
= msgpack_unpack_next(&unpacked
, capture_payload
,
1277 capture_payload_size
, NULL
);
1278 if (unpack_return
!= MSGPACK_UNPACK_SUCCESS
) {
1279 ERR("msgpack_unpack_next() failed to decode the "
1280 "MessagePack-encoded capture payload "
1281 "(size %zu); returned %d.",
1282 capture_payload_size
, unpack_return
);
1286 /* Get root array. */
1287 root_obj
= &unpacked
.data
;
1289 if (root_obj
->type
!= MSGPACK_OBJECT_ARRAY
) {
1290 ERR("Expecting an array as the root object; got type %d.",
1295 root_array_obj
= &root_obj
->via
.array
;
1297 /* Create an empty root array event field value. */
1298 ret
= lttng_event_field_value_array_create();
1304 * For each capture descriptor in the condition object:
1306 * 1. Get its corresponding captured field value MessagePack
1309 * 2. Create a corresponding event field value.
1311 * 3. Append it to `ret` (the root array event field value).
1313 count
= lttng_dynamic_pointer_array_get_count(
1314 &condition
->capture_descriptors
);
1317 for (i
= 0; i
< count
; i
++) {
1318 const struct lttng_capture_descriptor
*capture_descriptor
=
1319 lttng_condition_on_event_get_internal_capture_descriptor_at_index(
1320 &condition
->parent
, i
);
1321 const msgpack_object
*elem_obj
;
1322 struct lttng_event_field_value
*elem_field_val
;
1325 assert(capture_descriptor
);
1327 elem_obj
= &root_array_obj
->ptr
[i
];
1328 iret
= event_field_value_from_obj(elem_obj
,
1334 if (elem_field_val
) {
1335 iret
= lttng_event_field_value_array_append(ret
,
1338 iret
= lttng_event_field_value_array_append_unavailable(
1343 lttng_event_field_value_destroy(elem_field_val
);
1351 lttng_event_field_value_destroy(ret
);
1355 msgpack_unpacked_destroy(&unpacked
);
1360 struct lttng_evaluation
*lttng_evaluation_event_rule_create(
1361 const struct lttng_condition_on_event
*condition
,
1362 const char *trigger_name
,
1363 const char *capture_payload
, size_t capture_payload_size
,
1364 bool decode_capture_payload
)
1366 struct lttng_evaluation_event_rule
*hit
;
1367 struct lttng_evaluation
*evaluation
= NULL
;
1369 hit
= zmalloc(sizeof(struct lttng_evaluation_event_rule
));
1374 hit
->name
= strdup(trigger_name
);
1379 lttng_dynamic_buffer_init(&hit
->capture_payload
);
1381 if (capture_payload
) {
1382 const int ret
= lttng_dynamic_buffer_append(
1383 &hit
->capture_payload
, capture_payload
,
1384 capture_payload_size
);
1386 ERR("Failed to initialize capture payload of event rule evaluation");
1390 if (decode_capture_payload
) {
1391 hit
->captured_values
=
1392 event_field_value_from_capture_payload(
1395 capture_payload_size
);
1396 if (!hit
->captured_values
) {
1397 ERR("Failed to decode the capture payload: size = %zu",
1398 capture_payload_size
);
1404 hit
->parent
.type
= LTTNG_CONDITION_TYPE_ON_EVENT
;
1405 hit
->parent
.serialize
= lttng_evaluation_event_rule_serialize
;
1406 hit
->parent
.destroy
= lttng_evaluation_event_rule_destroy
;
1408 evaluation
= &hit
->parent
;
1413 lttng_evaluation_event_rule_destroy(&hit
->parent
);
1419 enum lttng_evaluation_status
lttng_evaluation_get_captured_values(
1420 const struct lttng_evaluation
*evaluation
,
1421 const struct lttng_event_field_value
**field_val
)
1423 struct lttng_evaluation_event_rule
*hit
;
1424 enum lttng_evaluation_status status
= LTTNG_EVALUATION_STATUS_OK
;
1427 * Event rule is currently the only type that can provide captured
1430 if (!evaluation
|| !is_event_rule_evaluation(evaluation
) ||
1432 status
= LTTNG_EVALUATION_STATUS_INVALID
;
1436 hit
= container_of(evaluation
, struct lttng_evaluation_event_rule
,
1438 if (!hit
->captured_values
) {
1439 status
= LTTNG_EVALUATION_STATUS_INVALID
;
1443 *field_val
= hit
->captured_values
;
1449 enum lttng_evaluation_status
lttng_evaluation_event_rule_get_trigger_name(
1450 const struct lttng_evaluation
*evaluation
, const char **name
)
1452 struct lttng_evaluation_event_rule
*hit
;
1453 enum lttng_evaluation_status status
= LTTNG_EVALUATION_STATUS_OK
;
1455 if (!evaluation
|| !is_event_rule_evaluation(evaluation
) || !name
) {
1456 status
= LTTNG_EVALUATION_STATUS_INVALID
;
1461 evaluation
, struct lttng_evaluation_event_rule
, parent
);
1468 enum lttng_error_code
1469 lttng_condition_on_event_generate_capture_descriptor_bytecode(
1470 struct lttng_condition
*condition
)
1472 enum lttng_error_code ret
;
1473 enum lttng_condition_status status
;
1474 unsigned int capture_count
, i
;
1476 if (!condition
|| !IS_EVENT_RULE_CONDITION(condition
)) {
1477 ret
= LTTNG_ERR_FATAL
;
1481 status
= lttng_condition_on_event_get_capture_descriptor_count(
1482 condition
, &capture_count
);
1483 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
1484 ret
= LTTNG_ERR_FATAL
;
1488 for (i
= 0; i
< capture_count
; i
++) {
1489 struct lttng_capture_descriptor
*local_capture_desc
=
1490 lttng_condition_on_event_get_internal_capture_descriptor_at_index(
1493 if (local_capture_desc
== NULL
) {
1494 ret
= LTTNG_ERR_FATAL
;
1498 /* Generate the bytecode. */
1499 status
= lttng_event_expr_to_bytecode(
1500 local_capture_desc
->event_expression
,
1501 &local_capture_desc
->bytecode
);
1502 if (status
< 0 || local_capture_desc
->bytecode
== NULL
) {
1503 ret
= LTTNG_ERR_INVALID_CAPTURE_EXPRESSION
;
1508 /* Everything went better than expected */
1516 const struct lttng_bytecode
*
1517 lttng_condition_on_event_get_capture_bytecode_at_index(
1518 const struct lttng_condition
*condition
, unsigned int index
)
1520 const struct lttng_condition_on_event
*on_event_cond
=
1521 container_of(condition
,
1522 const struct lttng_condition_on_event
,
1524 struct lttng_capture_descriptor
*desc
= NULL
;
1525 struct lttng_bytecode
*bytecode
= NULL
;
1527 enum lttng_condition_status status
;
1529 if (!condition
|| !IS_EVENT_RULE_CONDITION(condition
)) {
1533 status
= lttng_condition_on_event_get_capture_descriptor_count(
1535 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
1539 if (index
>= count
) {
1543 desc
= lttng_dynamic_pointer_array_get_pointer(
1544 &on_event_cond
->capture_descriptors
, index
);
1549 bytecode
= desc
->bytecode
;