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
);
746 ERR("Invalid event expression type encoutered while deserializing event expression: type = %" PRIu64
,
754 lttng_event_expr_destroy(expr
);
762 ssize_t
lttng_condition_on_event_create_from_payload(
763 struct lttng_payload_view
*view
,
764 struct lttng_condition
**_condition
)
767 ssize_t consumed_length
;
769 ssize_t event_rule_length
;
770 uint32_t i
, capture_descr_count
;
771 optional_uint64 error_count
;
772 struct lttng_condition
*condition
= NULL
;
773 struct lttng_event_rule
*event_rule
= NULL
;
775 if (!view
|| !_condition
) {
779 /* Struct lttng_event_rule. */
781 struct lttng_payload_view event_rule_view
=
782 lttng_payload_view_from_view(view
, offset
, -1);
784 event_rule_length
= lttng_event_rule_create_from_payload(
785 &event_rule_view
, &event_rule
);
788 if (event_rule_length
< 0 || !event_rule
) {
792 offset
+= event_rule_length
;
795 optional_ret
= optional_uint_from_buffer(&view
->buffer
,
796 sizeof(error_count
.value
), &offset
,
802 /* Create condition (no capture descriptors yet) at this point */
803 condition
= lttng_condition_on_event_create(event_rule
);
808 if (error_count
.is_set
) {
809 lttng_condition_on_event_set_error_count(
810 condition
, error_count
.value
);
813 /* Capture descriptor count. */
814 assert(event_rule_length
>= 0);
815 capture_descr_count
= uint_from_buffer(&view
->buffer
, sizeof(uint32_t), &offset
);
816 if (capture_descr_count
== UINT32_C(-1)) {
820 /* Capture descriptors. */
821 for (i
= 0; i
< capture_descr_count
; i
++) {
822 enum lttng_condition_status status
;
823 struct lttng_event_expr
*expr
= event_expr_from_payload(
830 /* Move ownership of `expr` to `condition`. */
831 status
= lttng_condition_on_event_append_capture_descriptor(
833 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
834 /* `expr` not moved: destroy it. */
835 lttng_event_expr_destroy(expr
);
840 consumed_length
= (ssize_t
) offset
;
841 *_condition
= condition
;
846 consumed_length
= -1;
849 lttng_event_rule_put(event_rule
);
850 lttng_condition_put(condition
);
851 return consumed_length
;
855 enum lttng_condition_status
lttng_condition_on_event_borrow_rule_mutable(
856 const struct lttng_condition
*condition
,
857 struct lttng_event_rule
**rule
)
859 struct lttng_condition_on_event
*event_rule
;
860 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
862 if (!condition
|| !IS_ON_EVENT_CONDITION(condition
) || !rule
) {
863 status
= LTTNG_CONDITION_STATUS_INVALID
;
867 event_rule
= container_of(
868 condition
, struct lttng_condition_on_event
, parent
);
869 if (!event_rule
->rule
) {
870 status
= LTTNG_CONDITION_STATUS_UNSET
;
874 *rule
= event_rule
->rule
;
879 enum lttng_condition_status
lttng_condition_on_event_get_rule(
880 const struct lttng_condition
*condition
,
881 const struct lttng_event_rule
**rule
)
883 struct lttng_event_rule
*mutable_rule
= NULL
;
884 const enum lttng_condition_status status
=
885 lttng_condition_on_event_borrow_rule_mutable(
886 condition
, &mutable_rule
);
888 *rule
= mutable_rule
;
893 void lttng_condition_on_event_set_error_counter_index(
894 struct lttng_condition
*condition
, uint64_t error_counter_index
)
896 struct lttng_condition_on_event
*on_event_cond
=
897 container_of(condition
,
898 struct lttng_condition_on_event
, parent
);
900 LTTNG_OPTIONAL_SET(&on_event_cond
->error_counter_index
, error_counter_index
);
904 uint64_t lttng_condition_on_event_get_error_counter_index(
905 const struct lttng_condition
*condition
)
907 const struct lttng_condition_on_event
*on_event_cond
=
908 container_of(condition
,
909 const struct lttng_condition_on_event
, parent
);
911 return LTTNG_OPTIONAL_GET(on_event_cond
->error_counter_index
);
915 void lttng_condition_on_event_set_error_count(struct lttng_condition
*condition
,
916 uint64_t error_count
)
918 struct lttng_condition_on_event
*on_event_cond
=
919 container_of(condition
,
920 struct lttng_condition_on_event
, parent
);
922 LTTNG_OPTIONAL_SET(&on_event_cond
->error_count
, error_count
);
925 uint64_t lttng_condition_on_event_get_error_count(
926 const struct lttng_condition
*condition
)
928 const struct lttng_condition_on_event
*on_event_cond
=
929 container_of(condition
,
930 const struct lttng_condition_on_event
, parent
);
932 return LTTNG_OPTIONAL_GET(on_event_cond
->error_count
);
935 enum lttng_condition_status
936 lttng_condition_on_event_append_capture_descriptor(
937 struct lttng_condition
*condition
,
938 struct lttng_event_expr
*expr
)
941 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
942 struct lttng_condition_on_event
*on_event_cond
=
943 container_of(condition
,
944 struct lttng_condition_on_event
, parent
);
945 struct lttng_capture_descriptor
*descriptor
= NULL
;
946 const struct lttng_event_rule
*rule
= NULL
;
948 /* Only accept l-values. */
949 if (!condition
|| !IS_ON_EVENT_CONDITION(condition
) || !expr
||
950 !lttng_event_expr_is_lvalue(expr
)) {
951 status
= LTTNG_CONDITION_STATUS_INVALID
;
955 status
= lttng_condition_on_event_get_rule(condition
, &rule
);
956 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
960 switch(lttng_event_rule_get_type(rule
)) {
961 case LTTNG_EVENT_RULE_TYPE_TRACEPOINT
:
962 case LTTNG_EVENT_RULE_TYPE_SYSCALL
:
964 status
= LTTNG_CONDITION_STATUS_OK
;
966 case LTTNG_EVENT_RULE_TYPE_UNKNOWN
:
967 status
= LTTNG_CONDITION_STATUS_INVALID
;
970 status
= LTTNG_CONDITION_STATUS_UNSUPPORTED
;
974 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
978 descriptor
= malloc(sizeof(*descriptor
));
979 if (descriptor
== NULL
) {
980 status
= LTTNG_CONDITION_STATUS_ERROR
;
984 descriptor
->event_expression
= expr
;
985 descriptor
->bytecode
= NULL
;
987 ret
= lttng_dynamic_pointer_array_add_pointer(
988 &on_event_cond
->capture_descriptors
, descriptor
);
990 status
= LTTNG_CONDITION_STATUS_ERROR
;
994 /* Ownership is transfered to the internal capture_descriptors array */
1001 enum lttng_condition_status
1002 lttng_condition_on_event_get_capture_descriptor_count(
1003 const struct lttng_condition
*condition
, unsigned int *count
)
1005 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
1006 const struct lttng_condition_on_event
*on_event_condition
=
1007 container_of(condition
,
1008 const struct lttng_condition_on_event
,
1011 if (!condition
|| !IS_ON_EVENT_CONDITION(condition
) || !count
) {
1012 status
= LTTNG_CONDITION_STATUS_INVALID
;
1016 *count
= lttng_dynamic_pointer_array_get_count(
1017 &on_event_condition
->capture_descriptors
);
1023 const struct lttng_event_expr
*
1024 lttng_condition_on_event_get_capture_descriptor_at_index(
1025 const struct lttng_condition
*condition
, unsigned int index
)
1027 const struct lttng_event_expr
*expr
= NULL
;
1028 const struct lttng_capture_descriptor
*desc
= NULL
;
1030 desc
= lttng_condition_on_event_get_internal_capture_descriptor_at_index(
1035 expr
= desc
->event_expression
;
1042 ssize_t
lttng_evaluation_on_event_create_from_payload(
1043 const struct lttng_condition_on_event
*condition
,
1044 struct lttng_payload_view
*view
,
1045 struct lttng_evaluation
**_evaluation
)
1047 ssize_t ret
, offset
= 0;
1048 const char *trigger_name
;
1049 struct lttng_evaluation
*evaluation
= NULL
;
1050 const struct lttng_evaluation_on_event_comm
*header
;
1051 const struct lttng_payload_view header_view
=
1052 lttng_payload_view_from_view(
1053 view
, 0, sizeof(*header
));
1054 uint32_t capture_payload_size
;
1055 const char *capture_payload
= NULL
;
1062 if (!lttng_payload_view_is_valid(&header_view
)) {
1063 ERR("Failed to initialize from malformed event rule evaluation: buffer too short to contain header");
1068 header
= (typeof(header
)) header_view
.buffer
.data
;
1070 /* Map the originating trigger's name. */
1071 offset
+= sizeof(*header
);
1073 const struct lttng_payload_view current_view
=
1074 lttng_payload_view_from_view(view
, offset
,
1075 header
->trigger_name_length
);
1077 if (!lttng_payload_view_is_valid(¤t_view
)) {
1078 ERR("Failed to initialize from malformed event rule evaluation: buffer too short to contain trigger name");
1083 trigger_name
= current_view
.buffer
.data
;
1084 if (!lttng_buffer_view_contains_string(¤t_view
.buffer
,
1085 trigger_name
, header
->trigger_name_length
)) {
1086 ERR("Failed to initialize from malformed event rule evaluation: invalid trigger name");
1092 offset
+= header
->trigger_name_length
;
1094 const struct lttng_payload_view current_view
=
1095 lttng_payload_view_from_view(view
, offset
, -1);
1097 if (current_view
.buffer
.size
< sizeof(capture_payload_size
)) {
1102 memcpy(&capture_payload_size
, current_view
.buffer
.data
,
1103 sizeof(capture_payload_size
));
1105 offset
+= sizeof(capture_payload_size
);
1107 if (capture_payload_size
> 0) {
1108 const struct lttng_payload_view current_view
=
1109 lttng_payload_view_from_view(view
, offset
, -1);
1111 if (current_view
.buffer
.size
< capture_payload_size
) {
1116 capture_payload
= current_view
.buffer
.data
;
1119 evaluation
= lttng_evaluation_on_event_create(condition
, trigger_name
,
1120 capture_payload
, capture_payload_size
, true);
1126 offset
+= capture_payload_size
;
1127 *_evaluation
= evaluation
;
1132 lttng_evaluation_destroy(evaluation
);
1136 static int lttng_evaluation_on_event_serialize(
1137 const struct lttng_evaluation
*evaluation
,
1138 struct lttng_payload
*payload
)
1141 struct lttng_evaluation_on_event
*hit
;
1142 struct lttng_evaluation_on_event_comm comm
;
1143 uint32_t capture_payload_size
;
1146 evaluation
, struct lttng_evaluation_on_event
, parent
);
1149 comm
.trigger_name_length
= strlen(hit
->name
) + 1;
1151 ret
= lttng_dynamic_buffer_append(
1152 &payload
->buffer
, &comm
, sizeof(comm
));
1157 ret
= lttng_dynamic_buffer_append(
1158 &payload
->buffer
, hit
->name
, comm
.trigger_name_length
);
1163 capture_payload_size
= (uint32_t) hit
->capture_payload
.size
;
1164 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, &capture_payload_size
,
1165 sizeof(capture_payload_size
));
1170 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, hit
->capture_payload
.data
,
1171 hit
->capture_payload
.size
);
1181 bool msgpack_str_is_equal(const struct msgpack_object
*obj
, const char *str
)
1183 bool is_equal
= true;
1185 assert(obj
->type
== MSGPACK_OBJECT_STR
);
1187 if (obj
->via
.str
.size
!= strlen(str
)) {
1192 if (strncmp(obj
->via
.str
.ptr
, str
, obj
->via
.str
.size
) != 0) {
1202 const msgpack_object
*get_msgpack_map_obj(const struct msgpack_object
*map_obj
,
1205 const msgpack_object
*ret
= NULL
;
1208 assert(map_obj
->type
== MSGPACK_OBJECT_MAP
);
1210 for (i
= 0; i
< map_obj
->via
.map
.size
; i
++) {
1211 const struct msgpack_object_kv
*kv
= &map_obj
->via
.map
.ptr
[i
];
1213 assert(kv
->key
.type
== MSGPACK_OBJECT_STR
);
1215 if (msgpack_str_is_equal(&kv
->key
, name
)) {
1225 static void lttng_evaluation_on_event_destroy(
1226 struct lttng_evaluation
*evaluation
)
1228 struct lttng_evaluation_on_event
*hit
;
1231 evaluation
, struct lttng_evaluation_on_event
, parent
);
1233 lttng_dynamic_buffer_reset(&hit
->capture_payload
);
1234 lttng_event_field_value_destroy(hit
->captured_values
);
1239 int event_field_value_from_obj(const msgpack_object
*obj
,
1240 struct lttng_event_field_value
**field_val
)
1247 switch (obj
->type
) {
1248 case MSGPACK_OBJECT_NIL
:
1252 case MSGPACK_OBJECT_POSITIVE_INTEGER
:
1253 *field_val
= lttng_event_field_value_uint_create(
1256 case MSGPACK_OBJECT_NEGATIVE_INTEGER
:
1257 *field_val
= lttng_event_field_value_int_create(
1260 case MSGPACK_OBJECT_FLOAT32
:
1261 case MSGPACK_OBJECT_FLOAT64
:
1262 *field_val
= lttng_event_field_value_real_create(
1265 case MSGPACK_OBJECT_STR
:
1266 *field_val
= lttng_event_field_value_string_create_with_size(
1267 obj
->via
.str
.ptr
, obj
->via
.str
.size
);
1269 case MSGPACK_OBJECT_ARRAY
:
1273 *field_val
= lttng_event_field_value_array_create();
1278 for (i
= 0; i
< obj
->via
.array
.size
; i
++) {
1279 const msgpack_object
*elem_obj
= &obj
->via
.array
.ptr
[i
];
1280 struct lttng_event_field_value
*elem_field_val
;
1282 ret
= event_field_value_from_obj(elem_obj
,
1288 if (elem_field_val
) {
1289 ret
= lttng_event_field_value_array_append(
1290 *field_val
, elem_field_val
);
1292 ret
= lttng_event_field_value_array_append_unavailable(
1297 lttng_event_field_value_destroy(elem_field_val
);
1304 case MSGPACK_OBJECT_MAP
:
1307 * As of this version, the only valid map object is
1308 * for an enumeration value, for example:
1315 * - Carling Black Label
1317 const msgpack_object
*inner_obj
;
1320 inner_obj
= get_msgpack_map_obj(obj
, "type");
1322 ERR("Missing `type` entry in map object");
1326 if (inner_obj
->type
!= MSGPACK_OBJECT_STR
) {
1327 ERR("Map object's `type` entry is not a string: type = %s",
1328 msgpack_object_type_str(inner_obj
->type
));
1332 if (!msgpack_str_is_equal(inner_obj
, "enum")) {
1333 ERR("Map object's `type` entry: expecting `enum`");
1337 inner_obj
= get_msgpack_map_obj(obj
, "value");
1339 ERR("Missing `value` entry in map object");
1343 if (inner_obj
->type
== MSGPACK_OBJECT_POSITIVE_INTEGER
) {
1344 *field_val
= lttng_event_field_value_enum_uint_create(
1345 inner_obj
->via
.u64
);
1346 } else if (inner_obj
->type
== MSGPACK_OBJECT_NEGATIVE_INTEGER
) {
1347 *field_val
= lttng_event_field_value_enum_int_create(
1348 inner_obj
->via
.i64
);
1350 ERR("Map object's `value` entry is not an integer: type = %s",
1351 msgpack_object_type_str(inner_obj
->type
));
1359 inner_obj
= get_msgpack_map_obj(obj
, "labels");
1365 if (inner_obj
->type
!= MSGPACK_OBJECT_ARRAY
) {
1366 ERR("Map object's `labels` entry is not an array: type = %s",
1367 msgpack_object_type_str(inner_obj
->type
));
1371 for (label_i
= 0; label_i
< inner_obj
->via
.array
.size
;
1374 const msgpack_object
*elem_obj
=
1375 &inner_obj
->via
.array
.ptr
[label_i
];
1377 if (elem_obj
->type
!= MSGPACK_OBJECT_STR
) {
1378 ERR("Map object's `labels` entry's type is not a string: type = %s",
1379 msgpack_object_type_str(elem_obj
->type
));
1383 iret
= lttng_event_field_value_enum_append_label_with_size(
1384 *field_val
, elem_obj
->via
.str
.ptr
,
1385 elem_obj
->via
.str
.size
);
1394 ERR("Unexpected object type: type = %s",
1395 msgpack_object_type_str(obj
->type
));
1406 lttng_event_field_value_destroy(*field_val
);
1415 struct lttng_event_field_value
*event_field_value_from_capture_payload(
1416 const struct lttng_condition_on_event
*condition
,
1417 const char *capture_payload
, size_t capture_payload_size
)
1419 struct lttng_event_field_value
*ret
= NULL
;
1420 msgpack_unpacked unpacked
;
1421 msgpack_unpack_return unpack_return
;
1422 const msgpack_object
*root_obj
;
1423 const msgpack_object_array
*root_array_obj
;
1428 assert(capture_payload
);
1430 /* Initialize value. */
1431 msgpack_unpacked_init(&unpacked
);
1434 unpack_return
= msgpack_unpack_next(&unpacked
, capture_payload
,
1435 capture_payload_size
, NULL
);
1436 if (unpack_return
!= MSGPACK_UNPACK_SUCCESS
) {
1437 ERR("msgpack_unpack_next() failed to decode the "
1438 "MessagePack-encoded capture payload: "
1439 "size = %zu, ret = %d",
1440 capture_payload_size
, unpack_return
);
1444 /* Get root array. */
1445 root_obj
= &unpacked
.data
;
1447 if (root_obj
->type
!= MSGPACK_OBJECT_ARRAY
) {
1448 ERR("Expecting an array as the root object: type = %s",
1449 msgpack_object_type_str(root_obj
->type
));
1453 root_array_obj
= &root_obj
->via
.array
;
1455 /* Create an empty root array event field value. */
1456 ret
= lttng_event_field_value_array_create();
1462 * For each capture descriptor in the condition object:
1464 * 1. Get its corresponding captured field value MessagePack
1467 * 2. Create a corresponding event field value.
1469 * 3. Append it to `ret` (the root array event field value).
1471 count
= lttng_dynamic_pointer_array_get_count(
1472 &condition
->capture_descriptors
);
1475 for (i
= 0; i
< count
; i
++) {
1476 const struct lttng_capture_descriptor
*capture_descriptor
=
1477 lttng_condition_on_event_get_internal_capture_descriptor_at_index(
1478 &condition
->parent
, i
);
1479 const msgpack_object
*elem_obj
;
1480 struct lttng_event_field_value
*elem_field_val
;
1483 assert(capture_descriptor
);
1485 elem_obj
= &root_array_obj
->ptr
[i
];
1486 iret
= event_field_value_from_obj(elem_obj
,
1492 if (elem_field_val
) {
1493 iret
= lttng_event_field_value_array_append(ret
,
1496 iret
= lttng_event_field_value_array_append_unavailable(
1501 lttng_event_field_value_destroy(elem_field_val
);
1509 lttng_event_field_value_destroy(ret
);
1513 msgpack_unpacked_destroy(&unpacked
);
1518 struct lttng_evaluation
*lttng_evaluation_on_event_create(
1519 const struct lttng_condition_on_event
*condition
,
1520 const char *trigger_name
,
1521 const char *capture_payload
, size_t capture_payload_size
,
1522 bool decode_capture_payload
)
1524 struct lttng_evaluation_on_event
*hit
;
1525 struct lttng_evaluation
*evaluation
= NULL
;
1527 hit
= zmalloc(sizeof(struct lttng_evaluation_on_event
));
1532 hit
->name
= strdup(trigger_name
);
1537 lttng_dynamic_buffer_init(&hit
->capture_payload
);
1539 if (capture_payload
) {
1540 const int ret
= lttng_dynamic_buffer_append(
1541 &hit
->capture_payload
, capture_payload
,
1542 capture_payload_size
);
1544 ERR("Failed to initialize capture payload of event rule evaluation");
1548 if (decode_capture_payload
) {
1549 hit
->captured_values
=
1550 event_field_value_from_capture_payload(
1553 capture_payload_size
);
1554 if (!hit
->captured_values
) {
1555 ERR("Failed to decode the capture payload: size = %zu",
1556 capture_payload_size
);
1562 hit
->parent
.type
= LTTNG_CONDITION_TYPE_ON_EVENT
;
1563 hit
->parent
.serialize
= lttng_evaluation_on_event_serialize
;
1564 hit
->parent
.destroy
= lttng_evaluation_on_event_destroy
;
1566 evaluation
= &hit
->parent
;
1571 lttng_evaluation_on_event_destroy(&hit
->parent
);
1577 enum lttng_evaluation_on_event_status
1578 lttng_evaluation_on_event_get_captured_values(
1579 const struct lttng_evaluation
*evaluation
,
1580 const struct lttng_event_field_value
**field_val
)
1582 struct lttng_evaluation_on_event
*hit
;
1583 enum lttng_evaluation_on_event_status status
=
1584 LTTNG_EVALUATION_ON_EVENT_STATUS_OK
;
1586 if (!evaluation
|| !is_on_event_evaluation(evaluation
) ||
1588 status
= LTTNG_EVALUATION_ON_EVENT_STATUS_INVALID
;
1592 hit
= container_of(evaluation
, struct lttng_evaluation_on_event
,
1594 if (!hit
->captured_values
) {
1595 status
= LTTNG_EVALUATION_ON_EVENT_STATUS_NONE
;
1599 *field_val
= hit
->captured_values
;
1605 enum lttng_evaluation_status
lttng_evaluation_on_event_get_trigger_name(
1606 const struct lttng_evaluation
*evaluation
, const char **name
)
1608 struct lttng_evaluation_on_event
*hit
;
1609 enum lttng_evaluation_status status
= LTTNG_EVALUATION_STATUS_OK
;
1611 if (!evaluation
|| !is_on_event_evaluation(evaluation
) || !name
) {
1612 status
= LTTNG_EVALUATION_STATUS_INVALID
;
1617 evaluation
, struct lttng_evaluation_on_event
, parent
);
1624 enum lttng_error_code
1625 lttng_condition_on_event_generate_capture_descriptor_bytecode(
1626 struct lttng_condition
*condition
)
1628 enum lttng_error_code ret
;
1629 enum lttng_condition_status status
;
1630 unsigned int capture_count
, i
;
1632 if (!condition
|| !IS_ON_EVENT_CONDITION(condition
)) {
1633 ret
= LTTNG_ERR_FATAL
;
1637 status
= lttng_condition_on_event_get_capture_descriptor_count(
1638 condition
, &capture_count
);
1639 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
1640 ret
= LTTNG_ERR_FATAL
;
1644 for (i
= 0; i
< capture_count
; i
++) {
1645 struct lttng_capture_descriptor
*local_capture_desc
=
1646 lttng_condition_on_event_get_internal_capture_descriptor_at_index(
1649 if (local_capture_desc
== NULL
) {
1650 ret
= LTTNG_ERR_FATAL
;
1654 /* Generate the bytecode. */
1655 status
= lttng_event_expr_to_bytecode(
1656 local_capture_desc
->event_expression
,
1657 &local_capture_desc
->bytecode
);
1658 if (status
< 0 || local_capture_desc
->bytecode
== NULL
) {
1659 ret
= LTTNG_ERR_INVALID_CAPTURE_EXPRESSION
;
1664 /* Everything went better than expected */
1672 const struct lttng_bytecode
*
1673 lttng_condition_on_event_get_capture_bytecode_at_index(
1674 const struct lttng_condition
*condition
, unsigned int index
)
1676 const struct lttng_condition_on_event
*on_event_cond
=
1677 container_of(condition
,
1678 const struct lttng_condition_on_event
,
1680 struct lttng_capture_descriptor
*desc
= NULL
;
1681 struct lttng_bytecode
*bytecode
= NULL
;
1683 enum lttng_condition_status status
;
1685 if (!condition
|| !IS_ON_EVENT_CONDITION(condition
)) {
1689 status
= lttng_condition_on_event_get_capture_descriptor_count(
1691 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
1695 if (index
>= count
) {
1699 desc
= lttng_dynamic_pointer_array_get_pointer(
1700 &on_event_cond
->capture_descriptors
, index
);
1705 bytecode
= desc
->bytecode
;