common: replace container_of with a C++ safe implementation
[lttng-tools.git] / src / common / actions / rotate-session.cpp
CommitLineData
bfb2ec6a
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/rotate-session-internal.hpp>
bfb2ec6a
SM
15#include <lttng/action/rotate-session.h>
16
17#define IS_ROTATE_SESSION_ACTION(action) \
17182cfd 18 (lttng_action_get_type(action) == LTTNG_ACTION_TYPE_ROTATE_SESSION)
bfb2ec6a 19
f1494934 20namespace {
bfb2ec6a
SM
21struct lttng_action_rotate_session {
22 struct lttng_action parent;
23
24 /* Owned by this. */
25 char *session_name;
7f4d5b07 26 struct lttng_rate_policy *policy;
bfb2ec6a
SM
27};
28
29struct lttng_action_rotate_session_comm {
30 /* Includes the trailing \0. */
31 uint32_t session_name_len;
32
33 /*
34 * Variable data:
35 *
36 * - session name (null terminated)
c2c58434 37 * - policy
bfb2ec6a
SM
38 */
39 char data[];
40} LTTNG_PACKED;
f1494934 41} /* namespace */
bfb2ec6a 42
7f4d5b07
JR
43static const struct lttng_rate_policy *
44lttng_action_rotate_session_internal_get_rate_policy(
2d57482c
JR
45 const struct lttng_action *action);
46
bfb2ec6a
SM
47static struct lttng_action_rotate_session *action_rotate_session_from_action(
48 struct lttng_action *action)
49{
a0377dfe 50 LTTNG_ASSERT(action);
bfb2ec6a 51
0114db0e 52 return lttng::utils::container_of(action, &lttng_action_rotate_session::parent);
bfb2ec6a
SM
53}
54
55static const struct lttng_action_rotate_session *
56action_rotate_session_from_action_const(const struct lttng_action *action)
57{
a0377dfe 58 LTTNG_ASSERT(action);
bfb2ec6a 59
0114db0e 60 return lttng::utils::container_of(action, &lttng_action_rotate_session::parent);
bfb2ec6a
SM
61}
62
63static bool lttng_action_rotate_session_validate(struct lttng_action *action)
64{
65 bool valid;
66 struct lttng_action_rotate_session *action_rotate_session;
67
68 if (!action) {
69 valid = false;
70 goto end;
71 }
72
73 action_rotate_session = action_rotate_session_from_action(action);
74
75 /* A non-empty session name is mandatory. */
76 if (!action_rotate_session->session_name ||
77 strlen(action_rotate_session->session_name) == 0) {
78 valid = false;
79 goto end;
80 }
81
82 valid = true;
83end:
84 return valid;
85}
86
87static bool lttng_action_rotate_session_is_equal(
88 const struct lttng_action *_a, const struct lttng_action *_b)
89{
90 bool is_equal = false;
91 const struct lttng_action_rotate_session *a, *b;
92
93 a = action_rotate_session_from_action_const(_a);
94 b = action_rotate_session_from_action_const(_b);
95
96 /* Action is not valid if this is not true. */
a0377dfe
FD
97 LTTNG_ASSERT(a->session_name);
98 LTTNG_ASSERT(b->session_name);
bfb2ec6a
SM
99 if (strcmp(a->session_name, b->session_name)) {
100 goto end;
101 }
102
7f4d5b07 103 is_equal = lttng_rate_policy_is_equal(a->policy, b->policy);
bfb2ec6a
SM
104end:
105 return is_equal;
106}
107static int lttng_action_rotate_session_serialize(
c0a66c84 108 struct lttng_action *action, struct lttng_payload *payload)
bfb2ec6a
SM
109{
110 struct lttng_action_rotate_session *action_rotate_session;
111 struct lttng_action_rotate_session_comm comm;
112 size_t session_name_len;
113 int ret;
114
a0377dfe
FD
115 LTTNG_ASSERT(action);
116 LTTNG_ASSERT(payload);
bfb2ec6a
SM
117
118 action_rotate_session = action_rotate_session_from_action(action);
119
a0377dfe 120 LTTNG_ASSERT(action_rotate_session->session_name);
bfb2ec6a
SM
121
122 DBG("Serializing rotate session action: session-name: %s",
123 action_rotate_session->session_name);
124
125 session_name_len = strlen(action_rotate_session->session_name) + 1;
126 comm.session_name_len = session_name_len;
127
c0a66c84
JG
128 ret = lttng_dynamic_buffer_append(
129 &payload->buffer, &comm, sizeof(comm));
bfb2ec6a
SM
130 if (ret) {
131 ret = -1;
132 goto end;
133 }
134
c0a66c84 135 ret = lttng_dynamic_buffer_append(&payload->buffer,
bfb2ec6a
SM
136 action_rotate_session->session_name, session_name_len);
137 if (ret) {
138 ret = -1;
139 goto end;
140 }
141
7f4d5b07 142 ret = lttng_rate_policy_serialize(
c2c58434
JR
143 action_rotate_session->policy, payload);
144 if (ret) {
145 ret = -1;
146 goto end;
147 }
bfb2ec6a
SM
148end:
149 return ret;
150}
151
152static void lttng_action_rotate_session_destroy(struct lttng_action *action)
153{
154 struct lttng_action_rotate_session *action_rotate_session;
155
156 if (!action) {
157 goto end;
158 }
159
160 action_rotate_session = action_rotate_session_from_action(action);
161
7f4d5b07 162 lttng_rate_policy_destroy(action_rotate_session->policy);
bfb2ec6a
SM
163 free(action_rotate_session->session_name);
164 free(action_rotate_session);
165
166end:
167 return;
168}
169
c0a66c84
JG
170ssize_t lttng_action_rotate_session_create_from_payload(
171 struct lttng_payload_view *view,
bfb2ec6a
SM
172 struct lttng_action **p_action)
173{
c2c58434 174 ssize_t consumed_len, ret;
bfb2ec6a
SM
175 const struct lttng_action_rotate_session_comm *comm;
176 const char *session_name;
177 struct lttng_action *action;
178 enum lttng_action_status status;
7f4d5b07 179 struct lttng_rate_policy *policy = NULL;
bfb2ec6a
SM
180
181 action = lttng_action_rotate_session_create();
182 if (!action) {
183 consumed_len = -1;
184 goto end;
185 }
186
c0a66c84 187 comm = (typeof(comm)) view->buffer.data;
bfb2ec6a
SM
188 session_name = (const char *) &comm->data;
189
190 if (!lttng_buffer_view_contains_string(
c0a66c84 191 &view->buffer, session_name, comm->session_name_len)) {
bfb2ec6a
SM
192 consumed_len = -1;
193 goto end;
194 }
c2c58434
JR
195 consumed_len = sizeof(*comm) + comm->session_name_len;
196
7f4d5b07 197 /* Rate policy. */
c2c58434
JR
198 {
199 struct lttng_payload_view policy_view =
200 lttng_payload_view_from_view(
201 view, consumed_len, -1);
7f4d5b07 202 ret = lttng_rate_policy_create_from_payload(
c2c58434
JR
203 &policy_view, &policy);
204 if (ret < 0) {
205 consumed_len = -1;
206 goto end;
207 }
208 consumed_len += ret;
209 }
bfb2ec6a
SM
210
211 status = lttng_action_rotate_session_set_session_name(
212 action, session_name);
213 if (status != LTTNG_ACTION_STATUS_OK) {
214 consumed_len = -1;
215 goto end;
216 }
217
a0377dfe 218 LTTNG_ASSERT(policy);
7f4d5b07 219 status = lttng_action_rotate_session_set_rate_policy(action, policy);
c2c58434
JR
220 if (status != LTTNG_ACTION_STATUS_OK) {
221 consumed_len = -1;
222 goto end;
223 }
224
bfb2ec6a
SM
225 *p_action = action;
226 action = NULL;
227
228end:
7f4d5b07 229 lttng_rate_policy_destroy(policy);
bfb2ec6a
SM
230 lttng_action_rotate_session_destroy(action);
231
232 return consumed_len;
233}
234
6a751b95
JR
235static enum lttng_error_code lttng_action_rotate_session_mi_serialize(
236 const struct lttng_action *action, struct mi_writer *writer)
237{
238 int ret;
239 enum lttng_error_code ret_code;
240 enum lttng_action_status status;
241 const char *session_name = NULL;
242 const struct lttng_rate_policy *policy = NULL;
243
a0377dfe
FD
244 LTTNG_ASSERT(action);
245 LTTNG_ASSERT(IS_ROTATE_SESSION_ACTION(action));
6a751b95
JR
246
247 status = lttng_action_rotate_session_get_session_name(
248 action, &session_name);
a0377dfe
FD
249 LTTNG_ASSERT(status == LTTNG_ACTION_STATUS_OK);
250 LTTNG_ASSERT(session_name != NULL);
6a751b95
JR
251
252 status = lttng_action_notify_get_rate_policy(action, &policy);
a0377dfe
FD
253 LTTNG_ASSERT(status == LTTNG_ACTION_STATUS_OK);
254 LTTNG_ASSERT(policy != NULL);
6a751b95
JR
255
256 /* Open action rotate session element. */
257 ret = mi_lttng_writer_open_element(
258 writer, mi_lttng_element_action_rotate_session);
259 if (ret) {
260 goto mi_error;
261 }
262
263 /* Session name. */
264 ret = mi_lttng_writer_write_element_string(
265 writer, mi_lttng_element_session_name, session_name);
266 if (ret) {
267 goto mi_error;
268 }
269
270 /* Rate policy. */
271 ret_code = lttng_rate_policy_mi_serialize(policy, writer);
272 if (ret_code != LTTNG_OK) {
273 goto end;
274 }
275
276 /* Close action rotate session element. */
277 ret = mi_lttng_writer_close_element(writer);
278 if (ret) {
279 goto mi_error;
280 }
281
282 ret_code = LTTNG_OK;
283 goto end;
284
285mi_error:
286 ret_code = LTTNG_ERR_MI_IO_FAIL;
287end:
288 return ret_code;
289}
290
bfb2ec6a
SM
291struct lttng_action *lttng_action_rotate_session_create(void)
292{
64803277 293 struct lttng_action_rotate_session *action_rotate = NULL;
7f4d5b07 294 struct lttng_rate_policy *policy = NULL;
c2c58434
JR
295 enum lttng_action_status status;
296
7f4d5b07
JR
297 /* Create a every N = 1 rate policy. */
298 policy = lttng_rate_policy_every_n_create(1);
c2c58434
JR
299 if (!policy) {
300 goto end;
301 }
bfb2ec6a 302
64803277
SM
303 action_rotate = zmalloc<lttng_action_rotate_session>();
304 if (!action_rotate) {
bfb2ec6a
SM
305 goto end;
306 }
307
64803277
SM
308 lttng_action_init(&action_rotate->parent,
309 LTTNG_ACTION_TYPE_ROTATE_SESSION,
bfb2ec6a
SM
310 lttng_action_rotate_session_validate,
311 lttng_action_rotate_session_serialize,
312 lttng_action_rotate_session_is_equal,
2d57482c 313 lttng_action_rotate_session_destroy,
588c4b0d 314 lttng_action_rotate_session_internal_get_rate_policy,
6a751b95
JR
315 lttng_action_generic_add_error_query_results,
316 lttng_action_rotate_session_mi_serialize);
bfb2ec6a 317
64803277
SM
318 status = lttng_action_rotate_session_set_rate_policy(
319 &action_rotate->parent, policy);
c2c58434 320 if (status != LTTNG_ACTION_STATUS_OK) {
64803277
SM
321 lttng_action_destroy(&action_rotate->parent);
322 action_rotate = NULL;
c2c58434
JR
323 goto end;
324 }
325
bfb2ec6a 326end:
7f4d5b07 327 lttng_rate_policy_destroy(policy);
64803277 328 return action_rotate ? &action_rotate->parent : nullptr;
bfb2ec6a
SM
329}
330
331enum lttng_action_status lttng_action_rotate_session_set_session_name(
332 struct lttng_action *action, const char *session_name)
333{
334 struct lttng_action_rotate_session *action_rotate_session;
335 enum lttng_action_status status;
336
337 if (!action || !IS_ROTATE_SESSION_ACTION(action) || !session_name ||
338 strlen(session_name) == 0) {
339 status = LTTNG_ACTION_STATUS_INVALID;
340 goto end;
341 }
342
343 action_rotate_session = action_rotate_session_from_action(action);
344
345 free(action_rotate_session->session_name);
346
347 action_rotate_session->session_name = strdup(session_name);
348 if (!action_rotate_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_rotate_session_get_session_name(
359 const struct lttng_action *action, const char **session_name)
360{
361 const struct lttng_action_rotate_session *action_rotate_session;
362 enum lttng_action_status status;
363
364 if (!action || !IS_ROTATE_SESSION_ACTION(action) || !session_name) {
365 status = LTTNG_ACTION_STATUS_INVALID;
366 goto end;
367 }
368
369 action_rotate_session = action_rotate_session_from_action_const(action);
370
371 *session_name = action_rotate_session->session_name;
372
373 status = LTTNG_ACTION_STATUS_OK;
374end:
375 return status;
376}
c2c58434 377
7f4d5b07 378enum lttng_action_status lttng_action_rotate_session_set_rate_policy(
c2c58434 379 struct lttng_action *action,
7f4d5b07 380 const struct lttng_rate_policy *policy)
c2c58434
JR
381{
382 enum lttng_action_status status;
383 struct lttng_action_rotate_session *rotate_session_action;
7f4d5b07 384 struct lttng_rate_policy *copy = NULL;
c2c58434
JR
385
386 if (!action || !policy || !IS_ROTATE_SESSION_ACTION(action)) {
387 status = LTTNG_ACTION_STATUS_INVALID;
388 goto end;
389 }
390
7f4d5b07 391 copy = lttng_rate_policy_copy(policy);
c2c58434
JR
392 if (!copy) {
393 status = LTTNG_ACTION_STATUS_ERROR;
394 goto end;
395 }
396
397 rotate_session_action = action_rotate_session_from_action(action);
398
7f4d5b07
JR
399 /* Free the previous rate policy .*/
400 lttng_rate_policy_destroy(rotate_session_action->policy);
c2c58434
JR
401
402 /* Assign the policy. */
403 rotate_session_action->policy = copy;
404 status = LTTNG_ACTION_STATUS_OK;
405 copy = NULL;
406
407end:
7f4d5b07 408 lttng_rate_policy_destroy(copy);
c2c58434
JR
409 return status;
410}
411
7f4d5b07 412enum lttng_action_status lttng_action_rotate_session_get_rate_policy(
c2c58434 413 const struct lttng_action *action,
7f4d5b07 414 const struct lttng_rate_policy **policy)
c2c58434
JR
415{
416 enum lttng_action_status status;
417 const struct lttng_action_rotate_session *rotate_session_action;
418
419 if (!action || !policy || !IS_ROTATE_SESSION_ACTION(action)) {
420 status = LTTNG_ACTION_STATUS_INVALID;
421 goto end;
422 }
423
424 rotate_session_action = action_rotate_session_from_action_const(action);
425
426 *policy = rotate_session_action->policy;
427 status = LTTNG_ACTION_STATUS_OK;
428end:
429 return status;
430}
2d57482c 431
7f4d5b07
JR
432static const struct lttng_rate_policy *
433lttng_action_rotate_session_internal_get_rate_policy(
2d57482c
JR
434 const struct lttng_action *action)
435{
436 const struct lttng_action_rotate_session *_action;
437 _action = action_rotate_session_from_action_const(action);
438
439 return _action->policy;
440}
This page took 0.056542 seconds and 4 git commands to generate.