2 * Copyright (C) 2019 Simon Marchi <simon.marchi@efficios.com>
4 * SPDX-License-Identifier: LGPL-2.1-only
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>
13 #include <lttng/action/rate-policy.h>
14 #include <lttng/action/start-session-internal.hpp>
15 #include <lttng/action/start-session.h>
17 #define IS_START_SESSION_ACTION(action) \
18 (lttng_action_get_type(action) == LTTNG_ACTION_TYPE_START_SESSION)
21 struct lttng_action_start_session
{
22 struct lttng_action parent
;
26 struct lttng_rate_policy
*policy
;
29 struct lttng_action_start_session_comm
{
30 /* Includes the trailing \0. */
31 uint32_t session_name_len
;
36 * - session name (null terminated)
43 static const struct lttng_rate_policy
*
44 lttng_action_start_session_internal_get_rate_policy(
45 const struct lttng_action
*action
);
47 static struct lttng_action_start_session
*action_start_session_from_action(
48 struct lttng_action
*action
)
52 return lttng::utils::container_of(action
, <tng_action_start_session::parent
);
55 static const struct lttng_action_start_session
*
56 action_start_session_from_action_const(const struct lttng_action
*action
)
60 return lttng::utils::container_of(action
, <tng_action_start_session::parent
);
63 static bool lttng_action_start_session_validate(struct lttng_action
*action
)
66 struct lttng_action_start_session
*action_start_session
;
73 action_start_session
= action_start_session_from_action(action
);
75 /* A non-empty session name is mandatory. */
76 if (!action_start_session
->session_name
||
77 strlen(action_start_session
->session_name
) == 0) {
87 static bool lttng_action_start_session_is_equal(
88 const struct lttng_action
*_a
, const struct lttng_action
*_b
)
90 bool is_equal
= false;
91 struct lttng_action_start_session
*a
, *b
;
93 a
= lttng::utils::container_of(_a
, <tng_action_start_session::parent
);
94 b
= lttng::utils::container_of(_b
, <tng_action_start_session::parent
);
96 /* Action is not valid if this is not true. */
97 LTTNG_ASSERT(a
->session_name
);
98 LTTNG_ASSERT(b
->session_name
);
99 if (strcmp(a
->session_name
, b
->session_name
)) {
103 is_equal
= lttng_rate_policy_is_equal(a
->policy
, b
->policy
);
108 static int lttng_action_start_session_serialize(
109 struct lttng_action
*action
, struct lttng_payload
*payload
)
111 struct lttng_action_start_session
*action_start_session
;
112 struct lttng_action_start_session_comm comm
;
113 size_t session_name_len
;
116 LTTNG_ASSERT(action
);
117 LTTNG_ASSERT(payload
);
119 action_start_session
= action_start_session_from_action(action
);
121 LTTNG_ASSERT(action_start_session
->session_name
);
123 DBG("Serializing start session action: session-name: %s",
124 action_start_session
->session_name
);
126 session_name_len
= strlen(action_start_session
->session_name
) + 1;
127 comm
.session_name_len
= session_name_len
;
129 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, &comm
, sizeof(comm
));
135 ret
= lttng_dynamic_buffer_append(&payload
->buffer
,
136 action_start_session
->session_name
, session_name_len
);
142 ret
= lttng_rate_policy_serialize(
143 action_start_session
->policy
, payload
);
154 static void lttng_action_start_session_destroy(struct lttng_action
*action
)
156 struct lttng_action_start_session
*action_start_session
;
162 action_start_session
= action_start_session_from_action(action
);
164 lttng_rate_policy_destroy(action_start_session
->policy
);
165 free(action_start_session
->session_name
);
166 free(action_start_session
);
172 ssize_t
lttng_action_start_session_create_from_payload(
173 struct lttng_payload_view
*view
,
174 struct lttng_action
**p_action
)
176 ssize_t consumed_len
, ret
;
177 const struct lttng_action_start_session_comm
*comm
;
178 const char *session_name
;
179 struct lttng_action
*action
= NULL
;
180 enum lttng_action_status status
;
181 struct lttng_rate_policy
*policy
= NULL
;
183 comm
= (typeof(comm
)) view
->buffer
.data
;
184 session_name
= (const char *) &comm
->data
;
187 if (!lttng_buffer_view_contains_string(&view
->buffer
, session_name
,
188 comm
->session_name_len
)) {
192 consumed_len
= sizeof(*comm
) + comm
->session_name_len
;
196 struct lttng_payload_view policy_view
=
197 lttng_payload_view_from_view(
198 view
, consumed_len
, -1);
199 ret
= lttng_rate_policy_create_from_payload(
200 &policy_view
, &policy
);
208 action
= lttng_action_start_session_create();
214 status
= lttng_action_start_session_set_session_name(
215 action
, session_name
);
216 if (status
!= LTTNG_ACTION_STATUS_OK
) {
221 LTTNG_ASSERT(policy
);
222 status
= lttng_action_start_session_set_rate_policy(action
, policy
);
223 if (status
!= LTTNG_ACTION_STATUS_OK
) {
232 lttng_rate_policy_destroy(policy
);
233 lttng_action_start_session_destroy(action
);
238 static enum lttng_error_code
lttng_action_start_session_mi_serialize(
239 const struct lttng_action
*action
, struct mi_writer
*writer
)
242 enum lttng_error_code ret_code
;
243 enum lttng_action_status status
;
244 const char *session_name
= NULL
;
245 const struct lttng_rate_policy
*policy
= NULL
;
247 LTTNG_ASSERT(action
);
248 LTTNG_ASSERT(IS_START_SESSION_ACTION(action
));
250 status
= lttng_action_start_session_get_session_name(
251 action
, &session_name
);
252 LTTNG_ASSERT(status
== LTTNG_ACTION_STATUS_OK
);
253 LTTNG_ASSERT(session_name
!= NULL
);
255 status
= lttng_action_start_session_get_rate_policy(action
, &policy
);
256 LTTNG_ASSERT(status
== LTTNG_ACTION_STATUS_OK
);
257 LTTNG_ASSERT(policy
!= NULL
);
259 /* Open action start session element. */
260 ret
= mi_lttng_writer_open_element(
261 writer
, mi_lttng_element_action_start_session
);
267 ret
= mi_lttng_writer_write_element_string(
268 writer
, mi_lttng_element_session_name
, session_name
);
274 ret_code
= lttng_rate_policy_mi_serialize(policy
, writer
);
275 if (ret_code
!= LTTNG_OK
) {
279 /* Close action start session element. */
280 ret
= mi_lttng_writer_close_element(writer
);
289 ret_code
= LTTNG_ERR_MI_IO_FAIL
;
294 struct lttng_action
*lttng_action_start_session_create(void)
296 struct lttng_action_start_session
*action_start
= NULL
;
297 struct lttng_rate_policy
*policy
= NULL
;
298 enum lttng_action_status status
;
300 /* Create a every N = 1 rate policy. */
301 policy
= lttng_rate_policy_every_n_create(1);
306 action_start
= zmalloc
<lttng_action_start_session
>();
311 lttng_action_init(&action_start
->parent
,
312 LTTNG_ACTION_TYPE_START_SESSION
,
313 lttng_action_start_session_validate
,
314 lttng_action_start_session_serialize
,
315 lttng_action_start_session_is_equal
,
316 lttng_action_start_session_destroy
,
317 lttng_action_start_session_internal_get_rate_policy
,
318 lttng_action_generic_add_error_query_results
,
319 lttng_action_start_session_mi_serialize
);
321 status
= lttng_action_start_session_set_rate_policy(
322 &action_start
->parent
, policy
);
323 if (status
!= LTTNG_ACTION_STATUS_OK
) {
324 lttng_action_destroy(&action_start
->parent
);
330 lttng_rate_policy_destroy(policy
);
331 return &action_start
->parent
;
334 enum lttng_action_status
lttng_action_start_session_set_session_name(
335 struct lttng_action
*action
, const char *session_name
)
337 struct lttng_action_start_session
*action_start_session
;
338 enum lttng_action_status status
;
340 if (!action
|| !IS_START_SESSION_ACTION(action
) || !session_name
||
341 strlen(session_name
) == 0) {
342 status
= LTTNG_ACTION_STATUS_INVALID
;
346 action_start_session
= action_start_session_from_action(action
);
348 free(action_start_session
->session_name
);
350 action_start_session
->session_name
= strdup(session_name
);
351 if (!action_start_session
->session_name
) {
352 status
= LTTNG_ACTION_STATUS_ERROR
;
356 status
= LTTNG_ACTION_STATUS_OK
;
361 enum lttng_action_status
lttng_action_start_session_get_session_name(
362 const struct lttng_action
*action
, const char **session_name
)
364 const struct lttng_action_start_session
*action_start_session
;
365 enum lttng_action_status status
;
367 if (!action
|| !IS_START_SESSION_ACTION(action
) || !session_name
) {
368 status
= LTTNG_ACTION_STATUS_INVALID
;
372 action_start_session
= action_start_session_from_action_const(action
);
374 *session_name
= action_start_session
->session_name
;
376 status
= LTTNG_ACTION_STATUS_OK
;
381 enum lttng_action_status
lttng_action_start_session_set_rate_policy(
382 struct lttng_action
*action
,
383 const struct lttng_rate_policy
*policy
)
385 enum lttng_action_status status
;
386 struct lttng_action_start_session
*start_session_action
;
387 struct lttng_rate_policy
*copy
= NULL
;
389 if (!action
|| !policy
|| !IS_START_SESSION_ACTION(action
)) {
390 status
= LTTNG_ACTION_STATUS_INVALID
;
394 copy
= lttng_rate_policy_copy(policy
);
396 status
= LTTNG_ACTION_STATUS_ERROR
;
400 start_session_action
= action_start_session_from_action(action
);
402 /* Release the previous rate policy .*/
403 lttng_rate_policy_destroy(start_session_action
->policy
);
405 /* Assign the policy. */
406 start_session_action
->policy
= copy
;
407 status
= LTTNG_ACTION_STATUS_OK
;
411 lttng_rate_policy_destroy(copy
);
415 enum lttng_action_status
lttng_action_start_session_get_rate_policy(
416 const struct lttng_action
*action
,
417 const struct lttng_rate_policy
**policy
)
419 enum lttng_action_status status
;
420 const struct lttng_action_start_session
*start_session_action
;
422 if (!action
|| !policy
|| !IS_START_SESSION_ACTION(action
)) {
423 status
= LTTNG_ACTION_STATUS_INVALID
;
427 start_session_action
= action_start_session_from_action_const(action
);
429 *policy
= start_session_action
->policy
;
430 status
= LTTNG_ACTION_STATUS_OK
;
435 static const struct lttng_rate_policy
*
436 lttng_action_start_session_internal_get_rate_policy(
437 const struct lttng_action
*action
)
439 const struct lttng_action_start_session
*_action
;
440 _action
= action_start_session_from_action_const(action
);
442 return _action
->policy
;