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/action/action-internal.h>
11 #include <common/credentials.h>
12 #include <common/payload.h>
13 #include <common/payload-view.h>
14 #include <common/error.h>
15 #include <common/dynamic-array.h>
16 #include <common/optional.h>
21 bool lttng_trigger_validate(struct lttng_trigger
*trigger
)
30 if (!trigger
->creds
.uid
.is_set
) {
35 valid
= lttng_condition_validate(trigger
->condition
) &&
36 lttng_action_validate(trigger
->action
);
41 struct lttng_trigger
*lttng_trigger_create(
42 struct lttng_condition
*condition
,
43 struct lttng_action
*action
)
45 struct lttng_trigger
*trigger
= NULL
;
47 if (!condition
|| !action
) {
51 trigger
= zmalloc(sizeof(struct lttng_trigger
));
56 urcu_ref_init(&trigger
->ref
);
58 trigger
->firing_policy
.type
= LTTNG_TRIGGER_FIRING_POLICY_EVERY_N
;
59 trigger
->firing_policy
.threshold
= 1;
61 lttng_condition_get(condition
);
62 trigger
->condition
= condition
;
64 lttng_action_get(action
);
65 trigger
->action
= action
;
72 * Note: the lack of reference counting 'get' on the condition object is normal.
73 * This API was exposed as such in 2.11. The client is not expected to call
74 * lttng_condition_destroy on the returned object.
76 struct lttng_condition
*lttng_trigger_get_condition(
77 struct lttng_trigger
*trigger
)
79 return trigger
? trigger
->condition
: NULL
;
83 const struct lttng_condition
*lttng_trigger_get_const_condition(
84 const struct lttng_trigger
*trigger
)
86 return trigger
->condition
;
91 * Note: the lack of reference counting 'get' on the action object is normal.
92 * This API was exposed as such in 2.11. The client is not expected to call
93 * lttng_action_destroy on the returned object.
95 struct lttng_action
*lttng_trigger_get_action(
96 struct lttng_trigger
*trigger
)
98 return trigger
? trigger
->action
: NULL
;
102 const struct lttng_action
*lttng_trigger_get_const_action(
103 const struct lttng_trigger
*trigger
)
105 return trigger
->action
;
108 static void trigger_destroy_ref(struct urcu_ref
*ref
)
110 struct lttng_trigger
*trigger
=
111 container_of(ref
, struct lttng_trigger
, ref
);
112 struct lttng_action
*action
= lttng_trigger_get_action(trigger
);
113 struct lttng_condition
*condition
=
114 lttng_trigger_get_condition(trigger
);
119 /* Release ownership. */
120 lttng_action_put(action
);
121 lttng_condition_put(condition
);
127 void lttng_trigger_destroy(struct lttng_trigger
*trigger
)
129 lttng_trigger_put(trigger
);
132 static bool is_firing_policy_valid(enum lttng_trigger_firing_policy policy
)
137 case LTTNG_TRIGGER_FIRING_POLICY_EVERY_N
:
138 case LTTNG_TRIGGER_FIRING_POLICY_ONCE_AFTER_N
:
150 ssize_t
lttng_trigger_create_from_payload(
151 struct lttng_payload_view
*src_view
,
152 struct lttng_trigger
**_trigger
)
154 ssize_t ret
, offset
= 0, condition_size
, action_size
, name_size
= 0;
155 struct lttng_condition
*condition
= NULL
;
156 struct lttng_action
*action
= NULL
;
157 const struct lttng_trigger_comm
*trigger_comm
;
158 const char *name
= NULL
;
159 uint64_t firing_policy_threshold
;
160 enum lttng_trigger_firing_policy firing_policy
;
161 struct lttng_credentials creds
= {
162 .uid
= LTTNG_OPTIONAL_INIT_UNSET
,
163 .gid
= LTTNG_OPTIONAL_INIT_UNSET
,
165 struct lttng_trigger
*trigger
= NULL
;
166 const struct lttng_payload_view trigger_comm_view
=
167 lttng_payload_view_from_view(
168 src_view
, 0, sizeof(*trigger_comm
));
170 if (!src_view
|| !_trigger
) {
175 if (!lttng_payload_view_is_valid(&trigger_comm_view
)) {
176 /* Payload not large enough to contain the header. */
181 /* lttng_trigger_comm header */
182 trigger_comm
= (typeof(trigger_comm
)) trigger_comm_view
.buffer
.data
;
184 /* Set the trigger's creds. */
185 if (trigger_comm
->uid
> (uint64_t) ((uid_t
) -1)) {
186 /* UID out of range for this platform. */
191 LTTNG_OPTIONAL_SET(&creds
.uid
, trigger_comm
->uid
);
193 offset
+= sizeof(*trigger_comm
);
195 firing_policy
= trigger_comm
->firing_policy_type
;
196 if (!is_firing_policy_valid(firing_policy
)) {
201 firing_policy_threshold
= trigger_comm
->firing_policy_threshold
;
202 if (trigger_comm
->name_length
!= 0) {
204 const struct lttng_payload_view name_view
=
205 lttng_payload_view_from_view(
207 trigger_comm
->name_length
);
209 if (!lttng_payload_view_is_valid(&name_view
)) {
214 name
= name_view
.buffer
.data
;
215 if (!lttng_buffer_view_contains_string(&name_view
.buffer
, name
,
216 trigger_comm
->name_length
)) {
221 offset
+= trigger_comm
->name_length
;
222 name_size
= trigger_comm
->name_length
;
226 /* struct lttng_condition */
227 struct lttng_payload_view condition_view
=
228 lttng_payload_view_from_view(
229 src_view
, offset
, -1);
231 condition_size
= lttng_condition_create_from_payload(&condition_view
,
235 if (condition_size
< 0) {
236 ret
= condition_size
;
240 offset
+= condition_size
;
242 /* struct lttng_action */
243 struct lttng_payload_view action_view
=
244 lttng_payload_view_from_view(
245 src_view
, offset
, -1);
247 action_size
= lttng_action_create_from_payload(&action_view
, &action
);
250 if (action_size
< 0) {
254 offset
+= action_size
;
256 /* Unexpected size of inner-elements; the buffer is corrupted. */
257 if ((ssize_t
) trigger_comm
->length
!= condition_size
+ action_size
+ name_size
) {
262 trigger
= lttng_trigger_create(condition
, action
);
268 lttng_trigger_set_credentials(trigger
, &creds
);
271 * The trigger object owns references to the action and condition
274 lttng_condition_put(condition
);
277 lttng_action_put(action
);
281 const enum lttng_trigger_status status
=
282 lttng_trigger_set_name(trigger
, name
);
284 if (status
!= LTTNG_TRIGGER_STATUS_OK
) {
290 /* Set the policy. */
292 const enum lttng_trigger_status status
=
293 lttng_trigger_set_firing_policy(trigger
,
295 firing_policy_threshold
);
297 if (status
!= LTTNG_TRIGGER_STATUS_OK
) {
306 lttng_condition_put(condition
);
307 lttng_action_put(action
);
312 lttng_trigger_put(trigger
);
319 * Both elements are stored contiguously, see their "*_comm" structure
320 * for the detailed format.
323 int lttng_trigger_serialize(const struct lttng_trigger
*trigger
,
324 struct lttng_payload
*payload
)
327 size_t header_offset
, size_before_payload
, size_name
;
328 struct lttng_trigger_comm trigger_comm
= {};
329 struct lttng_trigger_comm
*header
;
330 const struct lttng_credentials
*creds
= NULL
;
332 creds
= lttng_trigger_get_credentials(trigger
);
335 trigger_comm
.uid
= LTTNG_OPTIONAL_GET(creds
->uid
);
337 if (trigger
->name
!= NULL
) {
338 size_name
= strlen(trigger
->name
) + 1;
343 trigger_comm
.name_length
= size_name
;
344 trigger_comm
.firing_policy_type
= (uint8_t) trigger
->firing_policy
.type
;
345 trigger_comm
.firing_policy_threshold
= (uint64_t) trigger
->firing_policy
.threshold
;
347 header_offset
= payload
->buffer
.size
;
348 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, &trigger_comm
,
349 sizeof(trigger_comm
));
354 size_before_payload
= payload
->buffer
.size
;
357 ret
= lttng_dynamic_buffer_append(
358 &payload
->buffer
, trigger
->name
, size_name
);
363 ret
= lttng_condition_serialize(trigger
->condition
, payload
);
368 ret
= lttng_action_serialize(trigger
->action
, payload
);
373 /* Update payload size. */
374 header
= (typeof(header
)) (payload
->buffer
.data
+ header_offset
);
375 header
->length
= payload
->buffer
.size
- size_before_payload
;
381 bool lttng_trigger_is_equal(
382 const struct lttng_trigger
*a
, const struct lttng_trigger
*b
)
384 if (a
->firing_policy
.type
!= b
->firing_policy
.type
) {
388 if (a
->firing_policy
.threshold
!= b
->firing_policy
.threshold
) {
393 * Name is not taken into account since it is cosmetic only.
395 if (!lttng_condition_is_equal(a
->condition
, b
->condition
)) {
399 if (!lttng_action_is_equal(a
->action
, b
->action
)) {
403 if (!lttng_credentials_is_equal(lttng_trigger_get_credentials(a
),
404 lttng_trigger_get_credentials(b
))) {
411 enum lttng_trigger_status
lttng_trigger_set_name(struct lttng_trigger
*trigger
,
414 char *name_copy
= NULL
;
415 enum lttng_trigger_status status
= LTTNG_TRIGGER_STATUS_OK
;
417 if (!trigger
|| !name
||
419 status
= LTTNG_TRIGGER_STATUS_INVALID
;
423 name_copy
= strdup(name
);
425 status
= LTTNG_TRIGGER_STATUS_ERROR
;
431 trigger
->name
= name_copy
;
437 enum lttng_trigger_status
lttng_trigger_get_name(
438 const struct lttng_trigger
*trigger
, const char **name
)
440 enum lttng_trigger_status status
= LTTNG_TRIGGER_STATUS_OK
;
442 if (!trigger
|| !name
) {
443 status
= LTTNG_TRIGGER_STATUS_INVALID
;
447 if (!trigger
->name
) {
448 status
= LTTNG_TRIGGER_STATUS_UNSET
;
451 *name
= trigger
->name
;
457 int lttng_trigger_assign_name(struct lttng_trigger
*dst
,
458 const struct lttng_trigger
*src
)
461 enum lttng_trigger_status status
;
463 status
= lttng_trigger_set_name(dst
, src
->name
);
464 if (status
!= LTTNG_TRIGGER_STATUS_OK
) {
466 ERR("Failed to set name for trigger");
474 void lttng_trigger_set_tracer_token(struct lttng_trigger
*trigger
,
478 LTTNG_OPTIONAL_SET(&trigger
->tracer_token
, token
);
482 uint64_t lttng_trigger_get_tracer_token(const struct lttng_trigger
*trigger
)
486 return LTTNG_OPTIONAL_GET(trigger
->tracer_token
);
490 int lttng_trigger_generate_name(struct lttng_trigger
*trigger
,
494 char *generated_name
= NULL
;
496 ret
= asprintf(&generated_name
, "T%" PRIu64
"", unique_id
);
498 ERR("Failed to generate trigger name");
505 trigger
->name
= generated_name
;
511 void lttng_trigger_get(struct lttng_trigger
*trigger
)
513 urcu_ref_get(&trigger
->ref
);
517 void lttng_trigger_put(struct lttng_trigger
*trigger
)
523 urcu_ref_put(&trigger
->ref
, trigger_destroy_ref
);
526 static void delete_trigger_array_element(void *ptr
)
528 struct lttng_trigger
*trigger
= ptr
;
530 lttng_trigger_put(trigger
);
534 struct lttng_triggers
*lttng_triggers_create(void)
536 struct lttng_triggers
*triggers
= NULL
;
538 triggers
= zmalloc(sizeof(*triggers
));
543 lttng_dynamic_pointer_array_init(&triggers
->array
, delete_trigger_array_element
);
550 struct lttng_trigger
*lttng_triggers_borrow_mutable_at_index(
551 const struct lttng_triggers
*triggers
, unsigned int index
)
553 struct lttng_trigger
*trigger
= NULL
;
556 if (index
>= lttng_dynamic_pointer_array_get_count(&triggers
->array
)) {
560 trigger
= (struct lttng_trigger
*)
561 lttng_dynamic_pointer_array_get_pointer(
562 &triggers
->array
, index
);
568 int lttng_triggers_add(
569 struct lttng_triggers
*triggers
, struct lttng_trigger
*trigger
)
576 lttng_trigger_get(trigger
);
578 ret
= lttng_dynamic_pointer_array_add_pointer(&triggers
->array
, trigger
);
580 lttng_trigger_put(trigger
);
586 const struct lttng_trigger
*lttng_triggers_get_at_index(
587 const struct lttng_triggers
*triggers
, unsigned int index
)
589 return lttng_triggers_borrow_mutable_at_index(triggers
, index
);
592 enum lttng_trigger_status
lttng_triggers_get_count(const struct lttng_triggers
*triggers
, unsigned int *count
)
594 enum lttng_trigger_status status
= LTTNG_TRIGGER_STATUS_OK
;
596 if (!triggers
|| !count
) {
597 status
= LTTNG_TRIGGER_STATUS_INVALID
;
601 *count
= lttng_dynamic_pointer_array_get_count(&triggers
->array
);
606 void lttng_triggers_destroy(struct lttng_triggers
*triggers
)
612 lttng_dynamic_pointer_array_reset(&triggers
->array
);
616 int lttng_triggers_serialize(const struct lttng_triggers
*triggers
,
617 struct lttng_payload
*payload
)
620 unsigned int i
, count
;
621 size_t size_before_payload
;
622 struct lttng_triggers_comm triggers_comm
= {};
623 struct lttng_triggers_comm
*header
;
624 enum lttng_trigger_status status
;
625 const size_t header_offset
= payload
->buffer
.size
;
627 status
= lttng_triggers_get_count(triggers
, &count
);
628 if (status
!= LTTNG_TRIGGER_STATUS_OK
) {
629 ret
= LTTNG_ERR_INVALID
;
633 triggers_comm
.count
= count
;
635 /* Placeholder header; updated at the end. */
636 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, &triggers_comm
,
637 sizeof(triggers_comm
));
642 size_before_payload
= payload
->buffer
.size
;
644 for (i
= 0; i
< count
; i
++) {
645 const struct lttng_trigger
*trigger
=
646 lttng_triggers_get_at_index(triggers
, i
);
650 ret
= lttng_trigger_serialize(trigger
, payload
);
656 /* Update payload size. */
657 header
= (struct lttng_triggers_comm
*) ((char *) payload
->buffer
.data
+ header_offset
);
658 header
->length
= payload
->buffer
.size
- size_before_payload
;
664 ssize_t
lttng_triggers_create_from_payload(
665 struct lttng_payload_view
*src_view
,
666 struct lttng_triggers
**triggers
)
668 ssize_t ret
, offset
= 0, triggers_size
= 0;
670 const struct lttng_triggers_comm
*triggers_comm
;
671 struct lttng_triggers
*local_triggers
= NULL
;
673 if (!src_view
|| !triggers
) {
678 /* lttng_trigger_comms header */
679 triggers_comm
= (const struct lttng_triggers_comm
*) src_view
->buffer
.data
;
680 offset
+= sizeof(*triggers_comm
);
682 local_triggers
= lttng_triggers_create();
683 if (!local_triggers
) {
688 for (i
= 0; i
< triggers_comm
->count
; i
++) {
689 struct lttng_trigger
*trigger
= NULL
;
690 struct lttng_payload_view trigger_view
=
691 lttng_payload_view_from_view(src_view
, offset
, -1);
692 ssize_t trigger_size
;
694 trigger_size
= lttng_trigger_create_from_payload(
695 &trigger_view
, &trigger
);
696 if (trigger_size
< 0) {
701 /* Transfer ownership of the trigger to the collection. */
702 ret
= lttng_triggers_add(local_triggers
, trigger
);
703 lttng_trigger_put(trigger
);
709 offset
+= trigger_size
;
710 triggers_size
+= trigger_size
;
713 /* Unexpected size of inner-elements; the buffer is corrupted. */
714 if ((ssize_t
) triggers_comm
->length
!= triggers_size
) {
719 /* Pass ownership to caller. */
720 *triggers
= local_triggers
;
721 local_triggers
= NULL
;
726 lttng_triggers_destroy(local_triggers
);
731 const struct lttng_credentials
*lttng_trigger_get_credentials(
732 const struct lttng_trigger
*trigger
)
734 return &trigger
->creds
;
738 void lttng_trigger_set_credentials(struct lttng_trigger
*trigger
,
739 const struct lttng_credentials
*creds
)
742 trigger
->creds
= *creds
;
745 enum lttng_trigger_status
lttng_trigger_set_owner_uid(
746 struct lttng_trigger
*trigger
, uid_t uid
)
748 enum lttng_trigger_status ret
= LTTNG_TRIGGER_STATUS_OK
;
749 const struct lttng_credentials creds
= {
750 .uid
= LTTNG_OPTIONAL_INIT_VALUE(uid
),
751 .gid
= LTTNG_OPTIONAL_INIT_UNSET
,
755 ret
= LTTNG_TRIGGER_STATUS_INVALID
;
759 /* Client-side validation only to report a clearer error. */
760 if (geteuid() != 0) {
761 ret
= LTTNG_TRIGGER_STATUS_PERMISSION_DENIED
;
765 lttng_trigger_set_credentials(trigger
, &creds
);
771 enum lttng_trigger_status
lttng_trigger_get_owner_uid(
772 const struct lttng_trigger
*trigger
, uid_t
*uid
)
774 enum lttng_trigger_status ret
= LTTNG_TRIGGER_STATUS_OK
;
775 const struct lttng_credentials
*creds
= NULL
;
777 if (!trigger
|| !uid
) {
778 ret
= LTTNG_TRIGGER_STATUS_INVALID
;
782 if (!trigger
->creds
.uid
.is_set
) {
783 ret
= LTTNG_TRIGGER_STATUS_UNSET
;
787 creds
= lttng_trigger_get_credentials(trigger
);
788 *uid
= lttng_credentials_get_uid(creds
);
794 enum lttng_trigger_status
lttng_trigger_set_firing_policy(
795 struct lttng_trigger
*trigger
,
796 enum lttng_trigger_firing_policy policy_type
,
799 enum lttng_trigger_status ret
= LTTNG_TRIGGER_STATUS_OK
;
803 ret
= LTTNG_TRIGGER_STATUS_INVALID
;
807 trigger
->firing_policy
.type
= policy_type
;
808 trigger
->firing_policy
.threshold
= threshold
;
814 enum lttng_trigger_status
lttng_trigger_get_firing_policy(
815 const struct lttng_trigger
*trigger
,
816 enum lttng_trigger_firing_policy
*policy_type
,
819 enum lttng_trigger_status status
= LTTNG_TRIGGER_STATUS_OK
;
821 if (!trigger
|| !policy_type
|| !threshold
) {
822 status
= LTTNG_TRIGGER_STATUS_INVALID
;
826 *policy_type
= trigger
->firing_policy
.type
;
827 *threshold
= trigger
->firing_policy
.threshold
;
834 bool lttng_trigger_should_fire(const struct lttng_trigger
*trigger
)
836 bool ready_to_fire
= false;
840 switch (trigger
->firing_policy
.type
) {
841 case LTTNG_TRIGGER_FIRING_POLICY_EVERY_N
:
842 if (trigger
->firing_policy
.current_count
< trigger
->firing_policy
.threshold
) {
843 ready_to_fire
= true;
846 case LTTNG_TRIGGER_FIRING_POLICY_ONCE_AFTER_N
:
847 if (trigger
->firing_policy
.current_count
< trigger
->firing_policy
.threshold
) {
848 ready_to_fire
= true;
855 return ready_to_fire
;
859 void lttng_trigger_fire(struct lttng_trigger
*trigger
)
863 trigger
->firing_policy
.current_count
++;
865 switch (trigger
->firing_policy
.type
) {
866 case LTTNG_TRIGGER_FIRING_POLICY_EVERY_N
:
867 if (trigger
->firing_policy
.current_count
== trigger
->firing_policy
.threshold
) {
868 trigger
->firing_policy
.current_count
= 0;
872 case LTTNG_TRIGGER_FIRING_POLICY_ONCE_AFTER_N
:
875 * As an optimisation, deactivate the trigger condition and
876 * remove any checks in the traced application or kernel since
877 * the trigger will never fire again.