2 * Copyright (C) 2017 Jérémie Galarneau <jeremie.galarneau@efficios.com>
4 * SPDX-License-Identifier: LGPL-2.1-only
8 #include <lttng/trigger/trigger-internal.h>
9 #include <lttng/condition/condition-internal.h>
10 #include <lttng/action/action-internal.h>
11 #include <common/credentials.h>
12 #include <common/payload.h>
13 #include <common/payload-view.h>
14 #include <common/error.h>
15 #include <common/optional.h>
19 bool lttng_trigger_validate(struct lttng_trigger
*trigger
)
28 valid
= lttng_condition_validate(trigger
->condition
) &&
29 lttng_action_validate(trigger
->action
);
34 struct lttng_trigger
*lttng_trigger_create(
35 struct lttng_condition
*condition
,
36 struct lttng_action
*action
)
38 struct lttng_trigger
*trigger
= NULL
;
40 if (!condition
|| !action
) {
44 trigger
= zmalloc(sizeof(struct lttng_trigger
));
49 urcu_ref_init(&trigger
->ref
);
51 lttng_condition_get(condition
);
52 trigger
->condition
= condition
;
54 lttng_action_get(action
);
55 trigger
->action
= action
;
62 * Note: the lack of reference counting 'get' on the condition object is normal.
63 * This API was exposed as such in 2.11. The client is not expected to call
64 * lttng_condition_destroy on the returned object.
66 struct lttng_condition
*lttng_trigger_get_condition(
67 struct lttng_trigger
*trigger
)
69 return trigger
? trigger
->condition
: NULL
;
73 const struct lttng_condition
*lttng_trigger_get_const_condition(
74 const struct lttng_trigger
*trigger
)
76 return trigger
->condition
;
81 * Note: the lack of reference counting 'get' on the action object is normal.
82 * This API was exposed as such in 2.11. The client is not expected to call
83 * lttng_action_destroy on the returned object.
85 struct lttng_action
*lttng_trigger_get_action(
86 struct lttng_trigger
*trigger
)
88 return trigger
? trigger
->action
: NULL
;
92 const struct lttng_action
*lttng_trigger_get_const_action(
93 const struct lttng_trigger
*trigger
)
95 return trigger
->action
;
98 static void trigger_destroy_ref(struct urcu_ref
*ref
)
100 struct lttng_trigger
*trigger
=
101 container_of(ref
, struct lttng_trigger
, ref
);
102 struct lttng_action
*action
= lttng_trigger_get_action(trigger
);
103 struct lttng_condition
*condition
=
104 lttng_trigger_get_condition(trigger
);
109 /* Release ownership. */
110 lttng_action_put(action
);
111 lttng_condition_put(condition
);
116 void lttng_trigger_destroy(struct lttng_trigger
*trigger
)
118 lttng_trigger_put(trigger
);
122 ssize_t
lttng_trigger_create_from_payload(
123 struct lttng_payload_view
*src_view
,
124 struct lttng_trigger
**trigger
)
126 ssize_t ret
, offset
= 0, condition_size
, action_size
;
127 struct lttng_condition
*condition
= NULL
;
128 struct lttng_action
*action
= NULL
;
129 const struct lttng_trigger_comm
*trigger_comm
;
131 if (!src_view
|| !trigger
) {
136 /* lttng_trigger_comm header */
137 trigger_comm
= (typeof(trigger_comm
)) src_view
->buffer
.data
;
138 offset
+= sizeof(*trigger_comm
);
140 /* struct lttng_condition */
141 struct lttng_payload_view condition_view
=
142 lttng_payload_view_from_view(
143 src_view
, offset
, -1);
145 condition_size
= lttng_condition_create_from_payload(&condition_view
,
149 if (condition_size
< 0) {
150 ret
= condition_size
;
154 offset
+= condition_size
;
156 /* struct lttng_action */
157 struct lttng_payload_view action_view
=
158 lttng_payload_view_from_view(
159 src_view
, offset
, -1);
161 action_size
= lttng_action_create_from_payload(&action_view
, &action
);
164 if (action_size
< 0) {
168 offset
+= action_size
;
170 /* Unexpected size of inner-elements; the buffer is corrupted. */
171 if ((ssize_t
) trigger_comm
->length
!= condition_size
+ action_size
) {
176 *trigger
= lttng_trigger_create(condition
, action
);
183 * The trigger object owns references to the action and condition
186 lttng_condition_put(condition
);
189 lttng_action_put(action
);
195 lttng_condition_destroy(condition
);
196 lttng_action_destroy(action
);
202 * Both elements are stored contiguously, see their "*_comm" structure
203 * for the detailed format.
206 int lttng_trigger_serialize(struct lttng_trigger
*trigger
,
207 struct lttng_payload
*payload
)
210 size_t header_offset
, size_before_payload
;
211 struct lttng_trigger_comm trigger_comm
= {};
212 struct lttng_trigger_comm
*header
;
214 header_offset
= payload
->buffer
.size
;
215 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, &trigger_comm
,
216 sizeof(trigger_comm
));
221 size_before_payload
= payload
->buffer
.size
;
222 ret
= lttng_condition_serialize(trigger
->condition
, payload
);
227 ret
= lttng_action_serialize(trigger
->action
, payload
);
232 /* Update payload size. */
233 header
= (typeof(header
)) (payload
->buffer
.data
+ header_offset
);
234 header
->length
= payload
->buffer
.size
- size_before_payload
;
240 void lttng_trigger_get(struct lttng_trigger
*trigger
)
242 urcu_ref_get(&trigger
->ref
);
246 void lttng_trigger_put(struct lttng_trigger
*trigger
)
252 urcu_ref_put(&trigger
->ref
, trigger_destroy_ref
);
256 const struct lttng_credentials
*lttng_trigger_get_credentials(
257 const struct lttng_trigger
*trigger
)
259 return LTTNG_OPTIONAL_GET_PTR(trigger
->creds
);
263 void lttng_trigger_set_credentials(
264 struct lttng_trigger
*trigger
,
265 const struct lttng_credentials
*creds
)
268 LTTNG_OPTIONAL_SET(&trigger
->creds
, *creds
);