2 * Copyright (C) 2017 Jérémie Galarneau <jeremie.galarneau@efficios.com>
4 * SPDX-License-Identifier: LGPL-2.1-only
8 #include <common/credentials.hpp>
9 #include <common/dynamic-array.hpp>
10 #include <common/error.hpp>
11 #include <common/mi-lttng.hpp>
12 #include <common/optional.hpp>
13 #include <common/payload-view.hpp>
14 #include <common/payload.hpp>
16 #include <lttng/action/action-internal.hpp>
17 #include <lttng/condition/buffer-usage.h>
18 #include <lttng/condition/condition-internal.hpp>
19 #include <lttng/condition/event-rule-matches-internal.hpp>
20 #include <lttng/condition/event-rule-matches.h>
21 #include <lttng/domain.h>
22 #include <lttng/error-query-internal.hpp>
23 #include <lttng/event-expr-internal.hpp>
24 #include <lttng/event-rule/event-rule-internal.hpp>
25 #include <lttng/trigger/trigger-internal.hpp>
28 bool lttng_trigger_validate(const struct lttng_trigger
*trigger
)
37 if (!trigger
->creds
.uid
.is_set
) {
42 valid
= lttng_condition_validate(trigger
->condition
) &&
43 lttng_action_validate(trigger
->action
);
48 struct lttng_trigger
*lttng_trigger_create(
49 struct lttng_condition
*condition
,
50 struct lttng_action
*action
)
52 struct lttng_trigger
*trigger
= NULL
;
54 if (!condition
|| !action
) {
58 trigger
= zmalloc
<lttng_trigger
>();
63 urcu_ref_init(&trigger
->ref
);
65 lttng_condition_get(condition
);
66 trigger
->condition
= condition
;
68 lttng_action_get(action
);
69 trigger
->action
= action
;
71 pthread_mutex_init(&trigger
->lock
, NULL
);
72 trigger
->registered
= false;
79 * Note: the lack of reference counting 'get' on the condition object is normal.
80 * This API was exposed as such in 2.11. The client is not expected to call
81 * lttng_condition_destroy on the returned object.
83 struct lttng_condition
*lttng_trigger_get_condition(
84 struct lttng_trigger
*trigger
)
86 return trigger
? trigger
->condition
: NULL
;
89 const struct lttng_condition
*lttng_trigger_get_const_condition(
90 const struct lttng_trigger
*trigger
)
92 return trigger
? trigger
->condition
: NULL
;
96 * Note: the lack of reference counting 'get' on the action object is normal.
97 * This API was exposed as such in 2.11. The client is not expected to call
98 * lttng_action_destroy on the returned object.
100 struct lttng_action
*lttng_trigger_get_action(
101 struct lttng_trigger
*trigger
)
103 return trigger
? trigger
->action
: NULL
;
106 const struct lttng_action
*lttng_trigger_get_const_action(
107 const struct lttng_trigger
*trigger
)
109 return trigger
? trigger
->action
: NULL
;
112 static void trigger_destroy_ref(struct urcu_ref
*ref
)
114 struct lttng_trigger
*trigger
=
115 lttng::utils::container_of(ref
, <tng_trigger::ref
);
116 struct lttng_action
*action
= lttng_trigger_get_action(trigger
);
117 struct lttng_condition
*condition
=
118 lttng_trigger_get_condition(trigger
);
120 LTTNG_ASSERT(action
);
121 LTTNG_ASSERT(condition
);
123 /* Release ownership. */
124 lttng_action_put(action
);
125 lttng_condition_put(condition
);
127 pthread_mutex_destroy(&trigger
->lock
);
133 void lttng_trigger_destroy(struct lttng_trigger
*trigger
)
135 lttng_trigger_put(trigger
);
138 ssize_t
lttng_trigger_create_from_payload(
139 struct lttng_payload_view
*src_view
,
140 struct lttng_trigger
**_trigger
)
142 ssize_t ret
, offset
= 0, condition_size
, action_size
, name_size
= 0;
143 struct lttng_condition
*condition
= NULL
;
144 struct lttng_action
*action
= NULL
;
145 const struct lttng_trigger_comm
*trigger_comm
;
146 const char *name
= NULL
;
147 struct lttng_credentials creds
= {
148 .uid
= LTTNG_OPTIONAL_INIT_UNSET
,
149 .gid
= LTTNG_OPTIONAL_INIT_UNSET
,
151 struct lttng_trigger
*trigger
= NULL
;
152 const struct lttng_payload_view trigger_comm_view
=
153 lttng_payload_view_from_view(
154 src_view
, 0, sizeof(*trigger_comm
));
156 if (!src_view
|| !_trigger
) {
161 if (!lttng_payload_view_is_valid(&trigger_comm_view
)) {
162 /* Payload not large enough to contain the header. */
167 /* lttng_trigger_comm header */
168 trigger_comm
= (typeof(trigger_comm
)) trigger_comm_view
.buffer
.data
;
170 /* Set the trigger's creds. */
171 if (trigger_comm
->uid
> (uint64_t) ((uid_t
) -1)) {
172 /* UID out of range for this platform. */
177 LTTNG_OPTIONAL_SET(&creds
.uid
, trigger_comm
->uid
);
179 offset
+= sizeof(*trigger_comm
);
181 if (trigger_comm
->name_length
!= 0) {
183 const struct lttng_payload_view name_view
=
184 lttng_payload_view_from_view(
186 trigger_comm
->name_length
);
188 if (!lttng_payload_view_is_valid(&name_view
)) {
193 name
= name_view
.buffer
.data
;
194 if (!lttng_buffer_view_contains_string(&name_view
.buffer
, name
,
195 trigger_comm
->name_length
)) {
200 offset
+= trigger_comm
->name_length
;
201 name_size
= trigger_comm
->name_length
;
205 /* struct lttng_condition */
206 struct lttng_payload_view condition_view
=
207 lttng_payload_view_from_view(
208 src_view
, offset
, -1);
210 condition_size
= lttng_condition_create_from_payload(&condition_view
,
214 if (condition_size
< 0) {
215 ret
= condition_size
;
219 offset
+= condition_size
;
221 /* struct lttng_action */
222 struct lttng_payload_view action_view
=
223 lttng_payload_view_from_view(
224 src_view
, offset
, -1);
226 action_size
= lttng_action_create_from_payload(&action_view
, &action
);
229 if (action_size
< 0) {
233 offset
+= action_size
;
235 /* Unexpected size of inner-elements; the buffer is corrupted. */
236 if ((ssize_t
) trigger_comm
->length
!= condition_size
+ action_size
+ name_size
) {
241 trigger
= lttng_trigger_create(condition
, action
);
247 lttng_trigger_set_credentials(trigger
, &creds
);
250 * The trigger object owns references to the action and condition
253 lttng_condition_put(condition
);
256 lttng_action_put(action
);
260 const enum lttng_trigger_status status
=
261 lttng_trigger_set_name(trigger
, name
);
263 if (status
!= LTTNG_TRIGGER_STATUS_OK
) {
269 if (trigger_comm
->is_hidden
) {
270 lttng_trigger_set_hidden(trigger
);
276 lttng_condition_put(condition
);
277 lttng_action_put(action
);
282 lttng_trigger_put(trigger
);
289 * Both elements are stored contiguously, see their "*_comm" structure
290 * for the detailed format.
292 int lttng_trigger_serialize(const struct lttng_trigger
*trigger
,
293 struct lttng_payload
*payload
)
296 size_t header_offset
, size_before_payload
, size_name
;
297 struct lttng_trigger_comm trigger_comm
= {};
298 struct lttng_trigger_comm
*header
;
299 const struct lttng_credentials
*creds
= NULL
;
301 creds
= lttng_trigger_get_credentials(trigger
);
304 trigger_comm
.uid
= LTTNG_OPTIONAL_GET(creds
->uid
);
306 if (trigger
->name
!= NULL
) {
307 size_name
= strlen(trigger
->name
) + 1;
312 trigger_comm
.name_length
= size_name
;
314 trigger_comm
.is_hidden
= lttng_trigger_is_hidden(trigger
);
316 header_offset
= payload
->buffer
.size
;
317 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, &trigger_comm
,
318 sizeof(trigger_comm
));
323 size_before_payload
= payload
->buffer
.size
;
326 ret
= lttng_dynamic_buffer_append(
327 &payload
->buffer
, trigger
->name
, size_name
);
332 ret
= lttng_condition_serialize(trigger
->condition
, payload
);
337 ret
= lttng_action_serialize(trigger
->action
, payload
);
342 /* Update payload size. */
343 header
= (typeof(header
)) (payload
->buffer
.data
+ header_offset
);
344 header
->length
= payload
->buffer
.size
- size_before_payload
;
349 bool lttng_trigger_is_equal(
350 const struct lttng_trigger
*a
, const struct lttng_trigger
*b
)
352 if (!!a
->name
!= !!b
->name
) {
353 /* Both must be either anonymous or named. */
357 if (a
->name
&& strcmp(a
->name
, b
->name
) != 0) {
361 if (!lttng_condition_is_equal(a
->condition
, b
->condition
)) {
365 if (!lttng_action_is_equal(a
->action
, b
->action
)) {
369 if (!lttng_credentials_is_equal(lttng_trigger_get_credentials(a
),
370 lttng_trigger_get_credentials(b
))) {
374 if (a
->is_hidden
!= b
->is_hidden
) {
381 bool lttng_trigger_is_hidden(const struct lttng_trigger
*trigger
)
383 LTTNG_ASSERT(trigger
);
384 return trigger
->is_hidden
;
387 void lttng_trigger_set_hidden(struct lttng_trigger
*trigger
)
389 LTTNG_ASSERT(!trigger
->is_hidden
);
390 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
;
439 int lttng_trigger_assign_name(struct lttng_trigger
*dst
,
440 const struct lttng_trigger
*src
)
443 enum lttng_trigger_status status
;
445 status
= lttng_trigger_set_name(dst
, src
->name
);
446 if (status
!= LTTNG_TRIGGER_STATUS_OK
) {
448 ERR("Failed to set name for trigger");
455 void lttng_trigger_set_tracer_token(struct lttng_trigger
*trigger
,
458 LTTNG_ASSERT(trigger
);
459 LTTNG_OPTIONAL_SET(&trigger
->tracer_token
, token
);
462 uint64_t lttng_trigger_get_tracer_token(const struct lttng_trigger
*trigger
)
464 LTTNG_ASSERT(trigger
);
466 return LTTNG_OPTIONAL_GET(trigger
->tracer_token
);
469 int lttng_trigger_generate_name(struct lttng_trigger
*trigger
,
473 char *generated_name
= NULL
;
475 ret
= asprintf(&generated_name
, "trigger%" PRIu64
"", unique_id
);
477 ERR("Failed to generate trigger name");
484 trigger
->name
= generated_name
;
489 void lttng_trigger_get(struct lttng_trigger
*trigger
)
491 urcu_ref_get(&trigger
->ref
);
494 void lttng_trigger_put(struct lttng_trigger
*trigger
)
500 urcu_ref_put(&trigger
->ref
, trigger_destroy_ref
);
503 static void delete_trigger_array_element(void *ptr
)
505 struct lttng_trigger
*trigger
= (lttng_trigger
*) ptr
;
507 lttng_trigger_put(trigger
);
510 struct lttng_triggers
*lttng_triggers_create(void)
512 struct lttng_triggers
*triggers
= NULL
;
514 triggers
= zmalloc
<lttng_triggers
>();
519 lttng_dynamic_pointer_array_init(&triggers
->array
, delete_trigger_array_element
);
525 struct lttng_trigger
*lttng_triggers_borrow_mutable_at_index(
526 const struct lttng_triggers
*triggers
, unsigned int index
)
528 struct lttng_trigger
*trigger
= NULL
;
530 LTTNG_ASSERT(triggers
);
531 if (index
>= lttng_dynamic_pointer_array_get_count(&triggers
->array
)) {
535 trigger
= (struct lttng_trigger
*)
536 lttng_dynamic_pointer_array_get_pointer(
537 &triggers
->array
, index
);
542 int lttng_triggers_add(
543 struct lttng_triggers
*triggers
, struct lttng_trigger
*trigger
)
547 LTTNG_ASSERT(triggers
);
548 LTTNG_ASSERT(trigger
);
550 lttng_trigger_get(trigger
);
552 ret
= lttng_dynamic_pointer_array_add_pointer(&triggers
->array
, trigger
);
554 lttng_trigger_put(trigger
);
560 int lttng_triggers_remove_hidden_triggers(struct lttng_triggers
*triggers
)
563 unsigned int trigger_count
, i
= 0;
564 enum lttng_trigger_status trigger_status
;
566 LTTNG_ASSERT(triggers
);
568 trigger_status
= lttng_triggers_get_count(triggers
, &trigger_count
);
569 LTTNG_ASSERT(trigger_status
== LTTNG_TRIGGER_STATUS_OK
);
571 while (i
< trigger_count
) {
572 const struct lttng_trigger
*trigger
=
573 lttng_triggers_get_at_index(triggers
, i
);
575 if (lttng_trigger_is_hidden(trigger
)) {
576 ret
= lttng_dynamic_pointer_array_remove_pointer(
577 &triggers
->array
, i
);
593 const struct lttng_trigger
*lttng_triggers_get_at_index(
594 const struct lttng_triggers
*triggers
, unsigned int index
)
596 return lttng_triggers_borrow_mutable_at_index(triggers
, index
);
599 enum lttng_trigger_status
lttng_triggers_get_count(const struct lttng_triggers
*triggers
, unsigned int *count
)
601 enum lttng_trigger_status status
= LTTNG_TRIGGER_STATUS_OK
;
603 if (!triggers
|| !count
) {
604 status
= LTTNG_TRIGGER_STATUS_INVALID
;
608 *count
= lttng_dynamic_pointer_array_get_count(&triggers
->array
);
613 void lttng_triggers_destroy(struct lttng_triggers
*triggers
)
619 lttng_dynamic_pointer_array_reset(&triggers
->array
);
623 int lttng_triggers_serialize(const struct lttng_triggers
*triggers
,
624 struct lttng_payload
*payload
)
627 unsigned int i
, count
;
628 size_t size_before_payload
;
629 struct lttng_triggers_comm triggers_comm
= {};
630 struct lttng_triggers_comm
*header
;
631 enum lttng_trigger_status status
;
632 const size_t header_offset
= payload
->buffer
.size
;
634 status
= lttng_triggers_get_count(triggers
, &count
);
635 if (status
!= LTTNG_TRIGGER_STATUS_OK
) {
636 ret
= LTTNG_ERR_INVALID
;
640 triggers_comm
.count
= count
;
642 /* Placeholder header; updated at the end. */
643 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, &triggers_comm
,
644 sizeof(triggers_comm
));
649 size_before_payload
= payload
->buffer
.size
;
651 for (i
= 0; i
< count
; i
++) {
652 const struct lttng_trigger
*trigger
=
653 lttng_triggers_get_at_index(triggers
, i
);
655 LTTNG_ASSERT(trigger
);
657 ret
= lttng_trigger_serialize(trigger
, payload
);
663 /* Update payload size. */
664 header
= (struct lttng_triggers_comm
*) ((char *) payload
->buffer
.data
+ header_offset
);
665 header
->length
= payload
->buffer
.size
- size_before_payload
;
670 ssize_t
lttng_triggers_create_from_payload(
671 struct lttng_payload_view
*src_view
,
672 struct lttng_triggers
**triggers
)
674 ssize_t ret
, offset
= 0, triggers_size
= 0;
676 const struct lttng_triggers_comm
*triggers_comm
;
677 struct lttng_triggers
*local_triggers
= NULL
;
679 if (!src_view
|| !triggers
) {
684 /* lttng_trigger_comms header */
685 triggers_comm
= (const struct lttng_triggers_comm
*) src_view
->buffer
.data
;
686 offset
+= sizeof(*triggers_comm
);
688 local_triggers
= lttng_triggers_create();
689 if (!local_triggers
) {
694 for (i
= 0; i
< triggers_comm
->count
; i
++) {
695 struct lttng_trigger
*trigger
= NULL
;
696 struct lttng_payload_view trigger_view
=
697 lttng_payload_view_from_view(src_view
, offset
, -1);
698 ssize_t trigger_size
;
700 trigger_size
= lttng_trigger_create_from_payload(
701 &trigger_view
, &trigger
);
702 if (trigger_size
< 0) {
707 /* Transfer ownership of the trigger to the collection. */
708 ret
= lttng_triggers_add(local_triggers
, trigger
);
709 lttng_trigger_put(trigger
);
715 offset
+= trigger_size
;
716 triggers_size
+= trigger_size
;
719 /* Unexpected size of inner-elements; the buffer is corrupted. */
720 if ((ssize_t
) triggers_comm
->length
!= triggers_size
) {
725 /* Pass ownership to caller. */
726 *triggers
= local_triggers
;
727 local_triggers
= NULL
;
732 lttng_triggers_destroy(local_triggers
);
736 const struct lttng_credentials
*lttng_trigger_get_credentials(
737 const struct lttng_trigger
*trigger
)
739 return &trigger
->creds
;
742 void lttng_trigger_set_credentials(struct lttng_trigger
*trigger
,
743 const struct lttng_credentials
*creds
)
745 /* Triggers do not use the group id to authenticate the user. */
747 LTTNG_OPTIONAL_SET(&trigger
->creds
.uid
, LTTNG_OPTIONAL_GET(creds
->uid
));
748 LTTNG_OPTIONAL_UNSET(&trigger
->creds
.gid
);
751 enum lttng_trigger_status
lttng_trigger_set_owner_uid(
752 struct lttng_trigger
*trigger
, uid_t uid
)
754 enum lttng_trigger_status ret
= LTTNG_TRIGGER_STATUS_OK
;
755 const uid_t euid
= geteuid();
756 const struct lttng_credentials creds
= {
757 .uid
= LTTNG_OPTIONAL_INIT_VALUE(uid
),
758 .gid
= LTTNG_OPTIONAL_INIT_UNSET
,
762 ret
= LTTNG_TRIGGER_STATUS_INVALID
;
766 /* Client-side validation only to report a clearer error. */
767 if (euid
!= 0 && euid
!= uid
) {
768 ret
= LTTNG_TRIGGER_STATUS_PERMISSION_DENIED
;
772 lttng_trigger_set_credentials(trigger
, &creds
);
778 enum lttng_trigger_status
lttng_trigger_get_owner_uid(
779 const struct lttng_trigger
*trigger
, uid_t
*uid
)
781 enum lttng_trigger_status ret
= LTTNG_TRIGGER_STATUS_OK
;
782 const struct lttng_credentials
*creds
= NULL
;
784 if (!trigger
|| !uid
) {
785 ret
= LTTNG_TRIGGER_STATUS_INVALID
;
789 if (!trigger
->creds
.uid
.is_set
) {
790 ret
= LTTNG_TRIGGER_STATUS_UNSET
;
794 creds
= lttng_trigger_get_credentials(trigger
);
795 *uid
= lttng_credentials_get_uid(creds
);
801 enum lttng_domain_type
lttng_trigger_get_underlying_domain_type_restriction(
802 const struct lttng_trigger
*trigger
)
804 enum lttng_domain_type type
= LTTNG_DOMAIN_NONE
;
805 const struct lttng_event_rule
*event_rule
;
806 enum lttng_condition_status c_status
;
807 enum lttng_condition_type c_type
;
809 LTTNG_ASSERT(trigger
);
810 LTTNG_ASSERT(trigger
->condition
);
812 c_type
= lttng_condition_get_type(trigger
->condition
);
813 assert (c_type
!= LTTNG_CONDITION_TYPE_UNKNOWN
);
816 case LTTNG_CONDITION_TYPE_SESSION_CONSUMED_SIZE
:
817 case LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING
:
818 case LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED
:
819 /* Apply to any domain. */
820 type
= LTTNG_DOMAIN_NONE
;
822 case LTTNG_CONDITION_TYPE_EVENT_RULE_MATCHES
:
823 /* Return the domain of the event rule. */
824 c_status
= lttng_condition_event_rule_matches_get_rule(
825 trigger
->condition
, &event_rule
);
826 LTTNG_ASSERT(c_status
== LTTNG_CONDITION_STATUS_OK
);
827 type
= lttng_event_rule_get_domain_type(event_rule
);
829 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH
:
830 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW
:
831 /* Return the domain of the channel being monitored. */
832 c_status
= lttng_condition_buffer_usage_get_domain_type(
833 trigger
->condition
, &type
);
834 LTTNG_ASSERT(c_status
== LTTNG_CONDITION_STATUS_OK
);
844 * Generate bytecode related to the trigger.
845 * On success LTTNG_OK. On error, returns lttng_error code.
847 enum lttng_error_code
lttng_trigger_generate_bytecode(
848 struct lttng_trigger
*trigger
,
849 const struct lttng_credentials
*creds
)
851 enum lttng_error_code ret
;
852 struct lttng_condition
*condition
= NULL
;
854 condition
= lttng_trigger_get_condition(trigger
);
856 ret
= LTTNG_ERR_INVALID_TRIGGER
;
860 switch (lttng_condition_get_type(condition
)) {
861 case LTTNG_CONDITION_TYPE_EVENT_RULE_MATCHES
:
863 struct lttng_event_rule
*event_rule
;
864 const enum lttng_condition_status condition_status
=
865 lttng_condition_event_rule_matches_borrow_rule_mutable(
866 condition
, &event_rule
);
868 LTTNG_ASSERT(condition_status
== LTTNG_CONDITION_STATUS_OK
);
870 /* Generate the filter bytecode. */
871 ret
= lttng_event_rule_generate_filter_bytecode(
873 if (ret
!= LTTNG_OK
) {
877 /* Generate the capture bytecode. */
878 ret
= lttng_condition_event_rule_matches_generate_capture_descriptor_bytecode(
880 if (ret
!= LTTNG_OK
) {
895 struct lttng_trigger
*lttng_trigger_copy(const struct lttng_trigger
*trigger
)
898 struct lttng_payload copy_buffer
;
899 struct lttng_condition
*condition_copy
= NULL
;
900 struct lttng_action
*action_copy
= NULL
;
901 struct lttng_trigger
*copy
= NULL
;
902 enum lttng_trigger_status trigger_status
;
903 const char *trigger_name
;
904 uid_t trigger_owner_uid
;
906 lttng_payload_init(©_buffer
);
908 ret
= lttng_condition_serialize(trigger
->condition
, ©_buffer
);
914 struct lttng_payload_view view
=
915 lttng_payload_view_from_payload(
916 ©_buffer
, 0, -1);
918 ret
= lttng_condition_create_from_payload(
919 &view
, &condition_copy
);
925 lttng_payload_clear(©_buffer
);
927 ret
= lttng_action_serialize(trigger
->action
, ©_buffer
);
933 struct lttng_payload_view view
=
934 lttng_payload_view_from_payload(
935 ©_buffer
, 0, -1);
937 ret
= lttng_action_create_from_payload(
938 &view
, &action_copy
);
944 copy
= lttng_trigger_create(condition_copy
, action_copy
);
946 ERR("Failed to allocate trigger during trigger copy");
950 trigger_status
= lttng_trigger_get_name(trigger
, &trigger_name
);
951 switch (trigger_status
) {
952 case LTTNG_TRIGGER_STATUS_OK
:
953 trigger_status
= lttng_trigger_set_name(copy
, trigger_name
);
954 if (trigger_status
!= LTTNG_TRIGGER_STATUS_OK
) {
955 ERR("Failed to set name of new trigger during copy");
956 goto error_cleanup_trigger
;
959 case LTTNG_TRIGGER_STATUS_UNSET
:
962 ERR("Failed to get name of original trigger during copy");
963 goto error_cleanup_trigger
;
966 trigger_status
= lttng_trigger_get_owner_uid(
967 trigger
, &trigger_owner_uid
);
968 switch (trigger_status
) {
969 case LTTNG_TRIGGER_STATUS_OK
:
970 LTTNG_OPTIONAL_SET(©
->creds
.uid
, trigger_owner_uid
);
972 case LTTNG_TRIGGER_STATUS_UNSET
:
975 ERR("Failed to get owner uid of original trigger during copy");
976 goto error_cleanup_trigger
;
979 copy
->tracer_token
= trigger
->tracer_token
;
980 copy
->registered
= trigger
->registered
;
981 copy
->is_hidden
= trigger
->is_hidden
;
984 error_cleanup_trigger
:
985 lttng_trigger_destroy(copy
);
988 lttng_condition_put(condition_copy
);
989 lttng_action_put(action_copy
);
990 lttng_payload_reset(©_buffer
);
994 bool lttng_trigger_needs_tracer_notifier(const struct lttng_trigger
*trigger
)
996 bool needs_tracer_notifier
= false;
997 const struct lttng_condition
*condition
=
998 lttng_trigger_get_const_condition(trigger
);
1000 switch (lttng_condition_get_type(condition
)) {
1001 case LTTNG_CONDITION_TYPE_EVENT_RULE_MATCHES
:
1002 needs_tracer_notifier
= true;
1004 case LTTNG_CONDITION_TYPE_SESSION_CONSUMED_SIZE
:
1005 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH
:
1006 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW
:
1007 case LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING
:
1008 case LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED
:
1010 case LTTNG_CONDITION_TYPE_UNKNOWN
:
1015 return needs_tracer_notifier
;
1018 void lttng_trigger_set_as_registered(struct lttng_trigger
*trigger
)
1020 pthread_mutex_lock(&trigger
->lock
);
1021 trigger
->registered
= true;
1022 pthread_mutex_unlock(&trigger
->lock
);
1025 void lttng_trigger_set_as_unregistered(struct lttng_trigger
*trigger
)
1027 pthread_mutex_lock(&trigger
->lock
);
1028 trigger
->registered
= false;
1029 pthread_mutex_unlock(&trigger
->lock
);
1033 * The trigger must be locked before calling lttng_trigger_registered.
1034 * The lock is necessary since a trigger can be unregistered at anytime.
1035 * Manipulations requiring that the trigger be registered must always acquire
1036 * the trigger lock for the duration of the manipulation using
1037 * `lttng_trigger_lock` and `lttng_trigger_unlock`.
1039 bool lttng_trigger_is_registered(struct lttng_trigger
*trigger
)
1041 ASSERT_LOCKED(trigger
->lock
);
1042 return trigger
->registered
;
1045 void lttng_trigger_lock(struct lttng_trigger
*trigger
)
1047 pthread_mutex_lock(&trigger
->lock
);
1050 void lttng_trigger_unlock(struct lttng_trigger
*trigger
)
1052 pthread_mutex_unlock(&trigger
->lock
);
1055 enum lttng_error_code
lttng_trigger_mi_serialize(const struct lttng_trigger
*trigger
,
1056 struct mi_writer
*writer
,
1057 const struct mi_lttng_error_query_callbacks
1058 *error_query_callbacks
)
1061 enum lttng_error_code ret_code
;
1062 enum lttng_trigger_status trigger_status
;
1063 const struct lttng_condition
*condition
= NULL
;
1064 const struct lttng_action
*action
= NULL
;
1065 struct lttng_dynamic_array action_path_indexes
;
1068 LTTNG_ASSERT(trigger
);
1069 LTTNG_ASSERT(writer
);
1071 lttng_dynamic_array_init(&action_path_indexes
, sizeof(uint64_t), NULL
);
1073 /* Open trigger element. */
1074 ret
= mi_lttng_writer_open_element(writer
, mi_lttng_element_trigger
);
1079 trigger_status
= lttng_trigger_get_owner_uid(trigger
, &owner_uid
);
1080 LTTNG_ASSERT(trigger_status
== LTTNG_TRIGGER_STATUS_OK
);
1083 ret
= mi_lttng_writer_write_element_string(
1084 writer
, config_element_name
, trigger
->name
);
1090 ret
= mi_lttng_writer_write_element_signed_int(writer
,
1091 mi_lttng_element_trigger_owner_uid
,
1092 (int64_t) owner_uid
);
1098 condition
= lttng_trigger_get_const_condition(trigger
);
1099 LTTNG_ASSERT(condition
);
1100 ret_code
= lttng_condition_mi_serialize(
1101 trigger
, condition
, writer
, error_query_callbacks
);
1102 if (ret_code
!= LTTNG_OK
) {
1107 action
= lttng_trigger_get_const_action(trigger
);
1108 LTTNG_ASSERT(action
);
1109 ret_code
= lttng_action_mi_serialize(trigger
, action
, writer
,
1110 error_query_callbacks
, &action_path_indexes
);
1111 if (ret_code
!= LTTNG_OK
) {
1115 if (error_query_callbacks
&& error_query_callbacks
->trigger_cb
) {
1116 struct lttng_error_query_results
*results
= NULL
;
1118 ret_code
= error_query_callbacks
->trigger_cb(trigger
, &results
);
1119 if (ret_code
!= LTTNG_OK
) {
1123 ret_code
= lttng_error_query_results_mi_serialize(
1125 lttng_error_query_results_destroy(results
);
1126 if (ret_code
!= LTTNG_OK
) {
1131 /* Close trigger element. */
1132 ret
= mi_lttng_writer_close_element(writer
);
1137 ret_code
= LTTNG_OK
;
1141 ret_code
= LTTNG_ERR_MI_IO_FAIL
;
1143 lttng_dynamic_array_reset(&action_path_indexes
);
1147 /* Used by qsort, which expects the semantics of strcmp(). */
1148 static int compare_triggers_by_name(const void *a
, const void *b
)
1150 const struct lttng_trigger
*trigger_a
=
1151 *((const struct lttng_trigger
**) a
);
1152 const struct lttng_trigger
*trigger_b
=
1153 *((const struct lttng_trigger
**) b
);
1154 const char *name_a
, *name_b
;
1155 enum lttng_trigger_status trigger_status
;
1157 /* Anonymous triggers are not reachable here. */
1158 trigger_status
= lttng_trigger_get_name(trigger_a
, &name_a
);
1159 LTTNG_ASSERT(trigger_status
== LTTNG_TRIGGER_STATUS_OK
);
1161 trigger_status
= lttng_trigger_get_name(trigger_b
, &name_b
);
1162 LTTNG_ASSERT(trigger_status
== LTTNG_TRIGGER_STATUS_OK
);
1164 return strcmp(name_a
, name_b
);
1167 enum lttng_error_code
lttng_triggers_mi_serialize(const struct lttng_triggers
*triggers
,
1168 struct mi_writer
*writer
,
1169 const struct mi_lttng_error_query_callbacks
1170 *error_query_callbacks
)
1173 enum lttng_error_code ret_code
;
1174 enum lttng_trigger_status status
;
1175 unsigned int count
, i
;
1176 struct lttng_dynamic_pointer_array sorted_triggers
;
1178 LTTNG_ASSERT(triggers
);
1179 LTTNG_ASSERT(writer
);
1182 * Sort trigger by name to ensure an order at the MI level and ignore
1183 * any anonymous trigger present.
1185 lttng_dynamic_pointer_array_init(&sorted_triggers
, NULL
);
1187 status
= lttng_triggers_get_count(triggers
, &count
);
1188 LTTNG_ASSERT(status
== LTTNG_TRIGGER_STATUS_OK
);
1190 for (i
= 0; i
< count
; i
++) {
1192 const char *unused_name
;
1193 const struct lttng_trigger
*trigger
=
1194 lttng_triggers_get_at_index(triggers
, i
);
1196 status
= lttng_trigger_get_name(trigger
, &unused_name
);
1198 case LTTNG_TRIGGER_STATUS_OK
:
1200 case LTTNG_TRIGGER_STATUS_UNSET
:
1201 /* Don't list anonymous triggers. */
1207 add_ret
= lttng_dynamic_pointer_array_add_pointer(
1208 &sorted_triggers
, (void *) trigger
);
1211 ERR("Failed to lttng_trigger to sorting array.");
1212 ret_code
= LTTNG_ERR_NOMEM
;
1217 qsort(sorted_triggers
.array
.buffer
.data
, count
,
1218 sizeof(struct lttng_trigger
*),
1219 compare_triggers_by_name
);
1221 /* Open triggers element. */
1222 ret
= mi_lttng_writer_open_element(writer
, mi_lttng_element_triggers
);
1224 ret_code
= LTTNG_ERR_MI_IO_FAIL
;
1228 for (i
= 0; i
< lttng_dynamic_pointer_array_get_count(&sorted_triggers
); i
++) {
1229 const struct lttng_trigger
*trigger
=
1230 (const struct lttng_trigger
*)
1231 lttng_dynamic_pointer_array_get_pointer(
1232 &sorted_triggers
, i
);
1234 lttng_trigger_mi_serialize(trigger
, writer
, error_query_callbacks
);
1237 /* Close triggers element. */
1238 ret
= mi_lttng_writer_close_element(writer
);
1240 ret_code
= LTTNG_ERR_MI_IO_FAIL
;
1244 ret_code
= LTTNG_OK
;
1247 lttng_dynamic_pointer_array_reset(&sorted_triggers
);