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/macros.h>
11 #include <common/mi-lttng.h>
14 #include <lttng/condition/condition-internal.h>
15 #include <lttng/condition/event-rule-matches-internal.h>
16 #include <lttng/condition/event-rule-matches.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_MATCHES_CONDITION(condition) \
27 (lttng_condition_get_type(condition) == \
28 LTTNG_CONDITION_TYPE_EVENT_RULE_MATCHES)
30 static bool is_event_rule_matches_evaluation(
31 const struct lttng_evaluation
*evaluation
)
33 enum lttng_condition_type type
= lttng_evaluation_get_type(evaluation
);
35 return type
== LTTNG_CONDITION_TYPE_EVENT_RULE_MATCHES
;
38 static bool lttng_condition_event_rule_matches_validate(
39 const struct lttng_condition
*condition
);
40 static int lttng_condition_event_rule_matches_serialize(
41 const struct lttng_condition
*condition
,
42 struct lttng_payload
*payload
);
43 static bool lttng_condition_event_rule_matches_is_equal(
44 const struct lttng_condition
*_a
,
45 const struct lttng_condition
*_b
);
46 static void lttng_condition_event_rule_matches_destroy(
47 struct lttng_condition
*condition
);
49 static bool lttng_condition_event_rule_matches_validate(
50 const struct lttng_condition
*condition
)
53 struct lttng_condition_event_rule_matches
*event_rule
;
59 event_rule
= container_of(condition
,
60 struct lttng_condition_event_rule_matches
, parent
);
61 if (!event_rule
->rule
) {
62 ERR("Invalid on event condition: a rule must be set");
66 valid
= lttng_event_rule_validate(event_rule
->rule
);
71 static const char *msgpack_object_type_str(msgpack_object_type type
)
76 case MSGPACK_OBJECT_NIL
:
77 name
= "MSGPACK_OBJECT_NIL";
79 case MSGPACK_OBJECT_BOOLEAN
:
80 name
= "MSGPACK_OBJECT_BOOLEAN";
82 case MSGPACK_OBJECT_POSITIVE_INTEGER
:
83 name
= "MSGPACK_OBJECT_POSITIVE_INTEGER";
85 case MSGPACK_OBJECT_NEGATIVE_INTEGER
:
86 name
= "MSGPACK_OBJECT_NEGATIVE_INTEGER";
88 case MSGPACK_OBJECT_FLOAT32
:
89 name
= "MSGPACK_OBJECT_FLOAT32";
91 case MSGPACK_OBJECT_FLOAT
:
92 /* Same value as MSGPACK_OBJECT_FLOAT64 */
93 name
= "MSGPACK_OBJECT_FLOAT(64)";
95 case MSGPACK_OBJECT_STR
:
96 name
= "MSGPACK_OBJECT_STR";
98 case MSGPACK_OBJECT_ARRAY
:
99 name
= "MSGPACK_OBJECT_ARRAY";
101 case MSGPACK_OBJECT_MAP
:
102 name
= "MSGPACK_OBJECT_MAP";
104 case MSGPACK_OBJECT_BIN
:
105 name
= "MSGPACK_OBJECT_BIN";
107 case MSGPACK_OBJECT_EXT
:
108 name
= "MSGPACK_OBJECT_EXT";
118 * Serializes the C string `str` into `buf`.
120 * Encoding is the length of `str` plus one (for the null character),
121 * and then the string, including its null terminator.
124 int serialize_cstr(const char *str
, struct lttng_dynamic_buffer
*buf
)
127 const uint32_t len
= strlen(str
) + 1;
129 /* Serialize the length, including the null terminator. */
130 DBG("Serializing C string's length (including null terminator): "
132 ret
= lttng_dynamic_buffer_append(buf
, &len
, sizeof(len
));
137 /* Serialize the string. */
138 DBG("Serializing C string: '%s'", str
);
139 ret
= lttng_dynamic_buffer_append(buf
, str
, len
);
149 * Serializes the event expression `expr` into `buf`.
152 int serialize_event_expr(const struct lttng_event_expr
*expr
,
153 struct lttng_payload
*payload
)
155 const uint8_t type
= expr
->type
;
158 /* Serialize the expression's type. */
159 DBG("Serializing event expression's type: %d", expr
->type
);
160 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, &type
, sizeof(type
));
165 /* Serialize the expression */
166 switch (expr
->type
) {
167 case LTTNG_EVENT_EXPR_TYPE_EVENT_PAYLOAD_FIELD
:
168 case LTTNG_EVENT_EXPR_TYPE_CHANNEL_CONTEXT_FIELD
:
170 const struct lttng_event_expr_field
*field_expr
=
172 const struct lttng_event_expr_field
,
175 /* Serialize the field name. */
176 DBG("Serializing field event expression's field name: '%s'",
178 ret
= serialize_cstr(field_expr
->name
, &payload
->buffer
);
185 case LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD
:
187 const struct lttng_event_expr_app_specific_context_field
*field_expr
=
189 const struct lttng_event_expr_app_specific_context_field
,
192 /* Serialize the provider name. */
193 DBG("Serializing app-specific context field event expression's "
194 "provider name: '%s'",
195 field_expr
->provider_name
);
196 ret
= serialize_cstr(field_expr
->provider_name
, &payload
->buffer
);
201 /* Serialize the type name. */
202 DBG("Serializing app-specific context field event expression's "
204 field_expr
->provider_name
);
205 ret
= serialize_cstr(field_expr
->type_name
, &payload
->buffer
);
212 case LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT
:
214 const struct lttng_event_expr_array_field_element
*elem_expr
=
216 const struct lttng_event_expr_array_field_element
,
218 const uint32_t index
= elem_expr
->index
;
220 /* Serialize the index. */
221 DBG("Serializing array field element event expression's "
222 "index: %u", elem_expr
->index
);
223 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, &index
, sizeof(index
));
228 /* Serialize the parent array field expression. */
229 DBG("Serializing array field element event expression's "
230 "parent array field event expression");
231 ret
= serialize_event_expr(elem_expr
->array_field_expr
, payload
);
246 static struct lttng_capture_descriptor
*
247 lttng_condition_event_rule_matches_get_internal_capture_descriptor_at_index(
248 const struct lttng_condition
*condition
, unsigned int index
)
250 const struct lttng_condition_event_rule_matches
251 *event_rule_matches_cond
= container_of(condition
,
252 const struct lttng_condition_event_rule_matches
,
254 struct lttng_capture_descriptor
*desc
= NULL
;
256 enum lttng_condition_status status
;
258 if (!condition
|| !IS_EVENT_RULE_MATCHES_CONDITION(condition
)) {
262 status
= lttng_condition_event_rule_matches_get_capture_descriptor_count(
264 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
268 if (index
>= count
) {
272 desc
= lttng_dynamic_pointer_array_get_pointer(
273 &event_rule_matches_cond
->capture_descriptors
, index
);
278 static int lttng_condition_event_rule_matches_serialize(
279 const struct lttng_condition
*condition
,
280 struct lttng_payload
*payload
)
283 struct lttng_condition_event_rule_matches
*event_rule_matches_condition
;
284 enum lttng_condition_status status
;
285 /* Used for iteration and communication (size matters). */
286 uint32_t i
, capture_descr_count
;
288 if (!condition
|| !IS_EVENT_RULE_MATCHES_CONDITION(condition
)) {
293 DBG("Serializing on event condition");
294 event_rule_matches_condition
= container_of(condition
,
295 struct lttng_condition_event_rule_matches
, parent
);
297 DBG("Serializing on event condition's event rule");
298 ret
= lttng_event_rule_serialize(
299 event_rule_matches_condition
->rule
, payload
);
304 status
= lttng_condition_event_rule_matches_get_capture_descriptor_count(
305 condition
, &capture_descr_count
);
306 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
311 DBG("Serializing on event condition's capture descriptor count: %" PRIu32
,
312 capture_descr_count
);
313 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, &capture_descr_count
,
314 sizeof(capture_descr_count
));
319 for (i
= 0; i
< capture_descr_count
; i
++) {
320 const struct lttng_capture_descriptor
*desc
=
321 lttng_condition_event_rule_matches_get_internal_capture_descriptor_at_index(
324 DBG("Serializing on event condition's capture descriptor %" PRIu32
,
326 ret
= serialize_event_expr(desc
->event_expression
, payload
);
337 bool capture_descriptors_are_equal(
338 const struct lttng_condition
*condition_a
,
339 const struct lttng_condition
*condition_b
)
341 bool is_equal
= true;
342 unsigned int capture_descr_count_a
;
343 unsigned int capture_descr_count_b
;
345 enum lttng_condition_status status
;
347 status
= lttng_condition_event_rule_matches_get_capture_descriptor_count(
348 condition_a
, &capture_descr_count_a
);
349 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
353 status
= lttng_condition_event_rule_matches_get_capture_descriptor_count(
354 condition_b
, &capture_descr_count_b
);
355 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
359 if (capture_descr_count_a
!= capture_descr_count_b
) {
363 for (i
= 0; i
< capture_descr_count_a
; i
++) {
364 const struct lttng_event_expr
*expr_a
=
365 lttng_condition_event_rule_matches_get_capture_descriptor_at_index(
367 const struct lttng_event_expr
*expr_b
=
368 lttng_condition_event_rule_matches_get_capture_descriptor_at_index(
371 if (!lttng_event_expr_is_equal(expr_a
, expr_b
)) {
385 static bool lttng_condition_event_rule_matches_is_equal(
386 const struct lttng_condition
*_a
,
387 const struct lttng_condition
*_b
)
389 bool is_equal
= false;
390 struct lttng_condition_event_rule_matches
*a
, *b
;
392 a
= container_of(_a
, struct lttng_condition_event_rule_matches
, parent
);
393 b
= container_of(_b
, struct lttng_condition_event_rule_matches
, parent
);
395 /* Both event rules must be set or both must be unset. */
396 if ((a
->rule
&& !b
->rule
) || (!a
->rule
&& b
->rule
)) {
397 WARN("Comparing event_rule conditions with uninitialized rule");
401 is_equal
= lttng_event_rule_is_equal(a
->rule
, b
->rule
);
406 is_equal
= capture_descriptors_are_equal(_a
, _b
);
412 static void lttng_condition_event_rule_matches_destroy(
413 struct lttng_condition
*condition
)
415 struct lttng_condition_event_rule_matches
*event_rule_matches_condition
;
417 event_rule_matches_condition
= container_of(condition
,
418 struct lttng_condition_event_rule_matches
, parent
);
420 lttng_event_rule_put(event_rule_matches_condition
->rule
);
421 lttng_dynamic_pointer_array_reset(
422 &event_rule_matches_condition
->capture_descriptors
);
423 free(event_rule_matches_condition
);
427 void destroy_capture_descriptor(void *ptr
)
429 struct lttng_capture_descriptor
*desc
=
430 (struct lttng_capture_descriptor
*) ptr
;
432 lttng_event_expr_destroy(desc
->event_expression
);
433 free(desc
->bytecode
);
437 static enum lttng_error_code
lttng_condition_event_rule_matches_mi_serialize(
438 const struct lttng_condition
*condition
,
439 struct mi_writer
*writer
)
442 enum lttng_error_code ret_code
;
443 enum lttng_condition_status status
;
444 const struct lttng_event_rule
*rule
= NULL
;
445 unsigned int capture_descriptor_count
, i
;
449 assert(IS_EVENT_RULE_MATCHES_CONDITION(condition
));
451 status
= lttng_condition_event_rule_matches_get_rule(condition
, &rule
);
452 assert(status
== LTTNG_CONDITION_STATUS_OK
);
453 assert(rule
!= NULL
);
455 status
= lttng_condition_event_rule_matches_get_capture_descriptor_count(
456 condition
, &capture_descriptor_count
);
457 assert(status
== LTTNG_CONDITION_STATUS_OK
);
459 /* Open condition event rule matches element. */
460 ret
= mi_lttng_writer_open_element(
461 writer
, mi_lttng_element_condition_event_rule_matches
);
466 /* Serialize the event rule. */
467 ret_code
= lttng_event_rule_mi_serialize(rule
, writer
);
468 if (ret_code
!= LTTNG_OK
) {
472 /* Open the capture descriptors element. */
473 ret
= mi_lttng_writer_open_element(
474 writer
, mi_lttng_element_capture_descriptors
);
479 for (i
= 0; i
< capture_descriptor_count
; i
++) {
480 const struct lttng_event_expr
*descriptor
= NULL
;
482 descriptor
= lttng_condition_event_rule_matches_get_capture_descriptor_at_index(
486 ret_code
= lttng_event_expr_mi_serialize(descriptor
, writer
);
487 if (ret_code
!= LTTNG_OK
) {
492 /* Close capture descriptors element. */
493 ret
= mi_lttng_writer_close_element(writer
);
498 /* Close condition_event_rule_matches. */
499 ret
= mi_lttng_writer_close_element(writer
);
507 ret_code
= LTTNG_ERR_MI_IO_FAIL
;
512 struct lttng_condition
*lttng_condition_event_rule_matches_create(
513 struct lttng_event_rule
*rule
)
515 struct lttng_condition
*parent
= NULL
;
516 struct lttng_condition_event_rule_matches
*condition
= NULL
;
522 condition
= zmalloc(sizeof(struct lttng_condition_event_rule_matches
));
527 lttng_condition_init(&condition
->parent
,
528 LTTNG_CONDITION_TYPE_EVENT_RULE_MATCHES
);
529 condition
->parent
.validate
=
530 lttng_condition_event_rule_matches_validate
,
531 condition
->parent
.serialize
=
532 lttng_condition_event_rule_matches_serialize
,
533 condition
->parent
.equal
= lttng_condition_event_rule_matches_is_equal
,
534 condition
->parent
.destroy
= lttng_condition_event_rule_matches_destroy
,
535 condition
->parent
.mi_serialize
= lttng_condition_event_rule_matches_mi_serialize
,
537 lttng_event_rule_get(rule
);
538 condition
->rule
= rule
;
541 lttng_dynamic_pointer_array_init(&condition
->capture_descriptors
,
542 destroy_capture_descriptor
);
544 parent
= &condition
->parent
;
550 uint64_t uint_from_buffer(const struct lttng_buffer_view
*view
, size_t size
,
554 const struct lttng_buffer_view uint_view
=
555 lttng_buffer_view_from_view(view
, *offset
, size
);
557 if (!lttng_buffer_view_is_valid(&uint_view
)) {
564 ret
= (uint64_t) *uint_view
.data
;
566 case sizeof(uint32_t):
570 memcpy(&u32
, uint_view
.data
, sizeof(u32
));
571 ret
= (uint64_t) u32
;
575 memcpy(&ret
, uint_view
.data
, sizeof(ret
));
588 const char *str_from_buffer(const struct lttng_buffer_view
*view
,
594 len
= uint_from_buffer(view
, sizeof(uint32_t), offset
);
595 if (len
== UINT64_C(-1)) {
599 ret
= &view
->data
[*offset
];
601 if (!lttng_buffer_view_contains_string(view
, ret
, len
)) {
616 struct lttng_event_expr
*event_expr_from_payload(
617 struct lttng_payload_view
*view
, size_t *offset
)
619 struct lttng_event_expr
*expr
= NULL
;
623 type
= uint_from_buffer(&view
->buffer
, sizeof(uint8_t), offset
);
624 if (type
== UINT64_C(-1)) {
629 case LTTNG_EVENT_EXPR_TYPE_EVENT_PAYLOAD_FIELD
:
630 str
= str_from_buffer(&view
->buffer
, offset
);
635 expr
= lttng_event_expr_event_payload_field_create(str
);
637 case LTTNG_EVENT_EXPR_TYPE_CHANNEL_CONTEXT_FIELD
:
638 str
= str_from_buffer(&view
->buffer
, offset
);
643 expr
= lttng_event_expr_channel_context_field_create(str
);
645 case LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD
:
647 const char *provider_name
;
648 const char *type_name
;
650 provider_name
= str_from_buffer(&view
->buffer
, offset
);
651 if (!provider_name
) {
655 type_name
= str_from_buffer(&view
->buffer
, offset
);
660 expr
= lttng_event_expr_app_specific_context_field_create(
661 provider_name
, type_name
);
664 case LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT
:
666 struct lttng_event_expr
*array_field_expr
;
667 const uint64_t index
= uint_from_buffer(
668 &view
->buffer
, sizeof(uint32_t), offset
);
670 if (index
== UINT64_C(-1)) {
674 /* Array field expression is the encoded after this. */
675 array_field_expr
= event_expr_from_payload(view
, offset
);
676 if (!array_field_expr
) {
680 /* Move ownership of `array_field_expr` to new expression. */
681 expr
= lttng_event_expr_array_field_element_create(
682 array_field_expr
, (unsigned int) index
);
684 /* `array_field_expr` not moved: destroy it. */
685 lttng_event_expr_destroy(array_field_expr
);
691 ERR("Invalid event expression type encoutered while deserializing event expression: type = %" PRIu64
,
699 lttng_event_expr_destroy(expr
);
707 ssize_t
lttng_condition_event_rule_matches_create_from_payload(
708 struct lttng_payload_view
*view
,
709 struct lttng_condition
**_condition
)
711 ssize_t consumed_length
;
713 ssize_t event_rule_length
;
714 uint32_t i
, capture_descr_count
;
715 struct lttng_condition
*condition
= NULL
;
716 struct lttng_event_rule
*event_rule
= NULL
;
718 if (!view
|| !_condition
) {
722 /* Struct lttng_event_rule. */
724 struct lttng_payload_view event_rule_view
=
725 lttng_payload_view_from_view(view
, offset
, -1);
727 event_rule_length
= lttng_event_rule_create_from_payload(
728 &event_rule_view
, &event_rule
);
731 if (event_rule_length
< 0 || !event_rule
) {
735 offset
+= event_rule_length
;
737 /* Create condition (no capture descriptors yet) at this point */
738 condition
= lttng_condition_event_rule_matches_create(event_rule
);
743 /* Capture descriptor count. */
744 assert(event_rule_length
>= 0);
745 capture_descr_count
= uint_from_buffer(&view
->buffer
, sizeof(uint32_t), &offset
);
746 if (capture_descr_count
== UINT32_C(-1)) {
750 /* Capture descriptors. */
751 for (i
= 0; i
< capture_descr_count
; i
++) {
752 enum lttng_condition_status status
;
753 struct lttng_event_expr
*expr
= event_expr_from_payload(
760 /* Move ownership of `expr` to `condition`. */
761 status
= lttng_condition_event_rule_matches_append_capture_descriptor(
763 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
764 /* `expr` not moved: destroy it. */
765 lttng_event_expr_destroy(expr
);
770 consumed_length
= (ssize_t
) offset
;
771 *_condition
= condition
;
776 consumed_length
= -1;
779 lttng_event_rule_put(event_rule
);
780 lttng_condition_put(condition
);
781 return consumed_length
;
785 enum lttng_condition_status
786 lttng_condition_event_rule_matches_borrow_rule_mutable(
787 const struct lttng_condition
*condition
,
788 struct lttng_event_rule
**rule
)
790 struct lttng_condition_event_rule_matches
*event_rule
;
791 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
793 if (!condition
|| !IS_EVENT_RULE_MATCHES_CONDITION(condition
) ||
795 status
= LTTNG_CONDITION_STATUS_INVALID
;
799 event_rule
= container_of(condition
,
800 struct lttng_condition_event_rule_matches
, parent
);
801 if (!event_rule
->rule
) {
802 status
= LTTNG_CONDITION_STATUS_UNSET
;
806 *rule
= event_rule
->rule
;
811 enum lttng_condition_status
lttng_condition_event_rule_matches_get_rule(
812 const struct lttng_condition
*condition
,
813 const struct lttng_event_rule
**rule
)
815 struct lttng_event_rule
*mutable_rule
= NULL
;
816 const enum lttng_condition_status status
=
817 lttng_condition_event_rule_matches_borrow_rule_mutable(
818 condition
, &mutable_rule
);
820 *rule
= mutable_rule
;
825 void lttng_condition_event_rule_matches_set_error_counter_index(
826 struct lttng_condition
*condition
, uint64_t error_counter_index
)
828 struct lttng_condition_event_rule_matches
*event_rule_matches_cond
=
829 container_of(condition
,
830 struct lttng_condition_event_rule_matches
,
833 LTTNG_OPTIONAL_SET(&event_rule_matches_cond
->error_counter_index
,
834 error_counter_index
);
838 uint64_t lttng_condition_event_rule_matches_get_error_counter_index(
839 const struct lttng_condition
*condition
)
841 const struct lttng_condition_event_rule_matches
842 *event_rule_matches_cond
= container_of(condition
,
843 const struct lttng_condition_event_rule_matches
,
846 return LTTNG_OPTIONAL_GET(event_rule_matches_cond
->error_counter_index
);
849 enum lttng_condition_status
850 lttng_condition_event_rule_matches_append_capture_descriptor(
851 struct lttng_condition
*condition
,
852 struct lttng_event_expr
*expr
)
855 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
856 struct lttng_condition_event_rule_matches
*event_rule_matches_cond
=
857 container_of(condition
,
858 struct lttng_condition_event_rule_matches
,
860 struct lttng_capture_descriptor
*descriptor
= NULL
;
861 const struct lttng_event_rule
*rule
= NULL
;
863 /* Only accept l-values. */
864 if (!condition
|| !IS_EVENT_RULE_MATCHES_CONDITION(condition
) ||
865 !expr
|| !lttng_event_expr_is_lvalue(expr
)) {
866 status
= LTTNG_CONDITION_STATUS_INVALID
;
870 status
= lttng_condition_event_rule_matches_get_rule(condition
, &rule
);
871 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
875 switch(lttng_event_rule_get_type(rule
)) {
876 case LTTNG_EVENT_RULE_TYPE_USER_TRACEPOINT
:
877 case LTTNG_EVENT_RULE_TYPE_KERNEL_TRACEPOINT
:
878 case LTTNG_EVENT_RULE_TYPE_JUL_LOGGING
:
879 case LTTNG_EVENT_RULE_TYPE_LOG4J_LOGGING
:
880 case LTTNG_EVENT_RULE_TYPE_PYTHON_LOGGING
:
881 case LTTNG_EVENT_RULE_TYPE_KERNEL_SYSCALL
:
883 status
= LTTNG_CONDITION_STATUS_OK
;
885 case LTTNG_EVENT_RULE_TYPE_UNKNOWN
:
886 status
= LTTNG_CONDITION_STATUS_INVALID
;
889 status
= LTTNG_CONDITION_STATUS_UNSUPPORTED
;
893 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
897 descriptor
= malloc(sizeof(*descriptor
));
898 if (descriptor
== NULL
) {
899 status
= LTTNG_CONDITION_STATUS_ERROR
;
903 descriptor
->event_expression
= expr
;
904 descriptor
->bytecode
= NULL
;
906 ret
= lttng_dynamic_pointer_array_add_pointer(
907 &event_rule_matches_cond
->capture_descriptors
,
910 status
= LTTNG_CONDITION_STATUS_ERROR
;
914 /* Ownership is transfered to the internal capture_descriptors array */
921 enum lttng_condition_status
922 lttng_condition_event_rule_matches_get_capture_descriptor_count(
923 const struct lttng_condition
*condition
, unsigned int *count
)
925 enum lttng_condition_status status
= LTTNG_CONDITION_STATUS_OK
;
926 const struct lttng_condition_event_rule_matches
927 *event_rule_matches_condition
= container_of(condition
,
928 const struct lttng_condition_event_rule_matches
,
931 if (!condition
|| !IS_EVENT_RULE_MATCHES_CONDITION(condition
) ||
933 status
= LTTNG_CONDITION_STATUS_INVALID
;
937 *count
= lttng_dynamic_pointer_array_get_count(
938 &event_rule_matches_condition
->capture_descriptors
);
944 const struct lttng_event_expr
*
945 lttng_condition_event_rule_matches_get_capture_descriptor_at_index(
946 const struct lttng_condition
*condition
, unsigned int index
)
948 const struct lttng_event_expr
*expr
= NULL
;
949 const struct lttng_capture_descriptor
*desc
= NULL
;
951 desc
= lttng_condition_event_rule_matches_get_internal_capture_descriptor_at_index(
956 expr
= desc
->event_expression
;
963 ssize_t
lttng_evaluation_event_rule_matches_create_from_payload(
964 const struct lttng_condition_event_rule_matches
*condition
,
965 struct lttng_payload_view
*view
,
966 struct lttng_evaluation
**_evaluation
)
968 ssize_t ret
, offset
= 0;
969 struct lttng_evaluation
*evaluation
= NULL
;
970 uint32_t capture_payload_size
;
971 const char *capture_payload
= NULL
;
979 const struct lttng_payload_view current_view
=
980 lttng_payload_view_from_view(view
, offset
, -1);
982 if (current_view
.buffer
.size
< sizeof(capture_payload_size
)) {
987 memcpy(&capture_payload_size
, current_view
.buffer
.data
,
988 sizeof(capture_payload_size
));
990 offset
+= sizeof(capture_payload_size
);
992 if (capture_payload_size
> 0) {
993 const struct lttng_payload_view current_view
=
994 lttng_payload_view_from_view(view
, offset
, -1);
996 if (current_view
.buffer
.size
< capture_payload_size
) {
1001 capture_payload
= current_view
.buffer
.data
;
1004 evaluation
= lttng_evaluation_event_rule_matches_create(
1005 condition
, capture_payload
, capture_payload_size
, true);
1011 offset
+= capture_payload_size
;
1012 *_evaluation
= evaluation
;
1017 lttng_evaluation_destroy(evaluation
);
1021 static int lttng_evaluation_event_rule_matches_serialize(
1022 const struct lttng_evaluation
*evaluation
,
1023 struct lttng_payload
*payload
)
1026 struct lttng_evaluation_event_rule_matches
*hit
;
1027 uint32_t capture_payload_size
;
1029 hit
= container_of(evaluation
,
1030 struct lttng_evaluation_event_rule_matches
, parent
);
1032 capture_payload_size
= (uint32_t) hit
->capture_payload
.size
;
1033 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, &capture_payload_size
,
1034 sizeof(capture_payload_size
));
1039 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, hit
->capture_payload
.data
,
1040 hit
->capture_payload
.size
);
1050 bool msgpack_str_is_equal(const struct msgpack_object
*obj
, const char *str
)
1052 bool is_equal
= true;
1054 assert(obj
->type
== MSGPACK_OBJECT_STR
);
1056 if (obj
->via
.str
.size
!= strlen(str
)) {
1061 if (strncmp(obj
->via
.str
.ptr
, str
, obj
->via
.str
.size
) != 0) {
1071 const msgpack_object
*get_msgpack_map_obj(const struct msgpack_object
*map_obj
,
1074 const msgpack_object
*ret
= NULL
;
1077 assert(map_obj
->type
== MSGPACK_OBJECT_MAP
);
1079 for (i
= 0; i
< map_obj
->via
.map
.size
; i
++) {
1080 const struct msgpack_object_kv
*kv
= &map_obj
->via
.map
.ptr
[i
];
1082 assert(kv
->key
.type
== MSGPACK_OBJECT_STR
);
1084 if (msgpack_str_is_equal(&kv
->key
, name
)) {
1094 static void lttng_evaluation_event_rule_matches_destroy(
1095 struct lttng_evaluation
*evaluation
)
1097 struct lttng_evaluation_event_rule_matches
*hit
;
1099 hit
= container_of(evaluation
,
1100 struct lttng_evaluation_event_rule_matches
, parent
);
1101 lttng_dynamic_buffer_reset(&hit
->capture_payload
);
1102 lttng_event_field_value_destroy(hit
->captured_values
);
1107 int event_field_value_from_obj(const msgpack_object
*obj
,
1108 struct lttng_event_field_value
**field_val
)
1115 switch (obj
->type
) {
1116 case MSGPACK_OBJECT_NIL
:
1120 case MSGPACK_OBJECT_POSITIVE_INTEGER
:
1121 *field_val
= lttng_event_field_value_uint_create(
1124 case MSGPACK_OBJECT_NEGATIVE_INTEGER
:
1125 *field_val
= lttng_event_field_value_int_create(
1128 case MSGPACK_OBJECT_FLOAT32
:
1129 case MSGPACK_OBJECT_FLOAT64
:
1130 *field_val
= lttng_event_field_value_real_create(
1133 case MSGPACK_OBJECT_STR
:
1134 *field_val
= lttng_event_field_value_string_create_with_size(
1135 obj
->via
.str
.ptr
, obj
->via
.str
.size
);
1137 case MSGPACK_OBJECT_ARRAY
:
1141 *field_val
= lttng_event_field_value_array_create();
1146 for (i
= 0; i
< obj
->via
.array
.size
; i
++) {
1147 const msgpack_object
*elem_obj
= &obj
->via
.array
.ptr
[i
];
1148 struct lttng_event_field_value
*elem_field_val
;
1150 ret
= event_field_value_from_obj(elem_obj
,
1156 if (elem_field_val
) {
1157 ret
= lttng_event_field_value_array_append(
1158 *field_val
, elem_field_val
);
1160 ret
= lttng_event_field_value_array_append_unavailable(
1165 lttng_event_field_value_destroy(elem_field_val
);
1172 case MSGPACK_OBJECT_MAP
:
1175 * As of this version, the only valid map object is
1176 * for an enumeration value, for example:
1183 * - Carling Black Label
1185 const msgpack_object
*inner_obj
;
1188 inner_obj
= get_msgpack_map_obj(obj
, "type");
1190 ERR("Missing `type` entry in map object");
1194 if (inner_obj
->type
!= MSGPACK_OBJECT_STR
) {
1195 ERR("Map object's `type` entry is not a string: type = %s",
1196 msgpack_object_type_str(inner_obj
->type
));
1200 if (!msgpack_str_is_equal(inner_obj
, "enum")) {
1201 ERR("Map object's `type` entry: expecting `enum`");
1205 inner_obj
= get_msgpack_map_obj(obj
, "value");
1207 ERR("Missing `value` entry in map object");
1211 if (inner_obj
->type
== MSGPACK_OBJECT_POSITIVE_INTEGER
) {
1212 *field_val
= lttng_event_field_value_enum_uint_create(
1213 inner_obj
->via
.u64
);
1214 } else if (inner_obj
->type
== MSGPACK_OBJECT_NEGATIVE_INTEGER
) {
1215 *field_val
= lttng_event_field_value_enum_int_create(
1216 inner_obj
->via
.i64
);
1218 ERR("Map object's `value` entry is not an integer: type = %s",
1219 msgpack_object_type_str(inner_obj
->type
));
1227 inner_obj
= get_msgpack_map_obj(obj
, "labels");
1233 if (inner_obj
->type
!= MSGPACK_OBJECT_ARRAY
) {
1234 ERR("Map object's `labels` entry is not an array: type = %s",
1235 msgpack_object_type_str(inner_obj
->type
));
1239 for (label_i
= 0; label_i
< inner_obj
->via
.array
.size
;
1242 const msgpack_object
*elem_obj
=
1243 &inner_obj
->via
.array
.ptr
[label_i
];
1245 if (elem_obj
->type
!= MSGPACK_OBJECT_STR
) {
1246 ERR("Map object's `labels` entry's type is not a string: type = %s",
1247 msgpack_object_type_str(elem_obj
->type
));
1251 iret
= lttng_event_field_value_enum_append_label_with_size(
1252 *field_val
, elem_obj
->via
.str
.ptr
,
1253 elem_obj
->via
.str
.size
);
1262 ERR("Unexpected object type: type = %s",
1263 msgpack_object_type_str(obj
->type
));
1274 lttng_event_field_value_destroy(*field_val
);
1282 static struct lttng_event_field_value
*event_field_value_from_capture_payload(
1283 const struct lttng_condition_event_rule_matches
*condition
,
1284 const char *capture_payload
,
1285 size_t capture_payload_size
)
1287 struct lttng_event_field_value
*ret
= NULL
;
1288 msgpack_unpacked unpacked
;
1289 msgpack_unpack_return unpack_return
;
1290 const msgpack_object
*root_obj
;
1291 const msgpack_object_array
*root_array_obj
;
1296 assert(capture_payload
);
1298 /* Initialize value. */
1299 msgpack_unpacked_init(&unpacked
);
1302 unpack_return
= msgpack_unpack_next(&unpacked
, capture_payload
,
1303 capture_payload_size
, NULL
);
1304 if (unpack_return
!= MSGPACK_UNPACK_SUCCESS
) {
1305 ERR("msgpack_unpack_next() failed to decode the "
1306 "MessagePack-encoded capture payload: "
1307 "size = %zu, ret = %d",
1308 capture_payload_size
, unpack_return
);
1312 /* Get root array. */
1313 root_obj
= &unpacked
.data
;
1315 if (root_obj
->type
!= MSGPACK_OBJECT_ARRAY
) {
1316 ERR("Expecting an array as the root object: type = %s",
1317 msgpack_object_type_str(root_obj
->type
));
1321 root_array_obj
= &root_obj
->via
.array
;
1323 /* Create an empty root array event field value. */
1324 ret
= lttng_event_field_value_array_create();
1330 * For each capture descriptor in the condition object:
1332 * 1. Get its corresponding captured field value MessagePack
1335 * 2. Create a corresponding event field value.
1337 * 3. Append it to `ret` (the root array event field value).
1339 count
= lttng_dynamic_pointer_array_get_count(
1340 &condition
->capture_descriptors
);
1343 for (i
= 0; i
< count
; i
++) {
1344 const struct lttng_capture_descriptor
*capture_descriptor
=
1345 lttng_condition_event_rule_matches_get_internal_capture_descriptor_at_index(
1346 &condition
->parent
, i
);
1347 const msgpack_object
*elem_obj
;
1348 struct lttng_event_field_value
*elem_field_val
;
1351 assert(capture_descriptor
);
1353 elem_obj
= &root_array_obj
->ptr
[i
];
1354 iret
= event_field_value_from_obj(elem_obj
,
1360 if (elem_field_val
) {
1361 iret
= lttng_event_field_value_array_append(ret
,
1364 iret
= lttng_event_field_value_array_append_unavailable(
1369 lttng_event_field_value_destroy(elem_field_val
);
1377 lttng_event_field_value_destroy(ret
);
1381 msgpack_unpacked_destroy(&unpacked
);
1386 struct lttng_evaluation
*lttng_evaluation_event_rule_matches_create(
1387 const struct lttng_condition_event_rule_matches
*condition
,
1388 const char *capture_payload
,
1389 size_t capture_payload_size
,
1390 bool decode_capture_payload
)
1392 struct lttng_evaluation_event_rule_matches
*hit
;
1393 struct lttng_evaluation
*evaluation
= NULL
;
1395 hit
= zmalloc(sizeof(struct lttng_evaluation_event_rule_matches
));
1400 lttng_dynamic_buffer_init(&hit
->capture_payload
);
1402 if (capture_payload
) {
1403 const int ret
= lttng_dynamic_buffer_append(
1404 &hit
->capture_payload
, capture_payload
,
1405 capture_payload_size
);
1407 ERR("Failed to initialize capture payload of event rule evaluation");
1411 if (decode_capture_payload
) {
1412 hit
->captured_values
=
1413 event_field_value_from_capture_payload(
1416 capture_payload_size
);
1417 if (!hit
->captured_values
) {
1418 ERR("Failed to decode the capture payload: size = %zu",
1419 capture_payload_size
);
1425 hit
->parent
.type
= LTTNG_CONDITION_TYPE_EVENT_RULE_MATCHES
;
1426 hit
->parent
.serialize
= lttng_evaluation_event_rule_matches_serialize
;
1427 hit
->parent
.destroy
= lttng_evaluation_event_rule_matches_destroy
;
1429 evaluation
= &hit
->parent
;
1434 lttng_evaluation_event_rule_matches_destroy(&hit
->parent
);
1440 enum lttng_evaluation_event_rule_matches_status
1441 lttng_evaluation_event_rule_matches_get_captured_values(
1442 const struct lttng_evaluation
*evaluation
,
1443 const struct lttng_event_field_value
**field_val
)
1445 struct lttng_evaluation_event_rule_matches
*hit
;
1446 enum lttng_evaluation_event_rule_matches_status status
=
1447 LTTNG_EVALUATION_EVENT_RULE_MATCHES_STATUS_OK
;
1449 if (!evaluation
|| !is_event_rule_matches_evaluation(evaluation
) ||
1451 status
= LTTNG_EVALUATION_EVENT_RULE_MATCHES_STATUS_INVALID
;
1455 hit
= container_of(evaluation
,
1456 struct lttng_evaluation_event_rule_matches
, parent
);
1457 if (!hit
->captured_values
) {
1458 status
= LTTNG_EVALUATION_EVENT_RULE_MATCHES_STATUS_NONE
;
1462 *field_val
= hit
->captured_values
;
1469 enum lttng_error_code
1470 lttng_condition_event_rule_matches_generate_capture_descriptor_bytecode(
1471 struct lttng_condition
*condition
)
1473 enum lttng_error_code ret
;
1474 enum lttng_condition_status status
;
1475 unsigned int capture_count
, i
;
1477 if (!condition
|| !IS_EVENT_RULE_MATCHES_CONDITION(condition
)) {
1478 ret
= LTTNG_ERR_FATAL
;
1482 status
= lttng_condition_event_rule_matches_get_capture_descriptor_count(
1483 condition
, &capture_count
);
1484 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
1485 ret
= LTTNG_ERR_FATAL
;
1489 for (i
= 0; i
< capture_count
; i
++) {
1490 struct lttng_capture_descriptor
*local_capture_desc
=
1491 lttng_condition_event_rule_matches_get_internal_capture_descriptor_at_index(
1494 if (local_capture_desc
== NULL
) {
1495 ret
= LTTNG_ERR_FATAL
;
1499 /* Generate the bytecode. */
1500 status
= lttng_event_expr_to_bytecode(
1501 local_capture_desc
->event_expression
,
1502 &local_capture_desc
->bytecode
);
1503 if (status
< 0 || local_capture_desc
->bytecode
== NULL
) {
1504 ret
= LTTNG_ERR_INVALID_CAPTURE_EXPRESSION
;
1509 /* Everything went better than expected */
1517 const struct lttng_bytecode
*
1518 lttng_condition_event_rule_matches_get_capture_bytecode_at_index(
1519 const struct lttng_condition
*condition
, unsigned int index
)
1521 const struct lttng_condition_event_rule_matches
1522 *event_rule_matches_cond
= container_of(condition
,
1523 const struct lttng_condition_event_rule_matches
,
1525 struct lttng_capture_descriptor
*desc
= NULL
;
1526 struct lttng_bytecode
*bytecode
= NULL
;
1528 enum lttng_condition_status status
;
1530 if (!condition
|| !IS_EVENT_RULE_MATCHES_CONDITION(condition
)) {
1534 status
= lttng_condition_event_rule_matches_get_capture_descriptor_count(
1536 if (status
!= LTTNG_CONDITION_STATUS_OK
) {
1540 if (index
>= count
) {
1544 desc
= lttng_dynamic_pointer_array_get_pointer(
1545 &event_rule_matches_cond
->capture_descriptors
, index
);
1550 bytecode
= desc
->bytecode
;