2 * Copyright (C) 2017 Jérémie Galarneau <jeremie.galarneau@efficios.com>
4 * SPDX-License-Identifier: LGPL-2.1-only
9 #include <common/credentials.h>
10 #include <common/dynamic-array.h>
11 #include <common/error.h>
12 #include <common/mi-lttng.h>
13 #include <common/optional.h>
14 #include <common/payload-view.h>
15 #include <common/payload.h>
17 #include <lttng/action/action-internal.h>
18 #include <lttng/condition/buffer-usage.h>
19 #include <lttng/condition/condition-internal.h>
20 #include <lttng/condition/event-rule-matches-internal.h>
21 #include <lttng/condition/event-rule-matches.h>
22 #include <lttng/domain.h>
23 #include <lttng/error-query-internal.h>
24 #include <lttng/event-expr-internal.h>
25 #include <lttng/event-rule/event-rule-internal.h>
26 #include <lttng/trigger/trigger-internal.h>
30 bool lttng_trigger_validate(const struct lttng_trigger
*trigger
)
39 if (!trigger
->creds
.uid
.is_set
) {
44 valid
= lttng_condition_validate(trigger
->condition
) &&
45 lttng_action_validate(trigger
->action
);
50 struct lttng_trigger
*lttng_trigger_create(
51 struct lttng_condition
*condition
,
52 struct lttng_action
*action
)
54 struct lttng_trigger
*trigger
= NULL
;
56 if (!condition
|| !action
) {
60 trigger
= zmalloc(sizeof(struct lttng_trigger
));
65 urcu_ref_init(&trigger
->ref
);
67 lttng_condition_get(condition
);
68 trigger
->condition
= condition
;
70 lttng_action_get(action
);
71 trigger
->action
= action
;
73 pthread_mutex_init(&trigger
->lock
, NULL
);
74 trigger
->registered
= false;
81 * Note: the lack of reference counting 'get' on the condition object is normal.
82 * This API was exposed as such in 2.11. The client is not expected to call
83 * lttng_condition_destroy on the returned object.
85 struct lttng_condition
*lttng_trigger_get_condition(
86 struct lttng_trigger
*trigger
)
88 return trigger
? trigger
->condition
: NULL
;
91 const struct lttng_condition
*lttng_trigger_get_const_condition(
92 const struct lttng_trigger
*trigger
)
94 return trigger
? trigger
->condition
: NULL
;
98 * Note: the lack of reference counting 'get' on the action object is normal.
99 * This API was exposed as such in 2.11. The client is not expected to call
100 * lttng_action_destroy on the returned object.
102 struct lttng_action
*lttng_trigger_get_action(
103 struct lttng_trigger
*trigger
)
105 return trigger
? trigger
->action
: NULL
;
108 const struct lttng_action
*lttng_trigger_get_const_action(
109 const struct lttng_trigger
*trigger
)
111 return trigger
? trigger
->action
: NULL
;
114 static void trigger_destroy_ref(struct urcu_ref
*ref
)
116 struct lttng_trigger
*trigger
=
117 container_of(ref
, struct lttng_trigger
, ref
);
118 struct lttng_action
*action
= lttng_trigger_get_action(trigger
);
119 struct lttng_condition
*condition
=
120 lttng_trigger_get_condition(trigger
);
125 /* Release ownership. */
126 lttng_action_put(action
);
127 lttng_condition_put(condition
);
129 pthread_mutex_destroy(&trigger
->lock
);
135 void lttng_trigger_destroy(struct lttng_trigger
*trigger
)
137 lttng_trigger_put(trigger
);
141 ssize_t
lttng_trigger_create_from_payload(
142 struct lttng_payload_view
*src_view
,
143 struct lttng_trigger
**_trigger
)
145 ssize_t ret
, offset
= 0, condition_size
, action_size
, name_size
= 0;
146 struct lttng_condition
*condition
= NULL
;
147 struct lttng_action
*action
= NULL
;
148 const struct lttng_trigger_comm
*trigger_comm
;
149 const char *name
= NULL
;
150 struct lttng_credentials creds
= {
151 .uid
= LTTNG_OPTIONAL_INIT_UNSET
,
152 .gid
= LTTNG_OPTIONAL_INIT_UNSET
,
154 struct lttng_trigger
*trigger
= NULL
;
155 const struct lttng_payload_view trigger_comm_view
=
156 lttng_payload_view_from_view(
157 src_view
, 0, sizeof(*trigger_comm
));
159 if (!src_view
|| !_trigger
) {
164 if (!lttng_payload_view_is_valid(&trigger_comm_view
)) {
165 /* Payload not large enough to contain the header. */
170 /* lttng_trigger_comm header */
171 trigger_comm
= (typeof(trigger_comm
)) trigger_comm_view
.buffer
.data
;
173 /* Set the trigger's creds. */
174 if (trigger_comm
->uid
> (uint64_t) ((uid_t
) -1)) {
175 /* UID out of range for this platform. */
180 LTTNG_OPTIONAL_SET(&creds
.uid
, trigger_comm
->uid
);
182 offset
+= sizeof(*trigger_comm
);
184 if (trigger_comm
->name_length
!= 0) {
186 const struct lttng_payload_view name_view
=
187 lttng_payload_view_from_view(
189 trigger_comm
->name_length
);
191 if (!lttng_payload_view_is_valid(&name_view
)) {
196 name
= name_view
.buffer
.data
;
197 if (!lttng_buffer_view_contains_string(&name_view
.buffer
, name
,
198 trigger_comm
->name_length
)) {
203 offset
+= trigger_comm
->name_length
;
204 name_size
= trigger_comm
->name_length
;
208 /* struct lttng_condition */
209 struct lttng_payload_view condition_view
=
210 lttng_payload_view_from_view(
211 src_view
, offset
, -1);
213 condition_size
= lttng_condition_create_from_payload(&condition_view
,
217 if (condition_size
< 0) {
218 ret
= condition_size
;
222 offset
+= condition_size
;
224 /* struct lttng_action */
225 struct lttng_payload_view action_view
=
226 lttng_payload_view_from_view(
227 src_view
, offset
, -1);
229 action_size
= lttng_action_create_from_payload(&action_view
, &action
);
232 if (action_size
< 0) {
236 offset
+= action_size
;
238 /* Unexpected size of inner-elements; the buffer is corrupted. */
239 if ((ssize_t
) trigger_comm
->length
!= condition_size
+ action_size
+ name_size
) {
244 trigger
= lttng_trigger_create(condition
, action
);
250 lttng_trigger_set_credentials(trigger
, &creds
);
253 * The trigger object owns references to the action and condition
256 lttng_condition_put(condition
);
259 lttng_action_put(action
);
263 const enum lttng_trigger_status status
=
264 lttng_trigger_set_name(trigger
, name
);
266 if (status
!= LTTNG_TRIGGER_STATUS_OK
) {
272 if (trigger_comm
->is_hidden
) {
273 lttng_trigger_set_hidden(trigger
);
279 lttng_condition_put(condition
);
280 lttng_action_put(action
);
285 lttng_trigger_put(trigger
);
292 * Both elements are stored contiguously, see their "*_comm" structure
293 * for the detailed format.
296 int lttng_trigger_serialize(const struct lttng_trigger
*trigger
,
297 struct lttng_payload
*payload
)
300 size_t header_offset
, size_before_payload
, size_name
;
301 struct lttng_trigger_comm trigger_comm
= {};
302 struct lttng_trigger_comm
*header
;
303 const struct lttng_credentials
*creds
= NULL
;
305 creds
= lttng_trigger_get_credentials(trigger
);
308 trigger_comm
.uid
= LTTNG_OPTIONAL_GET(creds
->uid
);
310 if (trigger
->name
!= NULL
) {
311 size_name
= strlen(trigger
->name
) + 1;
316 trigger_comm
.name_length
= size_name
;
318 trigger_comm
.is_hidden
= lttng_trigger_is_hidden(trigger
);
320 header_offset
= payload
->buffer
.size
;
321 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, &trigger_comm
,
322 sizeof(trigger_comm
));
327 size_before_payload
= payload
->buffer
.size
;
330 ret
= lttng_dynamic_buffer_append(
331 &payload
->buffer
, trigger
->name
, size_name
);
336 ret
= lttng_condition_serialize(trigger
->condition
, payload
);
341 ret
= lttng_action_serialize(trigger
->action
, payload
);
346 /* Update payload size. */
347 header
= (typeof(header
)) (payload
->buffer
.data
+ header_offset
);
348 header
->length
= payload
->buffer
.size
- size_before_payload
;
354 bool lttng_trigger_is_equal(
355 const struct lttng_trigger
*a
, const struct lttng_trigger
*b
)
357 if (!!a
->name
!= !!b
->name
) {
358 /* Both must be either anonymous or named. */
362 if (a
->name
&& strcmp(a
->name
, b
->name
) != 0) {
366 if (!lttng_condition_is_equal(a
->condition
, b
->condition
)) {
370 if (!lttng_action_is_equal(a
->action
, b
->action
)) {
374 if (!lttng_credentials_is_equal(lttng_trigger_get_credentials(a
),
375 lttng_trigger_get_credentials(b
))) {
379 if (a
->is_hidden
!= b
->is_hidden
) {
387 bool lttng_trigger_is_hidden(const struct lttng_trigger
*trigger
)
389 return trigger
->is_hidden
;
393 void lttng_trigger_set_hidden(struct lttng_trigger
*trigger
)
395 assert(!trigger
->is_hidden
);
396 trigger
->is_hidden
= true;
400 enum lttng_trigger_status
lttng_trigger_set_name(struct lttng_trigger
*trigger
,
403 char *name_copy
= NULL
;
404 enum lttng_trigger_status status
= LTTNG_TRIGGER_STATUS_OK
;
407 status
= LTTNG_TRIGGER_STATUS_INVALID
;
412 name_copy
= strdup(name
);
414 status
= LTTNG_TRIGGER_STATUS_ERROR
;
421 trigger
->name
= name_copy
;
427 enum lttng_trigger_status
lttng_trigger_get_name(
428 const struct lttng_trigger
*trigger
, const char **name
)
430 enum lttng_trigger_status status
= LTTNG_TRIGGER_STATUS_OK
;
432 if (!trigger
|| !name
) {
433 status
= LTTNG_TRIGGER_STATUS_INVALID
;
437 if (!trigger
->name
) {
438 status
= LTTNG_TRIGGER_STATUS_UNSET
;
441 *name
= trigger
->name
;
447 int lttng_trigger_assign_name(struct lttng_trigger
*dst
,
448 const struct lttng_trigger
*src
)
451 enum lttng_trigger_status status
;
453 status
= lttng_trigger_set_name(dst
, src
->name
);
454 if (status
!= LTTNG_TRIGGER_STATUS_OK
) {
456 ERR("Failed to set name for trigger");
464 void lttng_trigger_set_tracer_token(struct lttng_trigger
*trigger
,
468 LTTNG_OPTIONAL_SET(&trigger
->tracer_token
, token
);
472 uint64_t lttng_trigger_get_tracer_token(const struct lttng_trigger
*trigger
)
476 return LTTNG_OPTIONAL_GET(trigger
->tracer_token
);
480 int lttng_trigger_generate_name(struct lttng_trigger
*trigger
,
484 char *generated_name
= NULL
;
486 ret
= asprintf(&generated_name
, "trigger%" PRIu64
"", unique_id
);
488 ERR("Failed to generate trigger name");
495 trigger
->name
= generated_name
;
501 void lttng_trigger_get(struct lttng_trigger
*trigger
)
503 urcu_ref_get(&trigger
->ref
);
507 void lttng_trigger_put(struct lttng_trigger
*trigger
)
513 urcu_ref_put(&trigger
->ref
, trigger_destroy_ref
);
516 static void delete_trigger_array_element(void *ptr
)
518 struct lttng_trigger
*trigger
= ptr
;
520 lttng_trigger_put(trigger
);
524 struct lttng_triggers
*lttng_triggers_create(void)
526 struct lttng_triggers
*triggers
= NULL
;
528 triggers
= zmalloc(sizeof(*triggers
));
533 lttng_dynamic_pointer_array_init(&triggers
->array
, delete_trigger_array_element
);
540 struct lttng_trigger
*lttng_triggers_borrow_mutable_at_index(
541 const struct lttng_triggers
*triggers
, unsigned int index
)
543 struct lttng_trigger
*trigger
= NULL
;
546 if (index
>= lttng_dynamic_pointer_array_get_count(&triggers
->array
)) {
550 trigger
= (struct lttng_trigger
*)
551 lttng_dynamic_pointer_array_get_pointer(
552 &triggers
->array
, index
);
558 int lttng_triggers_add(
559 struct lttng_triggers
*triggers
, struct lttng_trigger
*trigger
)
566 lttng_trigger_get(trigger
);
568 ret
= lttng_dynamic_pointer_array_add_pointer(&triggers
->array
, trigger
);
570 lttng_trigger_put(trigger
);
577 int lttng_triggers_remove_hidden_triggers(struct lttng_triggers
*triggers
)
580 unsigned int trigger_count
, i
= 0;
581 enum lttng_trigger_status trigger_status
;
585 trigger_status
= lttng_triggers_get_count(triggers
, &trigger_count
);
586 assert(trigger_status
== LTTNG_TRIGGER_STATUS_OK
);
588 while (i
< trigger_count
) {
589 const struct lttng_trigger
*trigger
=
590 lttng_triggers_get_at_index(triggers
, i
);
592 if (lttng_trigger_is_hidden(trigger
)) {
593 ret
= lttng_dynamic_pointer_array_remove_pointer(
594 &triggers
->array
, i
);
610 const struct lttng_trigger
*lttng_triggers_get_at_index(
611 const struct lttng_triggers
*triggers
, unsigned int index
)
613 return lttng_triggers_borrow_mutable_at_index(triggers
, index
);
616 enum lttng_trigger_status
lttng_triggers_get_count(const struct lttng_triggers
*triggers
, unsigned int *count
)
618 enum lttng_trigger_status status
= LTTNG_TRIGGER_STATUS_OK
;
620 if (!triggers
|| !count
) {
621 status
= LTTNG_TRIGGER_STATUS_INVALID
;
625 *count
= lttng_dynamic_pointer_array_get_count(&triggers
->array
);
630 void lttng_triggers_destroy(struct lttng_triggers
*triggers
)
636 lttng_dynamic_pointer_array_reset(&triggers
->array
);
640 int lttng_triggers_serialize(const struct lttng_triggers
*triggers
,
641 struct lttng_payload
*payload
)
644 unsigned int i
, count
;
645 size_t size_before_payload
;
646 struct lttng_triggers_comm triggers_comm
= {};
647 struct lttng_triggers_comm
*header
;
648 enum lttng_trigger_status status
;
649 const size_t header_offset
= payload
->buffer
.size
;
651 status
= lttng_triggers_get_count(triggers
, &count
);
652 if (status
!= LTTNG_TRIGGER_STATUS_OK
) {
653 ret
= LTTNG_ERR_INVALID
;
657 triggers_comm
.count
= count
;
659 /* Placeholder header; updated at the end. */
660 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, &triggers_comm
,
661 sizeof(triggers_comm
));
666 size_before_payload
= payload
->buffer
.size
;
668 for (i
= 0; i
< count
; i
++) {
669 const struct lttng_trigger
*trigger
=
670 lttng_triggers_get_at_index(triggers
, i
);
674 ret
= lttng_trigger_serialize(trigger
, payload
);
680 /* Update payload size. */
681 header
= (struct lttng_triggers_comm
*) ((char *) payload
->buffer
.data
+ header_offset
);
682 header
->length
= payload
->buffer
.size
- size_before_payload
;
688 ssize_t
lttng_triggers_create_from_payload(
689 struct lttng_payload_view
*src_view
,
690 struct lttng_triggers
**triggers
)
692 ssize_t ret
, offset
= 0, triggers_size
= 0;
694 const struct lttng_triggers_comm
*triggers_comm
;
695 struct lttng_triggers
*local_triggers
= NULL
;
697 if (!src_view
|| !triggers
) {
702 /* lttng_trigger_comms header */
703 triggers_comm
= (const struct lttng_triggers_comm
*) src_view
->buffer
.data
;
704 offset
+= sizeof(*triggers_comm
);
706 local_triggers
= lttng_triggers_create();
707 if (!local_triggers
) {
712 for (i
= 0; i
< triggers_comm
->count
; i
++) {
713 struct lttng_trigger
*trigger
= NULL
;
714 struct lttng_payload_view trigger_view
=
715 lttng_payload_view_from_view(src_view
, offset
, -1);
716 ssize_t trigger_size
;
718 trigger_size
= lttng_trigger_create_from_payload(
719 &trigger_view
, &trigger
);
720 if (trigger_size
< 0) {
725 /* Transfer ownership of the trigger to the collection. */
726 ret
= lttng_triggers_add(local_triggers
, trigger
);
727 lttng_trigger_put(trigger
);
733 offset
+= trigger_size
;
734 triggers_size
+= trigger_size
;
737 /* Unexpected size of inner-elements; the buffer is corrupted. */
738 if ((ssize_t
) triggers_comm
->length
!= triggers_size
) {
743 /* Pass ownership to caller. */
744 *triggers
= local_triggers
;
745 local_triggers
= NULL
;
750 lttng_triggers_destroy(local_triggers
);
755 const struct lttng_credentials
*lttng_trigger_get_credentials(
756 const struct lttng_trigger
*trigger
)
758 return &trigger
->creds
;
762 void lttng_trigger_set_credentials(struct lttng_trigger
*trigger
,
763 const struct lttng_credentials
*creds
)
765 /* Triggers do not use the group id to authenticate the user. */
767 LTTNG_OPTIONAL_SET(&trigger
->creds
.uid
, LTTNG_OPTIONAL_GET(creds
->uid
));
768 LTTNG_OPTIONAL_UNSET(&trigger
->creds
.gid
);
771 enum lttng_trigger_status
lttng_trigger_set_owner_uid(
772 struct lttng_trigger
*trigger
, uid_t uid
)
774 enum lttng_trigger_status ret
= LTTNG_TRIGGER_STATUS_OK
;
775 const uid_t euid
= geteuid();
776 const struct lttng_credentials creds
= {
777 .uid
= LTTNG_OPTIONAL_INIT_VALUE(uid
),
778 .gid
= LTTNG_OPTIONAL_INIT_UNSET
,
782 ret
= LTTNG_TRIGGER_STATUS_INVALID
;
786 /* Client-side validation only to report a clearer error. */
787 if (euid
!= 0 && euid
!= uid
) {
788 ret
= LTTNG_TRIGGER_STATUS_PERMISSION_DENIED
;
792 lttng_trigger_set_credentials(trigger
, &creds
);
798 enum lttng_trigger_status
lttng_trigger_get_owner_uid(
799 const struct lttng_trigger
*trigger
, uid_t
*uid
)
801 enum lttng_trigger_status ret
= LTTNG_TRIGGER_STATUS_OK
;
802 const struct lttng_credentials
*creds
= NULL
;
804 if (!trigger
|| !uid
) {
805 ret
= LTTNG_TRIGGER_STATUS_INVALID
;
809 if (!trigger
->creds
.uid
.is_set
) {
810 ret
= LTTNG_TRIGGER_STATUS_UNSET
;
814 creds
= lttng_trigger_get_credentials(trigger
);
815 *uid
= lttng_credentials_get_uid(creds
);
822 enum lttng_domain_type
lttng_trigger_get_underlying_domain_type_restriction(
823 const struct lttng_trigger
*trigger
)
825 enum lttng_domain_type type
= LTTNG_DOMAIN_NONE
;
826 const struct lttng_event_rule
*event_rule
;
827 enum lttng_condition_status c_status
;
828 enum lttng_condition_type c_type
;
831 assert(trigger
->condition
);
833 c_type
= lttng_condition_get_type(trigger
->condition
);
834 assert (c_type
!= LTTNG_CONDITION_TYPE_UNKNOWN
);
837 case LTTNG_CONDITION_TYPE_SESSION_CONSUMED_SIZE
:
838 case LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING
:
839 case LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED
:
840 /* Apply to any domain. */
841 type
= LTTNG_DOMAIN_NONE
;
843 case LTTNG_CONDITION_TYPE_EVENT_RULE_MATCHES
:
844 /* Return the domain of the event rule. */
845 c_status
= lttng_condition_event_rule_matches_get_rule(
846 trigger
->condition
, &event_rule
);
847 assert(c_status
== LTTNG_CONDITION_STATUS_OK
);
848 type
= lttng_event_rule_get_domain_type(event_rule
);
850 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH
:
851 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW
:
852 /* Return the domain of the channel being monitored. */
853 c_status
= lttng_condition_buffer_usage_get_domain_type(
854 trigger
->condition
, &type
);
855 assert(c_status
== LTTNG_CONDITION_STATUS_OK
);
865 * Generate bytecode related to the trigger.
866 * On success LTTNG_OK. On error, returns lttng_error code.
869 enum lttng_error_code
lttng_trigger_generate_bytecode(
870 struct lttng_trigger
*trigger
,
871 const struct lttng_credentials
*creds
)
873 enum lttng_error_code ret
;
874 struct lttng_condition
*condition
= NULL
;
876 condition
= lttng_trigger_get_condition(trigger
);
878 ret
= LTTNG_ERR_INVALID_TRIGGER
;
882 switch (lttng_condition_get_type(condition
)) {
883 case LTTNG_CONDITION_TYPE_EVENT_RULE_MATCHES
:
885 struct lttng_event_rule
*event_rule
;
886 const enum lttng_condition_status condition_status
=
887 lttng_condition_event_rule_matches_borrow_rule_mutable(
888 condition
, &event_rule
);
890 assert(condition_status
== LTTNG_CONDITION_STATUS_OK
);
892 /* Generate the filter bytecode. */
893 ret
= lttng_event_rule_generate_filter_bytecode(
895 if (ret
!= LTTNG_OK
) {
899 /* Generate the capture bytecode. */
900 ret
= lttng_condition_event_rule_matches_generate_capture_descriptor_bytecode(
902 if (ret
!= LTTNG_OK
) {
918 struct lttng_trigger
*lttng_trigger_copy(const struct lttng_trigger
*trigger
)
921 struct lttng_payload copy_buffer
;
922 struct lttng_condition
*condition_copy
= NULL
;
923 struct lttng_action
*action_copy
= NULL
;
924 struct lttng_trigger
*copy
= NULL
;
925 enum lttng_trigger_status trigger_status
;
926 const char *trigger_name
;
927 uid_t trigger_owner_uid
;
929 lttng_payload_init(©_buffer
);
931 ret
= lttng_condition_serialize(trigger
->condition
, ©_buffer
);
937 struct lttng_payload_view view
=
938 lttng_payload_view_from_payload(
939 ©_buffer
, 0, -1);
941 ret
= lttng_condition_create_from_payload(
942 &view
, &condition_copy
);
948 lttng_payload_clear(©_buffer
);
950 ret
= lttng_action_serialize(trigger
->action
, ©_buffer
);
956 struct lttng_payload_view view
=
957 lttng_payload_view_from_payload(
958 ©_buffer
, 0, -1);
960 ret
= lttng_action_create_from_payload(
961 &view
, &action_copy
);
967 copy
= lttng_trigger_create(condition_copy
, action_copy
);
969 ERR("Failed to allocate trigger during trigger copy");
973 trigger_status
= lttng_trigger_get_name(trigger
, &trigger_name
);
974 switch (trigger_status
) {
975 case LTTNG_TRIGGER_STATUS_OK
:
976 trigger_status
= lttng_trigger_set_name(copy
, trigger_name
);
977 if (trigger_status
!= LTTNG_TRIGGER_STATUS_OK
) {
978 ERR("Failed to set name of new trigger during copy");
979 goto error_cleanup_trigger
;
982 case LTTNG_TRIGGER_STATUS_UNSET
:
985 ERR("Failed to get name of original trigger during copy");
986 goto error_cleanup_trigger
;
989 trigger_status
= lttng_trigger_get_owner_uid(
990 trigger
, &trigger_owner_uid
);
991 switch (trigger_status
) {
992 case LTTNG_TRIGGER_STATUS_OK
:
993 LTTNG_OPTIONAL_SET(©
->creds
.uid
, trigger_owner_uid
);
995 case LTTNG_TRIGGER_STATUS_UNSET
:
998 ERR("Failed to get owner uid of original trigger during copy");
999 goto error_cleanup_trigger
;
1002 copy
->tracer_token
= trigger
->tracer_token
;
1003 copy
->registered
= trigger
->registered
;
1004 copy
->is_hidden
= trigger
->is_hidden
;
1007 error_cleanup_trigger
:
1008 lttng_trigger_destroy(copy
);
1011 lttng_condition_put(condition_copy
);
1012 lttng_action_put(action_copy
);
1013 lttng_payload_reset(©_buffer
);
1018 bool lttng_trigger_needs_tracer_notifier(const struct lttng_trigger
*trigger
)
1020 bool needs_tracer_notifier
= false;
1021 const struct lttng_condition
*condition
=
1022 lttng_trigger_get_const_condition(trigger
);
1024 switch (lttng_condition_get_type(condition
)) {
1025 case LTTNG_CONDITION_TYPE_EVENT_RULE_MATCHES
:
1026 needs_tracer_notifier
= true;
1028 case LTTNG_CONDITION_TYPE_SESSION_CONSUMED_SIZE
:
1029 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH
:
1030 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW
:
1031 case LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING
:
1032 case LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED
:
1034 case LTTNG_CONDITION_TYPE_UNKNOWN
:
1039 return needs_tracer_notifier
;
1043 void lttng_trigger_set_as_registered(struct lttng_trigger
*trigger
)
1045 pthread_mutex_lock(&trigger
->lock
);
1046 trigger
->registered
= true;
1047 pthread_mutex_unlock(&trigger
->lock
);
1051 void lttng_trigger_set_as_unregistered(struct lttng_trigger
*trigger
)
1053 pthread_mutex_lock(&trigger
->lock
);
1054 trigger
->registered
= false;
1055 pthread_mutex_unlock(&trigger
->lock
);
1059 * The trigger must be locked before calling lttng_trigger_registered.
1060 * The lock is necessary since a trigger can be unregistered at anytime.
1061 * Manipulations requiring that the trigger be registered must always acquire
1062 * the trigger lock for the duration of the manipulation using
1063 * `lttng_trigger_lock` and `lttng_trigger_unlock`.
1066 bool lttng_trigger_is_registered(struct lttng_trigger
*trigger
)
1068 ASSERT_LOCKED(trigger
->lock
);
1069 return trigger
->registered
;
1073 void lttng_trigger_lock(struct lttng_trigger
*trigger
)
1075 pthread_mutex_lock(&trigger
->lock
);
1079 void lttng_trigger_unlock(struct lttng_trigger
*trigger
)
1081 pthread_mutex_unlock(&trigger
->lock
);
1085 enum lttng_error_code
lttng_trigger_mi_serialize(const struct lttng_trigger
*trigger
,
1086 struct mi_writer
*writer
,
1087 const struct mi_lttng_error_query_callbacks
1088 *error_query_callbacks
)
1091 enum lttng_error_code ret_code
;
1092 enum lttng_trigger_status trigger_status
;
1093 const struct lttng_condition
*condition
= NULL
;
1094 const struct lttng_action
*action
= NULL
;
1095 struct lttng_dynamic_array action_path_indexes
;
1101 lttng_dynamic_array_init(&action_path_indexes
, sizeof(uint64_t), NULL
);
1103 /* Open trigger element. */
1104 ret
= mi_lttng_writer_open_element(writer
, mi_lttng_element_trigger
);
1109 trigger_status
= lttng_trigger_get_owner_uid(trigger
, &owner_uid
);
1110 assert(trigger_status
== LTTNG_TRIGGER_STATUS_OK
);
1113 ret
= mi_lttng_writer_write_element_string(
1114 writer
, config_element_name
, trigger
->name
);
1120 ret
= mi_lttng_writer_write_element_signed_int(writer
,
1121 mi_lttng_element_trigger_owner_uid
,
1122 (int64_t) owner_uid
);
1128 condition
= lttng_trigger_get_const_condition(trigger
);
1130 ret_code
= lttng_condition_mi_serialize(
1131 trigger
, condition
, writer
, error_query_callbacks
);
1132 if (ret_code
!= LTTNG_OK
) {
1137 action
= lttng_trigger_get_const_action(trigger
);
1139 ret_code
= lttng_action_mi_serialize(trigger
, action
, writer
,
1140 error_query_callbacks
, &action_path_indexes
);
1141 if (ret_code
!= LTTNG_OK
) {
1145 if (error_query_callbacks
&& error_query_callbacks
->trigger_cb
) {
1146 struct lttng_error_query_results
*results
= NULL
;
1148 ret_code
= error_query_callbacks
->trigger_cb(trigger
, &results
);
1149 if (ret_code
!= LTTNG_OK
) {
1153 ret_code
= lttng_error_query_results_mi_serialize(
1155 lttng_error_query_results_destroy(results
);
1156 if (ret_code
!= LTTNG_OK
) {
1161 /* Close trigger element. */
1162 ret
= mi_lttng_writer_close_element(writer
);
1167 ret_code
= LTTNG_OK
;
1171 ret_code
= LTTNG_ERR_MI_IO_FAIL
;
1173 lttng_dynamic_array_reset(&action_path_indexes
);
1177 /* Used by qsort, which expects the semantics of strcmp(). */
1178 static int compare_triggers_by_name(const void *a
, const void *b
)
1180 const struct lttng_trigger
*trigger_a
=
1181 *((const struct lttng_trigger
**) a
);
1182 const struct lttng_trigger
*trigger_b
=
1183 *((const struct lttng_trigger
**) b
);
1184 const char *name_a
, *name_b
;
1185 enum lttng_trigger_status trigger_status
;
1187 /* Anonymous triggers are not reachable here. */
1188 trigger_status
= lttng_trigger_get_name(trigger_a
, &name_a
);
1189 assert(trigger_status
== LTTNG_TRIGGER_STATUS_OK
);
1191 trigger_status
= lttng_trigger_get_name(trigger_b
, &name_b
);
1192 assert(trigger_status
== LTTNG_TRIGGER_STATUS_OK
);
1194 return strcmp(name_a
, name_b
);
1198 enum lttng_error_code
lttng_triggers_mi_serialize(const struct lttng_triggers
*triggers
,
1199 struct mi_writer
*writer
,
1200 const struct mi_lttng_error_query_callbacks
1201 *error_query_callbacks
)
1204 enum lttng_error_code ret_code
;
1205 enum lttng_trigger_status status
;
1206 unsigned int count
, i
;
1207 struct lttng_dynamic_pointer_array sorted_triggers
;
1213 * Sort trigger by name to ensure an order at the MI level and ignore
1214 * any anonymous trigger present.
1216 lttng_dynamic_pointer_array_init(&sorted_triggers
, NULL
);
1218 status
= lttng_triggers_get_count(triggers
, &count
);
1219 assert(status
== LTTNG_TRIGGER_STATUS_OK
);
1221 for (i
= 0; i
< count
; i
++) {
1223 const char *unused_name
;
1224 const struct lttng_trigger
*trigger
=
1225 lttng_triggers_get_at_index(triggers
, i
);
1227 status
= lttng_trigger_get_name(trigger
, &unused_name
);
1229 case LTTNG_TRIGGER_STATUS_OK
:
1231 case LTTNG_TRIGGER_STATUS_UNSET
:
1232 /* Don't list anonymous triggers. */
1238 add_ret
= lttng_dynamic_pointer_array_add_pointer(
1239 &sorted_triggers
, (void *) trigger
);
1242 ERR("Failed to lttng_trigger to sorting array.");
1243 ret_code
= LTTNG_ERR_NOMEM
;
1248 qsort(sorted_triggers
.array
.buffer
.data
, count
,
1249 sizeof(struct lttng_trigger
*),
1250 compare_triggers_by_name
);
1252 /* Open triggers element. */
1253 ret
= mi_lttng_writer_open_element(writer
, mi_lttng_element_triggers
);
1255 ret_code
= LTTNG_ERR_MI_IO_FAIL
;
1259 for (i
= 0; i
< lttng_dynamic_pointer_array_get_count(&sorted_triggers
); i
++) {
1260 const struct lttng_trigger
*trigger
=
1261 (const struct lttng_trigger
*)
1262 lttng_dynamic_pointer_array_get_pointer(
1263 &sorted_triggers
, i
);
1265 lttng_trigger_mi_serialize(trigger
, writer
, error_query_callbacks
);
1268 /* Close triggers element. */
1269 ret
= mi_lttng_writer_close_element(writer
);
1271 ret_code
= LTTNG_ERR_MI_IO_FAIL
;
1275 ret_code
= LTTNG_OK
;
1278 lttng_dynamic_pointer_array_reset(&sorted_triggers
);