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/event-rule.h>
11 #include <lttng/condition/event-rule-internal.h>
12 #include <lttng/condition/buffer-usage.h>
13 #include <lttng/event-rule/event-rule-internal.h>
14 #include <lttng/action/action-internal.h>
15 #include <common/credentials.h>
16 #include <common/payload.h>
17 #include <common/payload-view.h>
18 #include <lttng/domain.h>
19 #include <common/error.h>
20 #include <common/dynamic-array.h>
21 #include <common/optional.h>
26 bool lttng_trigger_validate(const struct lttng_trigger
*trigger
)
35 if (!trigger
->creds
.uid
.is_set
) {
40 valid
= lttng_condition_validate(trigger
->condition
) &&
41 lttng_action_validate(trigger
->action
);
46 struct lttng_trigger
*lttng_trigger_create(
47 struct lttng_condition
*condition
,
48 struct lttng_action
*action
)
50 struct lttng_trigger
*trigger
= NULL
;
52 if (!condition
|| !action
) {
56 trigger
= zmalloc(sizeof(struct lttng_trigger
));
61 urcu_ref_init(&trigger
->ref
);
63 trigger
->firing_policy
.type
= LTTNG_TRIGGER_FIRING_POLICY_EVERY_N
;
64 trigger
->firing_policy
.threshold
= 1;
66 lttng_condition_get(condition
);
67 trigger
->condition
= condition
;
69 lttng_action_get(action
);
70 trigger
->action
= action
;
77 * Note: the lack of reference counting 'get' on the condition object is normal.
78 * This API was exposed as such in 2.11. The client is not expected to call
79 * lttng_condition_destroy on the returned object.
81 struct lttng_condition
*lttng_trigger_get_condition(
82 struct lttng_trigger
*trigger
)
84 return trigger
? trigger
->condition
: NULL
;
87 const struct lttng_condition
*lttng_trigger_get_const_condition(
88 const struct lttng_trigger
*trigger
)
90 return trigger
? trigger
->condition
: NULL
;
95 * Note: the lack of reference counting 'get' on the action object is normal.
96 * This API was exposed as such in 2.11. The client is not expected to call
97 * lttng_action_destroy on the returned object.
99 struct lttng_action
*lttng_trigger_get_action(
100 struct lttng_trigger
*trigger
)
102 return trigger
? trigger
->action
: NULL
;
105 const struct lttng_action
*lttng_trigger_get_const_action(
106 const struct lttng_trigger
*trigger
)
108 return trigger
? trigger
->action
: NULL
;
111 static void trigger_destroy_ref(struct urcu_ref
*ref
)
113 struct lttng_trigger
*trigger
=
114 container_of(ref
, struct lttng_trigger
, ref
);
115 struct lttng_action
*action
= lttng_trigger_get_action(trigger
);
116 struct lttng_condition
*condition
=
117 lttng_trigger_get_condition(trigger
);
122 /* Release ownership. */
123 lttng_action_put(action
);
124 lttng_condition_put(condition
);
130 void lttng_trigger_destroy(struct lttng_trigger
*trigger
)
132 lttng_trigger_put(trigger
);
135 static bool is_firing_policy_valid(enum lttng_trigger_firing_policy policy
)
140 case LTTNG_TRIGGER_FIRING_POLICY_EVERY_N
:
141 case LTTNG_TRIGGER_FIRING_POLICY_ONCE_AFTER_N
:
153 ssize_t
lttng_trigger_create_from_payload(
154 struct lttng_payload_view
*src_view
,
155 struct lttng_trigger
**_trigger
)
157 ssize_t ret
, offset
= 0, condition_size
, action_size
, name_size
= 0;
158 struct lttng_condition
*condition
= NULL
;
159 struct lttng_action
*action
= NULL
;
160 const struct lttng_trigger_comm
*trigger_comm
;
161 const char *name
= NULL
;
162 uint64_t firing_policy_threshold
;
163 enum lttng_trigger_firing_policy firing_policy
;
164 struct lttng_credentials creds
= {
165 .uid
= LTTNG_OPTIONAL_INIT_UNSET
,
166 .gid
= LTTNG_OPTIONAL_INIT_UNSET
,
168 struct lttng_trigger
*trigger
= NULL
;
169 const struct lttng_payload_view trigger_comm_view
=
170 lttng_payload_view_from_view(
171 src_view
, 0, sizeof(*trigger_comm
));
173 if (!src_view
|| !_trigger
) {
178 if (!lttng_payload_view_is_valid(&trigger_comm_view
)) {
179 /* Payload not large enough to contain the header. */
184 /* lttng_trigger_comm header */
185 trigger_comm
= (typeof(trigger_comm
)) trigger_comm_view
.buffer
.data
;
187 /* Set the trigger's creds. */
188 if (trigger_comm
->uid
> (uint64_t) ((uid_t
) -1)) {
189 /* UID out of range for this platform. */
194 LTTNG_OPTIONAL_SET(&creds
.uid
, trigger_comm
->uid
);
196 offset
+= sizeof(*trigger_comm
);
198 firing_policy
= trigger_comm
->firing_policy_type
;
199 if (!is_firing_policy_valid(firing_policy
)) {
204 firing_policy_threshold
= trigger_comm
->firing_policy_threshold
;
205 if (trigger_comm
->name_length
!= 0) {
207 const struct lttng_payload_view name_view
=
208 lttng_payload_view_from_view(
210 trigger_comm
->name_length
);
212 if (!lttng_payload_view_is_valid(&name_view
)) {
217 name
= name_view
.buffer
.data
;
218 if (!lttng_buffer_view_contains_string(&name_view
.buffer
, name
,
219 trigger_comm
->name_length
)) {
224 offset
+= trigger_comm
->name_length
;
225 name_size
= trigger_comm
->name_length
;
229 /* struct lttng_condition */
230 struct lttng_payload_view condition_view
=
231 lttng_payload_view_from_view(
232 src_view
, offset
, -1);
234 condition_size
= lttng_condition_create_from_payload(&condition_view
,
238 if (condition_size
< 0) {
239 ret
= condition_size
;
243 offset
+= condition_size
;
245 /* struct lttng_action */
246 struct lttng_payload_view action_view
=
247 lttng_payload_view_from_view(
248 src_view
, offset
, -1);
250 action_size
= lttng_action_create_from_payload(&action_view
, &action
);
253 if (action_size
< 0) {
257 offset
+= action_size
;
259 /* Unexpected size of inner-elements; the buffer is corrupted. */
260 if ((ssize_t
) trigger_comm
->length
!= condition_size
+ action_size
+ name_size
) {
265 trigger
= lttng_trigger_create(condition
, action
);
271 lttng_trigger_set_credentials(trigger
, &creds
);
274 * The trigger object owns references to the action and condition
277 lttng_condition_put(condition
);
280 lttng_action_put(action
);
284 const enum lttng_trigger_status status
=
285 lttng_trigger_set_name(trigger
, name
);
287 if (status
!= LTTNG_TRIGGER_STATUS_OK
) {
293 /* Set the policy. */
295 const enum lttng_trigger_status status
=
296 lttng_trigger_set_firing_policy(trigger
,
298 firing_policy_threshold
);
300 if (status
!= LTTNG_TRIGGER_STATUS_OK
) {
309 lttng_condition_put(condition
);
310 lttng_action_put(action
);
315 lttng_trigger_put(trigger
);
322 * Both elements are stored contiguously, see their "*_comm" structure
323 * for the detailed format.
326 int lttng_trigger_serialize(const struct lttng_trigger
*trigger
,
327 struct lttng_payload
*payload
)
330 size_t header_offset
, size_before_payload
, size_name
;
331 struct lttng_trigger_comm trigger_comm
= {};
332 struct lttng_trigger_comm
*header
;
333 const struct lttng_credentials
*creds
= NULL
;
335 creds
= lttng_trigger_get_credentials(trigger
);
338 trigger_comm
.uid
= LTTNG_OPTIONAL_GET(creds
->uid
);
340 if (trigger
->name
!= NULL
) {
341 size_name
= strlen(trigger
->name
) + 1;
346 trigger_comm
.name_length
= size_name
;
347 trigger_comm
.firing_policy_type
= (uint8_t) trigger
->firing_policy
.type
;
348 trigger_comm
.firing_policy_threshold
= (uint64_t) trigger
->firing_policy
.threshold
;
350 header_offset
= payload
->buffer
.size
;
351 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, &trigger_comm
,
352 sizeof(trigger_comm
));
357 size_before_payload
= payload
->buffer
.size
;
360 ret
= lttng_dynamic_buffer_append(
361 &payload
->buffer
, trigger
->name
, size_name
);
366 ret
= lttng_condition_serialize(trigger
->condition
, payload
);
371 ret
= lttng_action_serialize(trigger
->action
, payload
);
376 /* Update payload size. */
377 header
= (typeof(header
)) (payload
->buffer
.data
+ header_offset
);
378 header
->length
= payload
->buffer
.size
- size_before_payload
;
384 bool lttng_trigger_is_equal(
385 const struct lttng_trigger
*a
, const struct lttng_trigger
*b
)
387 if (a
->firing_policy
.type
!= b
->firing_policy
.type
) {
391 if (a
->firing_policy
.threshold
!= b
->firing_policy
.threshold
) {
396 * Name is not taken into account since it is cosmetic only.
398 if (!lttng_condition_is_equal(a
->condition
, b
->condition
)) {
402 if (!lttng_action_is_equal(a
->action
, b
->action
)) {
406 if (!lttng_credentials_is_equal(lttng_trigger_get_credentials(a
),
407 lttng_trigger_get_credentials(b
))) {
414 enum lttng_trigger_status
lttng_trigger_set_name(struct lttng_trigger
*trigger
,
417 char *name_copy
= NULL
;
418 enum lttng_trigger_status status
= LTTNG_TRIGGER_STATUS_OK
;
420 if (!trigger
|| !name
||
422 status
= LTTNG_TRIGGER_STATUS_INVALID
;
426 name_copy
= strdup(name
);
428 status
= LTTNG_TRIGGER_STATUS_ERROR
;
434 trigger
->name
= name_copy
;
440 enum lttng_trigger_status
lttng_trigger_get_name(
441 const struct lttng_trigger
*trigger
, const char **name
)
443 enum lttng_trigger_status status
= LTTNG_TRIGGER_STATUS_OK
;
445 if (!trigger
|| !name
) {
446 status
= LTTNG_TRIGGER_STATUS_INVALID
;
450 if (!trigger
->name
) {
451 status
= LTTNG_TRIGGER_STATUS_UNSET
;
454 *name
= trigger
->name
;
460 int lttng_trigger_assign_name(struct lttng_trigger
*dst
,
461 const struct lttng_trigger
*src
)
464 enum lttng_trigger_status status
;
466 status
= lttng_trigger_set_name(dst
, src
->name
);
467 if (status
!= LTTNG_TRIGGER_STATUS_OK
) {
469 ERR("Failed to set name for trigger");
477 void lttng_trigger_set_tracer_token(struct lttng_trigger
*trigger
,
481 LTTNG_OPTIONAL_SET(&trigger
->tracer_token
, token
);
485 uint64_t lttng_trigger_get_tracer_token(const struct lttng_trigger
*trigger
)
489 return LTTNG_OPTIONAL_GET(trigger
->tracer_token
);
493 int lttng_trigger_generate_name(struct lttng_trigger
*trigger
,
497 char *generated_name
= NULL
;
499 ret
= asprintf(&generated_name
, "T%" PRIu64
"", unique_id
);
501 ERR("Failed to generate trigger name");
508 trigger
->name
= generated_name
;
514 void lttng_trigger_get(struct lttng_trigger
*trigger
)
516 urcu_ref_get(&trigger
->ref
);
520 void lttng_trigger_put(struct lttng_trigger
*trigger
)
526 urcu_ref_put(&trigger
->ref
, trigger_destroy_ref
);
529 static void delete_trigger_array_element(void *ptr
)
531 struct lttng_trigger
*trigger
= ptr
;
533 lttng_trigger_put(trigger
);
537 struct lttng_triggers
*lttng_triggers_create(void)
539 struct lttng_triggers
*triggers
= NULL
;
541 triggers
= zmalloc(sizeof(*triggers
));
546 lttng_dynamic_pointer_array_init(&triggers
->array
, delete_trigger_array_element
);
553 struct lttng_trigger
*lttng_triggers_borrow_mutable_at_index(
554 const struct lttng_triggers
*triggers
, unsigned int index
)
556 struct lttng_trigger
*trigger
= NULL
;
559 if (index
>= lttng_dynamic_pointer_array_get_count(&triggers
->array
)) {
563 trigger
= (struct lttng_trigger
*)
564 lttng_dynamic_pointer_array_get_pointer(
565 &triggers
->array
, index
);
571 int lttng_triggers_add(
572 struct lttng_triggers
*triggers
, struct lttng_trigger
*trigger
)
579 lttng_trigger_get(trigger
);
581 ret
= lttng_dynamic_pointer_array_add_pointer(&triggers
->array
, trigger
);
583 lttng_trigger_put(trigger
);
589 const struct lttng_trigger
*lttng_triggers_get_at_index(
590 const struct lttng_triggers
*triggers
, unsigned int index
)
592 return lttng_triggers_borrow_mutable_at_index(triggers
, index
);
595 enum lttng_trigger_status
lttng_triggers_get_count(const struct lttng_triggers
*triggers
, unsigned int *count
)
597 enum lttng_trigger_status status
= LTTNG_TRIGGER_STATUS_OK
;
599 if (!triggers
|| !count
) {
600 status
= LTTNG_TRIGGER_STATUS_INVALID
;
604 *count
= lttng_dynamic_pointer_array_get_count(&triggers
->array
);
609 void lttng_triggers_destroy(struct lttng_triggers
*triggers
)
615 lttng_dynamic_pointer_array_reset(&triggers
->array
);
619 int lttng_triggers_serialize(const struct lttng_triggers
*triggers
,
620 struct lttng_payload
*payload
)
623 unsigned int i
, count
;
624 size_t size_before_payload
;
625 struct lttng_triggers_comm triggers_comm
= {};
626 struct lttng_triggers_comm
*header
;
627 enum lttng_trigger_status status
;
628 const size_t header_offset
= payload
->buffer
.size
;
630 status
= lttng_triggers_get_count(triggers
, &count
);
631 if (status
!= LTTNG_TRIGGER_STATUS_OK
) {
632 ret
= LTTNG_ERR_INVALID
;
636 triggers_comm
.count
= count
;
638 /* Placeholder header; updated at the end. */
639 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, &triggers_comm
,
640 sizeof(triggers_comm
));
645 size_before_payload
= payload
->buffer
.size
;
647 for (i
= 0; i
< count
; i
++) {
648 const struct lttng_trigger
*trigger
=
649 lttng_triggers_get_at_index(triggers
, i
);
653 ret
= lttng_trigger_serialize(trigger
, payload
);
659 /* Update payload size. */
660 header
= (struct lttng_triggers_comm
*) ((char *) payload
->buffer
.data
+ header_offset
);
661 header
->length
= payload
->buffer
.size
- size_before_payload
;
667 ssize_t
lttng_triggers_create_from_payload(
668 struct lttng_payload_view
*src_view
,
669 struct lttng_triggers
**triggers
)
671 ssize_t ret
, offset
= 0, triggers_size
= 0;
673 const struct lttng_triggers_comm
*triggers_comm
;
674 struct lttng_triggers
*local_triggers
= NULL
;
676 if (!src_view
|| !triggers
) {
681 /* lttng_trigger_comms header */
682 triggers_comm
= (const struct lttng_triggers_comm
*) src_view
->buffer
.data
;
683 offset
+= sizeof(*triggers_comm
);
685 local_triggers
= lttng_triggers_create();
686 if (!local_triggers
) {
691 for (i
= 0; i
< triggers_comm
->count
; i
++) {
692 struct lttng_trigger
*trigger
= NULL
;
693 struct lttng_payload_view trigger_view
=
694 lttng_payload_view_from_view(src_view
, offset
, -1);
695 ssize_t trigger_size
;
697 trigger_size
= lttng_trigger_create_from_payload(
698 &trigger_view
, &trigger
);
699 if (trigger_size
< 0) {
704 /* Transfer ownership of the trigger to the collection. */
705 ret
= lttng_triggers_add(local_triggers
, trigger
);
706 lttng_trigger_put(trigger
);
712 offset
+= trigger_size
;
713 triggers_size
+= trigger_size
;
716 /* Unexpected size of inner-elements; the buffer is corrupted. */
717 if ((ssize_t
) triggers_comm
->length
!= triggers_size
) {
722 /* Pass ownership to caller. */
723 *triggers
= local_triggers
;
724 local_triggers
= NULL
;
729 lttng_triggers_destroy(local_triggers
);
734 const struct lttng_credentials
*lttng_trigger_get_credentials(
735 const struct lttng_trigger
*trigger
)
737 return &trigger
->creds
;
741 void lttng_trigger_set_credentials(struct lttng_trigger
*trigger
,
742 const struct lttng_credentials
*creds
)
745 trigger
->creds
= *creds
;
748 enum lttng_trigger_status
lttng_trigger_set_owner_uid(
749 struct lttng_trigger
*trigger
, uid_t uid
)
751 enum lttng_trigger_status ret
= LTTNG_TRIGGER_STATUS_OK
;
752 const struct lttng_credentials creds
= {
753 .uid
= LTTNG_OPTIONAL_INIT_VALUE(uid
),
754 .gid
= LTTNG_OPTIONAL_INIT_UNSET
,
758 ret
= LTTNG_TRIGGER_STATUS_INVALID
;
762 /* Client-side validation only to report a clearer error. */
763 if (geteuid() != 0) {
764 ret
= LTTNG_TRIGGER_STATUS_PERMISSION_DENIED
;
768 lttng_trigger_set_credentials(trigger
, &creds
);
774 enum lttng_trigger_status
lttng_trigger_get_owner_uid(
775 const struct lttng_trigger
*trigger
, uid_t
*uid
)
777 enum lttng_trigger_status ret
= LTTNG_TRIGGER_STATUS_OK
;
778 const struct lttng_credentials
*creds
= NULL
;
780 if (!trigger
|| !uid
) {
781 ret
= LTTNG_TRIGGER_STATUS_INVALID
;
785 if (!trigger
->creds
.uid
.is_set
) {
786 ret
= LTTNG_TRIGGER_STATUS_UNSET
;
790 creds
= lttng_trigger_get_credentials(trigger
);
791 *uid
= lttng_credentials_get_uid(creds
);
797 enum lttng_trigger_status
lttng_trigger_set_firing_policy(
798 struct lttng_trigger
*trigger
,
799 enum lttng_trigger_firing_policy policy_type
,
802 enum lttng_trigger_status ret
= LTTNG_TRIGGER_STATUS_OK
;
806 ret
= LTTNG_TRIGGER_STATUS_INVALID
;
810 trigger
->firing_policy
.type
= policy_type
;
811 trigger
->firing_policy
.threshold
= threshold
;
817 enum lttng_trigger_status
lttng_trigger_get_firing_policy(
818 const struct lttng_trigger
*trigger
,
819 enum lttng_trigger_firing_policy
*policy_type
,
822 enum lttng_trigger_status status
= LTTNG_TRIGGER_STATUS_OK
;
824 if (!trigger
|| !policy_type
|| !threshold
) {
825 status
= LTTNG_TRIGGER_STATUS_INVALID
;
829 *policy_type
= trigger
->firing_policy
.type
;
830 *threshold
= trigger
->firing_policy
.threshold
;
837 bool lttng_trigger_should_fire(const struct lttng_trigger
*trigger
)
839 bool ready_to_fire
= false;
843 switch (trigger
->firing_policy
.type
) {
844 case LTTNG_TRIGGER_FIRING_POLICY_EVERY_N
:
845 if (trigger
->firing_policy
.current_count
< trigger
->firing_policy
.threshold
) {
846 ready_to_fire
= true;
849 case LTTNG_TRIGGER_FIRING_POLICY_ONCE_AFTER_N
:
850 if (trigger
->firing_policy
.current_count
< trigger
->firing_policy
.threshold
) {
851 ready_to_fire
= true;
858 return ready_to_fire
;
862 void lttng_trigger_fire(struct lttng_trigger
*trigger
)
866 trigger
->firing_policy
.current_count
++;
868 switch (trigger
->firing_policy
.type
) {
869 case LTTNG_TRIGGER_FIRING_POLICY_EVERY_N
:
870 if (trigger
->firing_policy
.current_count
== trigger
->firing_policy
.threshold
) {
871 trigger
->firing_policy
.current_count
= 0;
875 case LTTNG_TRIGGER_FIRING_POLICY_ONCE_AFTER_N
:
878 * As an optimisation, deactivate the trigger condition and
879 * remove any checks in the traced application or kernel since
880 * the trigger will never fire again.
889 enum lttng_domain_type
lttng_trigger_get_underlying_domain_type_restriction(
890 const struct lttng_trigger
*trigger
)
892 enum lttng_domain_type type
= LTTNG_DOMAIN_NONE
;
893 const struct lttng_event_rule
*event_rule
;
894 enum lttng_condition_status c_status
;
895 enum lttng_condition_type c_type
;
898 assert(trigger
->condition
);
900 c_type
= lttng_condition_get_type(trigger
->condition
);
901 assert (c_type
!= LTTNG_CONDITION_TYPE_UNKNOWN
);
904 case LTTNG_CONDITION_TYPE_SESSION_CONSUMED_SIZE
:
905 case LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING
:
906 case LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED
:
907 /* Apply to any domain. */
908 type
= LTTNG_DOMAIN_NONE
;
910 case LTTNG_CONDITION_TYPE_EVENT_RULE_HIT
:
911 /* Return the domain of the event rule. */
912 c_status
= lttng_condition_event_rule_get_rule(
913 trigger
->condition
, &event_rule
);
914 assert(c_status
== LTTNG_CONDITION_STATUS_OK
);
915 type
= lttng_event_rule_get_domain_type(event_rule
);
917 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH
:
918 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW
:
919 /* Return the domain of the channel being monitored. */
920 c_status
= lttng_condition_buffer_usage_get_domain_type(
921 trigger
->condition
, &type
);
922 assert(c_status
== LTTNG_CONDITION_STATUS_OK
);
932 * Generate bytecode related to the trigger.
933 * On success LTTNG_OK. On error, returns lttng_error code.
936 enum lttng_error_code
lttng_trigger_generate_bytecode(
937 struct lttng_trigger
*trigger
,
938 const struct lttng_credentials
*creds
)
940 enum lttng_error_code ret
;
941 struct lttng_condition
*condition
= NULL
;
943 condition
= lttng_trigger_get_condition(trigger
);
945 ret
= LTTNG_ERR_INVALID_TRIGGER
;
949 switch (lttng_condition_get_type(condition
)) {
950 case LTTNG_CONDITION_TYPE_EVENT_RULE_HIT
:
952 struct lttng_event_rule
*event_rule
;
953 const enum lttng_condition_status condition_status
=
954 lttng_condition_event_rule_borrow_rule_mutable(
955 condition
, &event_rule
);
957 assert(condition_status
== LTTNG_CONDITION_STATUS_OK
);
958 ret
= lttng_event_rule_generate_filter_bytecode(
960 if (ret
!= LTTNG_OK
) {
976 struct lttng_trigger
*lttng_trigger_copy(const struct lttng_trigger
*trigger
)
979 struct lttng_payload copy_buffer
;
980 struct lttng_trigger
*copy
= NULL
;
982 lttng_payload_init(©_buffer
);
984 ret
= lttng_trigger_serialize(trigger
, ©_buffer
);
990 struct lttng_payload_view view
=
991 lttng_payload_view_from_payload(
992 ©_buffer
, 0, -1);
993 ret
= lttng_trigger_create_from_payload(
1002 lttng_payload_reset(©_buffer
);