2 * Copyright (C) 2017 Jérémie Galarneau <jeremie.galarneau@efficios.com>
4 * SPDX-License-Identifier: LGPL-2.1-only
8 #include <common/credentials.h>
9 #include <common/dynamic-array.h>
10 #include <common/error.h>
11 #include <common/mi-lttng.h>
12 #include <common/optional.h>
13 #include <common/payload-view.h>
14 #include <common/payload.h>
16 #include <lttng/action/action-internal.h>
17 #include <lttng/condition/buffer-usage.h>
18 #include <lttng/condition/condition-internal.h>
19 #include <lttng/condition/event-rule-matches-internal.h>
20 #include <lttng/condition/event-rule-matches.h>
21 #include <lttng/domain.h>
22 #include <lttng/error-query-internal.h>
23 #include <lttng/event-expr-internal.h>
24 #include <lttng/event-rule/event-rule-internal.h>
25 #include <lttng/trigger/trigger-internal.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 lttng_condition_get(condition
);
67 trigger
->condition
= condition
;
69 lttng_action_get(action
);
70 trigger
->action
= action
;
72 pthread_mutex_init(&trigger
->lock
, NULL
);
73 trigger
->registered
= false;
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
);
121 LTTNG_ASSERT(action
);
122 LTTNG_ASSERT(condition
);
124 /* Release ownership. */
125 lttng_action_put(action
);
126 lttng_condition_put(condition
);
128 pthread_mutex_destroy(&trigger
->lock
);
134 void lttng_trigger_destroy(struct lttng_trigger
*trigger
)
136 lttng_trigger_put(trigger
);
140 ssize_t
lttng_trigger_create_from_payload(
141 struct lttng_payload_view
*src_view
,
142 struct lttng_trigger
**_trigger
)
144 ssize_t ret
, offset
= 0, condition_size
, action_size
, name_size
= 0;
145 struct lttng_condition
*condition
= NULL
;
146 struct lttng_action
*action
= NULL
;
147 const struct lttng_trigger_comm
*trigger_comm
;
148 const char *name
= NULL
;
149 struct lttng_credentials creds
= {
150 .uid
= LTTNG_OPTIONAL_INIT_UNSET
,
151 .gid
= LTTNG_OPTIONAL_INIT_UNSET
,
153 struct lttng_trigger
*trigger
= NULL
;
154 const struct lttng_payload_view trigger_comm_view
=
155 lttng_payload_view_from_view(
156 src_view
, 0, sizeof(*trigger_comm
));
158 if (!src_view
|| !_trigger
) {
163 if (!lttng_payload_view_is_valid(&trigger_comm_view
)) {
164 /* Payload not large enough to contain the header. */
169 /* lttng_trigger_comm header */
170 trigger_comm
= (typeof(trigger_comm
)) trigger_comm_view
.buffer
.data
;
172 /* Set the trigger's creds. */
173 if (trigger_comm
->uid
> (uint64_t) ((uid_t
) -1)) {
174 /* UID out of range for this platform. */
179 LTTNG_OPTIONAL_SET(&creds
.uid
, trigger_comm
->uid
);
181 offset
+= sizeof(*trigger_comm
);
183 if (trigger_comm
->name_length
!= 0) {
185 const struct lttng_payload_view name_view
=
186 lttng_payload_view_from_view(
188 trigger_comm
->name_length
);
190 if (!lttng_payload_view_is_valid(&name_view
)) {
195 name
= name_view
.buffer
.data
;
196 if (!lttng_buffer_view_contains_string(&name_view
.buffer
, name
,
197 trigger_comm
->name_length
)) {
202 offset
+= trigger_comm
->name_length
;
203 name_size
= trigger_comm
->name_length
;
207 /* struct lttng_condition */
208 struct lttng_payload_view condition_view
=
209 lttng_payload_view_from_view(
210 src_view
, offset
, -1);
212 condition_size
= lttng_condition_create_from_payload(&condition_view
,
216 if (condition_size
< 0) {
217 ret
= condition_size
;
221 offset
+= condition_size
;
223 /* struct lttng_action */
224 struct lttng_payload_view action_view
=
225 lttng_payload_view_from_view(
226 src_view
, offset
, -1);
228 action_size
= lttng_action_create_from_payload(&action_view
, &action
);
231 if (action_size
< 0) {
235 offset
+= action_size
;
237 /* Unexpected size of inner-elements; the buffer is corrupted. */
238 if ((ssize_t
) trigger_comm
->length
!= condition_size
+ action_size
+ name_size
) {
243 trigger
= lttng_trigger_create(condition
, action
);
249 lttng_trigger_set_credentials(trigger
, &creds
);
252 * The trigger object owns references to the action and condition
255 lttng_condition_put(condition
);
258 lttng_action_put(action
);
262 const enum lttng_trigger_status status
=
263 lttng_trigger_set_name(trigger
, name
);
265 if (status
!= LTTNG_TRIGGER_STATUS_OK
) {
274 lttng_condition_put(condition
);
275 lttng_action_put(action
);
280 lttng_trigger_put(trigger
);
287 * Both elements are stored contiguously, see their "*_comm" structure
288 * for the detailed format.
291 int lttng_trigger_serialize(const struct lttng_trigger
*trigger
,
292 struct lttng_payload
*payload
)
295 size_t header_offset
, size_before_payload
, size_name
;
296 struct lttng_trigger_comm trigger_comm
= {};
297 struct lttng_trigger_comm
*header
;
298 const struct lttng_credentials
*creds
= NULL
;
300 creds
= lttng_trigger_get_credentials(trigger
);
303 trigger_comm
.uid
= LTTNG_OPTIONAL_GET(creds
->uid
);
305 if (trigger
->name
!= NULL
) {
306 size_name
= strlen(trigger
->name
) + 1;
311 trigger_comm
.name_length
= size_name
;
313 header_offset
= payload
->buffer
.size
;
314 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, &trigger_comm
,
315 sizeof(trigger_comm
));
320 size_before_payload
= payload
->buffer
.size
;
323 ret
= lttng_dynamic_buffer_append(
324 &payload
->buffer
, trigger
->name
, size_name
);
329 ret
= lttng_condition_serialize(trigger
->condition
, payload
);
334 ret
= lttng_action_serialize(trigger
->action
, payload
);
339 /* Update payload size. */
340 header
= (typeof(header
)) (payload
->buffer
.data
+ header_offset
);
341 header
->length
= payload
->buffer
.size
- size_before_payload
;
347 bool lttng_trigger_is_equal(
348 const struct lttng_trigger
*a
, const struct lttng_trigger
*b
)
350 if (!!a
->name
!= !!b
->name
) {
351 /* Both must be either anonymous or named. */
355 if (a
->name
&& strcmp(a
->name
, b
->name
) != 0) {
359 if (!lttng_condition_is_equal(a
->condition
, b
->condition
)) {
363 if (!lttng_action_is_equal(a
->action
, b
->action
)) {
367 if (!lttng_credentials_is_equal(lttng_trigger_get_credentials(a
),
368 lttng_trigger_get_credentials(b
))) {
372 if (a
->is_hidden
!= b
->is_hidden
) {
380 bool lttng_trigger_is_hidden(const struct lttng_trigger
*trigger
)
382 return trigger
->is_hidden
;
386 void lttng_trigger_set_hidden(struct lttng_trigger
*trigger
)
388 LTTNG_ASSERT(!trigger
->is_hidden
);
389 trigger
->is_hidden
= true;
393 enum lttng_trigger_status
lttng_trigger_set_name(struct lttng_trigger
*trigger
,
396 char *name_copy
= NULL
;
397 enum lttng_trigger_status status
= LTTNG_TRIGGER_STATUS_OK
;
400 status
= LTTNG_TRIGGER_STATUS_INVALID
;
405 name_copy
= strdup(name
);
407 status
= LTTNG_TRIGGER_STATUS_ERROR
;
414 trigger
->name
= name_copy
;
420 enum lttng_trigger_status
lttng_trigger_get_name(
421 const struct lttng_trigger
*trigger
, const char **name
)
423 enum lttng_trigger_status status
= LTTNG_TRIGGER_STATUS_OK
;
425 if (!trigger
|| !name
) {
426 status
= LTTNG_TRIGGER_STATUS_INVALID
;
430 if (!trigger
->name
) {
431 status
= LTTNG_TRIGGER_STATUS_UNSET
;
434 *name
= trigger
->name
;
440 int lttng_trigger_assign_name(struct lttng_trigger
*dst
,
441 const struct lttng_trigger
*src
)
444 enum lttng_trigger_status status
;
446 status
= lttng_trigger_set_name(dst
, src
->name
);
447 if (status
!= LTTNG_TRIGGER_STATUS_OK
) {
449 ERR("Failed to set name for trigger");
457 void lttng_trigger_set_tracer_token(struct lttng_trigger
*trigger
,
460 LTTNG_ASSERT(trigger
);
461 LTTNG_OPTIONAL_SET(&trigger
->tracer_token
, token
);
465 uint64_t lttng_trigger_get_tracer_token(const struct lttng_trigger
*trigger
)
467 LTTNG_ASSERT(trigger
);
469 return LTTNG_OPTIONAL_GET(trigger
->tracer_token
);
473 int lttng_trigger_generate_name(struct lttng_trigger
*trigger
,
477 char *generated_name
= NULL
;
479 ret
= asprintf(&generated_name
, "trigger%" PRIu64
"", unique_id
);
481 ERR("Failed to generate trigger name");
488 trigger
->name
= generated_name
;
494 void lttng_trigger_get(struct lttng_trigger
*trigger
)
496 urcu_ref_get(&trigger
->ref
);
500 void lttng_trigger_put(struct lttng_trigger
*trigger
)
506 urcu_ref_put(&trigger
->ref
, trigger_destroy_ref
);
509 static void delete_trigger_array_element(void *ptr
)
511 struct lttng_trigger
*trigger
= ptr
;
513 lttng_trigger_put(trigger
);
517 struct lttng_triggers
*lttng_triggers_create(void)
519 struct lttng_triggers
*triggers
= NULL
;
521 triggers
= zmalloc(sizeof(*triggers
));
526 lttng_dynamic_pointer_array_init(&triggers
->array
, delete_trigger_array_element
);
533 struct lttng_trigger
*lttng_triggers_borrow_mutable_at_index(
534 const struct lttng_triggers
*triggers
, unsigned int index
)
536 struct lttng_trigger
*trigger
= NULL
;
538 LTTNG_ASSERT(triggers
);
539 if (index
>= lttng_dynamic_pointer_array_get_count(&triggers
->array
)) {
543 trigger
= (struct lttng_trigger
*)
544 lttng_dynamic_pointer_array_get_pointer(
545 &triggers
->array
, index
);
551 int lttng_triggers_add(
552 struct lttng_triggers
*triggers
, struct lttng_trigger
*trigger
)
556 LTTNG_ASSERT(triggers
);
557 LTTNG_ASSERT(trigger
);
559 lttng_trigger_get(trigger
);
561 ret
= lttng_dynamic_pointer_array_add_pointer(&triggers
->array
, trigger
);
563 lttng_trigger_put(trigger
);
570 int lttng_triggers_remove_hidden_triggers(struct lttng_triggers
*triggers
)
573 unsigned int trigger_count
, i
= 0;
574 enum lttng_trigger_status trigger_status
;
576 LTTNG_ASSERT(triggers
);
578 trigger_status
= lttng_triggers_get_count(triggers
, &trigger_count
);
579 LTTNG_ASSERT(trigger_status
== LTTNG_TRIGGER_STATUS_OK
);
581 while (i
< trigger_count
) {
582 const struct lttng_trigger
*trigger
=
583 lttng_triggers_get_at_index(triggers
, i
);
585 if (lttng_trigger_is_hidden(trigger
)) {
586 ret
= lttng_dynamic_pointer_array_remove_pointer(
587 &triggers
->array
, i
);
603 const struct lttng_trigger
*lttng_triggers_get_at_index(
604 const struct lttng_triggers
*triggers
, unsigned int index
)
606 return lttng_triggers_borrow_mutable_at_index(triggers
, index
);
609 enum lttng_trigger_status
lttng_triggers_get_count(const struct lttng_triggers
*triggers
, unsigned int *count
)
611 enum lttng_trigger_status status
= LTTNG_TRIGGER_STATUS_OK
;
613 if (!triggers
|| !count
) {
614 status
= LTTNG_TRIGGER_STATUS_INVALID
;
618 *count
= lttng_dynamic_pointer_array_get_count(&triggers
->array
);
623 void lttng_triggers_destroy(struct lttng_triggers
*triggers
)
629 lttng_dynamic_pointer_array_reset(&triggers
->array
);
633 int lttng_triggers_serialize(const struct lttng_triggers
*triggers
,
634 struct lttng_payload
*payload
)
637 unsigned int i
, count
;
638 size_t size_before_payload
;
639 struct lttng_triggers_comm triggers_comm
= {};
640 struct lttng_triggers_comm
*header
;
641 enum lttng_trigger_status status
;
642 const size_t header_offset
= payload
->buffer
.size
;
644 status
= lttng_triggers_get_count(triggers
, &count
);
645 if (status
!= LTTNG_TRIGGER_STATUS_OK
) {
646 ret
= LTTNG_ERR_INVALID
;
650 triggers_comm
.count
= count
;
652 /* Placeholder header; updated at the end. */
653 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, &triggers_comm
,
654 sizeof(triggers_comm
));
659 size_before_payload
= payload
->buffer
.size
;
661 for (i
= 0; i
< count
; i
++) {
662 const struct lttng_trigger
*trigger
=
663 lttng_triggers_get_at_index(triggers
, i
);
665 LTTNG_ASSERT(trigger
);
667 ret
= lttng_trigger_serialize(trigger
, payload
);
673 /* Update payload size. */
674 header
= (struct lttng_triggers_comm
*) ((char *) payload
->buffer
.data
+ header_offset
);
675 header
->length
= payload
->buffer
.size
- size_before_payload
;
681 ssize_t
lttng_triggers_create_from_payload(
682 struct lttng_payload_view
*src_view
,
683 struct lttng_triggers
**triggers
)
685 ssize_t ret
, offset
= 0, triggers_size
= 0;
687 const struct lttng_triggers_comm
*triggers_comm
;
688 struct lttng_triggers
*local_triggers
= NULL
;
690 if (!src_view
|| !triggers
) {
695 /* lttng_trigger_comms header */
696 triggers_comm
= (const struct lttng_triggers_comm
*) src_view
->buffer
.data
;
697 offset
+= sizeof(*triggers_comm
);
699 local_triggers
= lttng_triggers_create();
700 if (!local_triggers
) {
705 for (i
= 0; i
< triggers_comm
->count
; i
++) {
706 struct lttng_trigger
*trigger
= NULL
;
707 struct lttng_payload_view trigger_view
=
708 lttng_payload_view_from_view(src_view
, offset
, -1);
709 ssize_t trigger_size
;
711 trigger_size
= lttng_trigger_create_from_payload(
712 &trigger_view
, &trigger
);
713 if (trigger_size
< 0) {
718 /* Transfer ownership of the trigger to the collection. */
719 ret
= lttng_triggers_add(local_triggers
, trigger
);
720 lttng_trigger_put(trigger
);
726 offset
+= trigger_size
;
727 triggers_size
+= trigger_size
;
730 /* Unexpected size of inner-elements; the buffer is corrupted. */
731 if ((ssize_t
) triggers_comm
->length
!= triggers_size
) {
736 /* Pass ownership to caller. */
737 *triggers
= local_triggers
;
738 local_triggers
= NULL
;
743 lttng_triggers_destroy(local_triggers
);
748 const struct lttng_credentials
*lttng_trigger_get_credentials(
749 const struct lttng_trigger
*trigger
)
751 return &trigger
->creds
;
755 void lttng_trigger_set_credentials(struct lttng_trigger
*trigger
,
756 const struct lttng_credentials
*creds
)
759 trigger
->creds
= *creds
;
762 enum lttng_trigger_status
lttng_trigger_set_owner_uid(
763 struct lttng_trigger
*trigger
, uid_t uid
)
765 enum lttng_trigger_status ret
= LTTNG_TRIGGER_STATUS_OK
;
766 const uid_t euid
= geteuid();
767 const struct lttng_credentials creds
= {
768 .uid
= LTTNG_OPTIONAL_INIT_VALUE(uid
),
769 .gid
= LTTNG_OPTIONAL_INIT_UNSET
,
773 ret
= LTTNG_TRIGGER_STATUS_INVALID
;
777 /* Client-side validation only to report a clearer error. */
778 if (euid
!= 0 && euid
!= uid
) {
779 ret
= LTTNG_TRIGGER_STATUS_PERMISSION_DENIED
;
783 lttng_trigger_set_credentials(trigger
, &creds
);
789 enum lttng_trigger_status
lttng_trigger_get_owner_uid(
790 const struct lttng_trigger
*trigger
, uid_t
*uid
)
792 enum lttng_trigger_status ret
= LTTNG_TRIGGER_STATUS_OK
;
793 const struct lttng_credentials
*creds
= NULL
;
795 if (!trigger
|| !uid
) {
796 ret
= LTTNG_TRIGGER_STATUS_INVALID
;
800 if (!trigger
->creds
.uid
.is_set
) {
801 ret
= LTTNG_TRIGGER_STATUS_UNSET
;
805 creds
= lttng_trigger_get_credentials(trigger
);
806 *uid
= lttng_credentials_get_uid(creds
);
813 enum lttng_domain_type
lttng_trigger_get_underlying_domain_type_restriction(
814 const struct lttng_trigger
*trigger
)
816 enum lttng_domain_type type
= LTTNG_DOMAIN_NONE
;
817 const struct lttng_event_rule
*event_rule
;
818 enum lttng_condition_status c_status
;
819 enum lttng_condition_type c_type
;
821 LTTNG_ASSERT(trigger
);
822 LTTNG_ASSERT(trigger
->condition
);
824 c_type
= lttng_condition_get_type(trigger
->condition
);
825 assert (c_type
!= LTTNG_CONDITION_TYPE_UNKNOWN
);
828 case LTTNG_CONDITION_TYPE_SESSION_CONSUMED_SIZE
:
829 case LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING
:
830 case LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED
:
831 /* Apply to any domain. */
832 type
= LTTNG_DOMAIN_NONE
;
834 case LTTNG_CONDITION_TYPE_EVENT_RULE_MATCHES
:
835 /* Return the domain of the event rule. */
836 c_status
= lttng_condition_event_rule_matches_get_rule(
837 trigger
->condition
, &event_rule
);
838 LTTNG_ASSERT(c_status
== LTTNG_CONDITION_STATUS_OK
);
839 type
= lttng_event_rule_get_domain_type(event_rule
);
841 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH
:
842 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW
:
843 /* Return the domain of the channel being monitored. */
844 c_status
= lttng_condition_buffer_usage_get_domain_type(
845 trigger
->condition
, &type
);
846 LTTNG_ASSERT(c_status
== LTTNG_CONDITION_STATUS_OK
);
856 * Generate bytecode related to the trigger.
857 * On success LTTNG_OK. On error, returns lttng_error code.
860 enum lttng_error_code
lttng_trigger_generate_bytecode(
861 struct lttng_trigger
*trigger
,
862 const struct lttng_credentials
*creds
)
864 enum lttng_error_code ret
;
865 struct lttng_condition
*condition
= NULL
;
867 condition
= lttng_trigger_get_condition(trigger
);
869 ret
= LTTNG_ERR_INVALID_TRIGGER
;
873 switch (lttng_condition_get_type(condition
)) {
874 case LTTNG_CONDITION_TYPE_EVENT_RULE_MATCHES
:
876 struct lttng_event_rule
*event_rule
;
877 const enum lttng_condition_status condition_status
=
878 lttng_condition_event_rule_matches_borrow_rule_mutable(
879 condition
, &event_rule
);
881 LTTNG_ASSERT(condition_status
== LTTNG_CONDITION_STATUS_OK
);
883 /* Generate the filter bytecode. */
884 ret
= lttng_event_rule_generate_filter_bytecode(
886 if (ret
!= LTTNG_OK
) {
890 /* Generate the capture bytecode. */
891 ret
= lttng_condition_event_rule_matches_generate_capture_descriptor_bytecode(
893 if (ret
!= LTTNG_OK
) {
909 struct lttng_trigger
*lttng_trigger_copy(const struct lttng_trigger
*trigger
)
912 struct lttng_payload copy_buffer
;
913 struct lttng_condition
*condition_copy
= NULL
;
914 struct lttng_action
*action_copy
= NULL
;
915 struct lttng_trigger
*copy
= NULL
;
916 enum lttng_trigger_status trigger_status
;
917 const char *trigger_name
;
918 uid_t trigger_owner_uid
;
920 lttng_payload_init(©_buffer
);
922 ret
= lttng_condition_serialize(trigger
->condition
, ©_buffer
);
928 struct lttng_payload_view view
=
929 lttng_payload_view_from_payload(
930 ©_buffer
, 0, -1);
932 ret
= lttng_condition_create_from_payload(
933 &view
, &condition_copy
);
939 lttng_payload_clear(©_buffer
);
941 ret
= lttng_action_serialize(trigger
->action
, ©_buffer
);
947 struct lttng_payload_view view
=
948 lttng_payload_view_from_payload(
949 ©_buffer
, 0, -1);
951 ret
= lttng_action_create_from_payload(
952 &view
, &action_copy
);
958 copy
= lttng_trigger_create(condition_copy
, action_copy
);
960 ERR("Failed to allocate trigger during trigger copy");
964 trigger_status
= lttng_trigger_get_name(trigger
, &trigger_name
);
965 switch (trigger_status
) {
966 case LTTNG_TRIGGER_STATUS_OK
:
967 trigger_status
= lttng_trigger_set_name(copy
, trigger_name
);
968 if (trigger_status
!= LTTNG_TRIGGER_STATUS_OK
) {
969 ERR("Failed to set name of new trigger during copy");
970 goto error_cleanup_trigger
;
973 case LTTNG_TRIGGER_STATUS_UNSET
:
976 ERR("Failed to get name of original trigger during copy");
977 goto error_cleanup_trigger
;
980 trigger_status
= lttng_trigger_get_owner_uid(
981 trigger
, &trigger_owner_uid
);
982 switch (trigger_status
) {
983 case LTTNG_TRIGGER_STATUS_OK
:
984 LTTNG_OPTIONAL_SET(©
->creds
.uid
, trigger_owner_uid
);
986 case LTTNG_TRIGGER_STATUS_UNSET
:
989 ERR("Failed to get owner uid of original trigger during copy");
990 goto error_cleanup_trigger
;
993 copy
->tracer_token
= trigger
->tracer_token
;
994 copy
->registered
= trigger
->registered
;
995 copy
->is_hidden
= trigger
->is_hidden
;
998 error_cleanup_trigger
:
999 lttng_trigger_destroy(copy
);
1002 lttng_condition_put(condition_copy
);
1003 lttng_action_put(action_copy
);
1004 lttng_payload_reset(©_buffer
);
1009 bool lttng_trigger_needs_tracer_notifier(const struct lttng_trigger
*trigger
)
1011 bool needs_tracer_notifier
= false;
1012 const struct lttng_condition
*condition
=
1013 lttng_trigger_get_const_condition(trigger
);
1015 switch (lttng_condition_get_type(condition
)) {
1016 case LTTNG_CONDITION_TYPE_EVENT_RULE_MATCHES
:
1017 needs_tracer_notifier
= true;
1019 case LTTNG_CONDITION_TYPE_SESSION_CONSUMED_SIZE
:
1020 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH
:
1021 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW
:
1022 case LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING
:
1023 case LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED
:
1025 case LTTNG_CONDITION_TYPE_UNKNOWN
:
1030 return needs_tracer_notifier
;
1034 void lttng_trigger_set_as_registered(struct lttng_trigger
*trigger
)
1036 pthread_mutex_lock(&trigger
->lock
);
1037 trigger
->registered
= true;
1038 pthread_mutex_unlock(&trigger
->lock
);
1042 void lttng_trigger_set_as_unregistered(struct lttng_trigger
*trigger
)
1044 pthread_mutex_lock(&trigger
->lock
);
1045 trigger
->registered
= false;
1046 pthread_mutex_unlock(&trigger
->lock
);
1050 * The trigger must be locked before calling lttng_trigger_registered.
1051 * The lock is necessary since a trigger can be unregistered at anytime.
1052 * Manipulations requiring that the trigger be registered must always acquire
1053 * the trigger lock for the duration of the manipulation using
1054 * `lttng_trigger_lock` and `lttng_trigger_unlock`.
1057 bool lttng_trigger_is_registered(struct lttng_trigger
*trigger
)
1059 ASSERT_LOCKED(trigger
->lock
);
1060 return trigger
->registered
;
1064 void lttng_trigger_lock(struct lttng_trigger
*trigger
)
1066 pthread_mutex_lock(&trigger
->lock
);
1070 void lttng_trigger_unlock(struct lttng_trigger
*trigger
)
1072 pthread_mutex_unlock(&trigger
->lock
);
1076 enum lttng_error_code
lttng_trigger_mi_serialize(const struct lttng_trigger
*trigger
,
1077 struct mi_writer
*writer
,
1078 const struct mi_lttng_error_query_callbacks
1079 *error_query_callbacks
)
1082 enum lttng_error_code ret_code
;
1083 enum lttng_trigger_status trigger_status
;
1084 const struct lttng_condition
*condition
= NULL
;
1085 const struct lttng_action
*action
= NULL
;
1086 struct lttng_dynamic_array action_path_indexes
;
1089 LTTNG_ASSERT(trigger
);
1090 LTTNG_ASSERT(writer
);
1092 lttng_dynamic_array_init(&action_path_indexes
, sizeof(uint64_t), NULL
);
1094 /* Open trigger element. */
1095 ret
= mi_lttng_writer_open_element(writer
, mi_lttng_element_trigger
);
1100 trigger_status
= lttng_trigger_get_owner_uid(trigger
, &owner_uid
);
1101 LTTNG_ASSERT(trigger_status
== LTTNG_TRIGGER_STATUS_OK
);
1104 ret
= mi_lttng_writer_write_element_string(
1105 writer
, config_element_name
, trigger
->name
);
1111 ret
= mi_lttng_writer_write_element_signed_int(writer
,
1112 mi_lttng_element_trigger_owner_uid
,
1113 (int64_t) owner_uid
);
1119 condition
= lttng_trigger_get_const_condition(trigger
);
1120 LTTNG_ASSERT(condition
);
1121 ret_code
= lttng_condition_mi_serialize(
1122 trigger
, condition
, writer
, error_query_callbacks
);
1123 if (ret_code
!= LTTNG_OK
) {
1128 action
= lttng_trigger_get_const_action(trigger
);
1129 LTTNG_ASSERT(action
);
1130 ret_code
= lttng_action_mi_serialize(trigger
, action
, writer
,
1131 error_query_callbacks
, &action_path_indexes
);
1132 if (ret_code
!= LTTNG_OK
) {
1136 if (error_query_callbacks
&& error_query_callbacks
->trigger_cb
) {
1137 struct lttng_error_query_results
*results
= NULL
;
1139 ret_code
= error_query_callbacks
->trigger_cb(trigger
, &results
);
1140 if (ret_code
!= LTTNG_OK
) {
1144 ret_code
= lttng_error_query_results_mi_serialize(
1146 lttng_error_query_results_destroy(results
);
1147 if (ret_code
!= LTTNG_OK
) {
1152 /* Close trigger element. */
1153 ret
= mi_lttng_writer_close_element(writer
);
1158 ret_code
= LTTNG_OK
;
1162 ret_code
= LTTNG_ERR_MI_IO_FAIL
;
1164 lttng_dynamic_array_reset(&action_path_indexes
);
1168 /* Used by qsort, which expects the semantics of strcmp(). */
1169 static int compare_triggers_by_name(const void *a
, const void *b
)
1171 const struct lttng_trigger
*trigger_a
=
1172 *((const struct lttng_trigger
**) a
);
1173 const struct lttng_trigger
*trigger_b
=
1174 *((const struct lttng_trigger
**) b
);
1175 const char *name_a
, *name_b
;
1176 enum lttng_trigger_status trigger_status
;
1178 /* Anonymous triggers are not reachable here. */
1179 trigger_status
= lttng_trigger_get_name(trigger_a
, &name_a
);
1180 LTTNG_ASSERT(trigger_status
== LTTNG_TRIGGER_STATUS_OK
);
1182 trigger_status
= lttng_trigger_get_name(trigger_b
, &name_b
);
1183 LTTNG_ASSERT(trigger_status
== LTTNG_TRIGGER_STATUS_OK
);
1185 return strcmp(name_a
, name_b
);
1189 enum lttng_error_code
lttng_triggers_mi_serialize(const struct lttng_triggers
*triggers
,
1190 struct mi_writer
*writer
,
1191 const struct mi_lttng_error_query_callbacks
1192 *error_query_callbacks
)
1195 enum lttng_error_code ret_code
;
1196 enum lttng_trigger_status status
;
1197 unsigned int count
, i
;
1198 struct lttng_dynamic_pointer_array sorted_triggers
;
1200 LTTNG_ASSERT(triggers
);
1201 LTTNG_ASSERT(writer
);
1204 * Sort trigger by name to ensure an order at the MI level and ignore
1205 * any anonymous trigger present.
1207 lttng_dynamic_pointer_array_init(&sorted_triggers
, NULL
);
1209 status
= lttng_triggers_get_count(triggers
, &count
);
1210 LTTNG_ASSERT(status
== LTTNG_TRIGGER_STATUS_OK
);
1212 for (i
= 0; i
< count
; i
++) {
1214 const char *unused_name
;
1215 const struct lttng_trigger
*trigger
=
1216 lttng_triggers_get_at_index(triggers
, i
);
1218 status
= lttng_trigger_get_name(trigger
, &unused_name
);
1220 case LTTNG_TRIGGER_STATUS_OK
:
1222 case LTTNG_TRIGGER_STATUS_UNSET
:
1223 /* Don't list anonymous triggers. */
1229 add_ret
= lttng_dynamic_pointer_array_add_pointer(
1230 &sorted_triggers
, (void *) trigger
);
1233 ERR("Failed to lttng_trigger to sorting array.");
1234 ret_code
= LTTNG_ERR_NOMEM
;
1239 qsort(sorted_triggers
.array
.buffer
.data
, count
,
1240 sizeof(struct lttng_trigger
*),
1241 compare_triggers_by_name
);
1243 /* Open triggers element. */
1244 ret
= mi_lttng_writer_open_element(writer
, mi_lttng_element_triggers
);
1246 ret_code
= LTTNG_ERR_MI_IO_FAIL
;
1250 for (i
= 0; i
< lttng_dynamic_pointer_array_get_count(&sorted_triggers
); i
++) {
1251 const struct lttng_trigger
*trigger
=
1252 (const struct lttng_trigger
*)
1253 lttng_dynamic_pointer_array_get_pointer(
1254 &sorted_triggers
, i
);
1256 lttng_trigger_mi_serialize(trigger
, writer
, error_query_callbacks
);
1259 /* Close triggers element. */
1260 ret
= mi_lttng_writer_close_element(writer
);
1262 ret_code
= LTTNG_ERR_MI_IO_FAIL
;
1266 ret_code
= LTTNG_OK
;
1269 lttng_dynamic_pointer_array_reset(&sorted_triggers
);