2 * Copyright (C) 2017 Jérémie Galarneau <jeremie.galarneau@efficios.com>
4 * SPDX-License-Identifier: LGPL-2.1-only
8 #include <lttng/trigger/trigger-internal.h>
9 #include <lttng/condition/condition-internal.h>
10 #include <lttng/condition/on-event-internal.h>
11 #include <lttng/condition/on-event.h>
12 #include <lttng/condition/on-event-internal.h>
13 #include <lttng/condition/buffer-usage.h>
14 #include <lttng/event-rule/event-rule-internal.h>
15 #include <lttng/event-expr-internal.h>
16 #include <lttng/action/action-internal.h>
17 #include <lttng/action/group.h>
18 #include <common/credentials.h>
19 #include <common/payload.h>
20 #include <common/payload-view.h>
21 #include <lttng/domain.h>
22 #include <common/error.h>
23 #include <common/dynamic-array.h>
24 #include <common/optional.h>
29 bool lttng_trigger_validate(const struct lttng_trigger
*trigger
)
38 if (!trigger
->creds
.uid
.is_set
) {
43 valid
= lttng_condition_validate(trigger
->condition
) &&
44 lttng_action_validate(trigger
->action
);
49 struct lttng_trigger
*lttng_trigger_create(
50 struct lttng_condition
*condition
,
51 struct lttng_action
*action
)
53 struct lttng_trigger
*trigger
= NULL
;
55 if (!condition
|| !action
) {
59 trigger
= zmalloc(sizeof(struct lttng_trigger
));
64 urcu_ref_init(&trigger
->ref
);
66 trigger
->firing_policy
.type
= LTTNG_TRIGGER_FIRING_POLICY_EVERY_N
;
67 trigger
->firing_policy
.threshold
= 1;
69 lttng_condition_get(condition
);
70 trigger
->condition
= condition
;
72 lttng_action_get(action
);
73 trigger
->action
= action
;
80 * Note: the lack of reference counting 'get' on the condition object is normal.
81 * This API was exposed as such in 2.11. The client is not expected to call
82 * lttng_condition_destroy on the returned object.
84 struct lttng_condition
*lttng_trigger_get_condition(
85 struct lttng_trigger
*trigger
)
87 return trigger
? trigger
->condition
: NULL
;
90 const struct lttng_condition
*lttng_trigger_get_const_condition(
91 const struct lttng_trigger
*trigger
)
93 return trigger
? trigger
->condition
: NULL
;
97 * Note: the lack of reference counting 'get' on the action object is normal.
98 * This API was exposed as such in 2.11. The client is not expected to call
99 * lttng_action_destroy on the returned object.
101 struct lttng_action
*lttng_trigger_get_action(
102 struct lttng_trigger
*trigger
)
104 return trigger
? trigger
->action
: NULL
;
107 const struct lttng_action
*lttng_trigger_get_const_action(
108 const struct lttng_trigger
*trigger
)
110 return trigger
? trigger
->action
: NULL
;
113 static void trigger_destroy_ref(struct urcu_ref
*ref
)
115 struct lttng_trigger
*trigger
=
116 container_of(ref
, struct lttng_trigger
, ref
);
117 struct lttng_action
*action
= lttng_trigger_get_action(trigger
);
118 struct lttng_condition
*condition
=
119 lttng_trigger_get_condition(trigger
);
124 /* Release ownership. */
125 lttng_action_put(action
);
126 lttng_condition_put(condition
);
132 void lttng_trigger_destroy(struct lttng_trigger
*trigger
)
134 lttng_trigger_put(trigger
);
137 static bool is_firing_policy_valid(enum lttng_trigger_firing_policy policy
)
142 case LTTNG_TRIGGER_FIRING_POLICY_EVERY_N
:
143 case LTTNG_TRIGGER_FIRING_POLICY_ONCE_AFTER_N
:
155 ssize_t
lttng_trigger_create_from_payload(
156 struct lttng_payload_view
*src_view
,
157 struct lttng_trigger
**_trigger
)
159 ssize_t ret
, offset
= 0, condition_size
, action_size
, name_size
= 0;
160 struct lttng_condition
*condition
= NULL
;
161 struct lttng_action
*action
= NULL
;
162 const struct lttng_trigger_comm
*trigger_comm
;
163 const char *name
= NULL
;
164 uint64_t firing_policy_threshold
;
165 enum lttng_trigger_firing_policy firing_policy
;
166 struct lttng_credentials creds
= {
167 .uid
= LTTNG_OPTIONAL_INIT_UNSET
,
168 .gid
= LTTNG_OPTIONAL_INIT_UNSET
,
170 struct lttng_trigger
*trigger
= NULL
;
171 const struct lttng_payload_view trigger_comm_view
=
172 lttng_payload_view_from_view(
173 src_view
, 0, sizeof(*trigger_comm
));
175 if (!src_view
|| !_trigger
) {
180 if (!lttng_payload_view_is_valid(&trigger_comm_view
)) {
181 /* Payload not large enough to contain the header. */
186 /* lttng_trigger_comm header */
187 trigger_comm
= (typeof(trigger_comm
)) trigger_comm_view
.buffer
.data
;
189 /* Set the trigger's creds. */
190 if (trigger_comm
->uid
> (uint64_t) ((uid_t
) -1)) {
191 /* UID out of range for this platform. */
196 LTTNG_OPTIONAL_SET(&creds
.uid
, trigger_comm
->uid
);
198 offset
+= sizeof(*trigger_comm
);
200 firing_policy
= trigger_comm
->firing_policy_type
;
201 if (!is_firing_policy_valid(firing_policy
)) {
206 firing_policy_threshold
= trigger_comm
->firing_policy_threshold
;
207 if (trigger_comm
->name_length
!= 0) {
209 const struct lttng_payload_view name_view
=
210 lttng_payload_view_from_view(
212 trigger_comm
->name_length
);
214 if (!lttng_payload_view_is_valid(&name_view
)) {
219 name
= name_view
.buffer
.data
;
220 if (!lttng_buffer_view_contains_string(&name_view
.buffer
, name
,
221 trigger_comm
->name_length
)) {
226 offset
+= trigger_comm
->name_length
;
227 name_size
= trigger_comm
->name_length
;
231 /* struct lttng_condition */
232 struct lttng_payload_view condition_view
=
233 lttng_payload_view_from_view(
234 src_view
, offset
, -1);
236 condition_size
= lttng_condition_create_from_payload(&condition_view
,
240 if (condition_size
< 0) {
241 ret
= condition_size
;
245 offset
+= condition_size
;
247 /* struct lttng_action */
248 struct lttng_payload_view action_view
=
249 lttng_payload_view_from_view(
250 src_view
, offset
, -1);
252 action_size
= lttng_action_create_from_payload(&action_view
, &action
);
255 if (action_size
< 0) {
259 offset
+= action_size
;
261 /* Unexpected size of inner-elements; the buffer is corrupted. */
262 if ((ssize_t
) trigger_comm
->length
!= condition_size
+ action_size
+ name_size
) {
267 trigger
= lttng_trigger_create(condition
, action
);
273 lttng_trigger_set_credentials(trigger
, &creds
);
276 * The trigger object owns references to the action and condition
279 lttng_condition_put(condition
);
282 lttng_action_put(action
);
286 const enum lttng_trigger_status status
=
287 lttng_trigger_set_name(trigger
, name
);
289 if (status
!= LTTNG_TRIGGER_STATUS_OK
) {
295 /* Set the policy. */
297 const enum lttng_trigger_status status
=
298 lttng_trigger_set_firing_policy(trigger
,
300 firing_policy_threshold
);
302 if (status
!= LTTNG_TRIGGER_STATUS_OK
) {
311 lttng_condition_put(condition
);
312 lttng_action_put(action
);
317 lttng_trigger_put(trigger
);
324 * Both elements are stored contiguously, see their "*_comm" structure
325 * for the detailed format.
328 int lttng_trigger_serialize(const struct lttng_trigger
*trigger
,
329 struct lttng_payload
*payload
)
332 size_t header_offset
, size_before_payload
, size_name
;
333 struct lttng_trigger_comm trigger_comm
= {};
334 struct lttng_trigger_comm
*header
;
335 const struct lttng_credentials
*creds
= NULL
;
337 creds
= lttng_trigger_get_credentials(trigger
);
340 trigger_comm
.uid
= LTTNG_OPTIONAL_GET(creds
->uid
);
342 if (trigger
->name
!= NULL
) {
343 size_name
= strlen(trigger
->name
) + 1;
348 trigger_comm
.name_length
= size_name
;
349 trigger_comm
.firing_policy_type
= (uint8_t) trigger
->firing_policy
.type
;
350 trigger_comm
.firing_policy_threshold
= (uint64_t) trigger
->firing_policy
.threshold
;
352 header_offset
= payload
->buffer
.size
;
353 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, &trigger_comm
,
354 sizeof(trigger_comm
));
359 size_before_payload
= payload
->buffer
.size
;
362 ret
= lttng_dynamic_buffer_append(
363 &payload
->buffer
, trigger
->name
, size_name
);
368 ret
= lttng_condition_serialize(trigger
->condition
, payload
);
373 ret
= lttng_action_serialize(trigger
->action
, payload
);
378 /* Update payload size. */
379 header
= (typeof(header
)) (payload
->buffer
.data
+ header_offset
);
380 header
->length
= payload
->buffer
.size
- size_before_payload
;
386 bool lttng_trigger_is_equal(
387 const struct lttng_trigger
*a
, const struct lttng_trigger
*b
)
389 if (a
->firing_policy
.type
!= b
->firing_policy
.type
) {
393 if (a
->firing_policy
.threshold
!= b
->firing_policy
.threshold
) {
398 * FIXME: frdeso: this is a change of behavior.
399 * See internal tracker issue 1028.
401 if (strcmp(a
->name
, b
->name
) != 0) {
405 if (!lttng_condition_is_equal(a
->condition
, b
->condition
)) {
409 if (!lttng_action_is_equal(a
->action
, b
->action
)) {
413 if (!lttng_credentials_is_equal(lttng_trigger_get_credentials(a
),
414 lttng_trigger_get_credentials(b
))) {
421 enum lttng_trigger_status
lttng_trigger_set_name(struct lttng_trigger
*trigger
,
424 char *name_copy
= NULL
;
425 enum lttng_trigger_status status
= LTTNG_TRIGGER_STATUS_OK
;
427 if (!trigger
|| !name
||
429 status
= LTTNG_TRIGGER_STATUS_INVALID
;
433 name_copy
= strdup(name
);
435 status
= LTTNG_TRIGGER_STATUS_ERROR
;
441 trigger
->name
= name_copy
;
447 enum lttng_trigger_status
lttng_trigger_get_name(
448 const struct lttng_trigger
*trigger
, const char **name
)
450 enum lttng_trigger_status status
= LTTNG_TRIGGER_STATUS_OK
;
452 if (!trigger
|| !name
) {
453 status
= LTTNG_TRIGGER_STATUS_INVALID
;
457 if (!trigger
->name
) {
458 status
= LTTNG_TRIGGER_STATUS_UNSET
;
461 *name
= trigger
->name
;
467 int lttng_trigger_assign_name(struct lttng_trigger
*dst
,
468 const struct lttng_trigger
*src
)
471 enum lttng_trigger_status status
;
473 status
= lttng_trigger_set_name(dst
, src
->name
);
474 if (status
!= LTTNG_TRIGGER_STATUS_OK
) {
476 ERR("Failed to set name for trigger");
484 void lttng_trigger_set_tracer_token(struct lttng_trigger
*trigger
,
488 LTTNG_OPTIONAL_SET(&trigger
->tracer_token
, token
);
492 uint64_t lttng_trigger_get_tracer_token(const struct lttng_trigger
*trigger
)
496 return LTTNG_OPTIONAL_GET(trigger
->tracer_token
);
500 int lttng_trigger_generate_name(struct lttng_trigger
*trigger
,
504 char *generated_name
= NULL
;
506 ret
= asprintf(&generated_name
, "T%" PRIu64
"", unique_id
);
508 ERR("Failed to generate trigger name");
515 trigger
->name
= generated_name
;
521 void lttng_trigger_get(struct lttng_trigger
*trigger
)
523 urcu_ref_get(&trigger
->ref
);
527 void lttng_trigger_put(struct lttng_trigger
*trigger
)
533 urcu_ref_put(&trigger
->ref
, trigger_destroy_ref
);
536 static void delete_trigger_array_element(void *ptr
)
538 struct lttng_trigger
*trigger
= ptr
;
540 lttng_trigger_put(trigger
);
544 struct lttng_triggers
*lttng_triggers_create(void)
546 struct lttng_triggers
*triggers
= NULL
;
548 triggers
= zmalloc(sizeof(*triggers
));
553 lttng_dynamic_pointer_array_init(&triggers
->array
, delete_trigger_array_element
);
560 struct lttng_trigger
*lttng_triggers_borrow_mutable_at_index(
561 const struct lttng_triggers
*triggers
, unsigned int index
)
563 struct lttng_trigger
*trigger
= NULL
;
566 if (index
>= lttng_dynamic_pointer_array_get_count(&triggers
->array
)) {
570 trigger
= (struct lttng_trigger
*)
571 lttng_dynamic_pointer_array_get_pointer(
572 &triggers
->array
, index
);
578 int lttng_triggers_add(
579 struct lttng_triggers
*triggers
, struct lttng_trigger
*trigger
)
586 lttng_trigger_get(trigger
);
588 ret
= lttng_dynamic_pointer_array_add_pointer(&triggers
->array
, trigger
);
590 lttng_trigger_put(trigger
);
596 const struct lttng_trigger
*lttng_triggers_get_at_index(
597 const struct lttng_triggers
*triggers
, unsigned int index
)
599 return lttng_triggers_borrow_mutable_at_index(triggers
, index
);
602 enum lttng_trigger_status
lttng_triggers_get_count(const struct lttng_triggers
*triggers
, unsigned int *count
)
604 enum lttng_trigger_status status
= LTTNG_TRIGGER_STATUS_OK
;
606 if (!triggers
|| !count
) {
607 status
= LTTNG_TRIGGER_STATUS_INVALID
;
611 *count
= lttng_dynamic_pointer_array_get_count(&triggers
->array
);
616 void lttng_triggers_destroy(struct lttng_triggers
*triggers
)
622 lttng_dynamic_pointer_array_reset(&triggers
->array
);
626 int lttng_triggers_serialize(const struct lttng_triggers
*triggers
,
627 struct lttng_payload
*payload
)
630 unsigned int i
, count
;
631 size_t size_before_payload
;
632 struct lttng_triggers_comm triggers_comm
= {};
633 struct lttng_triggers_comm
*header
;
634 enum lttng_trigger_status status
;
635 const size_t header_offset
= payload
->buffer
.size
;
637 status
= lttng_triggers_get_count(triggers
, &count
);
638 if (status
!= LTTNG_TRIGGER_STATUS_OK
) {
639 ret
= LTTNG_ERR_INVALID
;
643 triggers_comm
.count
= count
;
645 /* Placeholder header; updated at the end. */
646 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, &triggers_comm
,
647 sizeof(triggers_comm
));
652 size_before_payload
= payload
->buffer
.size
;
654 for (i
= 0; i
< count
; i
++) {
655 const struct lttng_trigger
*trigger
=
656 lttng_triggers_get_at_index(triggers
, i
);
660 ret
= lttng_trigger_serialize(trigger
, payload
);
666 /* Update payload size. */
667 header
= (struct lttng_triggers_comm
*) ((char *) payload
->buffer
.data
+ header_offset
);
668 header
->length
= payload
->buffer
.size
- size_before_payload
;
674 ssize_t
lttng_triggers_create_from_payload(
675 struct lttng_payload_view
*src_view
,
676 struct lttng_triggers
**triggers
)
678 ssize_t ret
, offset
= 0, triggers_size
= 0;
680 const struct lttng_triggers_comm
*triggers_comm
;
681 struct lttng_triggers
*local_triggers
= NULL
;
683 if (!src_view
|| !triggers
) {
688 /* lttng_trigger_comms header */
689 triggers_comm
= (const struct lttng_triggers_comm
*) src_view
->buffer
.data
;
690 offset
+= sizeof(*triggers_comm
);
692 local_triggers
= lttng_triggers_create();
693 if (!local_triggers
) {
698 for (i
= 0; i
< triggers_comm
->count
; i
++) {
699 struct lttng_trigger
*trigger
= NULL
;
700 struct lttng_payload_view trigger_view
=
701 lttng_payload_view_from_view(src_view
, offset
, -1);
702 ssize_t trigger_size
;
704 trigger_size
= lttng_trigger_create_from_payload(
705 &trigger_view
, &trigger
);
706 if (trigger_size
< 0) {
711 /* Transfer ownership of the trigger to the collection. */
712 ret
= lttng_triggers_add(local_triggers
, trigger
);
713 lttng_trigger_put(trigger
);
719 offset
+= trigger_size
;
720 triggers_size
+= trigger_size
;
723 /* Unexpected size of inner-elements; the buffer is corrupted. */
724 if ((ssize_t
) triggers_comm
->length
!= triggers_size
) {
729 /* Pass ownership to caller. */
730 *triggers
= local_triggers
;
731 local_triggers
= NULL
;
736 lttng_triggers_destroy(local_triggers
);
741 const struct lttng_credentials
*lttng_trigger_get_credentials(
742 const struct lttng_trigger
*trigger
)
744 return &trigger
->creds
;
748 void lttng_trigger_set_credentials(struct lttng_trigger
*trigger
,
749 const struct lttng_credentials
*creds
)
752 trigger
->creds
= *creds
;
755 enum lttng_trigger_status
lttng_trigger_set_owner_uid(
756 struct lttng_trigger
*trigger
, uid_t uid
)
758 enum lttng_trigger_status ret
= LTTNG_TRIGGER_STATUS_OK
;
759 const struct lttng_credentials creds
= {
760 .uid
= LTTNG_OPTIONAL_INIT_VALUE(uid
),
761 .gid
= LTTNG_OPTIONAL_INIT_UNSET
,
765 ret
= LTTNG_TRIGGER_STATUS_INVALID
;
769 /* Client-side validation only to report a clearer error. */
770 if (geteuid() != 0) {
771 ret
= LTTNG_TRIGGER_STATUS_PERMISSION_DENIED
;
775 lttng_trigger_set_credentials(trigger
, &creds
);
781 enum lttng_trigger_status
lttng_trigger_get_owner_uid(
782 const struct lttng_trigger
*trigger
, uid_t
*uid
)
784 enum lttng_trigger_status ret
= LTTNG_TRIGGER_STATUS_OK
;
785 const struct lttng_credentials
*creds
= NULL
;
787 if (!trigger
|| !uid
) {
788 ret
= LTTNG_TRIGGER_STATUS_INVALID
;
792 if (!trigger
->creds
.uid
.is_set
) {
793 ret
= LTTNG_TRIGGER_STATUS_UNSET
;
797 creds
= lttng_trigger_get_credentials(trigger
);
798 *uid
= lttng_credentials_get_uid(creds
);
804 enum lttng_trigger_status
lttng_trigger_set_firing_policy(
805 struct lttng_trigger
*trigger
,
806 enum lttng_trigger_firing_policy policy_type
,
809 enum lttng_trigger_status ret
= LTTNG_TRIGGER_STATUS_OK
;
813 ret
= LTTNG_TRIGGER_STATUS_INVALID
;
817 trigger
->firing_policy
.type
= policy_type
;
818 trigger
->firing_policy
.threshold
= threshold
;
824 enum lttng_trigger_status
lttng_trigger_get_firing_policy(
825 const struct lttng_trigger
*trigger
,
826 enum lttng_trigger_firing_policy
*policy_type
,
829 enum lttng_trigger_status status
= LTTNG_TRIGGER_STATUS_OK
;
831 if (!trigger
|| !policy_type
|| !threshold
) {
832 status
= LTTNG_TRIGGER_STATUS_INVALID
;
836 *policy_type
= trigger
->firing_policy
.type
;
837 *threshold
= trigger
->firing_policy
.threshold
;
844 bool lttng_trigger_should_fire(const struct lttng_trigger
*trigger
)
846 bool ready_to_fire
= false;
850 switch (trigger
->firing_policy
.type
) {
851 case LTTNG_TRIGGER_FIRING_POLICY_EVERY_N
:
852 if (trigger
->firing_policy
.current_count
< trigger
->firing_policy
.threshold
) {
853 ready_to_fire
= true;
856 case LTTNG_TRIGGER_FIRING_POLICY_ONCE_AFTER_N
:
857 if (trigger
->firing_policy
.current_count
< trigger
->firing_policy
.threshold
) {
858 ready_to_fire
= true;
865 return ready_to_fire
;
869 void lttng_trigger_fire(struct lttng_trigger
*trigger
)
873 trigger
->firing_policy
.current_count
++;
875 switch (trigger
->firing_policy
.type
) {
876 case LTTNG_TRIGGER_FIRING_POLICY_EVERY_N
:
877 if (trigger
->firing_policy
.current_count
== trigger
->firing_policy
.threshold
) {
878 trigger
->firing_policy
.current_count
= 0;
882 case LTTNG_TRIGGER_FIRING_POLICY_ONCE_AFTER_N
:
885 * As an optimisation, deactivate the trigger condition and
886 * remove any checks in the traced application or kernel since
887 * the trigger will never fire again.
896 enum lttng_domain_type
lttng_trigger_get_underlying_domain_type_restriction(
897 const struct lttng_trigger
*trigger
)
899 enum lttng_domain_type type
= LTTNG_DOMAIN_NONE
;
900 const struct lttng_event_rule
*event_rule
;
901 enum lttng_condition_status c_status
;
902 enum lttng_condition_type c_type
;
905 assert(trigger
->condition
);
907 c_type
= lttng_condition_get_type(trigger
->condition
);
908 assert (c_type
!= LTTNG_CONDITION_TYPE_UNKNOWN
);
911 case LTTNG_CONDITION_TYPE_SESSION_CONSUMED_SIZE
:
912 case LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING
:
913 case LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED
:
914 /* Apply to any domain. */
915 type
= LTTNG_DOMAIN_NONE
;
917 case LTTNG_CONDITION_TYPE_ON_EVENT
:
918 /* Return the domain of the event rule. */
919 c_status
= lttng_condition_on_event_get_rule(
920 trigger
->condition
, &event_rule
);
921 assert(c_status
== LTTNG_CONDITION_STATUS_OK
);
922 type
= lttng_event_rule_get_domain_type(event_rule
);
924 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH
:
925 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW
:
926 /* Return the domain of the channel being monitored. */
927 c_status
= lttng_condition_buffer_usage_get_domain_type(
928 trigger
->condition
, &type
);
929 assert(c_status
== LTTNG_CONDITION_STATUS_OK
);
939 * Generate bytecode related to the trigger.
940 * On success LTTNG_OK. On error, returns lttng_error code.
943 enum lttng_error_code
lttng_trigger_generate_bytecode(
944 struct lttng_trigger
*trigger
,
945 const struct lttng_credentials
*creds
)
947 enum lttng_error_code ret
;
948 struct lttng_condition
*condition
= NULL
;
950 condition
= lttng_trigger_get_condition(trigger
);
952 ret
= LTTNG_ERR_INVALID_TRIGGER
;
956 switch (lttng_condition_get_type(condition
)) {
957 case LTTNG_CONDITION_TYPE_ON_EVENT
:
959 struct lttng_event_rule
*event_rule
;
960 const enum lttng_condition_status condition_status
=
961 lttng_condition_on_event_borrow_rule_mutable(
962 condition
, &event_rule
);
964 assert(condition_status
== LTTNG_CONDITION_STATUS_OK
);
966 /* Generate the filter bytecode. */
967 ret
= lttng_event_rule_generate_filter_bytecode(
969 if (ret
!= LTTNG_OK
) {
973 /* Generate the capture bytecode. */
974 ret
= lttng_condition_on_event_generate_capture_descriptor_bytecode(
976 if (ret
!= LTTNG_OK
) {
992 struct lttng_trigger
*lttng_trigger_copy(const struct lttng_trigger
*trigger
)
995 struct lttng_payload copy_buffer
;
996 struct lttng_trigger
*copy
= NULL
;
998 lttng_payload_init(©_buffer
);
1000 ret
= lttng_trigger_serialize(trigger
, ©_buffer
);
1006 struct lttng_payload_view view
=
1007 lttng_payload_view_from_payload(
1008 ©_buffer
, 0, -1);
1009 ret
= lttng_trigger_create_from_payload(
1018 lttng_payload_reset(©_buffer
);
1024 bool action_type_needs_tracer_notifier(enum lttng_action_type action_type
)
1026 switch (action_type
) {
1027 case LTTNG_ACTION_TYPE_NOTIFY
:
1028 case LTTNG_ACTION_TYPE_START_SESSION
:
1029 case LTTNG_ACTION_TYPE_STOP_SESSION
:
1030 case LTTNG_ACTION_TYPE_SNAPSHOT_SESSION
:
1031 case LTTNG_ACTION_TYPE_ROTATE_SESSION
:
1033 case LTTNG_ACTION_TYPE_INCREMENT_VALUE
:
1035 case LTTNG_ACTION_TYPE_GROUP
:
1036 case LTTNG_ACTION_TYPE_UNKNOWN
:
1043 bool action_needs_tracer_notifier(const struct lttng_action
*action
)
1045 bool needs_tracer_notifier
= false;
1046 unsigned int i
, count
;
1047 enum lttng_action_status action_status
;
1048 enum lttng_action_type action_type
;
1051 /* If there is only one action. Check if it needs a tracer notifier. */
1052 action_type
= lttng_action_get_type(action
);
1053 if (action_type
!= LTTNG_ACTION_TYPE_GROUP
) {
1054 needs_tracer_notifier
= action_type_needs_tracer_notifier(
1060 * Iterate over all the actions of the action group and check if any of
1061 * them needs a tracer notifier.
1063 action_status
= lttng_action_group_get_count(action
, &count
);
1064 assert(action_status
== LTTNG_ACTION_STATUS_OK
);
1065 for (i
= 0; i
< count
; i
++) {
1066 const struct lttng_action
*inner_action
=
1067 lttng_action_group_get_at_index(action
, i
);
1069 action_type
= lttng_action_get_type(inner_action
);
1070 if (action_type_needs_tracer_notifier(action_type
)) {
1071 needs_tracer_notifier
= true;
1077 return needs_tracer_notifier
;
1081 bool lttng_trigger_needs_tracer_notifier(const struct lttng_trigger
*trigger
)
1083 bool needs_tracer_notifier
= false;
1084 const struct lttng_condition
*condition
=
1085 lttng_trigger_get_const_condition(trigger
);
1086 const struct lttng_action
*action
=
1087 lttng_trigger_get_const_action(trigger
);
1089 switch (lttng_condition_get_type(condition
)) {
1090 case LTTNG_CONDITION_TYPE_ON_EVENT
:
1091 needs_tracer_notifier
= action_needs_tracer_notifier(action
);
1093 case LTTNG_CONDITION_TYPE_SESSION_CONSUMED_SIZE
:
1094 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH
:
1095 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW
:
1096 case LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING
:
1097 case LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED
:
1099 case LTTNG_CONDITION_TYPE_UNKNOWN
:
1104 return needs_tracer_notifier
;