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/event-rule-internal.h>
16 #include <lttng/condition/event-rule.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_EVENT_RULE_HIT)
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_EVENT_RULE_HIT
;
37 static bool lttng_condition_event_rule_validate(
38 const struct lttng_condition
*condition
);
39 static int lttng_condition_event_rule_serialize(
40 const struct lttng_condition
*condition
,
41 struct lttng_payload
*payload
);
42 static bool lttng_condition_event_rule_is_equal(
43 const struct lttng_condition
*_a
,
44 const struct lttng_condition
*_b
);
45 static void lttng_condition_event_rule_destroy(
46 struct lttng_condition
*condition
);
48 static bool lttng_condition_event_rule_validate(
49 const struct lttng_condition
*condition
)
52 struct lttng_condition_event_rule
*event_rule
;
58 event_rule
= container_of(
59 condition
, struct lttng_condition_event_rule
, parent
);
60 if (!event_rule
->rule
) {
61 ERR("Invalid session 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 character.
77 int serialize_cstr(const char *str
, struct lttng_dynamic_buffer
*buf
)
80 uint32_t len
= strlen(str
) + 1;
82 /* Serialize the length, including the null character */
83 DBG("Serializing C string's length (including null character): "
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
)
111 /* Serialize the expression's type */
112 DBG("Serializing event expression's type: %d", expr
->type
);
114 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, &type
, sizeof(type
));
119 /* Serialize the expression */
120 switch (expr
->type
) {
121 case LTTNG_EVENT_EXPR_TYPE_EVENT_PAYLOAD_FIELD
:
122 case LTTNG_EVENT_EXPR_TYPE_CHANNEL_CONTEXT_FIELD
:
124 const struct lttng_event_expr_field
*field_expr
=
126 const struct lttng_event_expr_field
,
129 /* Serialize the field name */
130 DBG("Serializing field event expression's field name: \"%s\"",
132 ret
= serialize_cstr(field_expr
->name
, &payload
->buffer
);
139 case LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD
:
141 const struct lttng_event_expr_app_specific_context_field
*field_expr
=
143 const struct lttng_event_expr_app_specific_context_field
,
146 /* Serialize the provider name */
147 DBG("Serializing app-specific context field event expression's "
148 "provider name: \"%s\"",
149 field_expr
->provider_name
);
150 ret
= serialize_cstr(field_expr
->provider_name
, &payload
->buffer
);
155 /* Serialize the type name */
156 DBG("Serializing app-specific context field event expression's "
158 field_expr
->provider_name
);
159 ret
= serialize_cstr(field_expr
->type_name
, &payload
->buffer
);
166 case LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT
:
168 const struct lttng_event_expr_array_field_element
*elem_expr
=
170 const struct lttng_event_expr_array_field_element
,
172 uint32_t index
= elem_expr
->index
;
174 /* Serialize the index */
175 DBG("Serializing array field element event expression's "
176 "index: %u", elem_expr
->index
);
177 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, &index
, sizeof(index
));
182 /* Serialize the parent array field expression */
183 DBG("Serializing array field element event expression's "
184 "parent array field event expression.");
185 ret
= serialize_event_expr(elem_expr
->array_field_expr
, payload
);
201 struct lttng_capture_descriptor
*
202 lttng_condition_event_rule_get_internal_capture_descriptor_at_index(
203 const struct lttng_condition
*condition
, unsigned int index
)
205 const struct lttng_condition_event_rule
*event_rule_cond
=
206 container_of(condition
,
207 const struct lttng_condition_event_rule
,
209 struct lttng_capture_descriptor
*desc
= NULL
;
211 enum lttng_condition_status status
;
213 if (!condition
|| !IS_EVENT_RULE_CONDITION(condition
)) {
217 status
= lttng_condition_event_rule_get_capture_descriptor_count(
219 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
223 if (index
>= count
) {
227 desc
= lttng_dynamic_pointer_array_get_pointer(
228 &event_rule_cond
->capture_descriptors
, index
);
233 static int lttng_condition_event_rule_serialize(
234 const struct lttng_condition
*condition
,
235 struct lttng_payload
*payload
)
238 struct lttng_condition_event_rule
*event_rule
;
239 enum lttng_condition_status status
;
240 uint32_t 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_event_rule
, parent
);
252 DBG("Serializing event rule condition's event rule");
253 ret
= lttng_event_rule_serialize(event_rule
->rule
, payload
);
258 status
= lttng_condition_event_rule_get_capture_descriptor_count(
259 condition
, &capture_descr_count
);
260 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
265 DBG("Serializing event rule condition's capture descriptor count: %" PRIu32
,
266 capture_descr_count
);
267 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, &capture_descr_count
,
268 sizeof(capture_descr_count
));
273 for (i
= 0; i
< capture_descr_count
; i
++) {
274 const struct lttng_capture_descriptor
*desc
=
275 lttng_condition_event_rule_get_internal_capture_descriptor_at_index(
278 DBG("Serializing event rule condition's capture descriptor %" PRIu32
,
280 ret
= serialize_event_expr(desc
->event_expression
, payload
);
286 * Appending the internal index payload linked with the
288 * TODO: might want to move to an englobing object to describe a
289 * capture descriptor publicly.
291 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, &desc
->capture_index
,
292 sizeof(desc
->capture_index
));
303 bool capture_descriptors_are_equal(
304 const struct lttng_condition
*condition_a
,
305 const struct lttng_condition
*condition_b
)
307 bool is_equal
= true;
308 unsigned int capture_descr_count_a
;
309 unsigned int capture_descr_count_b
;
311 enum lttng_condition_status status
;
313 status
= lttng_condition_event_rule_get_capture_descriptor_count(
314 condition_a
, &capture_descr_count_a
);
315 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
319 status
= lttng_condition_event_rule_get_capture_descriptor_count(
320 condition_b
, &capture_descr_count_b
);
321 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
325 if (capture_descr_count_a
!= capture_descr_count_b
) {
329 for (i
= 0; i
< capture_descr_count_a
; i
++) {
330 const struct lttng_event_expr
*expr_a
=
331 lttng_condition_event_rule_get_capture_descriptor_at_index(
334 const struct lttng_event_expr
*expr_b
=
335 lttng_condition_event_rule_get_capture_descriptor_at_index(
339 if (!lttng_event_expr_is_equal(expr_a
, expr_b
)) {
353 static bool lttng_condition_event_rule_is_equal(
354 const struct lttng_condition
*_a
,
355 const struct lttng_condition
*_b
)
357 bool is_equal
= false;
358 struct lttng_condition_event_rule
*a
, *b
;
360 a
= container_of(_a
, struct lttng_condition_event_rule
, parent
);
361 b
= container_of(_b
, struct lttng_condition_event_rule
, parent
);
363 /* Both session names must be set or both must be unset. */
364 if ((a
->rule
&& !b
->rule
) || (!a
->rule
&& b
->rule
)) {
365 WARN("Comparing session event_rule conditions with uninitialized rule.");
369 is_equal
= lttng_event_rule_is_equal(a
->rule
, b
->rule
);
374 is_equal
= capture_descriptors_are_equal(_a
, _b
);
380 static void lttng_condition_event_rule_destroy(
381 struct lttng_condition
*condition
)
383 struct lttng_condition_event_rule
*event_rule
;
385 event_rule
= container_of(
386 condition
, struct lttng_condition_event_rule
, parent
);
388 lttng_event_rule_destroy(event_rule
->rule
);
389 lttng_dynamic_pointer_array_reset(&event_rule
->capture_descriptors
);
394 void destroy_capture_descriptor(void *ptr
)
396 struct lttng_capture_descriptor
*desc
=
397 (struct lttng_capture_descriptor
*) ptr
;
398 lttng_event_expr_destroy(desc
->event_expression
);
402 struct lttng_condition
*lttng_condition_event_rule_create(
403 struct lttng_event_rule
*rule
)
405 struct lttng_condition
*parent
= NULL
;
406 struct lttng_condition_event_rule
*condition
= NULL
;
412 condition
= zmalloc(sizeof(struct lttng_condition_event_rule
));
417 lttng_condition_init(&condition
->parent
,
418 LTTNG_CONDITION_TYPE_EVENT_RULE_HIT
);
419 condition
->parent
.validate
= lttng_condition_event_rule_validate
,
420 condition
->parent
.serialize
= lttng_condition_event_rule_serialize
,
421 condition
->parent
.equal
= lttng_condition_event_rule_is_equal
,
422 condition
->parent
.destroy
= lttng_condition_event_rule_destroy
,
424 lttng_event_rule_get(rule
);
426 condition
->rule
= rule
;
427 lttng_dynamic_pointer_array_init(&condition
->capture_descriptors
,
428 destroy_capture_descriptor
);
430 parent
= &condition
->parent
;
436 int64_t int_from_buffer(const struct lttng_buffer_view
*view
, size_t size
,
441 if (*offset
+ size
> view
->size
) {
448 ret
= (int64_t) view
->data
[*offset
];
450 case sizeof(int32_t):
454 memcpy(&s32
, &view
->data
[*offset
], sizeof(s32
));
459 memcpy(&ret
, &view
->data
[*offset
], sizeof(ret
));
471 uint64_t uint_from_buffer(const struct lttng_buffer_view
*view
, size_t size
,
476 if (*offset
+ size
> view
->size
) {
483 ret
= (uint64_t) view
->data
[*offset
];
485 case sizeof(uint32_t):
489 memcpy(&u32
, &view
->data
[*offset
], sizeof(u32
));
490 ret
= (uint64_t) u32
;
494 memcpy(&ret
, &view
->data
[*offset
], sizeof(ret
));
507 const char *str_from_buffer(const struct lttng_buffer_view
*view
,
513 len
= uint_from_buffer(view
, sizeof(uint32_t), offset
);
514 if (len
== UINT64_C(-1)) {
518 ret
= &view
->data
[*offset
];
520 if (!lttng_buffer_view_contains_string(view
, ret
, len
)) {
535 struct lttng_event_expr
*event_expr_from_payload(
536 struct lttng_payload_view
*view
, size_t *offset
)
538 struct lttng_event_expr
*expr
= NULL
;
542 type
= uint_from_buffer(&view
->buffer
, sizeof(uint8_t), offset
);
543 if (type
== UINT64_C(-1)) {
548 case LTTNG_EVENT_EXPR_TYPE_EVENT_PAYLOAD_FIELD
:
549 str
= str_from_buffer(&view
->buffer
, offset
);
554 expr
= lttng_event_expr_event_payload_field_create(str
);
556 case LTTNG_EVENT_EXPR_TYPE_CHANNEL_CONTEXT_FIELD
:
557 str
= str_from_buffer(&view
->buffer
, offset
);
562 expr
= lttng_event_expr_channel_context_field_create(str
);
564 case LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD
:
566 const char *provider_name
;
567 const char *type_name
;
569 provider_name
= str_from_buffer(&view
->buffer
, offset
);
570 if (!provider_name
) {
574 type_name
= str_from_buffer(&view
->buffer
, offset
);
579 expr
= lttng_event_expr_app_specific_context_field_create(
580 provider_name
, type_name
);
583 case LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT
:
585 struct lttng_event_expr
*array_field_expr
;
588 index
= uint_from_buffer(&view
->buffer
, sizeof(uint32_t), offset
);
589 if (index
== UINT64_C(-1)) {
593 /* Array field expression is the encoded after this */
594 array_field_expr
= event_expr_from_payload(view
, offset
);
595 if (!array_field_expr
) {
599 /* Move ownership of `array_field_expr` to new expression */
600 expr
= lttng_event_expr_array_field_element_create(
601 array_field_expr
, (unsigned int) index
);
603 /* `array_field_expr` not moved: destroy it */
604 lttng_event_expr_destroy(array_field_expr
);
616 lttng_event_expr_destroy(expr
);
624 ssize_t
lttng_condition_event_rule_create_from_payload(
625 struct lttng_payload_view
*view
,
626 struct lttng_condition
**_condition
)
628 ssize_t consumed_length
;
631 uint64_t capture_descr_count
;
633 struct lttng_condition
*condition
= NULL
;
634 struct lttng_event_rule
*event_rule
= NULL
;
636 if (!view
|| !_condition
) {
640 /* Struct lttng_event_rule */
642 struct lttng_payload_view event_rule_view
=
643 lttng_payload_view_from_view(view
, offset
, -1);
644 size
= lttng_event_rule_create_from_payload(
645 &event_rule_view
, &event_rule
);
648 if (size
< 0 || !event_rule
) {
652 /* Create condition (no capture descriptors yet) at this point */
653 condition
= lttng_condition_event_rule_create(event_rule
);
659 /* Capture descriptor count */
661 offset
+= (size_t) size
;
662 capture_descr_count
= uint_from_buffer(&view
->buffer
, sizeof(uint32_t), &offset
);
663 if (capture_descr_count
== UINT64_C(-1)) {
667 /* Capture descriptors */
668 for (i
= 0; i
< capture_descr_count
; i
++) {
669 enum lttng_condition_status status
;
670 struct lttng_capture_descriptor
*desc
;
671 struct lttng_event_expr
*expr
= event_expr_from_payload(
673 int32_t payload_index
= int_from_buffer(&view
->buffer
, sizeof(int32_t),
680 /* Move ownership of `expr` to `condition` */
681 status
= lttng_condition_event_rule_append_capture_descriptor(
683 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
684 /* `expr` not moved: destroy it */
685 lttng_event_expr_destroy(expr
);
690 * Set the internal payload object for the descriptor. This can
691 * be used by liblttng-ctl to access capture msgpack payload on
694 desc
= lttng_condition_event_rule_get_internal_capture_descriptor_at_index(condition
, i
);
698 desc
->capture_index
= payload_index
;
701 consumed_length
= (ssize_t
) offset
;
702 *_condition
= condition
;
707 consumed_length
= -1;
710 lttng_event_rule_destroy(event_rule
);
711 lttng_condition_destroy(condition
);
712 return consumed_length
;
716 enum lttng_condition_status
lttng_condition_event_rule_get_rule_mutable(
717 const struct lttng_condition
*condition
,
718 struct lttng_event_rule
**rule
)
720 struct lttng_condition_event_rule
*event_rule
;
721 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
723 if (!condition
|| !IS_EVENT_RULE_CONDITION(condition
) || !rule
) {
724 status
= LTTNG_CONDITION_STATUS_INVALID
;
728 event_rule
= container_of(
729 condition
, struct lttng_condition_event_rule
, parent
);
730 if (!event_rule
->rule
) {
731 status
= LTTNG_CONDITION_STATUS_UNSET
;
734 *rule
= event_rule
->rule
;
739 enum lttng_condition_status
lttng_condition_event_rule_get_rule(
740 const struct lttng_condition
*condition
,
741 const struct lttng_event_rule
**rule
)
743 struct lttng_event_rule
*mutable_rule
= NULL
;
744 enum lttng_condition_status status
;
746 status
= lttng_condition_event_rule_get_rule_mutable(
747 condition
, &mutable_rule
);
748 *rule
= mutable_rule
;
752 enum lttng_condition_status
753 lttng_condition_event_rule_append_capture_descriptor(
754 struct lttng_condition
*condition
,
755 struct lttng_event_expr
*expr
)
757 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
758 struct lttng_condition_event_rule
*event_rule_cond
=
759 container_of(condition
,
760 struct lttng_condition_event_rule
, parent
);
762 struct lttng_capture_descriptor
*descriptor
= NULL
;
763 const struct lttng_event_rule
*rule
= NULL
;
765 /* Only accept l-values */
766 if (!condition
|| !IS_EVENT_RULE_CONDITION(condition
) || !expr
||
767 !lttng_event_expr_is_lvalue(expr
)) {
768 status
= LTTNG_CONDITION_STATUS_INVALID
;
772 status
= lttng_condition_event_rule_get_rule(condition
, &rule
);
773 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
777 switch(lttng_event_rule_get_type(rule
)) {
778 case LTTNG_EVENT_RULE_TYPE_TRACEPOINT
:
779 case LTTNG_EVENT_RULE_TYPE_SYSCALL
:
781 status
= LTTNG_CONDITION_STATUS_OK
;
783 case LTTNG_EVENT_RULE_TYPE_UNKNOWN
:
784 status
= LTTNG_CONDITION_STATUS_INVALID
;
787 status
= LTTNG_CONDITION_STATUS_UNSUPPORTED
;
791 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
795 descriptor
= malloc(sizeof(*descriptor
));
796 if (descriptor
== NULL
) {
797 status
= LTTNG_CONDITION_STATUS_ERROR
;
801 descriptor
->capture_index
= -1;
802 descriptor
->event_expression
= expr
;
804 ret
= lttng_dynamic_pointer_array_add_pointer(
805 &event_rule_cond
->capture_descriptors
, descriptor
);
807 status
= LTTNG_CONDITION_STATUS_ERROR
;
811 /* Ownership is transfered to the internal capture_descriptors array */
818 enum lttng_condition_status
819 lttng_condition_event_rule_get_capture_descriptor_count(
820 const struct lttng_condition
*condition
, unsigned int *count
)
822 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
823 const struct lttng_condition_event_rule
*event_rule_cond
=
824 container_of(condition
,
825 const struct lttng_condition_event_rule
,
828 if (!condition
|| !IS_EVENT_RULE_CONDITION(condition
) || !count
) {
829 status
= LTTNG_CONDITION_STATUS_INVALID
;
833 *count
= lttng_dynamic_pointer_array_get_count(
834 &event_rule_cond
->capture_descriptors
);
840 const struct lttng_event_expr
*
841 lttng_condition_event_rule_get_capture_descriptor_at_index(
842 const struct lttng_condition
*condition
, unsigned int index
)
844 const struct lttng_event_expr
*expr
= NULL
;
845 const struct lttng_capture_descriptor
*desc
= NULL
;
847 desc
= lttng_condition_event_rule_get_internal_capture_descriptor_at_index(
852 expr
= desc
->event_expression
;
859 ssize_t
lttng_evaluation_event_rule_create_from_payload(
860 const struct lttng_condition_event_rule
*condition
,
861 struct lttng_payload_view
*view
,
862 struct lttng_evaluation
**_evaluation
)
864 ssize_t ret
, offset
= 0;
866 struct lttng_evaluation
*evaluation
= NULL
;
867 const struct lttng_evaluation_event_rule_comm
*comm
=
868 (const struct lttng_evaluation_event_rule_comm
*)
870 uint32_t capture_payload_size
;
871 const char *capture_payload
= NULL
;
878 if (view
->buffer
.size
< sizeof(*comm
)) {
883 /* Map the name, view of the payload */
884 offset
+= sizeof(*comm
);
886 struct lttng_payload_view current_view
=
887 lttng_payload_view_from_view(view
, offset
,
888 comm
->trigger_name_length
);
889 name
= current_view
.buffer
.data
;
895 if (!lttng_buffer_view_contains_string(¤t_view
.buffer
,
896 name
, comm
->trigger_name_length
)) {
902 offset
+= comm
->trigger_name_length
;
904 struct lttng_payload_view current_view
= lttng_payload_view_from_view(view
, offset
, -1);
906 if (current_view
.buffer
.size
< sizeof(capture_payload_size
)) {
911 memcpy(&capture_payload_size
, current_view
.buffer
.data
,
912 sizeof(capture_payload_size
));
914 offset
+= sizeof(capture_payload_size
);
916 if (capture_payload_size
> 0) {
917 struct lttng_payload_view current_view
= lttng_payload_view_from_view(view
, offset
, -1);
919 if (current_view
.buffer
.size
< capture_payload_size
) {
924 capture_payload
= current_view
.buffer
.data
;
927 evaluation
= lttng_evaluation_event_rule_create(condition
, name
,
928 capture_payload
, capture_payload_size
, true);
934 offset
+= capture_payload_size
;
935 *_evaluation
= evaluation
;
940 lttng_evaluation_destroy(evaluation
);
944 static int lttng_evaluation_event_rule_serialize(
945 const struct lttng_evaluation
*evaluation
,
946 struct lttng_payload
*payload
)
949 struct lttng_evaluation_event_rule
*hit
;
950 struct lttng_evaluation_event_rule_comm comm
;
951 uint32_t capture_payload_size
;
954 evaluation
, struct lttng_evaluation_event_rule
, parent
);
955 comm
.trigger_name_length
= strlen(hit
->name
) + 1;
956 ret
= lttng_dynamic_buffer_append(
957 &payload
->buffer
, &comm
, sizeof(comm
));
961 ret
= lttng_dynamic_buffer_append(
962 &payload
->buffer
, hit
->name
, comm
.trigger_name_length
);
967 capture_payload_size
= (uint32_t) hit
->capture_payload
.size
;
968 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, &capture_payload_size
,
969 sizeof(capture_payload_size
));
974 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, hit
->capture_payload
.data
,
975 hit
->capture_payload
.size
);
985 bool msgpack_str_is_equal(const struct msgpack_object
*obj
, const char *str
)
987 bool is_equal
= true;
989 assert(obj
->type
== MSGPACK_OBJECT_STR
);
991 if (obj
->via
.str
.size
!= strlen(str
)) {
996 if (strncmp(obj
->via
.str
.ptr
, str
, obj
->via
.str
.size
) != 0) {
1006 const msgpack_object
*get_msgpack_map_obj(const struct msgpack_object
*map_obj
,
1009 const msgpack_object
*ret
= NULL
;
1012 assert(map_obj
->type
== MSGPACK_OBJECT_MAP
);
1014 for (i
= 0; i
< map_obj
->via
.map
.size
; i
++) {
1015 const struct msgpack_object_kv
*kv
= &map_obj
->via
.map
.ptr
[i
];
1017 assert(kv
->key
.type
== MSGPACK_OBJECT_STR
);
1019 if (msgpack_str_is_equal(&kv
->key
, name
)) {
1029 static void lttng_evaluation_event_rule_destroy(
1030 struct lttng_evaluation
*evaluation
)
1032 struct lttng_evaluation_event_rule
*hit
;
1035 evaluation
, struct lttng_evaluation_event_rule
, parent
);
1037 lttng_dynamic_buffer_reset(&hit
->capture_payload
);
1038 if (hit
->captured_values
) {
1039 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
)
1052 switch (obj
->type
) {
1053 case MSGPACK_OBJECT_NIL
:
1057 case MSGPACK_OBJECT_POSITIVE_INTEGER
:
1058 *field_val
= lttng_event_field_value_uint_create(
1061 case MSGPACK_OBJECT_NEGATIVE_INTEGER
:
1062 *field_val
= lttng_event_field_value_int_create(
1065 case MSGPACK_OBJECT_FLOAT32
:
1066 case MSGPACK_OBJECT_FLOAT64
:
1067 *field_val
= lttng_event_field_value_real_create(
1070 case MSGPACK_OBJECT_STR
:
1071 *field_val
= lttng_event_field_value_string_create_with_size(
1072 obj
->via
.str
.ptr
, obj
->via
.str
.size
);
1074 case MSGPACK_OBJECT_ARRAY
:
1078 *field_val
= lttng_event_field_value_array_create();
1083 for (i
= 0; i
< obj
->via
.array
.size
; i
++) {
1084 const msgpack_object
*elem_obj
= &obj
->via
.array
.ptr
[i
];
1085 struct lttng_event_field_value
*elem_field_val
;
1087 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 (it's a %d).",
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 (it's a %d).",
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 (it's a %d).",
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 (it's a %d).",
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 %d.", obj
->type
);
1211 lttng_event_field_value_destroy(*field_val
);
1220 struct lttng_event_field_value
*event_field_value_from_capture_payload(
1221 const struct lttng_condition_event_rule
*condition
,
1222 const char *capture_payload
, size_t capture_payload_size
)
1224 struct lttng_event_field_value
*ret
= NULL
;
1225 msgpack_unpacked unpacked
;
1226 msgpack_unpack_return unpack_return
;
1227 const msgpack_object
*root_obj
;
1228 const msgpack_object_array
*root_array_obj
;
1233 assert(capture_payload
);
1235 /* Initialize value */
1236 msgpack_unpacked_init(&unpacked
);
1239 unpack_return
= msgpack_unpack_next(&unpacked
, capture_payload
,
1240 capture_payload_size
, NULL
);
1241 if (unpack_return
!= MSGPACK_UNPACK_SUCCESS
) {
1242 ERR("msgpack_unpack_next() failed to decode the "
1243 "MessagePack-encoded capture payload "
1244 "(size %zu); returned %d.",
1245 capture_payload_size
, unpack_return
);
1249 /* Get root array */
1250 root_obj
= &unpacked
.data
;
1252 if (root_obj
->type
!= MSGPACK_OBJECT_ARRAY
) {
1253 ERR("Expecting an array as the root object; got type %d.",
1258 root_array_obj
= &root_obj
->via
.array
;
1260 /* Create an empty root array event field value */
1261 ret
= lttng_event_field_value_array_create();
1267 * For each capture descriptor in the condition object:
1269 * 1. Get its corresponding captured field value MessagePack
1272 * 2. Create a corresponding event field value.
1274 * 3. Append it to `ret` (the root array event field value).
1276 count
= lttng_dynamic_pointer_array_get_count(
1277 &condition
->capture_descriptors
);
1280 for (i
= 0; i
< count
; i
++) {
1281 const struct lttng_capture_descriptor
*capture_descriptor
=
1282 lttng_condition_event_rule_get_internal_capture_descriptor_at_index(
1283 &condition
->parent
, i
);
1284 const msgpack_object
*elem_obj
;
1285 struct lttng_event_field_value
*elem_field_val
;
1288 assert(capture_descriptor
);
1289 assert(capture_descriptor
->capture_index
>= 0);
1291 if (capture_descriptor
->capture_index
>= root_array_obj
->size
) {
1292 ERR("Root array object of size %u does not have enough "
1293 "elements for the capture index %u "
1294 "(for capture descriptor #%zu).",
1295 (unsigned int) root_array_obj
->size
,
1296 (unsigned int) capture_descriptor
->capture_index
,
1301 elem_obj
= &root_array_obj
->ptr
[(size_t) capture_descriptor
->capture_index
];
1302 iret
= event_field_value_from_obj(elem_obj
,
1308 if (elem_field_val
) {
1309 iret
= lttng_event_field_value_array_append(ret
,
1312 iret
= lttng_event_field_value_array_append_unavailable(
1317 lttng_event_field_value_destroy(elem_field_val
);
1325 lttng_event_field_value_destroy(ret
);
1329 msgpack_unpacked_destroy(&unpacked
);
1334 struct lttng_evaluation
*lttng_evaluation_event_rule_create(
1335 const struct lttng_condition_event_rule
*condition
,
1336 const char *trigger_name
,
1337 const char *capture_payload
, size_t capture_payload_size
,
1338 bool decode_capture_payload
)
1340 struct lttng_evaluation_event_rule
*hit
;
1341 struct lttng_evaluation
*evaluation
= NULL
;
1343 hit
= zmalloc(sizeof(struct lttng_evaluation_event_rule
));
1348 hit
->name
= strdup(trigger_name
);
1353 lttng_dynamic_buffer_init(&hit
->capture_payload
);
1355 if (capture_payload
) {
1356 lttng_dynamic_buffer_append(&hit
->capture_payload
,
1357 capture_payload
, capture_payload_size
);
1359 if (decode_capture_payload
) {
1360 hit
->captured_values
=
1361 event_field_value_from_capture_payload(
1364 capture_payload_size
);
1365 if (!hit
->captured_values
) {
1366 ERR("Failed to decode the capture payload (size %zu).",
1367 capture_payload_size
);
1373 hit
->parent
.type
= LTTNG_CONDITION_TYPE_EVENT_RULE_HIT
;
1374 hit
->parent
.serialize
= lttng_evaluation_event_rule_serialize
;
1375 hit
->parent
.destroy
= lttng_evaluation_event_rule_destroy
;
1377 evaluation
= &hit
->parent
;
1382 lttng_evaluation_event_rule_destroy(&hit
->parent
);
1388 enum lttng_evaluation_status
lttng_evaluation_get_captured_values(
1389 const struct lttng_evaluation
*evaluation
,
1390 const struct lttng_event_field_value
**field_val
)
1392 struct lttng_evaluation_event_rule
*hit
;
1393 enum lttng_evaluation_status status
= LTTNG_EVALUATION_STATUS_OK
;
1395 if (!evaluation
|| !is_event_rule_evaluation(evaluation
) ||
1397 status
= LTTNG_EVALUATION_STATUS_INVALID
;
1401 hit
= container_of(evaluation
, struct lttng_evaluation_event_rule
,
1403 if (!hit
->captured_values
) {
1404 status
= LTTNG_EVALUATION_STATUS_INVALID
;
1408 *field_val
= hit
->captured_values
;
1414 enum lttng_evaluation_status
lttng_evaluation_event_rule_get_trigger_name(
1415 const struct lttng_evaluation
*evaluation
, const char **name
)
1417 struct lttng_evaluation_event_rule
*hit
;
1418 enum lttng_evaluation_status status
= LTTNG_EVALUATION_STATUS_OK
;
1420 if (!evaluation
|| !is_event_rule_evaluation(evaluation
) || !name
) {
1421 status
= LTTNG_EVALUATION_STATUS_INVALID
;
1426 evaluation
, struct lttng_evaluation_event_rule
, parent
);
1433 enum lttng_error_code
1434 lttng_condition_event_rule_generate_capture_descriptor_bytecode_set(
1435 struct lttng_condition
*condition
,
1436 struct lttng_dynamic_pointer_array
*bytecode_set
)
1438 enum lttng_error_code ret
;
1439 enum lttng_condition_status status
;
1440 unsigned int capture_count
;
1441 const struct lttng_condition_event_rule_capture_bytecode_element
*set_element
;
1442 struct lttng_capture_descriptor
*local_capture_desc
;
1444 struct lttng_condition_event_rule_capture_bytecode_element
*set_element_to_append
=
1446 struct lttng_bytecode
*bytecode
= NULL
;
1448 if (!condition
|| !IS_EVENT_RULE_CONDITION(condition
) ||
1450 ret
= LTTNG_ERR_FATAL
;
1454 status
= lttng_condition_event_rule_get_capture_descriptor_count(
1455 condition
, &capture_count
);
1456 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
1457 ret
= LTTNG_ERR_FATAL
;
1462 * O(n^2), don't care. This code path is not hot.
1463 * Before inserting into the set, validate that the expression is not
1464 * already present in it.
1466 for (unsigned int i
= 0; i
< capture_count
; i
++) {
1467 int found_in_set
= false;
1469 set_count
= lttng_dynamic_pointer_array_get_count(bytecode_set
);
1471 local_capture_desc
=
1472 lttng_condition_event_rule_get_internal_capture_descriptor_at_index(
1474 if (local_capture_desc
== NULL
) {
1475 ret
= LTTNG_ERR_FATAL
;
1480 * Iterate over the set to check if already present in the set.
1482 for (ssize_t j
= 0; j
< set_count
; j
++) {
1483 set_element
= (struct lttng_condition_event_rule_capture_bytecode_element
1485 lttng_dynamic_pointer_array_get_pointer(
1487 if (set_element
== NULL
) {
1488 ret
= LTTNG_ERR_FATAL
;
1492 if (!lttng_event_expr_is_equal(
1493 local_capture_desc
->event_expression
,
1494 set_element
->expression
)) {
1495 /* Check against next set element */
1500 * Already present in the set, assign the
1501 * capture index of the capture descriptor for
1504 found_in_set
= true;
1505 local_capture_desc
->capture_index
= j
;
1506 /* Exit inner loop */
1511 /* Process next local capture descriptor */
1516 * Not found in the set.
1517 * Insert the capture descriptor in the set.
1519 set_element_to_append
= malloc(sizeof(*set_element_to_append
));
1520 if (set_element_to_append
== NULL
) {
1521 ret
= LTTNG_ERR_NOMEM
;
1525 /* Generate the bytecode */
1526 status
= lttng_event_expr_to_bytecode(
1527 local_capture_desc
->event_expression
,
1529 if (status
< 0 || bytecode
== NULL
) {
1530 /* TODO: return pertinent capture related error code */
1531 ret
= LTTNG_ERR_FILTER_INVAL
;
1535 set_element_to_append
->bytecode
= bytecode
;
1538 * Ensure the lifetime of the event expression.
1539 * Our reference will be put on condition destroy.
1541 lttng_event_expr_get(local_capture_desc
->event_expression
);
1542 set_element_to_append
->expression
=
1543 local_capture_desc
->event_expression
;
1545 ret
= lttng_dynamic_pointer_array_add_pointer(
1546 bytecode_set
, set_element_to_append
);
1548 ret
= LTTNG_ERR_NOMEM
;
1552 /* Ownership tranfered to the bytecode set */
1553 set_element_to_append
= NULL
;
1556 /* Assign the capture descriptor for future use */
1557 local_capture_desc
->capture_index
= set_count
;
1560 /* Everything went better than expected */
1564 free(set_element_to_append
);