Clean-up: action-executor: typo and missing tab
[lttng-tools.git] / src / common / trigger.c
... / ...
CommitLineData
1/*
2 * Copyright (C) 2017 Jérémie Galarneau <jeremie.galarneau@efficios.com>
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
5 *
6 */
7
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>
16#include <assert.h>
17
18LTTNG_HIDDEN
19bool lttng_trigger_validate(struct lttng_trigger *trigger)
20{
21 bool valid;
22
23 if (!trigger) {
24 valid = false;
25 goto end;
26 }
27
28 valid = lttng_condition_validate(trigger->condition) &&
29 lttng_action_validate(trigger->action);
30end:
31 return valid;
32}
33
34struct lttng_trigger *lttng_trigger_create(
35 struct lttng_condition *condition,
36 struct lttng_action *action)
37{
38 struct lttng_trigger *trigger = NULL;
39
40 if (!condition || !action) {
41 goto end;
42 }
43
44 trigger = zmalloc(sizeof(struct lttng_trigger));
45 if (!trigger) {
46 goto end;
47 }
48
49 urcu_ref_init(&trigger->ref);
50
51 lttng_condition_get(condition);
52 trigger->condition = condition;
53
54 lttng_action_get(action);
55 trigger->action = action;
56
57end:
58 return trigger;
59}
60
61/*
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.
65 */
66struct lttng_condition *lttng_trigger_get_condition(
67 struct lttng_trigger *trigger)
68{
69 return trigger ? trigger->condition : NULL;
70}
71
72LTTNG_HIDDEN
73const struct lttng_condition *lttng_trigger_get_const_condition(
74 const struct lttng_trigger *trigger)
75{
76 return trigger->condition;
77}
78
79
80/*
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.
84 */
85struct lttng_action *lttng_trigger_get_action(
86 struct lttng_trigger *trigger)
87{
88 return trigger ? trigger->action : NULL;
89}
90
91LTTNG_HIDDEN
92const struct lttng_action *lttng_trigger_get_const_action(
93 const struct lttng_trigger *trigger)
94{
95 return trigger->action;
96}
97
98static void trigger_destroy_ref(struct urcu_ref *ref)
99{
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);
105
106 assert(action);
107 assert(condition);
108
109 /* Release ownership. */
110 lttng_action_put(action);
111 lttng_condition_put(condition);
112
113 free(trigger);
114}
115
116void lttng_trigger_destroy(struct lttng_trigger *trigger)
117{
118 lttng_trigger_put(trigger);
119}
120
121LTTNG_HIDDEN
122ssize_t lttng_trigger_create_from_payload(
123 struct lttng_payload_view *src_view,
124 struct lttng_trigger **trigger)
125{
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;
130
131 if (!src_view || !trigger) {
132 ret = -1;
133 goto end;
134 }
135
136 /* lttng_trigger_comm header */
137 trigger_comm = (typeof(trigger_comm)) src_view->buffer.data;
138 offset += sizeof(*trigger_comm);
139 {
140 /* struct lttng_condition */
141 struct lttng_payload_view condition_view =
142 lttng_payload_view_from_view(
143 src_view, offset, -1);
144
145 condition_size = lttng_condition_create_from_payload(&condition_view,
146 &condition);
147 }
148
149 if (condition_size < 0) {
150 ret = condition_size;
151 goto end;
152 }
153
154 offset += condition_size;
155 {
156 /* struct lttng_action */
157 struct lttng_payload_view action_view =
158 lttng_payload_view_from_view(
159 src_view, offset, -1);
160
161 action_size = lttng_action_create_from_payload(&action_view, &action);
162 }
163
164 if (action_size < 0) {
165 ret = action_size;
166 goto end;
167 }
168 offset += action_size;
169
170 /* Unexpected size of inner-elements; the buffer is corrupted. */
171 if ((ssize_t) trigger_comm->length != condition_size + action_size) {
172 ret = -1;
173 goto error;
174 }
175
176 *trigger = lttng_trigger_create(condition, action);
177 if (!*trigger) {
178 ret = -1;
179 goto error;
180 }
181
182 /*
183 * The trigger object owns references to the action and condition
184 * objects.
185 */
186 lttng_condition_put(condition);
187 condition = NULL;
188
189 lttng_action_put(action);
190 action = NULL;
191
192 ret = offset;
193
194error:
195 lttng_condition_destroy(condition);
196 lttng_action_destroy(action);
197end:
198 return ret;
199}
200
201/*
202 * Both elements are stored contiguously, see their "*_comm" structure
203 * for the detailed format.
204 */
205LTTNG_HIDDEN
206int lttng_trigger_serialize(struct lttng_trigger *trigger,
207 struct lttng_payload *payload)
208{
209 int ret;
210 size_t header_offset, size_before_payload;
211 struct lttng_trigger_comm trigger_comm = {};
212 struct lttng_trigger_comm *header;
213
214 header_offset = payload->buffer.size;
215 ret = lttng_dynamic_buffer_append(&payload->buffer, &trigger_comm,
216 sizeof(trigger_comm));
217 if (ret) {
218 goto end;
219 }
220
221 size_before_payload = payload->buffer.size;
222 ret = lttng_condition_serialize(trigger->condition, payload);
223 if (ret) {
224 goto end;
225 }
226
227 ret = lttng_action_serialize(trigger->action, payload);
228 if (ret) {
229 goto end;
230 }
231
232 /* Update payload size. */
233 header = (typeof(header)) (payload->buffer.data + header_offset);
234 header->length = payload->buffer.size - size_before_payload;
235end:
236 return ret;
237}
238
239LTTNG_HIDDEN
240void lttng_trigger_get(struct lttng_trigger *trigger)
241{
242 urcu_ref_get(&trigger->ref);
243}
244
245LTTNG_HIDDEN
246void lttng_trigger_put(struct lttng_trigger *trigger)
247{
248 if (!trigger) {
249 return;
250 }
251
252 urcu_ref_put(&trigger->ref , trigger_destroy_ref);
253}
254
255LTTNG_HIDDEN
256const struct lttng_credentials *lttng_trigger_get_credentials(
257 const struct lttng_trigger *trigger)
258{
259 return LTTNG_OPTIONAL_GET_PTR(trigger->creds);
260}
261
262LTTNG_HIDDEN
263void lttng_trigger_set_credentials(
264 struct lttng_trigger *trigger,
265 const struct lttng_credentials *creds)
266{
267 assert(creds);
268 LTTNG_OPTIONAL_SET(&trigger->creds, *creds);
269}
This page took 0.022759 seconds and 4 git commands to generate.