action executor: use an execution context to validate enqueued action before execution
[lttng-tools.git] / src / common / actions / start-session.c
CommitLineData
58397d0d
SM
1/*
2 * Copyright (C) 2019 Simon Marchi <simon.marchi@efficios.com>
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
5 *
6 */
7
8#include <assert.h>
9#include <common/error.h>
10#include <common/macros.h>
11#include <lttng/action/action-internal.h>
1345b16b
JR
12#include <lttng/action/firing-policy-internal.h>
13#include <lttng/action/firing-policy.h>
58397d0d
SM
14#include <lttng/action/start-session-internal.h>
15#include <lttng/action/start-session.h>
16
17#define IS_START_SESSION_ACTION(action) \
17182cfd 18 (lttng_action_get_type(action) == LTTNG_ACTION_TYPE_START_SESSION)
58397d0d
SM
19
20struct lttng_action_start_session {
21 struct lttng_action parent;
22
23 /* Owned by this. */
24 char *session_name;
1345b16b 25 struct lttng_firing_policy *policy;
58397d0d
SM
26};
27
28struct lttng_action_start_session_comm {
29 /* Includes the trailing \0. */
30 uint32_t session_name_len;
31
32 /*
33 * Variable data:
34 *
35 * - session name (null terminated)
1345b16b 36 * - policy
58397d0d
SM
37 */
38 char data[];
39} LTTNG_PACKED;
40
2d57482c
JR
41static const struct lttng_firing_policy *
42lttng_action_start_session_internal_get_firing_policy(
43 const struct lttng_action *action);
44
58397d0d
SM
45static struct lttng_action_start_session *action_start_session_from_action(
46 struct lttng_action *action)
47{
48 assert(action);
49
50 return container_of(action, struct lttng_action_start_session, parent);
51}
52
53static const struct lttng_action_start_session *
54action_start_session_from_action_const(const struct lttng_action *action)
55{
56 assert(action);
57
58 return container_of(action, struct lttng_action_start_session, parent);
59}
60
61static bool lttng_action_start_session_validate(struct lttng_action *action)
62{
63 bool valid;
64 struct lttng_action_start_session *action_start_session;
65
66 if (!action) {
67 valid = false;
68 goto end;
69 }
70
71 action_start_session = action_start_session_from_action(action);
72
73 /* A non-empty session name is mandatory. */
74 if (!action_start_session->session_name ||
75 strlen(action_start_session->session_name) == 0) {
76 valid = false;
77 goto end;
78 }
79
80 valid = true;
81end:
82 return valid;
83}
84
85static bool lttng_action_start_session_is_equal(
86 const struct lttng_action *_a, const struct lttng_action *_b)
87{
88 bool is_equal = false;
89 struct lttng_action_start_session *a, *b;
90
91 a = container_of(_a, struct lttng_action_start_session, parent);
92 b = container_of(_b, struct lttng_action_start_session, parent);
93
94 /* Action is not valid if this is not true. */
95 assert(a->session_name);
96 assert(b->session_name);
97 if (strcmp(a->session_name, b->session_name)) {
98 goto end;
99 }
100
1345b16b 101 is_equal = lttng_firing_policy_is_equal(a->policy, b->policy);
58397d0d
SM
102end:
103 return is_equal;
104}
105
106static int lttng_action_start_session_serialize(
c0a66c84 107 struct lttng_action *action, struct lttng_payload *payload)
58397d0d
SM
108{
109 struct lttng_action_start_session *action_start_session;
110 struct lttng_action_start_session_comm comm;
111 size_t session_name_len;
112 int ret;
113
114 assert(action);
c0a66c84 115 assert(payload);
58397d0d
SM
116
117 action_start_session = action_start_session_from_action(action);
118
119 assert(action_start_session->session_name);
120
121 DBG("Serializing start session action: session-name: %s",
122 action_start_session->session_name);
123
124 session_name_len = strlen(action_start_session->session_name) + 1;
125 comm.session_name_len = session_name_len;
126
c0a66c84 127 ret = lttng_dynamic_buffer_append(&payload->buffer, &comm, sizeof(comm));
58397d0d
SM
128 if (ret) {
129 ret = -1;
130 goto end;
131 }
132
c0a66c84 133 ret = lttng_dynamic_buffer_append(&payload->buffer,
58397d0d
SM
134 action_start_session->session_name, session_name_len);
135 if (ret) {
136 ret = -1;
137 goto end;
138 }
139
1345b16b
JR
140 ret = lttng_firing_policy_serialize(
141 action_start_session->policy, payload);
142 if (ret) {
143 ret = -1;
144 goto end;
145 }
146
58397d0d
SM
147 ret = 0;
148end:
149 return ret;
150}
151
152static void lttng_action_start_session_destroy(struct lttng_action *action)
153{
154 struct lttng_action_start_session *action_start_session;
155
156 if (!action) {
157 goto end;
158 }
159
160 action_start_session = action_start_session_from_action(action);
161
1345b16b 162 lttng_firing_policy_destroy(action_start_session->policy);
58397d0d
SM
163 free(action_start_session->session_name);
164 free(action_start_session);
165
166end:
167 return;
168}
169
c0a66c84
JG
170ssize_t lttng_action_start_session_create_from_payload(
171 struct lttng_payload_view *view,
58397d0d
SM
172 struct lttng_action **p_action)
173{
1345b16b 174 ssize_t consumed_len, ret;
58397d0d
SM
175 const struct lttng_action_start_session_comm *comm;
176 const char *session_name;
1345b16b 177 struct lttng_action *action = NULL;
58397d0d 178 enum lttng_action_status status;
1345b16b 179 struct lttng_firing_policy *policy = NULL;
58397d0d 180
c0a66c84 181 comm = (typeof(comm)) view->buffer.data;
58397d0d
SM
182 session_name = (const char *) &comm->data;
183
1345b16b 184 /* Session name */
c0a66c84
JG
185 if (!lttng_buffer_view_contains_string(&view->buffer, session_name,
186 comm->session_name_len)) {
58397d0d
SM
187 consumed_len = -1;
188 goto end;
189 }
1345b16b
JR
190 consumed_len = sizeof(*comm) + comm->session_name_len;
191
192 /* Firing policy. */
193 {
194 struct lttng_payload_view policy_view =
195 lttng_payload_view_from_view(
196 view, consumed_len, -1);
197 ret = lttng_firing_policy_create_from_payload(
198 &policy_view, &policy);
199 if (ret < 0) {
200 consumed_len = -1;
201 goto end;
202 }
203 consumed_len += ret;
204 }
205
206 action = lttng_action_start_session_create();
207 if (!action) {
208 consumed_len = -1;
209 goto end;
210 }
58397d0d
SM
211
212 status = lttng_action_start_session_set_session_name(
213 action, session_name);
214 if (status != LTTNG_ACTION_STATUS_OK) {
215 consumed_len = -1;
216 goto end;
217 }
218
1345b16b
JR
219 assert(policy);
220 status = lttng_action_start_session_set_firing_policy(action, policy);
221 if (status != LTTNG_ACTION_STATUS_OK) {
222 consumed_len = -1;
223 goto end;
224 }
225
58397d0d
SM
226 *p_action = action;
227 action = NULL;
228
229end:
1345b16b 230 lttng_firing_policy_destroy(policy);
58397d0d
SM
231 lttng_action_start_session_destroy(action);
232
233 return consumed_len;
234}
235
236struct lttng_action *lttng_action_start_session_create(void)
237{
1345b16b
JR
238 struct lttng_action *action = NULL;
239 struct lttng_firing_policy *policy = NULL;
240 enum lttng_action_status status;
241
242 /* Create a every N = 1 firing policy. */
243 policy = lttng_firing_policy_every_n_create(1);
244 if (!policy) {
245 goto end;
246 }
58397d0d
SM
247
248 action = zmalloc(sizeof(struct lttng_action_start_session));
249 if (!action) {
250 goto end;
251 }
252
253 lttng_action_init(action, LTTNG_ACTION_TYPE_START_SESSION,
254 lttng_action_start_session_validate,
255 lttng_action_start_session_serialize,
256 lttng_action_start_session_is_equal,
2d57482c
JR
257 lttng_action_start_session_destroy,
258 lttng_action_start_session_internal_get_firing_policy);
58397d0d 259
1345b16b
JR
260 status = lttng_action_start_session_set_firing_policy(action, policy);
261 if (status != LTTNG_ACTION_STATUS_OK) {
262 free(action);
263 action = NULL;
264 goto end;
265 }
266
58397d0d 267end:
1345b16b 268 lttng_firing_policy_destroy(policy);
58397d0d
SM
269 return action;
270}
271
272enum lttng_action_status lttng_action_start_session_set_session_name(
273 struct lttng_action *action, const char *session_name)
274{
275 struct lttng_action_start_session *action_start_session;
276 enum lttng_action_status status;
277
278 if (!action || !IS_START_SESSION_ACTION(action) || !session_name ||
279 strlen(session_name) == 0) {
280 status = LTTNG_ACTION_STATUS_INVALID;
281 goto end;
282 }
283
284 action_start_session = action_start_session_from_action(action);
285
286 free(action_start_session->session_name);
287
288 action_start_session->session_name = strdup(session_name);
289 if (!action_start_session->session_name) {
290 status = LTTNG_ACTION_STATUS_ERROR;
291 goto end;
292 }
293
294 status = LTTNG_ACTION_STATUS_OK;
295end:
296 return status;
297}
298
299enum lttng_action_status lttng_action_start_session_get_session_name(
300 const struct lttng_action *action, const char **session_name)
301{
302 const struct lttng_action_start_session *action_start_session;
303 enum lttng_action_status status;
304
305 if (!action || !IS_START_SESSION_ACTION(action) || !session_name) {
306 status = LTTNG_ACTION_STATUS_INVALID;
307 goto end;
308 }
309
310 action_start_session = action_start_session_from_action_const(action);
311
312 *session_name = action_start_session->session_name;
313
314 status = LTTNG_ACTION_STATUS_OK;
315end:
316 return status;
317}
1345b16b
JR
318
319enum lttng_action_status lttng_action_start_session_set_firing_policy(
320 struct lttng_action *action,
321 const struct lttng_firing_policy *policy)
322{
323 enum lttng_action_status status;
324 struct lttng_action_start_session *start_session_action;
325 struct lttng_firing_policy *copy = NULL;
326
327 if (!action || !policy || !IS_START_SESSION_ACTION(action)) {
328 status = LTTNG_ACTION_STATUS_INVALID;
329 goto end;
330 }
331
332 copy = lttng_firing_policy_copy(policy);
333 if (!copy) {
334 status = LTTNG_ACTION_STATUS_ERROR;
335 goto end;
336 }
337
338 start_session_action = action_start_session_from_action(action);
339
340 /* Release the previous firing policy .*/
341 lttng_firing_policy_destroy(start_session_action->policy);
342
343 /* Assign the policy. */
344 start_session_action->policy = copy;
345 status = LTTNG_ACTION_STATUS_OK;
346 copy = NULL;
347
348end:
349 lttng_firing_policy_destroy(copy);
350 return status;
351}
352
353enum lttng_action_status lttng_action_start_session_get_firing_policy(
354 const struct lttng_action *action,
355 const struct lttng_firing_policy **policy)
356{
357 enum lttng_action_status status;
358 const struct lttng_action_start_session *start_session_action;
359
360 if (!action || !policy || !IS_START_SESSION_ACTION(action)) {
361 status = LTTNG_ACTION_STATUS_INVALID;
362 goto end;
363 }
364
365 start_session_action = action_start_session_from_action_const(action);
366
367 *policy = start_session_action->policy;
368 status = LTTNG_ACTION_STATUS_OK;
369end:
370 return status;
371}
2d57482c
JR
372
373static const struct lttng_firing_policy *
374lttng_action_start_session_internal_get_firing_policy(
375 const struct lttng_action *action)
376{
377 const struct lttng_action_start_session *_action;
378 _action = action_start_session_from_action_const(action);
379
380 return _action->policy;
381}
This page took 0.041116 seconds and 4 git commands to generate.