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 typedef LTTNG_OPTIONAL(uint64_t) optional_uint64
;
32 static bool is_on_event_evaluation(const struct lttng_evaluation
*evaluation
)
34 enum lttng_condition_type type
= lttng_evaluation_get_type(evaluation
);
36 return type
== LTTNG_CONDITION_TYPE_ON_EVENT
;
39 static bool lttng_condition_on_event_validate(
40 const struct lttng_condition
*condition
);
41 static int lttng_condition_on_event_serialize(
42 const struct lttng_condition
*condition
,
43 struct lttng_payload
*payload
);
44 static bool lttng_condition_on_event_is_equal(
45 const struct lttng_condition
*_a
,
46 const struct lttng_condition
*_b
);
47 static void lttng_condition_on_event_destroy(
48 struct lttng_condition
*condition
);
50 static bool lttng_condition_on_event_validate(
51 const struct lttng_condition
*condition
)
54 struct lttng_condition_on_event
*event_rule
;
60 event_rule
= container_of(
61 condition
, struct lttng_condition_on_event
, parent
);
62 if (!event_rule
->rule
) {
63 ERR("Invalid on event condition: a rule must be set");
67 valid
= lttng_event_rule_validate(event_rule
->rule
);
72 static const char *msgpack_object_type_str(msgpack_object_type type
)
77 case MSGPACK_OBJECT_NIL
:
78 name
= "MSGPACK_OBJECT_NIL";
80 case MSGPACK_OBJECT_BOOLEAN
:
81 name
= "MSGPACK_OBJECT_BOOLEAN";
83 case MSGPACK_OBJECT_POSITIVE_INTEGER
:
84 name
= "MSGPACK_OBJECT_POSITIVE_INTEGER";
86 case MSGPACK_OBJECT_NEGATIVE_INTEGER
:
87 name
= "MSGPACK_OBJECT_NEGATIVE_INTEGER";
89 case MSGPACK_OBJECT_FLOAT32
:
90 name
= "MSGPACK_OBJECT_FLOAT32";
92 case MSGPACK_OBJECT_FLOAT
:
93 /* Same value as MSGPACK_OBJECT_FLOAT64 */
94 name
= "MSGPACK_OBJECT_FLOAT(64)";
96 case MSGPACK_OBJECT_STR
:
97 name
= "MSGPACK_OBJECT_STR";
99 case MSGPACK_OBJECT_ARRAY
:
100 name
= "MSGPACK_OBJECT_ARRAY";
102 case MSGPACK_OBJECT_MAP
:
103 name
= "MSGPACK_OBJECT_MAP";
105 case MSGPACK_OBJECT_BIN
:
106 name
= "MSGPACK_OBJECT_BIN";
108 case MSGPACK_OBJECT_EXT
:
109 name
= "MSGPACK_OBJECT_EXT";
119 * Serializes the C string `str` into `buf`.
121 * Encoding is the length of `str` plus one (for the null character),
122 * and then the string, including its null terminator.
125 int serialize_cstr(const char *str
, struct lttng_dynamic_buffer
*buf
)
128 const uint32_t len
= strlen(str
) + 1;
130 /* Serialize the length, including the null terminator. */
131 DBG("Serializing C string's length (including null terminator): "
133 ret
= lttng_dynamic_buffer_append(buf
, &len
, sizeof(len
));
138 /* Serialize the string. */
139 DBG("Serializing C string: '%s'", str
);
140 ret
= lttng_dynamic_buffer_append(buf
, str
, len
);
150 * Serializes the event expression `expr` into `buf`.
153 int serialize_event_expr(const struct lttng_event_expr
*expr
,
154 struct lttng_payload
*payload
)
156 const uint8_t type
= expr
->type
;
159 /* Serialize the expression's type. */
160 DBG("Serializing event expression's type: %d", expr
->type
);
161 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, &type
, sizeof(type
));
166 /* Serialize the expression */
167 switch (expr
->type
) {
168 case LTTNG_EVENT_EXPR_TYPE_EVENT_PAYLOAD_FIELD
:
169 case LTTNG_EVENT_EXPR_TYPE_CHANNEL_CONTEXT_FIELD
:
171 const struct lttng_event_expr_field
*field_expr
=
173 const struct lttng_event_expr_field
,
176 /* Serialize the field name. */
177 DBG("Serializing field event expression's field name: '%s'",
179 ret
= serialize_cstr(field_expr
->name
, &payload
->buffer
);
186 case LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD
:
188 const struct lttng_event_expr_app_specific_context_field
*field_expr
=
190 const struct lttng_event_expr_app_specific_context_field
,
193 /* Serialize the provider name. */
194 DBG("Serializing app-specific context field event expression's "
195 "provider name: '%s'",
196 field_expr
->provider_name
);
197 ret
= serialize_cstr(field_expr
->provider_name
, &payload
->buffer
);
202 /* Serialize the type name. */
203 DBG("Serializing app-specific context field event expression's "
205 field_expr
->provider_name
);
206 ret
= serialize_cstr(field_expr
->type_name
, &payload
->buffer
);
213 case LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT
:
215 const struct lttng_event_expr_array_field_element
*elem_expr
=
217 const struct lttng_event_expr_array_field_element
,
219 const uint32_t index
= elem_expr
->index
;
221 /* Serialize the index. */
222 DBG("Serializing array field element event expression's "
223 "index: %u", elem_expr
->index
);
224 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, &index
, sizeof(index
));
229 /* Serialize the parent array field expression. */
230 DBG("Serializing array field element event expression's "
231 "parent array field event expression");
232 ret
= serialize_event_expr(elem_expr
->array_field_expr
, payload
);
248 struct lttng_capture_descriptor
*
249 lttng_condition_on_event_get_internal_capture_descriptor_at_index(
250 const struct lttng_condition
*condition
, unsigned int index
)
252 const struct lttng_condition_on_event
*on_event_cond
=
253 container_of(condition
,
254 const struct lttng_condition_on_event
,
256 struct lttng_capture_descriptor
*desc
= NULL
;
258 enum lttng_condition_status status
;
260 if (!condition
|| !IS_ON_EVENT_CONDITION(condition
)) {
264 status
= lttng_condition_on_event_get_capture_descriptor_count(
266 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
270 if (index
>= count
) {
274 desc
= lttng_dynamic_pointer_array_get_pointer(
275 &on_event_cond
->capture_descriptors
, index
);
280 static int lttng_condition_on_event_serialize(
281 const struct lttng_condition
*condition
,
282 struct lttng_payload
*payload
)
285 struct lttng_condition_on_event
*on_event_condition
;
286 enum lttng_condition_status status
;
287 /* Used for iteration and communication (size matters). */
288 uint32_t i
, capture_descr_count
;
289 LTTNG_OPTIONAL_COMM(typeof(on_event_condition
->error_count
.value
)) error_count_comm
;
291 if (!condition
|| !IS_ON_EVENT_CONDITION(condition
)) {
296 DBG("Serializing on event condition");
297 on_event_condition
= container_of(
298 condition
, struct lttng_condition_on_event
, parent
);
300 DBG("Serializing on event condition's event rule");
301 ret
= lttng_event_rule_serialize(on_event_condition
->rule
, payload
);
306 error_count_comm
= (typeof(error_count_comm
)) {
307 .is_set
= on_event_condition
->error_count
.is_set
,
308 .value
= on_event_condition
->error_count
.value
,
312 char error_count_value_str
[MAX_INT_DEC_LEN(on_event_condition
->error_count
.value
)];
313 const int fmt_ret
= snprintf(error_count_value_str
,
314 sizeof(error_count_value_str
), "%" PRIu64
,
315 on_event_condition
->error_count
.value
);
318 DBG("Serializing event rule condition's error count: value = %s",
319 on_event_condition
->error_count
.is_set
?
320 error_count_value_str
:
324 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, &error_count_comm
,
325 sizeof(error_count_comm
));
330 status
= lttng_condition_on_event_get_capture_descriptor_count(
331 condition
, &capture_descr_count
);
332 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
337 DBG("Serializing on event condition's capture descriptor count: %" PRIu32
,
338 capture_descr_count
);
339 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, &capture_descr_count
,
340 sizeof(capture_descr_count
));
345 for (i
= 0; i
< capture_descr_count
; i
++) {
346 const struct lttng_capture_descriptor
*desc
=
347 lttng_condition_on_event_get_internal_capture_descriptor_at_index(
350 DBG("Serializing on event condition's capture descriptor %" PRIu32
,
352 ret
= serialize_event_expr(desc
->event_expression
, payload
);
363 bool capture_descriptors_are_equal(
364 const struct lttng_condition
*condition_a
,
365 const struct lttng_condition
*condition_b
)
367 bool is_equal
= true;
368 unsigned int capture_descr_count_a
;
369 unsigned int capture_descr_count_b
;
371 enum lttng_condition_status status
;
373 status
= lttng_condition_on_event_get_capture_descriptor_count(
374 condition_a
, &capture_descr_count_a
);
375 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
379 status
= lttng_condition_on_event_get_capture_descriptor_count(
380 condition_b
, &capture_descr_count_b
);
381 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
385 if (capture_descr_count_a
!= capture_descr_count_b
) {
389 for (i
= 0; i
< capture_descr_count_a
; i
++) {
390 const struct lttng_event_expr
*expr_a
=
391 lttng_condition_on_event_get_capture_descriptor_at_index(
394 const struct lttng_event_expr
*expr_b
=
395 lttng_condition_on_event_get_capture_descriptor_at_index(
399 if (!lttng_event_expr_is_equal(expr_a
, expr_b
)) {
413 static bool lttng_condition_on_event_is_equal(
414 const struct lttng_condition
*_a
,
415 const struct lttng_condition
*_b
)
417 bool is_equal
= false;
418 struct lttng_condition_on_event
*a
, *b
;
420 a
= container_of(_a
, struct lttng_condition_on_event
, parent
);
421 b
= container_of(_b
, struct lttng_condition_on_event
, parent
);
423 /* Both event rules must be set or both must be unset. */
424 if ((a
->rule
&& !b
->rule
) || (!a
->rule
&& b
->rule
)) {
425 WARN("Comparing event_rule conditions with uninitialized rule");
429 is_equal
= lttng_event_rule_is_equal(a
->rule
, b
->rule
);
434 is_equal
= capture_descriptors_are_equal(_a
, _b
);
440 static void lttng_condition_on_event_destroy(
441 struct lttng_condition
*condition
)
443 struct lttng_condition_on_event
*on_event_condition
;
445 on_event_condition
= container_of(
446 condition
, struct lttng_condition_on_event
, parent
);
448 lttng_event_rule_put(on_event_condition
->rule
);
449 lttng_dynamic_pointer_array_reset(&on_event_condition
->capture_descriptors
);
450 free(on_event_condition
);
454 void destroy_capture_descriptor(void *ptr
)
456 struct lttng_capture_descriptor
*desc
=
457 (struct lttng_capture_descriptor
*) ptr
;
459 lttng_event_expr_destroy(desc
->event_expression
);
460 free(desc
->bytecode
);
464 struct lttng_condition
*lttng_condition_on_event_create(
465 struct lttng_event_rule
*rule
)
467 struct lttng_condition
*parent
= NULL
;
468 struct lttng_condition_on_event
*condition
= NULL
;
474 condition
= zmalloc(sizeof(struct lttng_condition_on_event
));
479 lttng_condition_init(&condition
->parent
,
480 LTTNG_CONDITION_TYPE_ON_EVENT
);
481 condition
->parent
.validate
= lttng_condition_on_event_validate
,
482 condition
->parent
.serialize
= lttng_condition_on_event_serialize
,
483 condition
->parent
.equal
= lttng_condition_on_event_is_equal
,
484 condition
->parent
.destroy
= lttng_condition_on_event_destroy
,
486 lttng_event_rule_get(rule
);
487 condition
->rule
= rule
;
490 lttng_dynamic_pointer_array_init(&condition
->capture_descriptors
,
491 destroy_capture_descriptor
);
493 parent
= &condition
->parent
;
499 uint64_t uint_from_buffer(const struct lttng_buffer_view
*view
, size_t size
,
503 const struct lttng_buffer_view uint_view
=
504 lttng_buffer_view_from_view(view
, *offset
, size
);
506 if (!lttng_buffer_view_is_valid(&uint_view
)) {
513 ret
= (uint64_t) *uint_view
.data
;
515 case sizeof(uint32_t):
519 memcpy(&u32
, uint_view
.data
, sizeof(u32
));
520 ret
= (uint64_t) u32
;
524 memcpy(&ret
, uint_view
.data
, sizeof(ret
));
537 int optional_uint_from_buffer(
538 const struct lttng_buffer_view
*view
,
539 size_t inner_value_size
,
541 optional_uint64
*value
)
546 * Those cases are identical except for the optional's inner type width.
548 switch (inner_value_size
) {
549 case sizeof(uint8_t):
551 LTTNG_OPTIONAL_COMM(uint8_t) *value_comm
;
552 const struct lttng_buffer_view optional_uint_view
=
553 lttng_buffer_view_from_view(view
, *offset
,
554 sizeof(*value_comm
));
556 if (!lttng_buffer_view_is_valid(&optional_uint_view
)) {
561 value_comm
= (typeof(value_comm
)) optional_uint_view
.data
;
562 *value
= (typeof(*value
)) {
563 .is_set
= value_comm
->is_set
,
564 .value
= (uint64_t) value_comm
->value
,
567 *offset
+= sizeof(*value_comm
);
570 case sizeof(uint16_t):
572 LTTNG_OPTIONAL_COMM(uint16_t) *value_comm
;
573 const struct lttng_buffer_view optional_uint_view
=
574 lttng_buffer_view_from_view(view
, *offset
,
575 sizeof(*value_comm
));
577 if (!lttng_buffer_view_is_valid(&optional_uint_view
)) {
582 value_comm
= (typeof(value_comm
)) optional_uint_view
.data
;
583 *value
= (typeof(*value
)) {
584 .is_set
= value_comm
->is_set
,
585 .value
= (uint64_t) value_comm
->value
,
588 *offset
+= sizeof(*value_comm
);
591 case sizeof(uint32_t):
593 LTTNG_OPTIONAL_COMM(uint32_t) *value_comm
;
594 const struct lttng_buffer_view optional_uint_view
=
595 lttng_buffer_view_from_view(view
, *offset
,
596 sizeof(*value_comm
));
598 if (!lttng_buffer_view_is_valid(&optional_uint_view
)) {
603 value_comm
= (typeof(value_comm
)) optional_uint_view
.data
;
604 *value
= (typeof(*value
)) {
605 .is_set
= value_comm
->is_set
,
606 .value
= (uint64_t) value_comm
->value
,
609 *offset
+= sizeof(*value_comm
);
612 case sizeof(uint64_t):
614 LTTNG_OPTIONAL_COMM(uint64_t) *value_comm
;
615 const struct lttng_buffer_view optional_uint_view
=
616 lttng_buffer_view_from_view(view
, *offset
,
617 sizeof(*value_comm
));
619 if (!lttng_buffer_view_is_valid(&optional_uint_view
)) {
624 value_comm
= (typeof(value_comm
)) optional_uint_view
.data
;
625 *value
= (typeof(*value
)) {
626 .is_set
= value_comm
->is_set
,
627 .value
= (uint64_t) value_comm
->value
,
630 *offset
+= sizeof(*value_comm
);
643 const char *str_from_buffer(const struct lttng_buffer_view
*view
,
649 len
= uint_from_buffer(view
, sizeof(uint32_t), offset
);
650 if (len
== UINT64_C(-1)) {
654 ret
= &view
->data
[*offset
];
656 if (!lttng_buffer_view_contains_string(view
, ret
, len
)) {
671 struct lttng_event_expr
*event_expr_from_payload(
672 struct lttng_payload_view
*view
, size_t *offset
)
674 struct lttng_event_expr
*expr
= NULL
;
678 type
= uint_from_buffer(&view
->buffer
, sizeof(uint8_t), offset
);
679 if (type
== UINT64_C(-1)) {
684 case LTTNG_EVENT_EXPR_TYPE_EVENT_PAYLOAD_FIELD
:
685 str
= str_from_buffer(&view
->buffer
, offset
);
690 expr
= lttng_event_expr_event_payload_field_create(str
);
692 case LTTNG_EVENT_EXPR_TYPE_CHANNEL_CONTEXT_FIELD
:
693 str
= str_from_buffer(&view
->buffer
, offset
);
698 expr
= lttng_event_expr_channel_context_field_create(str
);
700 case LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD
:
702 const char *provider_name
;
703 const char *type_name
;
705 provider_name
= str_from_buffer(&view
->buffer
, offset
);
706 if (!provider_name
) {
710 type_name
= str_from_buffer(&view
->buffer
, offset
);
715 expr
= lttng_event_expr_app_specific_context_field_create(
716 provider_name
, type_name
);
719 case LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT
:
721 struct lttng_event_expr
*array_field_expr
;
722 const uint64_t index
= uint_from_buffer(
723 &view
->buffer
, sizeof(uint32_t), offset
);
725 if (index
== UINT64_C(-1)) {
729 /* Array field expression is the encoded after this. */
730 array_field_expr
= event_expr_from_payload(view
, offset
);
731 if (!array_field_expr
) {
735 /* Move ownership of `array_field_expr` to new expression. */
736 expr
= lttng_event_expr_array_field_element_create(
737 array_field_expr
, (unsigned int) index
);
739 /* `array_field_expr` not moved: destroy it. */
740 lttng_event_expr_destroy(array_field_expr
);
752 lttng_event_expr_destroy(expr
);
760 ssize_t
lttng_condition_on_event_create_from_payload(
761 struct lttng_payload_view
*view
,
762 struct lttng_condition
**_condition
)
765 ssize_t consumed_length
;
767 ssize_t event_rule_length
;
768 uint32_t i
, capture_descr_count
;
769 optional_uint64 error_count
;
770 struct lttng_condition
*condition
= NULL
;
771 struct lttng_event_rule
*event_rule
= NULL
;
773 if (!view
|| !_condition
) {
777 /* Struct lttng_event_rule. */
779 struct lttng_payload_view event_rule_view
=
780 lttng_payload_view_from_view(view
, offset
, -1);
782 event_rule_length
= lttng_event_rule_create_from_payload(
783 &event_rule_view
, &event_rule
);
786 if (event_rule_length
< 0 || !event_rule
) {
790 offset
+= event_rule_length
;
793 optional_ret
= optional_uint_from_buffer(&view
->buffer
,
794 sizeof(error_count
.value
), &offset
,
800 /* Create condition (no capture descriptors yet) at this point */
801 condition
= lttng_condition_on_event_create(event_rule
);
806 if (error_count
.is_set
) {
807 lttng_condition_on_event_set_error_count(
808 condition
, error_count
.value
);
811 /* Capture descriptor count. */
812 assert(event_rule_length
>= 0);
813 capture_descr_count
= uint_from_buffer(&view
->buffer
, sizeof(uint32_t), &offset
);
814 if (capture_descr_count
== UINT32_C(-1)) {
818 /* Capture descriptors. */
819 for (i
= 0; i
< capture_descr_count
; i
++) {
820 enum lttng_condition_status status
;
821 struct lttng_event_expr
*expr
= event_expr_from_payload(
828 /* Move ownership of `expr` to `condition`. */
829 status
= lttng_condition_on_event_append_capture_descriptor(
831 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
832 /* `expr` not moved: destroy it. */
833 lttng_event_expr_destroy(expr
);
838 consumed_length
= (ssize_t
) offset
;
839 *_condition
= condition
;
844 consumed_length
= -1;
847 lttng_event_rule_put(event_rule
);
848 lttng_condition_put(condition
);
849 return consumed_length
;
853 enum lttng_condition_status
lttng_condition_on_event_borrow_rule_mutable(
854 const struct lttng_condition
*condition
,
855 struct lttng_event_rule
**rule
)
857 struct lttng_condition_on_event
*event_rule
;
858 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
860 if (!condition
|| !IS_ON_EVENT_CONDITION(condition
) || !rule
) {
861 status
= LTTNG_CONDITION_STATUS_INVALID
;
865 event_rule
= container_of(
866 condition
, struct lttng_condition_on_event
, parent
);
867 if (!event_rule
->rule
) {
868 status
= LTTNG_CONDITION_STATUS_UNSET
;
872 *rule
= event_rule
->rule
;
877 enum lttng_condition_status
lttng_condition_on_event_get_rule(
878 const struct lttng_condition
*condition
,
879 const struct lttng_event_rule
**rule
)
881 struct lttng_event_rule
*mutable_rule
= NULL
;
882 const enum lttng_condition_status status
=
883 lttng_condition_on_event_borrow_rule_mutable(
884 condition
, &mutable_rule
);
886 *rule
= mutable_rule
;
891 void lttng_condition_on_event_set_error_counter_index(
892 struct lttng_condition
*condition
, uint64_t error_counter_index
)
894 struct lttng_condition_on_event
*on_event_cond
=
895 container_of(condition
,
896 struct lttng_condition_on_event
, parent
);
898 LTTNG_OPTIONAL_SET(&on_event_cond
->error_counter_index
, error_counter_index
);
902 uint64_t lttng_condition_on_event_get_error_counter_index(
903 const struct lttng_condition
*condition
)
905 const struct lttng_condition_on_event
*on_event_cond
=
906 container_of(condition
,
907 const struct lttng_condition_on_event
, parent
);
909 return LTTNG_OPTIONAL_GET(on_event_cond
->error_counter_index
);
913 void lttng_condition_on_event_set_error_count(struct lttng_condition
*condition
,
914 uint64_t error_count
)
916 struct lttng_condition_on_event
*on_event_cond
=
917 container_of(condition
,
918 struct lttng_condition_on_event
, parent
);
920 LTTNG_OPTIONAL_SET(&on_event_cond
->error_count
, error_count
);
923 uint64_t lttng_condition_on_event_get_error_count(
924 const struct lttng_condition
*condition
)
926 const struct lttng_condition_on_event
*on_event_cond
=
927 container_of(condition
,
928 const struct lttng_condition_on_event
, parent
);
930 return LTTNG_OPTIONAL_GET(on_event_cond
->error_count
);
933 enum lttng_condition_status
934 lttng_condition_on_event_append_capture_descriptor(
935 struct lttng_condition
*condition
,
936 struct lttng_event_expr
*expr
)
939 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
940 struct lttng_condition_on_event
*on_event_cond
=
941 container_of(condition
,
942 struct lttng_condition_on_event
, parent
);
943 struct lttng_capture_descriptor
*descriptor
= NULL
;
944 const struct lttng_event_rule
*rule
= NULL
;
946 /* Only accept l-values. */
947 if (!condition
|| !IS_ON_EVENT_CONDITION(condition
) || !expr
||
948 !lttng_event_expr_is_lvalue(expr
)) {
949 status
= LTTNG_CONDITION_STATUS_INVALID
;
953 status
= lttng_condition_on_event_get_rule(condition
, &rule
);
954 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
958 switch(lttng_event_rule_get_type(rule
)) {
959 case LTTNG_EVENT_RULE_TYPE_TRACEPOINT
:
960 case LTTNG_EVENT_RULE_TYPE_SYSCALL
:
962 status
= LTTNG_CONDITION_STATUS_OK
;
964 case LTTNG_EVENT_RULE_TYPE_UNKNOWN
:
965 status
= LTTNG_CONDITION_STATUS_INVALID
;
968 status
= LTTNG_CONDITION_STATUS_UNSUPPORTED
;
972 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
976 descriptor
= malloc(sizeof(*descriptor
));
977 if (descriptor
== NULL
) {
978 status
= LTTNG_CONDITION_STATUS_ERROR
;
982 descriptor
->event_expression
= expr
;
983 descriptor
->bytecode
= NULL
;
985 ret
= lttng_dynamic_pointer_array_add_pointer(
986 &on_event_cond
->capture_descriptors
, descriptor
);
988 status
= LTTNG_CONDITION_STATUS_ERROR
;
992 /* Ownership is transfered to the internal capture_descriptors array */
999 enum lttng_condition_status
1000 lttng_condition_on_event_get_capture_descriptor_count(
1001 const struct lttng_condition
*condition
, unsigned int *count
)
1003 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
1004 const struct lttng_condition_on_event
*on_event_condition
=
1005 container_of(condition
,
1006 const struct lttng_condition_on_event
,
1009 if (!condition
|| !IS_ON_EVENT_CONDITION(condition
) || !count
) {
1010 status
= LTTNG_CONDITION_STATUS_INVALID
;
1014 *count
= lttng_dynamic_pointer_array_get_count(
1015 &on_event_condition
->capture_descriptors
);
1021 const struct lttng_event_expr
*
1022 lttng_condition_on_event_get_capture_descriptor_at_index(
1023 const struct lttng_condition
*condition
, unsigned int index
)
1025 const struct lttng_event_expr
*expr
= NULL
;
1026 const struct lttng_capture_descriptor
*desc
= NULL
;
1028 desc
= lttng_condition_on_event_get_internal_capture_descriptor_at_index(
1033 expr
= desc
->event_expression
;
1040 ssize_t
lttng_evaluation_on_event_create_from_payload(
1041 const struct lttng_condition_on_event
*condition
,
1042 struct lttng_payload_view
*view
,
1043 struct lttng_evaluation
**_evaluation
)
1045 ssize_t ret
, offset
= 0;
1046 const char *trigger_name
;
1047 struct lttng_evaluation
*evaluation
= NULL
;
1048 const struct lttng_evaluation_on_event_comm
*header
;
1049 const struct lttng_payload_view header_view
=
1050 lttng_payload_view_from_view(
1051 view
, 0, sizeof(*header
));
1052 uint32_t capture_payload_size
;
1053 const char *capture_payload
= NULL
;
1060 if (!lttng_payload_view_is_valid(&header_view
)) {
1061 ERR("Failed to initialize from malformed event rule evaluation: buffer too short to contain header");
1066 header
= (typeof(header
)) header_view
.buffer
.data
;
1068 /* Map the originating trigger's name. */
1069 offset
+= sizeof(*header
);
1071 const struct lttng_payload_view current_view
=
1072 lttng_payload_view_from_view(view
, offset
,
1073 header
->trigger_name_length
);
1075 if (!lttng_payload_view_is_valid(¤t_view
)) {
1076 ERR("Failed to initialize from malformed event rule evaluation: buffer too short to contain trigger name");
1081 trigger_name
= current_view
.buffer
.data
;
1082 if (!lttng_buffer_view_contains_string(¤t_view
.buffer
,
1083 trigger_name
, header
->trigger_name_length
)) {
1084 ERR("Failed to initialize from malformed event rule evaluation: invalid trigger name");
1090 offset
+= header
->trigger_name_length
;
1092 const struct lttng_payload_view current_view
=
1093 lttng_payload_view_from_view(view
, offset
, -1);
1095 if (current_view
.buffer
.size
< sizeof(capture_payload_size
)) {
1100 memcpy(&capture_payload_size
, current_view
.buffer
.data
,
1101 sizeof(capture_payload_size
));
1103 offset
+= sizeof(capture_payload_size
);
1105 if (capture_payload_size
> 0) {
1106 const struct lttng_payload_view current_view
=
1107 lttng_payload_view_from_view(view
, offset
, -1);
1109 if (current_view
.buffer
.size
< capture_payload_size
) {
1114 capture_payload
= current_view
.buffer
.data
;
1117 evaluation
= lttng_evaluation_on_event_create(condition
, trigger_name
,
1118 capture_payload
, capture_payload_size
, true);
1124 offset
+= capture_payload_size
;
1125 *_evaluation
= evaluation
;
1130 lttng_evaluation_destroy(evaluation
);
1134 static int lttng_evaluation_on_event_serialize(
1135 const struct lttng_evaluation
*evaluation
,
1136 struct lttng_payload
*payload
)
1139 struct lttng_evaluation_on_event
*hit
;
1140 struct lttng_evaluation_on_event_comm comm
;
1141 uint32_t capture_payload_size
;
1144 evaluation
, struct lttng_evaluation_on_event
, parent
);
1147 comm
.trigger_name_length
= strlen(hit
->name
) + 1;
1149 ret
= lttng_dynamic_buffer_append(
1150 &payload
->buffer
, &comm
, sizeof(comm
));
1155 ret
= lttng_dynamic_buffer_append(
1156 &payload
->buffer
, hit
->name
, comm
.trigger_name_length
);
1161 capture_payload_size
= (uint32_t) hit
->capture_payload
.size
;
1162 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, &capture_payload_size
,
1163 sizeof(capture_payload_size
));
1168 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, hit
->capture_payload
.data
,
1169 hit
->capture_payload
.size
);
1179 bool msgpack_str_is_equal(const struct msgpack_object
*obj
, const char *str
)
1181 bool is_equal
= true;
1183 assert(obj
->type
== MSGPACK_OBJECT_STR
);
1185 if (obj
->via
.str
.size
!= strlen(str
)) {
1190 if (strncmp(obj
->via
.str
.ptr
, str
, obj
->via
.str
.size
) != 0) {
1200 const msgpack_object
*get_msgpack_map_obj(const struct msgpack_object
*map_obj
,
1203 const msgpack_object
*ret
= NULL
;
1206 assert(map_obj
->type
== MSGPACK_OBJECT_MAP
);
1208 for (i
= 0; i
< map_obj
->via
.map
.size
; i
++) {
1209 const struct msgpack_object_kv
*kv
= &map_obj
->via
.map
.ptr
[i
];
1211 assert(kv
->key
.type
== MSGPACK_OBJECT_STR
);
1213 if (msgpack_str_is_equal(&kv
->key
, name
)) {
1223 static void lttng_evaluation_on_event_destroy(
1224 struct lttng_evaluation
*evaluation
)
1226 struct lttng_evaluation_on_event
*hit
;
1229 evaluation
, struct lttng_evaluation_on_event
, parent
);
1231 lttng_dynamic_buffer_reset(&hit
->capture_payload
);
1232 lttng_event_field_value_destroy(hit
->captured_values
);
1237 int event_field_value_from_obj(const msgpack_object
*obj
,
1238 struct lttng_event_field_value
**field_val
)
1245 switch (obj
->type
) {
1246 case MSGPACK_OBJECT_NIL
:
1250 case MSGPACK_OBJECT_POSITIVE_INTEGER
:
1251 *field_val
= lttng_event_field_value_uint_create(
1254 case MSGPACK_OBJECT_NEGATIVE_INTEGER
:
1255 *field_val
= lttng_event_field_value_int_create(
1258 case MSGPACK_OBJECT_FLOAT32
:
1259 case MSGPACK_OBJECT_FLOAT64
:
1260 *field_val
= lttng_event_field_value_real_create(
1263 case MSGPACK_OBJECT_STR
:
1264 *field_val
= lttng_event_field_value_string_create_with_size(
1265 obj
->via
.str
.ptr
, obj
->via
.str
.size
);
1267 case MSGPACK_OBJECT_ARRAY
:
1271 *field_val
= lttng_event_field_value_array_create();
1276 for (i
= 0; i
< obj
->via
.array
.size
; i
++) {
1277 const msgpack_object
*elem_obj
= &obj
->via
.array
.ptr
[i
];
1278 struct lttng_event_field_value
*elem_field_val
;
1280 ret
= event_field_value_from_obj(elem_obj
,
1286 if (elem_field_val
) {
1287 ret
= lttng_event_field_value_array_append(
1288 *field_val
, elem_field_val
);
1290 ret
= lttng_event_field_value_array_append_unavailable(
1295 lttng_event_field_value_destroy(elem_field_val
);
1302 case MSGPACK_OBJECT_MAP
:
1305 * As of this version, the only valid map object is
1306 * for an enumeration value, for example:
1313 * - Carling Black Label
1315 const msgpack_object
*inner_obj
;
1318 inner_obj
= get_msgpack_map_obj(obj
, "type");
1320 ERR("Missing `type` entry in map object");
1324 if (inner_obj
->type
!= MSGPACK_OBJECT_STR
) {
1325 ERR("Map object's `type` entry is not a string: type = %s",
1326 msgpack_object_type_str(inner_obj
->type
));
1330 if (!msgpack_str_is_equal(inner_obj
, "enum")) {
1331 ERR("Map object's `type` entry: expecting `enum`");
1335 inner_obj
= get_msgpack_map_obj(obj
, "value");
1337 ERR("Missing `value` entry in map object");
1341 if (inner_obj
->type
== MSGPACK_OBJECT_POSITIVE_INTEGER
) {
1342 *field_val
= lttng_event_field_value_enum_uint_create(
1343 inner_obj
->via
.u64
);
1344 } else if (inner_obj
->type
== MSGPACK_OBJECT_NEGATIVE_INTEGER
) {
1345 *field_val
= lttng_event_field_value_enum_int_create(
1346 inner_obj
->via
.i64
);
1348 ERR("Map object's `value` entry is not an integer: type = %s",
1349 msgpack_object_type_str(inner_obj
->type
));
1357 inner_obj
= get_msgpack_map_obj(obj
, "labels");
1363 if (inner_obj
->type
!= MSGPACK_OBJECT_ARRAY
) {
1364 ERR("Map object's `labels` entry is not an array: type = %s",
1365 msgpack_object_type_str(inner_obj
->type
));
1369 for (label_i
= 0; label_i
< inner_obj
->via
.array
.size
;
1372 const msgpack_object
*elem_obj
=
1373 &inner_obj
->via
.array
.ptr
[label_i
];
1375 if (elem_obj
->type
!= MSGPACK_OBJECT_STR
) {
1376 ERR("Map object's `labels` entry's type is not a string: type = %s",
1377 msgpack_object_type_str(elem_obj
->type
));
1381 iret
= lttng_event_field_value_enum_append_label_with_size(
1382 *field_val
, elem_obj
->via
.str
.ptr
,
1383 elem_obj
->via
.str
.size
);
1392 ERR("Unexpected object type: type = %s",
1393 msgpack_object_type_str(obj
->type
));
1404 lttng_event_field_value_destroy(*field_val
);
1413 struct lttng_event_field_value
*event_field_value_from_capture_payload(
1414 const struct lttng_condition_on_event
*condition
,
1415 const char *capture_payload
, size_t capture_payload_size
)
1417 struct lttng_event_field_value
*ret
= NULL
;
1418 msgpack_unpacked unpacked
;
1419 msgpack_unpack_return unpack_return
;
1420 const msgpack_object
*root_obj
;
1421 const msgpack_object_array
*root_array_obj
;
1426 assert(capture_payload
);
1428 /* Initialize value. */
1429 msgpack_unpacked_init(&unpacked
);
1432 unpack_return
= msgpack_unpack_next(&unpacked
, capture_payload
,
1433 capture_payload_size
, NULL
);
1434 if (unpack_return
!= MSGPACK_UNPACK_SUCCESS
) {
1435 ERR("msgpack_unpack_next() failed to decode the "
1436 "MessagePack-encoded capture payload: "
1437 "size = %zu, ret = %d",
1438 capture_payload_size
, unpack_return
);
1442 /* Get root array. */
1443 root_obj
= &unpacked
.data
;
1445 if (root_obj
->type
!= MSGPACK_OBJECT_ARRAY
) {
1446 ERR("Expecting an array as the root object: type = %s",
1447 msgpack_object_type_str(root_obj
->type
));
1451 root_array_obj
= &root_obj
->via
.array
;
1453 /* Create an empty root array event field value. */
1454 ret
= lttng_event_field_value_array_create();
1460 * For each capture descriptor in the condition object:
1462 * 1. Get its corresponding captured field value MessagePack
1465 * 2. Create a corresponding event field value.
1467 * 3. Append it to `ret` (the root array event field value).
1469 count
= lttng_dynamic_pointer_array_get_count(
1470 &condition
->capture_descriptors
);
1473 for (i
= 0; i
< count
; i
++) {
1474 const struct lttng_capture_descriptor
*capture_descriptor
=
1475 lttng_condition_on_event_get_internal_capture_descriptor_at_index(
1476 &condition
->parent
, i
);
1477 const msgpack_object
*elem_obj
;
1478 struct lttng_event_field_value
*elem_field_val
;
1481 assert(capture_descriptor
);
1483 elem_obj
= &root_array_obj
->ptr
[i
];
1484 iret
= event_field_value_from_obj(elem_obj
,
1490 if (elem_field_val
) {
1491 iret
= lttng_event_field_value_array_append(ret
,
1494 iret
= lttng_event_field_value_array_append_unavailable(
1499 lttng_event_field_value_destroy(elem_field_val
);
1507 lttng_event_field_value_destroy(ret
);
1511 msgpack_unpacked_destroy(&unpacked
);
1516 struct lttng_evaluation
*lttng_evaluation_on_event_create(
1517 const struct lttng_condition_on_event
*condition
,
1518 const char *trigger_name
,
1519 const char *capture_payload
, size_t capture_payload_size
,
1520 bool decode_capture_payload
)
1522 struct lttng_evaluation_on_event
*hit
;
1523 struct lttng_evaluation
*evaluation
= NULL
;
1525 hit
= zmalloc(sizeof(struct lttng_evaluation_on_event
));
1530 hit
->name
= strdup(trigger_name
);
1535 lttng_dynamic_buffer_init(&hit
->capture_payload
);
1537 if (capture_payload
) {
1538 const int ret
= lttng_dynamic_buffer_append(
1539 &hit
->capture_payload
, capture_payload
,
1540 capture_payload_size
);
1542 ERR("Failed to initialize capture payload of event rule evaluation");
1546 if (decode_capture_payload
) {
1547 hit
->captured_values
=
1548 event_field_value_from_capture_payload(
1551 capture_payload_size
);
1552 if (!hit
->captured_values
) {
1553 ERR("Failed to decode the capture payload: size = %zu",
1554 capture_payload_size
);
1560 hit
->parent
.type
= LTTNG_CONDITION_TYPE_ON_EVENT
;
1561 hit
->parent
.serialize
= lttng_evaluation_on_event_serialize
;
1562 hit
->parent
.destroy
= lttng_evaluation_on_event_destroy
;
1564 evaluation
= &hit
->parent
;
1569 lttng_evaluation_on_event_destroy(&hit
->parent
);
1575 enum lttng_evaluation_on_event_status
1576 lttng_evaluation_on_event_get_captured_values(
1577 const struct lttng_evaluation
*evaluation
,
1578 const struct lttng_event_field_value
**field_val
)
1580 struct lttng_evaluation_on_event
*hit
;
1581 enum lttng_evaluation_on_event_status status
=
1582 LTTNG_EVALUATION_ON_EVENT_STATUS_OK
;
1584 if (!evaluation
|| !is_on_event_evaluation(evaluation
) ||
1586 status
= LTTNG_EVALUATION_ON_EVENT_STATUS_INVALID
;
1590 hit
= container_of(evaluation
, struct lttng_evaluation_on_event
,
1592 if (!hit
->captured_values
) {
1593 status
= LTTNG_EVALUATION_ON_EVENT_STATUS_NONE
;
1597 *field_val
= hit
->captured_values
;
1603 enum lttng_evaluation_status
lttng_evaluation_on_event_get_trigger_name(
1604 const struct lttng_evaluation
*evaluation
, const char **name
)
1606 struct lttng_evaluation_on_event
*hit
;
1607 enum lttng_evaluation_status status
= LTTNG_EVALUATION_STATUS_OK
;
1609 if (!evaluation
|| !is_on_event_evaluation(evaluation
) || !name
) {
1610 status
= LTTNG_EVALUATION_STATUS_INVALID
;
1615 evaluation
, struct lttng_evaluation_on_event
, parent
);
1622 enum lttng_error_code
1623 lttng_condition_on_event_generate_capture_descriptor_bytecode(
1624 struct lttng_condition
*condition
)
1626 enum lttng_error_code ret
;
1627 enum lttng_condition_status status
;
1628 unsigned int capture_count
, i
;
1630 if (!condition
|| !IS_ON_EVENT_CONDITION(condition
)) {
1631 ret
= LTTNG_ERR_FATAL
;
1635 status
= lttng_condition_on_event_get_capture_descriptor_count(
1636 condition
, &capture_count
);
1637 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
1638 ret
= LTTNG_ERR_FATAL
;
1642 for (i
= 0; i
< capture_count
; i
++) {
1643 struct lttng_capture_descriptor
*local_capture_desc
=
1644 lttng_condition_on_event_get_internal_capture_descriptor_at_index(
1647 if (local_capture_desc
== NULL
) {
1648 ret
= LTTNG_ERR_FATAL
;
1652 /* Generate the bytecode. */
1653 status
= lttng_event_expr_to_bytecode(
1654 local_capture_desc
->event_expression
,
1655 &local_capture_desc
->bytecode
);
1656 if (status
< 0 || local_capture_desc
->bytecode
== NULL
) {
1657 ret
= LTTNG_ERR_INVALID_CAPTURE_EXPRESSION
;
1662 /* Everything went better than expected */
1670 const struct lttng_bytecode
*
1671 lttng_condition_on_event_get_capture_bytecode_at_index(
1672 const struct lttng_condition
*condition
, unsigned int index
)
1674 const struct lttng_condition_on_event
*on_event_cond
=
1675 container_of(condition
,
1676 const struct lttng_condition_on_event
,
1678 struct lttng_capture_descriptor
*desc
= NULL
;
1679 struct lttng_bytecode
*bytecode
= NULL
;
1681 enum lttng_condition_status status
;
1683 if (!condition
|| !IS_ON_EVENT_CONDITION(condition
)) {
1687 status
= lttng_condition_on_event_get_capture_descriptor_count(
1689 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
1693 if (index
>= count
) {
1697 desc
= lttng_dynamic_pointer_array_get_pointer(
1698 &on_event_cond
->capture_descriptors
, index
);
1703 bytecode
= desc
->bytecode
;