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