2 * Copyright (C) 2019 Simon Marchi <simon.marchi@efficios.com>
4 * SPDX-License-Identifier: LGPL-2.1-only
8 #include <common/error.h>
9 #include <common/macros.h>
10 #include <common/mi-lttng.h>
11 #include <lttng/action/action-internal.h>
12 #include <lttng/action/rate-policy-internal.h>
13 #include <lttng/action/rate-policy.h>
14 #include <lttng/action/rotate-session-internal.h>
15 #include <lttng/action/rotate-session.h>
17 #define IS_ROTATE_SESSION_ACTION(action) \
18 (lttng_action_get_type(action) == LTTNG_ACTION_TYPE_ROTATE_SESSION)
20 struct lttng_action_rotate_session
{
21 struct lttng_action parent
;
25 struct lttng_rate_policy
*policy
;
28 struct lttng_action_rotate_session_comm
{
29 /* Includes the trailing \0. */
30 uint32_t session_name_len
;
35 * - session name (null terminated)
41 static const struct lttng_rate_policy
*
42 lttng_action_rotate_session_internal_get_rate_policy(
43 const struct lttng_action
*action
);
45 static struct lttng_action_rotate_session
*action_rotate_session_from_action(
46 struct lttng_action
*action
)
50 return container_of(action
, struct lttng_action_rotate_session
, parent
);
53 static const struct lttng_action_rotate_session
*
54 action_rotate_session_from_action_const(const struct lttng_action
*action
)
58 return container_of(action
, struct lttng_action_rotate_session
, parent
);
61 static bool lttng_action_rotate_session_validate(struct lttng_action
*action
)
64 struct lttng_action_rotate_session
*action_rotate_session
;
71 action_rotate_session
= action_rotate_session_from_action(action
);
73 /* A non-empty session name is mandatory. */
74 if (!action_rotate_session
->session_name
||
75 strlen(action_rotate_session
->session_name
) == 0) {
85 static bool lttng_action_rotate_session_is_equal(
86 const struct lttng_action
*_a
, const struct lttng_action
*_b
)
88 bool is_equal
= false;
89 const struct lttng_action_rotate_session
*a
, *b
;
91 a
= action_rotate_session_from_action_const(_a
);
92 b
= action_rotate_session_from_action_const(_b
);
94 /* Action is not valid if this is not true. */
95 LTTNG_ASSERT(a
->session_name
);
96 LTTNG_ASSERT(b
->session_name
);
97 if (strcmp(a
->session_name
, b
->session_name
)) {
101 is_equal
= lttng_rate_policy_is_equal(a
->policy
, b
->policy
);
105 static int lttng_action_rotate_session_serialize(
106 struct lttng_action
*action
, struct lttng_payload
*payload
)
108 struct lttng_action_rotate_session
*action_rotate_session
;
109 struct lttng_action_rotate_session_comm comm
;
110 size_t session_name_len
;
113 LTTNG_ASSERT(action
);
114 LTTNG_ASSERT(payload
);
116 action_rotate_session
= action_rotate_session_from_action(action
);
118 LTTNG_ASSERT(action_rotate_session
->session_name
);
120 DBG("Serializing rotate session action: session-name: %s",
121 action_rotate_session
->session_name
);
123 session_name_len
= strlen(action_rotate_session
->session_name
) + 1;
124 comm
.session_name_len
= session_name_len
;
126 ret
= lttng_dynamic_buffer_append(
127 &payload
->buffer
, &comm
, sizeof(comm
));
133 ret
= lttng_dynamic_buffer_append(&payload
->buffer
,
134 action_rotate_session
->session_name
, session_name_len
);
140 ret
= lttng_rate_policy_serialize(
141 action_rotate_session
->policy
, payload
);
150 static void lttng_action_rotate_session_destroy(struct lttng_action
*action
)
152 struct lttng_action_rotate_session
*action_rotate_session
;
158 action_rotate_session
= action_rotate_session_from_action(action
);
160 lttng_rate_policy_destroy(action_rotate_session
->policy
);
161 free(action_rotate_session
->session_name
);
162 free(action_rotate_session
);
168 ssize_t
lttng_action_rotate_session_create_from_payload(
169 struct lttng_payload_view
*view
,
170 struct lttng_action
**p_action
)
172 ssize_t consumed_len
, ret
;
173 const struct lttng_action_rotate_session_comm
*comm
;
174 const char *session_name
;
175 struct lttng_action
*action
;
176 enum lttng_action_status status
;
177 struct lttng_rate_policy
*policy
= NULL
;
179 action
= lttng_action_rotate_session_create();
185 comm
= (typeof(comm
)) view
->buffer
.data
;
186 session_name
= (const char *) &comm
->data
;
188 if (!lttng_buffer_view_contains_string(
189 &view
->buffer
, session_name
, comm
->session_name_len
)) {
193 consumed_len
= sizeof(*comm
) + comm
->session_name_len
;
197 struct lttng_payload_view policy_view
=
198 lttng_payload_view_from_view(
199 view
, consumed_len
, -1);
200 ret
= lttng_rate_policy_create_from_payload(
201 &policy_view
, &policy
);
209 status
= lttng_action_rotate_session_set_session_name(
210 action
, session_name
);
211 if (status
!= LTTNG_ACTION_STATUS_OK
) {
216 LTTNG_ASSERT(policy
);
217 status
= lttng_action_rotate_session_set_rate_policy(action
, policy
);
218 if (status
!= LTTNG_ACTION_STATUS_OK
) {
227 lttng_rate_policy_destroy(policy
);
228 lttng_action_rotate_session_destroy(action
);
233 static enum lttng_error_code
lttng_action_rotate_session_mi_serialize(
234 const struct lttng_action
*action
, struct mi_writer
*writer
)
237 enum lttng_error_code ret_code
;
238 enum lttng_action_status status
;
239 const char *session_name
= NULL
;
240 const struct lttng_rate_policy
*policy
= NULL
;
242 LTTNG_ASSERT(action
);
243 LTTNG_ASSERT(IS_ROTATE_SESSION_ACTION(action
));
245 status
= lttng_action_rotate_session_get_session_name(
246 action
, &session_name
);
247 LTTNG_ASSERT(status
== LTTNG_ACTION_STATUS_OK
);
248 LTTNG_ASSERT(session_name
!= NULL
);
250 status
= lttng_action_notify_get_rate_policy(action
, &policy
);
251 LTTNG_ASSERT(status
== LTTNG_ACTION_STATUS_OK
);
252 LTTNG_ASSERT(policy
!= NULL
);
254 /* Open action rotate session element. */
255 ret
= mi_lttng_writer_open_element(
256 writer
, mi_lttng_element_action_rotate_session
);
262 ret
= mi_lttng_writer_write_element_string(
263 writer
, mi_lttng_element_session_name
, session_name
);
269 ret_code
= lttng_rate_policy_mi_serialize(policy
, writer
);
270 if (ret_code
!= LTTNG_OK
) {
274 /* Close action rotate session element. */
275 ret
= mi_lttng_writer_close_element(writer
);
284 ret_code
= LTTNG_ERR_MI_IO_FAIL
;
289 struct lttng_action
*lttng_action_rotate_session_create(void)
291 struct lttng_action
*action
= NULL
;
292 struct lttng_rate_policy
*policy
= NULL
;
293 enum lttng_action_status status
;
295 /* Create a every N = 1 rate policy. */
296 policy
= lttng_rate_policy_every_n_create(1);
301 action
= zmalloc(sizeof(struct lttng_action_rotate_session
));
306 lttng_action_init(action
, LTTNG_ACTION_TYPE_ROTATE_SESSION
,
307 lttng_action_rotate_session_validate
,
308 lttng_action_rotate_session_serialize
,
309 lttng_action_rotate_session_is_equal
,
310 lttng_action_rotate_session_destroy
,
311 lttng_action_rotate_session_internal_get_rate_policy
,
312 lttng_action_generic_add_error_query_results
,
313 lttng_action_rotate_session_mi_serialize
);
315 status
= lttng_action_rotate_session_set_rate_policy(action
, policy
);
316 if (status
!= LTTNG_ACTION_STATUS_OK
) {
323 lttng_rate_policy_destroy(policy
);
327 enum lttng_action_status
lttng_action_rotate_session_set_session_name(
328 struct lttng_action
*action
, const char *session_name
)
330 struct lttng_action_rotate_session
*action_rotate_session
;
331 enum lttng_action_status status
;
333 if (!action
|| !IS_ROTATE_SESSION_ACTION(action
) || !session_name
||
334 strlen(session_name
) == 0) {
335 status
= LTTNG_ACTION_STATUS_INVALID
;
339 action_rotate_session
= action_rotate_session_from_action(action
);
341 free(action_rotate_session
->session_name
);
343 action_rotate_session
->session_name
= strdup(session_name
);
344 if (!action_rotate_session
->session_name
) {
345 status
= LTTNG_ACTION_STATUS_ERROR
;
349 status
= LTTNG_ACTION_STATUS_OK
;
354 enum lttng_action_status
lttng_action_rotate_session_get_session_name(
355 const struct lttng_action
*action
, const char **session_name
)
357 const struct lttng_action_rotate_session
*action_rotate_session
;
358 enum lttng_action_status status
;
360 if (!action
|| !IS_ROTATE_SESSION_ACTION(action
) || !session_name
) {
361 status
= LTTNG_ACTION_STATUS_INVALID
;
365 action_rotate_session
= action_rotate_session_from_action_const(action
);
367 *session_name
= action_rotate_session
->session_name
;
369 status
= LTTNG_ACTION_STATUS_OK
;
374 enum lttng_action_status
lttng_action_rotate_session_set_rate_policy(
375 struct lttng_action
*action
,
376 const struct lttng_rate_policy
*policy
)
378 enum lttng_action_status status
;
379 struct lttng_action_rotate_session
*rotate_session_action
;
380 struct lttng_rate_policy
*copy
= NULL
;
382 if (!action
|| !policy
|| !IS_ROTATE_SESSION_ACTION(action
)) {
383 status
= LTTNG_ACTION_STATUS_INVALID
;
387 copy
= lttng_rate_policy_copy(policy
);
389 status
= LTTNG_ACTION_STATUS_ERROR
;
393 rotate_session_action
= action_rotate_session_from_action(action
);
395 /* Free the previous rate policy .*/
396 lttng_rate_policy_destroy(rotate_session_action
->policy
);
398 /* Assign the policy. */
399 rotate_session_action
->policy
= copy
;
400 status
= LTTNG_ACTION_STATUS_OK
;
404 lttng_rate_policy_destroy(copy
);
408 enum lttng_action_status
lttng_action_rotate_session_get_rate_policy(
409 const struct lttng_action
*action
,
410 const struct lttng_rate_policy
**policy
)
412 enum lttng_action_status status
;
413 const struct lttng_action_rotate_session
*rotate_session_action
;
415 if (!action
|| !policy
|| !IS_ROTATE_SESSION_ACTION(action
)) {
416 status
= LTTNG_ACTION_STATUS_INVALID
;
420 rotate_session_action
= action_rotate_session_from_action_const(action
);
422 *policy
= rotate_session_action
->policy
;
423 status
= LTTNG_ACTION_STATUS_OK
;
428 static const struct lttng_rate_policy
*
429 lttng_action_rotate_session_internal_get_rate_policy(
430 const struct lttng_action
*action
)
432 const struct lttng_action_rotate_session
*_action
;
433 _action
= action_rotate_session_from_action_const(action
);
435 return _action
->policy
;