Add type-checked versions of allocation and deallocations functions
[lttng-tools.git] / src / common / actions / stop-session.cpp
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
c9e313bc
SM
8#include <common/error.hpp>
9#include <common/macros.hpp>
10#include <common/mi-lttng.hpp>
11#include <lttng/action/action-internal.hpp>
12#include <lttng/action/rate-policy-internal.hpp>
7f4d5b07 13#include <lttng/action/rate-policy.h>
c9e313bc 14#include <lttng/action/stop-session-internal.hpp>
931bdbaa
SM
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;
7f4d5b07 25 struct lttng_rate_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
7f4d5b07
JR
41static const struct lttng_rate_policy *
42lttng_action_stop_session_internal_get_rate_policy(
2d57482c
JR
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{
a0377dfe 48 LTTNG_ASSERT(action);
931bdbaa
SM
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{
a0377dfe 56 LTTNG_ASSERT(action);
931bdbaa
SM
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. */
a0377dfe
FD
95 LTTNG_ASSERT(a->session_name);
96 LTTNG_ASSERT(b->session_name);
931bdbaa
SM
97 if (strcmp(a->session_name, b->session_name)) {
98 goto end;
99 }
100
7f4d5b07 101 is_equal = lttng_rate_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
a0377dfe
FD
114 LTTNG_ASSERT(action);
115 LTTNG_ASSERT(payload);
931bdbaa
SM
116
117 action_stop_session = action_stop_session_from_action(action);
118
a0377dfe 119 LTTNG_ASSERT(action_stop_session->session_name);
931bdbaa
SM
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
7f4d5b07 141 ret = lttng_rate_policy_serialize(action_stop_session->policy, payload);
a5ec75db
JR
142 if (ret) {
143 ret = -1;
144 goto end;
145 }
146
931bdbaa
SM
147 ret = 0;
148end:
149 return ret;
150}
151
152static void lttng_action_stop_session_destroy(struct lttng_action *action)
153{
154 struct lttng_action_stop_session *action_stop_session;
155
156 if (!action) {
157 goto end;
158 }
159
160 action_stop_session = action_stop_session_from_action(action);
161
7f4d5b07 162 lttng_rate_policy_destroy(action_stop_session->policy);
931bdbaa
SM
163 free(action_stop_session->session_name);
164 free(action_stop_session);
165
166end:
167 return;
168}
169
c0a66c84
JG
170ssize_t lttng_action_stop_session_create_from_payload(
171 struct lttng_payload_view *view,
931bdbaa
SM
172 struct lttng_action **p_action)
173{
a5ec75db 174 ssize_t consumed_len, ret;
931bdbaa
SM
175 const struct lttng_action_stop_session_comm *comm;
176 const char *session_name;
a5ec75db 177 struct lttng_action *action = NULL;
931bdbaa 178 enum lttng_action_status status;
7f4d5b07 179 struct lttng_rate_policy *policy = NULL;
931bdbaa 180
c0a66c84 181 comm = (typeof(comm)) view->buffer.data;
931bdbaa
SM
182 session_name = (const char *) &comm->data;
183
a5ec75db 184 /* Session name. */
931bdbaa 185 if (!lttng_buffer_view_contains_string(
c0a66c84 186 &view->buffer, session_name, comm->session_name_len)) {
931bdbaa
SM
187 consumed_len = -1;
188 goto end;
189 }
a5ec75db
JR
190 consumed_len = sizeof(*comm) + comm->session_name_len;
191
7f4d5b07 192 /* Rate policy. */
a5ec75db
JR
193 {
194 struct lttng_payload_view policy_view =
195 lttng_payload_view_from_view(
196 view, consumed_len, -1);
7f4d5b07 197 ret = lttng_rate_policy_create_from_payload(
a5ec75db
JR
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_stop_session_create();
207 if (!action) {
208 consumed_len = -1;
209 goto end;
210 }
931bdbaa
SM
211
212 status = lttng_action_stop_session_set_session_name(
213 action, session_name);
214 if (status != LTTNG_ACTION_STATUS_OK) {
215 consumed_len = -1;
216 goto end;
217 }
218
a0377dfe 219 LTTNG_ASSERT(policy);
7f4d5b07 220 status = lttng_action_stop_session_set_rate_policy(action, policy);
a5ec75db
JR
221 if (status != LTTNG_ACTION_STATUS_OK) {
222 consumed_len = -1;
223 goto end;
224 }
225
931bdbaa
SM
226 *p_action = action;
227 action = NULL;
228
229end:
7f4d5b07 230 lttng_rate_policy_destroy(policy);
931bdbaa
SM
231 lttng_action_stop_session_destroy(action);
232
233 return consumed_len;
234}
235
6a751b95
JR
236static enum lttng_error_code lttng_action_stop_session_mi_serialize(
237 const struct lttng_action *action, struct mi_writer *writer)
238{
239 int ret;
240 enum lttng_error_code ret_code;
241 enum lttng_action_status status;
242 const char *session_name = NULL;
243 const struct lttng_rate_policy *policy = NULL;
244
a0377dfe
FD
245 LTTNG_ASSERT(action);
246 LTTNG_ASSERT(IS_STOP_SESSION_ACTION(action));
6a751b95
JR
247
248 status = lttng_action_stop_session_get_session_name(
249 action, &session_name);
a0377dfe
FD
250 LTTNG_ASSERT(status == LTTNG_ACTION_STATUS_OK);
251 LTTNG_ASSERT(session_name != NULL);
6a751b95
JR
252
253 status = lttng_action_stop_session_get_rate_policy(action, &policy);
a0377dfe
FD
254 LTTNG_ASSERT(status == LTTNG_ACTION_STATUS_OK);
255 LTTNG_ASSERT(policy != NULL);
6a751b95
JR
256
257 /* Open action stop session. */
258 ret = mi_lttng_writer_open_element(
259 writer, mi_lttng_element_action_start_session);
260 if (ret) {
261 goto mi_error;
262 }
263
264 /* Session name. */
265 ret = mi_lttng_writer_write_element_string(
266 writer, mi_lttng_element_session_name, session_name);
267 if (ret) {
268 goto mi_error;
269 }
270
271 /* Rate policy. */
272 ret_code = lttng_rate_policy_mi_serialize(policy, writer);
273 if (ret_code != LTTNG_OK) {
274 goto end;
275 }
276
277 /* Close action stop session element. */
278 ret = mi_lttng_writer_close_element(writer);
279 if (ret) {
280 goto mi_error;
281 }
282
283 ret_code = LTTNG_OK;
284 goto end;
285
286mi_error:
287 ret_code = LTTNG_ERR_MI_IO_FAIL;
288end:
289 return ret_code;
290}
291
931bdbaa
SM
292struct lttng_action *lttng_action_stop_session_create(void)
293{
64803277 294 struct lttng_action_stop_session *action_stop = NULL;
7f4d5b07 295 struct lttng_rate_policy *policy = NULL;
a5ec75db
JR
296 enum lttng_action_status status;
297
7f4d5b07
JR
298 /* Create a every N = 1 rate policy. */
299 policy = lttng_rate_policy_every_n_create(1);
a5ec75db
JR
300 if (!policy) {
301 goto end;
302 }
931bdbaa 303
64803277
SM
304 action_stop = zmalloc<lttng_action_stop_session>();
305 if (!action_stop) {
931bdbaa
SM
306 goto end;
307 }
308
64803277 309 lttng_action_init(&action_stop->parent, LTTNG_ACTION_TYPE_STOP_SESSION,
931bdbaa
SM
310 lttng_action_stop_session_validate,
311 lttng_action_stop_session_serialize,
312 lttng_action_stop_session_is_equal,
2d57482c 313 lttng_action_stop_session_destroy,
588c4b0d 314 lttng_action_stop_session_internal_get_rate_policy,
6a751b95
JR
315 lttng_action_generic_add_error_query_results,
316 lttng_action_stop_session_mi_serialize);
931bdbaa 317
64803277
SM
318 status = lttng_action_stop_session_set_rate_policy(
319 &action_stop->parent, policy);
a5ec75db 320 if (status != LTTNG_ACTION_STATUS_OK) {
64803277
SM
321 lttng_action_destroy(&action_stop->parent);
322 action_stop = NULL;
a5ec75db
JR
323 goto end;
324 }
325
931bdbaa 326end:
7f4d5b07 327 lttng_rate_policy_destroy(policy);
64803277 328 return &action_stop->parent;
931bdbaa
SM
329}
330
331enum lttng_action_status lttng_action_stop_session_set_session_name(
332 struct lttng_action *action, const char *session_name)
333{
334 struct lttng_action_stop_session *action_stop_session;
335 enum lttng_action_status status;
336
337 if (!action || !IS_STOP_SESSION_ACTION(action) || !session_name ||
338 strlen(session_name) == 0) {
339 status = LTTNG_ACTION_STATUS_INVALID;
340 goto end;
341 }
342
343 action_stop_session = action_stop_session_from_action(action);
344
345 free(action_stop_session->session_name);
346
347 action_stop_session->session_name = strdup(session_name);
348 if (!action_stop_session->session_name) {
349 status = LTTNG_ACTION_STATUS_ERROR;
350 goto end;
351 }
352
353 status = LTTNG_ACTION_STATUS_OK;
354end:
355 return status;
356}
357
358enum lttng_action_status lttng_action_stop_session_get_session_name(
359 const struct lttng_action *action, const char **session_name)
360{
361 const struct lttng_action_stop_session *action_stop_session;
362 enum lttng_action_status status;
363
364 if (!action || !IS_STOP_SESSION_ACTION(action) || !session_name) {
365 status = LTTNG_ACTION_STATUS_INVALID;
366 goto end;
367 }
368
369 action_stop_session = action_stop_session_from_action_const(action);
370
371 *session_name = action_stop_session->session_name;
372
373 status = LTTNG_ACTION_STATUS_OK;
374end:
375 return status;
376}
a5ec75db 377
7f4d5b07 378enum lttng_action_status lttng_action_stop_session_set_rate_policy(
a5ec75db 379 struct lttng_action *action,
7f4d5b07 380 const struct lttng_rate_policy *policy)
a5ec75db
JR
381{
382 enum lttng_action_status status;
383 struct lttng_action_stop_session *stop_session_action;
7f4d5b07 384 struct lttng_rate_policy *copy = NULL;
a5ec75db
JR
385
386 if (!action || !policy || !IS_STOP_SESSION_ACTION(action)) {
387 status = LTTNG_ACTION_STATUS_INVALID;
388 goto end;
389 }
390
7f4d5b07 391 copy = lttng_rate_policy_copy(policy);
a5ec75db
JR
392 if (!copy) {
393 status = LTTNG_ACTION_STATUS_ERROR;
394 goto end;
395 }
396 stop_session_action = action_stop_session_from_action(action);
397
7f4d5b07
JR
398 /* Free the previous rate policy .*/
399 lttng_rate_policy_destroy(stop_session_action->policy);
a5ec75db
JR
400
401 stop_session_action->policy = copy;
402 status = LTTNG_ACTION_STATUS_OK;
403 copy = NULL;
404
405end:
7f4d5b07 406 lttng_rate_policy_destroy(copy);
a5ec75db
JR
407 return status;
408}
409
7f4d5b07 410enum lttng_action_status lttng_action_stop_session_get_rate_policy(
a5ec75db 411 const struct lttng_action *action,
7f4d5b07 412 const struct lttng_rate_policy **policy)
a5ec75db
JR
413{
414 enum lttng_action_status status;
415 const struct lttng_action_stop_session *stop_session_action;
416
417 if (!action || !policy || !IS_STOP_SESSION_ACTION(action)) {
418 status = LTTNG_ACTION_STATUS_INVALID;
419 goto end;
420 }
421
422 stop_session_action = action_stop_session_from_action_const(action);
423
424 *policy = stop_session_action->policy;
425 status = LTTNG_ACTION_STATUS_OK;
426end:
427 return status;
428}
2d57482c 429
7f4d5b07
JR
430static const struct lttng_rate_policy *
431lttng_action_stop_session_internal_get_rate_policy(
2d57482c
JR
432 const struct lttng_action *action)
433{
434 const struct lttng_action_stop_session *_action;
435 _action = action_stop_session_from_action_const(action);
436
437 return _action->policy;
438}
This page took 0.055794 seconds and 4 git commands to generate.