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_ON_EVENT_CONDITION(condition) \
27 (lttng_condition_get_type(condition) == \
28 LTTNG_CONDITION_TYPE_ON_EVENT)
30 static bool is_on_event_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 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
=
171 const struct lttng_event_expr_field
,
174 /* Serialize the field name. */
175 DBG("Serializing field event expression's field name: '%s'",
177 ret
= serialize_cstr(field_expr
->name
, &payload
->buffer
);
184 case LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD
:
186 const struct lttng_event_expr_app_specific_context_field
*field_expr
=
188 const struct lttng_event_expr_app_specific_context_field
,
191 /* Serialize the provider name. */
192 DBG("Serializing app-specific context field event expression's "
193 "provider name: '%s'",
194 field_expr
->provider_name
);
195 ret
= serialize_cstr(field_expr
->provider_name
, &payload
->buffer
);
200 /* Serialize the type name. */
201 DBG("Serializing app-specific context field event expression's "
203 field_expr
->provider_name
);
204 ret
= serialize_cstr(field_expr
->type_name
, &payload
->buffer
);
211 case LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT
:
213 const struct lttng_event_expr_array_field_element
*elem_expr
=
215 const struct lttng_event_expr_array_field_element
,
217 const uint32_t index
= elem_expr
->index
;
219 /* Serialize the index. */
220 DBG("Serializing array field element event expression's "
221 "index: %u", elem_expr
->index
);
222 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, &index
, sizeof(index
));
227 /* Serialize the parent array field expression. */
228 DBG("Serializing array field element event expression's "
229 "parent array field event expression");
230 ret
= serialize_event_expr(elem_expr
->array_field_expr
, payload
);
246 struct lttng_capture_descriptor
*
247 lttng_condition_on_event_get_internal_capture_descriptor_at_index(
248 const struct lttng_condition
*condition
, unsigned int index
)
250 const struct lttng_condition_on_event
*on_event_cond
=
251 container_of(condition
,
252 const struct lttng_condition_on_event
,
254 struct lttng_capture_descriptor
*desc
= NULL
;
256 enum lttng_condition_status status
;
258 if (!condition
|| !IS_ON_EVENT_CONDITION(condition
)) {
262 status
= lttng_condition_on_event_get_capture_descriptor_count(
264 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
268 if (index
>= count
) {
272 desc
= lttng_dynamic_pointer_array_get_pointer(
273 &on_event_cond
->capture_descriptors
, index
);
278 static int lttng_condition_on_event_serialize(
279 const struct lttng_condition
*condition
,
280 struct lttng_payload
*payload
)
283 struct lttng_condition_on_event
*on_event_condition
;
284 enum lttng_condition_status status
;
285 /* Used for iteration and communication (size matters). */
286 uint32_t i
, capture_descr_count
;
288 if (!condition
|| !IS_ON_EVENT_CONDITION(condition
)) {
293 DBG("Serializing on event condition");
294 on_event_condition
= container_of(
295 condition
, struct lttng_condition_on_event
, parent
);
297 DBG("Serializing on event condition's event rule");
298 ret
= lttng_event_rule_serialize(on_event_condition
->rule
, payload
);
303 status
= lttng_condition_on_event_get_capture_descriptor_count(
304 condition
, &capture_descr_count
);
305 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
310 DBG("Serializing on event condition's capture descriptor count: %" PRIu32
,
311 capture_descr_count
);
312 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, &capture_descr_count
,
313 sizeof(capture_descr_count
));
318 for (i
= 0; i
< capture_descr_count
; i
++) {
319 const struct lttng_capture_descriptor
*desc
=
320 lttng_condition_on_event_get_internal_capture_descriptor_at_index(
323 DBG("Serializing on event condition's capture descriptor %" PRIu32
,
325 ret
= serialize_event_expr(desc
->event_expression
, payload
);
336 bool capture_descriptors_are_equal(
337 const struct lttng_condition
*condition_a
,
338 const struct lttng_condition
*condition_b
)
340 bool is_equal
= true;
341 unsigned int capture_descr_count_a
;
342 unsigned int capture_descr_count_b
;
344 enum lttng_condition_status status
;
346 status
= lttng_condition_on_event_get_capture_descriptor_count(
347 condition_a
, &capture_descr_count_a
);
348 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
352 status
= lttng_condition_on_event_get_capture_descriptor_count(
353 condition_b
, &capture_descr_count_b
);
354 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
358 if (capture_descr_count_a
!= capture_descr_count_b
) {
362 for (i
= 0; i
< capture_descr_count_a
; i
++) {
363 const struct lttng_event_expr
*expr_a
=
364 lttng_condition_on_event_get_capture_descriptor_at_index(
367 const struct lttng_event_expr
*expr_b
=
368 lttng_condition_on_event_get_capture_descriptor_at_index(
372 if (!lttng_event_expr_is_equal(expr_a
, expr_b
)) {
386 static bool lttng_condition_on_event_is_equal(
387 const struct lttng_condition
*_a
,
388 const struct lttng_condition
*_b
)
390 bool is_equal
= false;
391 struct lttng_condition_on_event
*a
, *b
;
393 a
= container_of(_a
, struct lttng_condition_on_event
, parent
);
394 b
= container_of(_b
, struct lttng_condition_on_event
, parent
);
396 /* Both event rules must be set or both must be unset. */
397 if ((a
->rule
&& !b
->rule
) || (!a
->rule
&& b
->rule
)) {
398 WARN("Comparing event_rule conditions with uninitialized rule");
402 is_equal
= lttng_event_rule_is_equal(a
->rule
, b
->rule
);
407 is_equal
= capture_descriptors_are_equal(_a
, _b
);
413 static void lttng_condition_on_event_destroy(
414 struct lttng_condition
*condition
)
416 struct lttng_condition_on_event
*on_event_condition
;
418 on_event_condition
= container_of(
419 condition
, struct lttng_condition_on_event
, parent
);
421 lttng_event_rule_put(on_event_condition
->rule
);
422 lttng_dynamic_pointer_array_reset(&on_event_condition
->capture_descriptors
);
423 free(on_event_condition
);
427 void destroy_capture_descriptor(void *ptr
)
429 struct lttng_capture_descriptor
*desc
=
430 (struct lttng_capture_descriptor
*) ptr
;
432 lttng_event_expr_destroy(desc
->event_expression
);
433 free(desc
->bytecode
);
437 struct lttng_condition
*lttng_condition_on_event_create(
438 struct lttng_event_rule
*rule
)
440 struct lttng_condition
*parent
= NULL
;
441 struct lttng_condition_on_event
*condition
= NULL
;
447 condition
= zmalloc(sizeof(struct lttng_condition_on_event
));
452 lttng_condition_init(&condition
->parent
,
453 LTTNG_CONDITION_TYPE_ON_EVENT
);
454 condition
->parent
.validate
= lttng_condition_on_event_validate
,
455 condition
->parent
.serialize
= lttng_condition_on_event_serialize
,
456 condition
->parent
.equal
= lttng_condition_on_event_is_equal
,
457 condition
->parent
.destroy
= lttng_condition_on_event_destroy
,
459 lttng_event_rule_get(rule
);
460 condition
->rule
= rule
;
463 lttng_dynamic_pointer_array_init(&condition
->capture_descriptors
,
464 destroy_capture_descriptor
);
466 parent
= &condition
->parent
;
472 uint64_t uint_from_buffer(const struct lttng_buffer_view
*view
, size_t size
,
476 const struct lttng_buffer_view uint_view
=
477 lttng_buffer_view_from_view(view
, *offset
, size
);
479 if (!lttng_buffer_view_is_valid(&uint_view
)) {
486 ret
= (uint64_t) *uint_view
.data
;
488 case sizeof(uint32_t):
492 memcpy(&u32
, uint_view
.data
, sizeof(u32
));
493 ret
= (uint64_t) u32
;
497 memcpy(&ret
, uint_view
.data
, sizeof(ret
));
510 const char *str_from_buffer(const struct lttng_buffer_view
*view
,
516 len
= uint_from_buffer(view
, sizeof(uint32_t), offset
);
517 if (len
== UINT64_C(-1)) {
521 ret
= &view
->data
[*offset
];
523 if (!lttng_buffer_view_contains_string(view
, ret
, len
)) {
538 struct lttng_event_expr
*event_expr_from_payload(
539 struct lttng_payload_view
*view
, size_t *offset
)
541 struct lttng_event_expr
*expr
= NULL
;
545 type
= uint_from_buffer(&view
->buffer
, sizeof(uint8_t), offset
);
546 if (type
== UINT64_C(-1)) {
551 case LTTNG_EVENT_EXPR_TYPE_EVENT_PAYLOAD_FIELD
:
552 str
= str_from_buffer(&view
->buffer
, offset
);
557 expr
= lttng_event_expr_event_payload_field_create(str
);
559 case LTTNG_EVENT_EXPR_TYPE_CHANNEL_CONTEXT_FIELD
:
560 str
= str_from_buffer(&view
->buffer
, offset
);
565 expr
= lttng_event_expr_channel_context_field_create(str
);
567 case LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD
:
569 const char *provider_name
;
570 const char *type_name
;
572 provider_name
= str_from_buffer(&view
->buffer
, offset
);
573 if (!provider_name
) {
577 type_name
= str_from_buffer(&view
->buffer
, offset
);
582 expr
= lttng_event_expr_app_specific_context_field_create(
583 provider_name
, type_name
);
586 case LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT
:
588 struct lttng_event_expr
*array_field_expr
;
589 const uint64_t index
= uint_from_buffer(
590 &view
->buffer
, sizeof(uint32_t), offset
);
592 if (index
== UINT64_C(-1)) {
596 /* Array field expression is the encoded after this. */
597 array_field_expr
= event_expr_from_payload(view
, offset
);
598 if (!array_field_expr
) {
602 /* Move ownership of `array_field_expr` to new expression. */
603 expr
= lttng_event_expr_array_field_element_create(
604 array_field_expr
, (unsigned int) index
);
606 /* `array_field_expr` not moved: destroy it. */
607 lttng_event_expr_destroy(array_field_expr
);
619 lttng_event_expr_destroy(expr
);
627 ssize_t
lttng_condition_on_event_create_from_payload(
628 struct lttng_payload_view
*view
,
629 struct lttng_condition
**_condition
)
631 ssize_t consumed_length
;
633 ssize_t event_rule_length
;
634 uint32_t i
, capture_descr_count
;
635 struct lttng_condition
*condition
= NULL
;
636 struct lttng_event_rule
*event_rule
= NULL
;
638 if (!view
|| !_condition
) {
642 /* Struct lttng_event_rule. */
644 struct lttng_payload_view event_rule_view
=
645 lttng_payload_view_from_view(view
, offset
, -1);
647 event_rule_length
= lttng_event_rule_create_from_payload(
648 &event_rule_view
, &event_rule
);
651 if (event_rule_length
< 0 || !event_rule
) {
655 /* Create condition (no capture descriptors yet) at this point */
656 condition
= lttng_condition_on_event_create(event_rule
);
661 /* Capture descriptor count. */
662 assert(event_rule_length
>= 0);
663 offset
+= (size_t) event_rule_length
;
664 capture_descr_count
= uint_from_buffer(&view
->buffer
, sizeof(uint32_t), &offset
);
665 if (capture_descr_count
== UINT32_C(-1)) {
669 /* Capture descriptors. */
670 for (i
= 0; i
< capture_descr_count
; i
++) {
671 enum lttng_condition_status status
;
672 struct lttng_event_expr
*expr
= event_expr_from_payload(
679 /* Move ownership of `expr` to `condition`. */
680 status
= lttng_condition_on_event_append_capture_descriptor(
682 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
683 /* `expr` not moved: destroy it. */
684 lttng_event_expr_destroy(expr
);
689 consumed_length
= (ssize_t
) offset
;
690 *_condition
= condition
;
695 consumed_length
= -1;
698 lttng_event_rule_put(event_rule
);
699 lttng_condition_put(condition
);
700 return consumed_length
;
704 enum lttng_condition_status
lttng_condition_on_event_borrow_rule_mutable(
705 const struct lttng_condition
*condition
,
706 struct lttng_event_rule
**rule
)
708 struct lttng_condition_on_event
*event_rule
;
709 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
711 if (!condition
|| !IS_ON_EVENT_CONDITION(condition
) || !rule
) {
712 status
= LTTNG_CONDITION_STATUS_INVALID
;
716 event_rule
= container_of(
717 condition
, struct lttng_condition_on_event
, parent
);
718 if (!event_rule
->rule
) {
719 status
= LTTNG_CONDITION_STATUS_UNSET
;
723 *rule
= event_rule
->rule
;
728 enum lttng_condition_status
lttng_condition_on_event_get_rule(
729 const struct lttng_condition
*condition
,
730 const struct lttng_event_rule
**rule
)
732 struct lttng_event_rule
*mutable_rule
= NULL
;
733 const enum lttng_condition_status status
=
734 lttng_condition_on_event_borrow_rule_mutable(
735 condition
, &mutable_rule
);
737 *rule
= mutable_rule
;
741 enum lttng_condition_status
742 lttng_condition_on_event_append_capture_descriptor(
743 struct lttng_condition
*condition
,
744 struct lttng_event_expr
*expr
)
747 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
748 struct lttng_condition_on_event
*event_rule_cond
=
749 container_of(condition
,
750 struct lttng_condition_on_event
, parent
);
751 struct lttng_capture_descriptor
*descriptor
= NULL
;
752 const struct lttng_event_rule
*rule
= NULL
;
754 /* Only accept l-values. */
755 if (!condition
|| !IS_ON_EVENT_CONDITION(condition
) || !expr
||
756 !lttng_event_expr_is_lvalue(expr
)) {
757 status
= LTTNG_CONDITION_STATUS_INVALID
;
761 status
= lttng_condition_on_event_get_rule(condition
, &rule
);
762 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
766 switch(lttng_event_rule_get_type(rule
)) {
767 case LTTNG_EVENT_RULE_TYPE_TRACEPOINT
:
768 case LTTNG_EVENT_RULE_TYPE_SYSCALL
:
770 status
= LTTNG_CONDITION_STATUS_OK
;
772 case LTTNG_EVENT_RULE_TYPE_UNKNOWN
:
773 status
= LTTNG_CONDITION_STATUS_INVALID
;
776 status
= LTTNG_CONDITION_STATUS_UNSUPPORTED
;
780 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
784 descriptor
= malloc(sizeof(*descriptor
));
785 if (descriptor
== NULL
) {
786 status
= LTTNG_CONDITION_STATUS_ERROR
;
790 descriptor
->event_expression
= expr
;
791 descriptor
->bytecode
= NULL
;
793 ret
= lttng_dynamic_pointer_array_add_pointer(
794 &event_rule_cond
->capture_descriptors
, descriptor
);
796 status
= LTTNG_CONDITION_STATUS_ERROR
;
800 /* Ownership is transfered to the internal capture_descriptors array */
807 enum lttng_condition_status
808 lttng_condition_on_event_get_capture_descriptor_count(
809 const struct lttng_condition
*condition
, unsigned int *count
)
811 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
812 const struct lttng_condition_on_event
*on_event_condition
=
813 container_of(condition
,
814 const struct lttng_condition_on_event
,
817 if (!condition
|| !IS_ON_EVENT_CONDITION(condition
) || !count
) {
818 status
= LTTNG_CONDITION_STATUS_INVALID
;
822 *count
= lttng_dynamic_pointer_array_get_count(
823 &on_event_condition
->capture_descriptors
);
829 const struct lttng_event_expr
*
830 lttng_condition_on_event_get_capture_descriptor_at_index(
831 const struct lttng_condition
*condition
, unsigned int index
)
833 const struct lttng_event_expr
*expr
= NULL
;
834 const struct lttng_capture_descriptor
*desc
= NULL
;
836 desc
= lttng_condition_on_event_get_internal_capture_descriptor_at_index(
841 expr
= desc
->event_expression
;
848 ssize_t
lttng_evaluation_on_event_create_from_payload(
849 const struct lttng_condition_on_event
*condition
,
850 struct lttng_payload_view
*view
,
851 struct lttng_evaluation
**_evaluation
)
853 ssize_t ret
, offset
= 0;
854 const char *trigger_name
;
855 struct lttng_evaluation
*evaluation
= NULL
;
856 const struct lttng_evaluation_on_event_comm
*header
;
857 const struct lttng_payload_view header_view
=
858 lttng_payload_view_from_view(
859 view
, 0, sizeof(*header
));
860 uint32_t capture_payload_size
;
861 const char *capture_payload
= NULL
;
868 if (!lttng_payload_view_is_valid(&header_view
)) {
869 ERR("Failed to initialize from malformed event rule evaluation: buffer too short to contain header");
874 header
= (typeof(header
)) header_view
.buffer
.data
;
876 /* Map the originating trigger's name. */
877 offset
+= sizeof(*header
);
879 const struct lttng_payload_view current_view
=
880 lttng_payload_view_from_view(view
, offset
,
881 header
->trigger_name_length
);
883 if (!lttng_payload_view_is_valid(¤t_view
)) {
884 ERR("Failed to initialize from malformed event rule evaluation: buffer too short to contain trigger name");
889 trigger_name
= current_view
.buffer
.data
;
890 if (!lttng_buffer_view_contains_string(¤t_view
.buffer
,
891 trigger_name
, header
->trigger_name_length
)) {
892 ERR("Failed to initialize from malformed event rule evaluation: invalid trigger name");
898 offset
+= header
->trigger_name_length
;
900 const struct lttng_payload_view current_view
=
901 lttng_payload_view_from_view(view
, offset
, -1);
903 if (current_view
.buffer
.size
< sizeof(capture_payload_size
)) {
908 memcpy(&capture_payload_size
, current_view
.buffer
.data
,
909 sizeof(capture_payload_size
));
911 offset
+= sizeof(capture_payload_size
);
913 if (capture_payload_size
> 0) {
914 const struct lttng_payload_view current_view
=
915 lttng_payload_view_from_view(view
, offset
, -1);
917 if (current_view
.buffer
.size
< capture_payload_size
) {
922 capture_payload
= current_view
.buffer
.data
;
925 evaluation
= lttng_evaluation_on_event_create(condition
, trigger_name
,
926 capture_payload
, capture_payload_size
, true);
932 offset
+= capture_payload_size
;
933 *_evaluation
= evaluation
;
938 lttng_evaluation_destroy(evaluation
);
942 static int lttng_evaluation_on_event_serialize(
943 const struct lttng_evaluation
*evaluation
,
944 struct lttng_payload
*payload
)
947 struct lttng_evaluation_on_event
*hit
;
948 struct lttng_evaluation_on_event_comm comm
;
949 uint32_t capture_payload_size
;
952 evaluation
, struct lttng_evaluation_on_event
, parent
);
955 comm
.trigger_name_length
= strlen(hit
->name
) + 1;
957 ret
= lttng_dynamic_buffer_append(
958 &payload
->buffer
, &comm
, sizeof(comm
));
963 ret
= lttng_dynamic_buffer_append(
964 &payload
->buffer
, hit
->name
, comm
.trigger_name_length
);
969 capture_payload_size
= (uint32_t) hit
->capture_payload
.size
;
970 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, &capture_payload_size
,
971 sizeof(capture_payload_size
));
976 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, hit
->capture_payload
.data
,
977 hit
->capture_payload
.size
);
987 bool msgpack_str_is_equal(const struct msgpack_object
*obj
, const char *str
)
989 bool is_equal
= true;
991 assert(obj
->type
== MSGPACK_OBJECT_STR
);
993 if (obj
->via
.str
.size
!= strlen(str
)) {
998 if (strncmp(obj
->via
.str
.ptr
, str
, obj
->via
.str
.size
) != 0) {
1008 const msgpack_object
*get_msgpack_map_obj(const struct msgpack_object
*map_obj
,
1011 const msgpack_object
*ret
= NULL
;
1014 assert(map_obj
->type
== MSGPACK_OBJECT_MAP
);
1016 for (i
= 0; i
< map_obj
->via
.map
.size
; i
++) {
1017 const struct msgpack_object_kv
*kv
= &map_obj
->via
.map
.ptr
[i
];
1019 assert(kv
->key
.type
== MSGPACK_OBJECT_STR
);
1021 if (msgpack_str_is_equal(&kv
->key
, name
)) {
1031 static void lttng_evaluation_on_event_destroy(
1032 struct lttng_evaluation
*evaluation
)
1034 struct lttng_evaluation_on_event
*hit
;
1037 evaluation
, struct lttng_evaluation_on_event
, parent
);
1039 lttng_dynamic_buffer_reset(&hit
->capture_payload
);
1040 lttng_event_field_value_destroy(hit
->captured_values
);
1045 int event_field_value_from_obj(const msgpack_object
*obj
,
1046 struct lttng_event_field_value
**field_val
)
1053 switch (obj
->type
) {
1054 case MSGPACK_OBJECT_NIL
:
1058 case MSGPACK_OBJECT_POSITIVE_INTEGER
:
1059 *field_val
= lttng_event_field_value_uint_create(
1062 case MSGPACK_OBJECT_NEGATIVE_INTEGER
:
1063 *field_val
= lttng_event_field_value_int_create(
1066 case MSGPACK_OBJECT_FLOAT32
:
1067 case MSGPACK_OBJECT_FLOAT64
:
1068 *field_val
= lttng_event_field_value_real_create(
1071 case MSGPACK_OBJECT_STR
:
1072 *field_val
= lttng_event_field_value_string_create_with_size(
1073 obj
->via
.str
.ptr
, obj
->via
.str
.size
);
1075 case MSGPACK_OBJECT_ARRAY
:
1079 *field_val
= lttng_event_field_value_array_create();
1084 for (i
= 0; i
< obj
->via
.array
.size
; i
++) {
1085 const msgpack_object
*elem_obj
= &obj
->via
.array
.ptr
[i
];
1086 struct lttng_event_field_value
*elem_field_val
;
1088 ret
= event_field_value_from_obj(elem_obj
,
1094 if (elem_field_val
) {
1095 ret
= lttng_event_field_value_array_append(
1096 *field_val
, elem_field_val
);
1098 ret
= lttng_event_field_value_array_append_unavailable(
1103 lttng_event_field_value_destroy(elem_field_val
);
1110 case MSGPACK_OBJECT_MAP
:
1113 * As of this version, the only valid map object is
1114 * for an enumeration value, for example:
1121 * - Carling Black Label
1123 const msgpack_object
*inner_obj
;
1126 inner_obj
= get_msgpack_map_obj(obj
, "type");
1128 ERR("Missing `type` entry in map object");
1132 if (inner_obj
->type
!= MSGPACK_OBJECT_STR
) {
1133 ERR("Map object's `type` entry is not a string: type = %s",
1134 msgpack_object_type_str(inner_obj
->type
));
1138 if (!msgpack_str_is_equal(inner_obj
, "enum")) {
1139 ERR("Map object's `type` entry: expecting `enum`");
1143 inner_obj
= get_msgpack_map_obj(obj
, "value");
1145 ERR("Missing `value` entry in map object");
1149 if (inner_obj
->type
== MSGPACK_OBJECT_POSITIVE_INTEGER
) {
1150 *field_val
= lttng_event_field_value_enum_uint_create(
1151 inner_obj
->via
.u64
);
1152 } else if (inner_obj
->type
== MSGPACK_OBJECT_NEGATIVE_INTEGER
) {
1153 *field_val
= lttng_event_field_value_enum_int_create(
1154 inner_obj
->via
.i64
);
1156 ERR("Map object's `value` entry is not an integer: type = %s",
1157 msgpack_object_type_str(inner_obj
->type
));
1165 inner_obj
= get_msgpack_map_obj(obj
, "labels");
1171 if (inner_obj
->type
!= MSGPACK_OBJECT_ARRAY
) {
1172 ERR("Map object's `labels` entry is not an array: type = %s",
1173 msgpack_object_type_str(inner_obj
->type
));
1177 for (label_i
= 0; label_i
< inner_obj
->via
.array
.size
;
1180 const msgpack_object
*elem_obj
=
1181 &inner_obj
->via
.array
.ptr
[label_i
];
1183 if (elem_obj
->type
!= MSGPACK_OBJECT_STR
) {
1184 ERR("Map object's `labels` entry's type is not a string: type = %s",
1185 msgpack_object_type_str(elem_obj
->type
));
1189 iret
= lttng_event_field_value_enum_append_label_with_size(
1190 *field_val
, elem_obj
->via
.str
.ptr
,
1191 elem_obj
->via
.str
.size
);
1200 ERR("Unexpected object type: type = %s",
1201 msgpack_object_type_str(obj
->type
));
1212 lttng_event_field_value_destroy(*field_val
);
1221 struct lttng_event_field_value
*event_field_value_from_capture_payload(
1222 const struct lttng_condition_on_event
*condition
,
1223 const char *capture_payload
, size_t capture_payload_size
)
1225 struct lttng_event_field_value
*ret
= NULL
;
1226 msgpack_unpacked unpacked
;
1227 msgpack_unpack_return unpack_return
;
1228 const msgpack_object
*root_obj
;
1229 const msgpack_object_array
*root_array_obj
;
1234 assert(capture_payload
);
1236 /* Initialize value. */
1237 msgpack_unpacked_init(&unpacked
);
1240 unpack_return
= msgpack_unpack_next(&unpacked
, capture_payload
,
1241 capture_payload_size
, NULL
);
1242 if (unpack_return
!= MSGPACK_UNPACK_SUCCESS
) {
1243 ERR("msgpack_unpack_next() failed to decode the "
1244 "MessagePack-encoded capture payload: "
1245 "size = %zu, ret = %d",
1246 capture_payload_size
, unpack_return
);
1250 /* Get root array. */
1251 root_obj
= &unpacked
.data
;
1253 if (root_obj
->type
!= MSGPACK_OBJECT_ARRAY
) {
1254 ERR("Expecting an array as the root object: type = %s",
1255 msgpack_object_type_str(root_obj
->type
));
1259 root_array_obj
= &root_obj
->via
.array
;
1261 /* Create an empty root array event field value. */
1262 ret
= lttng_event_field_value_array_create();
1268 * For each capture descriptor in the condition object:
1270 * 1. Get its corresponding captured field value MessagePack
1273 * 2. Create a corresponding event field value.
1275 * 3. Append it to `ret` (the root array event field value).
1277 count
= lttng_dynamic_pointer_array_get_count(
1278 &condition
->capture_descriptors
);
1281 for (i
= 0; i
< count
; i
++) {
1282 const struct lttng_capture_descriptor
*capture_descriptor
=
1283 lttng_condition_on_event_get_internal_capture_descriptor_at_index(
1284 &condition
->parent
, i
);
1285 const msgpack_object
*elem_obj
;
1286 struct lttng_event_field_value
*elem_field_val
;
1289 assert(capture_descriptor
);
1291 elem_obj
= &root_array_obj
->ptr
[i
];
1292 iret
= event_field_value_from_obj(elem_obj
,
1298 if (elem_field_val
) {
1299 iret
= lttng_event_field_value_array_append(ret
,
1302 iret
= lttng_event_field_value_array_append_unavailable(
1307 lttng_event_field_value_destroy(elem_field_val
);
1315 lttng_event_field_value_destroy(ret
);
1319 msgpack_unpacked_destroy(&unpacked
);
1324 struct lttng_evaluation
*lttng_evaluation_on_event_create(
1325 const struct lttng_condition_on_event
*condition
,
1326 const char *trigger_name
,
1327 const char *capture_payload
, size_t capture_payload_size
,
1328 bool decode_capture_payload
)
1330 struct lttng_evaluation_on_event
*hit
;
1331 struct lttng_evaluation
*evaluation
= NULL
;
1333 hit
= zmalloc(sizeof(struct lttng_evaluation_on_event
));
1338 hit
->name
= strdup(trigger_name
);
1343 lttng_dynamic_buffer_init(&hit
->capture_payload
);
1345 if (capture_payload
) {
1346 const int ret
= lttng_dynamic_buffer_append(
1347 &hit
->capture_payload
, capture_payload
,
1348 capture_payload_size
);
1350 ERR("Failed to initialize capture payload of event rule evaluation");
1354 if (decode_capture_payload
) {
1355 hit
->captured_values
=
1356 event_field_value_from_capture_payload(
1359 capture_payload_size
);
1360 if (!hit
->captured_values
) {
1361 ERR("Failed to decode the capture payload: size = %zu",
1362 capture_payload_size
);
1368 hit
->parent
.type
= LTTNG_CONDITION_TYPE_ON_EVENT
;
1369 hit
->parent
.serialize
= lttng_evaluation_on_event_serialize
;
1370 hit
->parent
.destroy
= lttng_evaluation_on_event_destroy
;
1372 evaluation
= &hit
->parent
;
1377 lttng_evaluation_on_event_destroy(&hit
->parent
);
1383 enum lttng_evaluation_status
lttng_evaluation_on_event_get_captured_values(
1384 const struct lttng_evaluation
*evaluation
,
1385 const struct lttng_event_field_value
**field_val
)
1387 struct lttng_evaluation_on_event
*hit
;
1388 enum lttng_evaluation_status status
= LTTNG_EVALUATION_STATUS_OK
;
1390 if (!evaluation
|| !is_on_event_evaluation(evaluation
) ||
1392 status
= LTTNG_EVALUATION_STATUS_INVALID
;
1396 hit
= container_of(evaluation
, struct lttng_evaluation_on_event
,
1398 if (!hit
->captured_values
) {
1399 status
= LTTNG_EVALUATION_STATUS_INVALID
;
1403 *field_val
= hit
->captured_values
;
1409 enum lttng_evaluation_status
lttng_evaluation_on_event_get_trigger_name(
1410 const struct lttng_evaluation
*evaluation
, const char **name
)
1412 struct lttng_evaluation_on_event
*hit
;
1413 enum lttng_evaluation_status status
= LTTNG_EVALUATION_STATUS_OK
;
1415 if (!evaluation
|| !is_on_event_evaluation(evaluation
) || !name
) {
1416 status
= LTTNG_EVALUATION_STATUS_INVALID
;
1421 evaluation
, struct lttng_evaluation_on_event
, parent
);
1428 enum lttng_error_code
1429 lttng_condition_on_event_generate_capture_descriptor_bytecode(
1430 struct lttng_condition
*condition
)
1432 enum lttng_error_code ret
;
1433 enum lttng_condition_status status
;
1434 unsigned int capture_count
, i
;
1436 if (!condition
|| !IS_ON_EVENT_CONDITION(condition
)) {
1437 ret
= LTTNG_ERR_FATAL
;
1441 status
= lttng_condition_on_event_get_capture_descriptor_count(
1442 condition
, &capture_count
);
1443 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
1444 ret
= LTTNG_ERR_FATAL
;
1448 for (i
= 0; i
< capture_count
; i
++) {
1449 struct lttng_capture_descriptor
*local_capture_desc
=
1450 lttng_condition_on_event_get_internal_capture_descriptor_at_index(
1453 if (local_capture_desc
== NULL
) {
1454 ret
= LTTNG_ERR_FATAL
;
1458 /* Generate the bytecode. */
1459 status
= lttng_event_expr_to_bytecode(
1460 local_capture_desc
->event_expression
,
1461 &local_capture_desc
->bytecode
);
1462 if (status
< 0 || local_capture_desc
->bytecode
== NULL
) {
1463 ret
= LTTNG_ERR_INVALID_CAPTURE_EXPRESSION
;
1468 /* Everything went better than expected */
1476 const struct lttng_bytecode
*
1477 lttng_condition_on_event_get_capture_bytecode_at_index(
1478 const struct lttng_condition
*condition
, unsigned int index
)
1480 const struct lttng_condition_on_event
*event_rule_cond
=
1481 container_of(condition
,
1482 const struct lttng_condition_on_event
,
1484 struct lttng_capture_descriptor
*desc
= NULL
;
1485 struct lttng_bytecode
*bytecode
= NULL
;
1487 enum lttng_condition_status status
;
1489 if (!condition
|| !IS_ON_EVENT_CONDITION(condition
)) {
1493 status
= lttng_condition_on_event_get_capture_descriptor_count(
1495 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
1499 if (index
>= count
) {
1503 desc
= lttng_dynamic_pointer_array_get_pointer(
1504 &event_rule_cond
->capture_descriptors
, index
);
1509 bytecode
= desc
->bytecode
;