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