2 * Copyright (C) 2017 Jérémie Galarneau <jeremie.galarneau@efficios.com>
4 * SPDX-License-Identifier: LGPL-2.1-only
8 #include <lttng/trigger/trigger-internal.h>
9 #include <lttng/condition/condition-internal.h>
10 #include <lttng/condition/event-rule-internal.h>
11 #include <lttng/condition/event-rule.h>
12 #include <lttng/condition/buffer-usage.h>
13 #include <lttng/event-rule/event-rule-internal.h>
14 #include <lttng/event-expr-internal.h>
15 #include <lttng/action/action-internal.h>
16 #include <lttng/domain.h>
17 #include <common/error.h>
18 #include <common/dynamic-array.h>
22 static void lttng_trigger_set_internal_object_ownership(
23 struct lttng_trigger
*trigger
)
26 * This is necessary to faciliate the object destroy phase. A trigger
27 * created by a client does not OWN the internal objects (condition and
28 * action) but when a trigger object is created on the sessiond side or
29 * for listing triggers (mostly via create_from_buffer) the object is
30 * the owner of the internal objects. Hence, we set the ownership bool
31 * to true, in such case, to facilitate object lifetime management and
34 * TODO: I'm open to any other solution
37 trigger
->owns_internal_objects
= true;
40 static void destroy_lttng_condition_event_rule_capture_bytecode_element(void *ptr
)
42 struct lttng_condition_event_rule_capture_bytecode_element
*element
=
44 lttng_event_expr_destroy(element
->expression
);
45 free(element
->bytecode
);
50 bool lttng_trigger_validate(const struct lttng_trigger
*trigger
)
59 valid
= lttng_condition_validate(trigger
->condition
) &&
60 lttng_action_validate(trigger
->action
);
65 struct lttng_trigger
*lttng_trigger_create(
66 struct lttng_condition
*condition
,
67 struct lttng_action
*action
)
69 struct lttng_trigger
*trigger
= NULL
;
71 if (!condition
|| !action
) {
75 trigger
= zmalloc(sizeof(struct lttng_trigger
));
80 urcu_ref_init(&trigger
->ref
);
81 trigger
->owns_internal_objects
= false;
82 trigger
->firing_policy
.type
= LTTNG_TRIGGER_FIRE_EVERY_N
;
83 trigger
->firing_policy
.threshold
= 1;
84 trigger
->condition
= condition
;
85 trigger
->action
= action
;
87 trigger
->creds
.set
= false;
89 lttng_dynamic_pointer_array_init(&trigger
->capture_bytecode_set
,
90 destroy_lttng_condition_event_rule_capture_bytecode_element
);
96 struct lttng_condition
*lttng_trigger_get_condition(
97 struct lttng_trigger
*trigger
)
99 return trigger
? trigger
->condition
: NULL
;
102 const struct lttng_condition
*lttng_trigger_get_const_condition(
103 const struct lttng_trigger
*trigger
)
105 return trigger
? trigger
->condition
: NULL
;
108 struct lttng_action
*lttng_trigger_get_action(
109 struct lttng_trigger
*trigger
)
111 return trigger
? trigger
->action
: NULL
;
114 const struct lttng_action
*lttng_trigger_get_const_action(
115 const struct lttng_trigger
*trigger
)
117 return trigger
? trigger
->action
: NULL
;
120 static void trigger_destroy_ref(struct urcu_ref
*ref
)
122 struct lttng_trigger
*trigger
=
123 container_of(ref
, struct lttng_trigger
, ref
);
125 lttng_dynamic_pointer_array_reset(&trigger
->capture_bytecode_set
);
127 if (trigger
->owns_internal_objects
) {
128 struct lttng_action
*action
= lttng_trigger_get_action(trigger
);
129 struct lttng_condition
*condition
=
130 lttng_trigger_get_condition(trigger
);
134 lttng_action_destroy(action
);
135 lttng_condition_destroy(condition
);
142 void lttng_trigger_destroy(struct lttng_trigger
*trigger
)
144 lttng_trigger_put(trigger
);
148 ssize_t
lttng_trigger_create_from_buffer(
149 const struct lttng_buffer_view
*src_view
,
150 struct lttng_trigger
**trigger
)
152 ssize_t ret
, offset
= 0, condition_size
, action_size
, name_size
= 0;
153 enum lttng_trigger_status status
;
154 struct lttng_condition
*condition
= NULL
;
155 struct lttng_action
*action
= NULL
;
156 const struct lttng_trigger_comm
*trigger_comm
;
157 struct lttng_buffer_view condition_view
;
158 struct lttng_buffer_view action_view
;
159 struct lttng_buffer_view name_view
;
160 const char *name
= NULL
;
161 unsigned long long firing_threshold
;
162 enum lttng_trigger_firing_policy_type firing_policy
;
164 if (!src_view
|| !trigger
) {
169 /* lttng_trigger_comm header */
170 trigger_comm
= (const struct lttng_trigger_comm
*) src_view
->data
;
171 offset
+= sizeof(*trigger_comm
);
173 firing_policy
= trigger_comm
->policy_type
;
174 firing_threshold
= trigger_comm
->policy_threshold
;
175 if (trigger_comm
->name_length
!= 0) {
176 name_view
= lttng_buffer_view_from_view(
177 src_view
, offset
, trigger_comm
->name_length
);
178 name
= name_view
.data
;
179 if (trigger_comm
->name_length
== 1 ||
180 name
[trigger_comm
->name_length
- 1] != '\0' ||
181 strlen(name
) != trigger_comm
->name_length
- 1) {
185 offset
+= trigger_comm
->name_length
;
186 name_size
= trigger_comm
->name_length
;
189 condition_view
= lttng_buffer_view_from_view(src_view
, offset
, -1);
191 /* struct lttng_condition */
192 condition_size
= lttng_condition_create_from_buffer(&condition_view
,
194 if (condition_size
< 0) {
195 ret
= condition_size
;
198 offset
+= condition_size
;
200 /* struct lttng_action */
201 action_view
= lttng_buffer_view_from_view(src_view
, offset
, -1);
202 action_size
= lttng_action_create_from_buffer(&action_view
, &action
);
203 if (action_size
< 0) {
207 offset
+= action_size
;
209 /* Unexpected size of inner-elements; the buffer is corrupted. */
210 if ((ssize_t
) trigger_comm
->length
!= condition_size
+ action_size
+ name_size
) {
215 *trigger
= lttng_trigger_create(condition
, action
);
221 /* Take ownership of the internal object from there */
222 lttng_trigger_set_internal_object_ownership(*trigger
);
227 status
= lttng_trigger_set_name(*trigger
, name
);
228 if (status
!= LTTNG_TRIGGER_STATUS_OK
) {
234 status
= lttng_trigger_set_firing_policy(*trigger
, firing_policy
, firing_threshold
);
235 if (status
!= LTTNG_TRIGGER_STATUS_OK
) {
244 lttng_condition_destroy(condition
);
245 lttng_action_destroy(action
);
250 * Both elements are stored contiguously, see their "*_comm" structure
251 * for the detailed format.
254 int lttng_trigger_serialize(const struct lttng_trigger
*trigger
,
255 struct lttng_dynamic_buffer
*buf
,
259 size_t header_offset
, size_before_payload
, size_name
;
260 struct lttng_trigger_comm trigger_comm
= { 0 };
261 struct lttng_trigger_comm
*header
;
263 header_offset
= buf
->size
;
265 if (trigger
->name
!= NULL
) {
266 size_name
= strlen(trigger
->name
) + 1;
271 trigger_comm
.name_length
= size_name
;
272 trigger_comm
.policy_type
= (uint8_t) trigger
->firing_policy
.type
;
273 trigger_comm
.policy_threshold
= (uint64_t) trigger
->firing_policy
.threshold
;
275 ret
= lttng_dynamic_buffer_append(buf
, &trigger_comm
,
276 sizeof(trigger_comm
));
281 size_before_payload
= buf
->size
;
284 ret
= lttng_dynamic_buffer_append(buf
, trigger
->name
, size_name
);
289 ret
= lttng_condition_serialize(trigger
->condition
, buf
, fd_to_send
);
294 ret
= lttng_action_serialize(trigger
->action
, buf
);
299 /* Update payload size. */
300 header
= (struct lttng_trigger_comm
*) ((char *) buf
->data
+ header_offset
);
301 header
->length
= buf
->size
- size_before_payload
;
306 enum lttng_trigger_status
lttng_trigger_set_name(struct lttng_trigger
*trigger
, const char* name
)
308 char *name_copy
= NULL
;
309 enum lttng_trigger_status status
= LTTNG_TRIGGER_STATUS_OK
;
311 if (!trigger
|| !name
||
313 status
= LTTNG_TRIGGER_STATUS_INVALID
;
317 name_copy
= strdup(name
);
319 status
= LTTNG_TRIGGER_STATUS_ERROR
;
327 trigger
->name
= name_copy
;
333 enum lttng_trigger_status
lttng_trigger_get_name(const struct lttng_trigger
*trigger
, const char **name
)
335 enum lttng_trigger_status status
= LTTNG_TRIGGER_STATUS_OK
;
337 if (!trigger
|| !name
) {
338 status
= LTTNG_TRIGGER_STATUS_INVALID
;
342 if (!trigger
->name
) {
343 status
= LTTNG_TRIGGER_STATUS_UNSET
;
346 *name
= trigger
->name
;
352 int lttng_trigger_assign(struct lttng_trigger
*dst
,
353 const struct lttng_trigger
*src
)
356 enum lttng_trigger_status status
;
357 /* todo some validation */
359 status
= lttng_trigger_set_name(dst
, src
->name
);
360 if (status
!= LTTNG_TRIGGER_STATUS_OK
) {
362 ERR("Failed to set name for trigger");
370 void lttng_trigger_set_key(struct lttng_trigger
*trigger
, uint64_t key
)
373 trigger
->key
.value
= key
;
374 trigger
->key
.set
= true;
378 uint64_t lttng_trigger_get_key(const struct lttng_trigger
*trigger
)
382 assert(trigger
->key
.set
== true);
383 return trigger
->key
.value
;
387 int lttng_trigger_generate_name(struct lttng_trigger
*trigger
, uint64_t offset
)
390 char *generated_name
= NULL
;
391 assert(trigger
->key
.set
);
393 ret
= asprintf(&generated_name
, "T%" PRIu64
"", trigger
->key
.value
+ offset
);
395 ERR("Failed to generate trigger name");
403 trigger
->name
= generated_name
;
409 void lttng_trigger_get(struct lttng_trigger
*trigger
)
411 urcu_ref_get(&trigger
->ref
);
415 void lttng_trigger_put(struct lttng_trigger
*trigger
)
421 urcu_ref_put(&trigger
->ref
, trigger_destroy_ref
);
424 static void delete_trigger_array_element(void *ptr
)
426 struct lttng_trigger
*trigger
= ptr
;
427 lttng_trigger_destroy(trigger
);
431 bool lttng_trigger_is_equal(
432 const struct lttng_trigger
*a
, const struct lttng_trigger
*b
)
434 /* TODO: Optimization: for now a trigger with a firing policy that is
435 * not the same even if the conditions and actions is the same is
436 * treated as a "completely" different trigger. In a perfect world we
437 * would simply add a supplemental counter internally (sessiond side) to
438 * remove overhead on the tracer side.
440 if (a
->firing_policy
.type
!= b
->firing_policy
.type
) {
444 if (a
->firing_policy
.threshold
!= b
->firing_policy
.threshold
) {
449 * Name is not taken into account since it is cosmetic only
451 if (!lttng_condition_is_equal(a
->condition
, b
->condition
)) {
454 if (!lttng_action_is_equal(a
->action
, b
->action
)) {
462 struct lttng_triggers
*lttng_triggers_create(void)
464 struct lttng_triggers
*triggers
= NULL
;
466 triggers
= zmalloc(sizeof(*triggers
));
471 lttng_dynamic_pointer_array_init(&triggers
->array
, delete_trigger_array_element
);
480 struct lttng_trigger
*lttng_triggers_get_pointer_of_index(
481 const struct lttng_triggers
*triggers
, unsigned int index
)
484 if (index
>= lttng_dynamic_pointer_array_get_count(&triggers
->array
)) {
487 return lttng_dynamic_pointer_array_get_pointer(&triggers
->array
, index
);
491 int lttng_triggers_add(
492 struct lttng_triggers
*triggers
, struct lttng_trigger
*trigger
)
497 return lttng_dynamic_pointer_array_add_pointer(&triggers
->array
, trigger
);
500 const struct lttng_trigger
*lttng_triggers_get_at_index(
501 const struct lttng_triggers
*triggers
, unsigned int index
)
504 return lttng_triggers_get_pointer_of_index(triggers
, index
);
507 enum lttng_trigger_status
lttng_triggers_get_count(const struct lttng_triggers
*triggers
, unsigned int *count
)
509 enum lttng_trigger_status status
= LTTNG_TRIGGER_STATUS_OK
;
511 if (!triggers
|| !count
) {
512 status
= LTTNG_TRIGGER_STATUS_INVALID
;
516 *count
= lttng_dynamic_pointer_array_get_count(&triggers
->array
);
521 void lttng_triggers_destroy(struct lttng_triggers
*triggers
)
527 lttng_dynamic_pointer_array_reset(&triggers
->array
);
531 int lttng_triggers_serialize(const struct lttng_triggers
*triggers
,
532 struct lttng_dynamic_buffer
*buffer
)
536 size_t header_offset
, size_before_payload
;
537 struct lttng_triggers_comm triggers_comm
= { 0 };
538 struct lttng_triggers_comm
*header
;
539 struct lttng_trigger
*trigger
;
540 enum lttng_trigger_status status
;
542 header_offset
= buffer
->size
;
544 status
= lttng_triggers_get_count(triggers
, &count
);
545 if (status
!= LTTNG_TRIGGER_STATUS_OK
) {
546 ret
= LTTNG_ERR_INVALID
;
550 triggers_comm
.count
= count
;
552 ret
= lttng_dynamic_buffer_append(buffer
, &triggers_comm
,
553 sizeof(triggers_comm
));
558 size_before_payload
= buffer
->size
;
560 for (int i
= 0; i
< count
; i
++) {
561 trigger
= lttng_triggers_get_pointer_of_index(triggers
, i
);
566 ret
= lttng_trigger_serialize(trigger
, buffer
, NULL
);
572 /* Update payload size. */
573 header
= (struct lttng_triggers_comm
*) ((char *) buffer
->data
+ header_offset
);
574 header
->length
= buffer
->size
- size_before_payload
;
580 ssize_t
lttng_triggers_create_from_buffer(
581 const struct lttng_buffer_view
*src_view
,
582 struct lttng_triggers
**triggers
)
584 ssize_t ret
, offset
= 0, trigger_size
, triggers_size
= 0;
585 const struct lttng_triggers_comm
*triggers_comm
;
586 struct lttng_buffer_view trigger_view
;
587 struct lttng_triggers
*local_triggers
= NULL
;
589 if (!src_view
|| !triggers
) {
594 /* lttng_trigger_comms header */
595 triggers_comm
= (const struct lttng_triggers_comm
*) src_view
->data
;
596 offset
+= sizeof(*triggers_comm
);
598 local_triggers
= lttng_triggers_create();
599 if (!local_triggers
) {
604 for (int i
= 0; i
< triggers_comm
->count
; i
++) {
605 struct lttng_trigger
*trigger
= NULL
;
606 trigger_view
= lttng_buffer_view_from_view(src_view
, offset
, -1);
607 trigger_size
= lttng_trigger_create_from_buffer(&trigger_view
,
609 if (trigger_size
< 0) {
614 /* Pass ownership of the trigger to the collection */
615 ret
= lttng_triggers_add(local_triggers
, trigger
);
621 offset
+= trigger_size
;
622 triggers_size
+= trigger_size
;
625 /* Unexpected size of inner-elements; the buffer is corrupted. */
626 if ((ssize_t
) triggers_comm
->length
!= triggers_size
) {
631 /* Pass ownership to caller */
632 *triggers
= local_triggers
;
633 local_triggers
= NULL
;
638 lttng_triggers_destroy(local_triggers
);
643 const struct lttng_credentials
*lttng_trigger_get_credentials(
644 const struct lttng_trigger
*trigger
)
646 assert(trigger
->creds
.set
);
647 return &(trigger
->creds
.credentials
);
651 void lttng_trigger_set_credentials(
652 struct lttng_trigger
*trigger
, uid_t uid
, gid_t gid
)
654 trigger
->creds
.credentials
.uid
= uid
;
655 trigger
->creds
.credentials
.gid
= gid
;
656 trigger
->creds
.set
= true;
659 enum lttng_trigger_status
lttng_trigger_set_firing_policy(
660 struct lttng_trigger
*trigger
,
661 enum lttng_trigger_firing_policy_type policy_type
,
662 unsigned long long threshold
)
664 enum lttng_trigger_status ret
= LTTNG_TRIGGER_STATUS_OK
;
668 ret
= LTTNG_TRIGGER_STATUS_INVALID
;
672 trigger
->firing_policy
.type
= policy_type
;
673 trigger
->firing_policy
.threshold
= threshold
;
679 enum lttng_trigger_status
lttng_trigger_get_firing_policy(
680 const struct lttng_trigger
*trigger
,
681 enum lttng_trigger_firing_policy_type
*policy_type
,
682 unsigned long long *threshold
)
684 enum lttng_trigger_status status
= LTTNG_TRIGGER_STATUS_OK
;
686 if (!trigger
|| !policy_type
|| !threshold
) {
687 status
= LTTNG_TRIGGER_STATUS_INVALID
;
691 *policy_type
= trigger
->firing_policy
.type
;
692 *threshold
= trigger
->firing_policy
.threshold
;
699 bool lttng_trigger_is_ready_to_fire(struct lttng_trigger
*trigger
)
702 bool ready_to_fire
= false;
704 trigger
->firing_policy
.current_count
++;
706 switch (trigger
->firing_policy
.type
) {
707 case LTTNG_TRIGGER_FIRE_EVERY_N
:
708 if (trigger
->firing_policy
.current_count
== trigger
->firing_policy
.threshold
) {
709 trigger
->firing_policy
.current_count
= 0;
710 ready_to_fire
= true;
713 case LTTNG_TRIGGER_FIRE_ONCE_AFTER_N
:
714 if (trigger
->firing_policy
.current_count
== trigger
->firing_policy
.threshold
) {
715 /* TODO: remove the trigger of at least deactivate it on
716 * the tracers side to remove any work overhead on the
717 * traced application or kernel since the trigger will
719 * Still this branch should be left here since event
720 * could still be in the pipe. These will be discarded.
722 ready_to_fire
= true;
729 return ready_to_fire
;
733 enum lttng_domain_type
lttng_trigger_get_underlying_domain_type_restriction(
734 const struct lttng_trigger
*trigger
)
736 enum lttng_domain_type type
= LTTNG_DOMAIN_NONE
;
737 const struct lttng_event_rule
*event_rule
;
738 enum lttng_condition_status c_status
;
739 enum lttng_condition_type c_type
;
742 assert(trigger
->condition
);
743 c_type
= lttng_condition_get_type(trigger
->condition
);
744 if (c_type
== LTTNG_CONDITION_TYPE_UNKNOWN
) {
749 case LTTNG_CONDITION_TYPE_SESSION_CONSUMED_SIZE
:
750 case LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING
:
751 case LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED
:
752 type
= LTTNG_DOMAIN_NONE
;
754 case LTTNG_CONDITION_TYPE_EVENT_RULE_HIT
:
755 c_status
= lttng_condition_event_rule_get_rule(
756 trigger
->condition
, &event_rule
);
757 if (c_status
!= LTTNG_CONDITION_STATUS_OK
) {
758 /* The condition object is invalid */
762 type
= lttng_event_rule_get_domain_type(event_rule
);
764 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH
:
765 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW
:
766 c_status
= lttng_condition_buffer_usage_get_domain_type(
767 trigger
->condition
, &type
);
768 if (c_status
!= LTTNG_CONDITION_STATUS_OK
) {
769 /* The condition object is invalid */
774 type
= LTTNG_DOMAIN_NONE
;
782 unsigned int lttng_trigger_get_capture_bytecode_count(
783 const struct lttng_trigger
*trigger
)
785 unsigned int count
= 0;
790 count
= lttng_dynamic_pointer_array_get_count(
791 &trigger
->capture_bytecode_set
);
798 const struct lttng_bytecode
*
799 lttng_trigger_get_capture_bytecode_at_index(
800 const struct lttng_trigger
*trigger
, unsigned int index
)
802 struct lttng_condition_event_rule_capture_bytecode_element
*element
= NULL
;
803 struct lttng_bytecode
*bytecode
= NULL
;
805 element
= lttng_dynamic_pointer_array_get_pointer(
806 &trigger
->capture_bytecode_set
, index
);
808 if (element
== NULL
) {
811 bytecode
= element
->bytecode
;