2 * Copyright (C) 2019 Simon Marchi <simon.marchi@efficios.com>
4 * SPDX-License-Identifier: LGPL-2.1-only
9 #include <common/error.h>
10 #include <common/macros.h>
11 #include <common/mi-lttng.h>
12 #include <lttng/action/action-internal.h>
13 #include <lttng/action/rate-policy-internal.h>
14 #include <lttng/action/rate-policy.h>
15 #include <lttng/action/start-session-internal.h>
16 #include <lttng/action/start-session.h>
18 #define IS_START_SESSION_ACTION(action) \
19 (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)
42 static const struct lttng_rate_policy
*
43 lttng_action_start_session_internal_get_rate_policy(
44 const struct lttng_action
*action
);
46 static struct lttng_action_start_session
*action_start_session_from_action(
47 struct lttng_action
*action
)
51 return container_of(action
, struct lttng_action_start_session
, parent
);
54 static const struct lttng_action_start_session
*
55 action_start_session_from_action_const(const struct lttng_action
*action
)
59 return container_of(action
, struct lttng_action_start_session
, parent
);
62 static bool lttng_action_start_session_validate(struct lttng_action
*action
)
65 struct lttng_action_start_session
*action_start_session
;
72 action_start_session
= action_start_session_from_action(action
);
74 /* A non-empty session name is mandatory. */
75 if (!action_start_session
->session_name
||
76 strlen(action_start_session
->session_name
) == 0) {
86 static bool lttng_action_start_session_is_equal(
87 const struct lttng_action
*_a
, const struct lttng_action
*_b
)
89 bool is_equal
= false;
90 struct lttng_action_start_session
*a
, *b
;
92 a
= container_of(_a
, struct lttng_action_start_session
, parent
);
93 b
= container_of(_b
, struct lttng_action_start_session
, parent
);
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
)) {
102 is_equal
= lttng_rate_policy_is_equal(a
->policy
, b
->policy
);
107 static int lttng_action_start_session_serialize(
108 struct lttng_action
*action
, struct lttng_payload
*payload
)
110 struct lttng_action_start_session
*action_start_session
;
111 struct lttng_action_start_session_comm comm
;
112 size_t session_name_len
;
118 action_start_session
= action_start_session_from_action(action
);
120 assert(action_start_session
->session_name
);
122 DBG("Serializing start session action: session-name: %s",
123 action_start_session
->session_name
);
125 session_name_len
= strlen(action_start_session
->session_name
) + 1;
126 comm
.session_name_len
= session_name_len
;
128 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, &comm
, sizeof(comm
));
134 ret
= lttng_dynamic_buffer_append(&payload
->buffer
,
135 action_start_session
->session_name
, session_name_len
);
141 ret
= lttng_rate_policy_serialize(
142 action_start_session
->policy
, payload
);
153 static void lttng_action_start_session_destroy(struct lttng_action
*action
)
155 struct lttng_action_start_session
*action_start_session
;
161 action_start_session
= action_start_session_from_action(action
);
163 lttng_rate_policy_destroy(action_start_session
->policy
);
164 free(action_start_session
->session_name
);
165 free(action_start_session
);
171 ssize_t
lttng_action_start_session_create_from_payload(
172 struct lttng_payload_view
*view
,
173 struct lttng_action
**p_action
)
175 ssize_t consumed_len
, ret
;
176 const struct lttng_action_start_session_comm
*comm
;
177 const char *session_name
;
178 struct lttng_action
*action
= NULL
;
179 enum lttng_action_status status
;
180 struct lttng_rate_policy
*policy
= NULL
;
182 comm
= (typeof(comm
)) view
->buffer
.data
;
183 session_name
= (const char *) &comm
->data
;
186 if (!lttng_buffer_view_contains_string(&view
->buffer
, session_name
,
187 comm
->session_name_len
)) {
191 consumed_len
= sizeof(*comm
) + comm
->session_name_len
;
195 struct lttng_payload_view policy_view
=
196 lttng_payload_view_from_view(
197 view
, consumed_len
, -1);
198 ret
= lttng_rate_policy_create_from_payload(
199 &policy_view
, &policy
);
207 action
= lttng_action_start_session_create();
213 status
= lttng_action_start_session_set_session_name(
214 action
, session_name
);
215 if (status
!= LTTNG_ACTION_STATUS_OK
) {
221 status
= lttng_action_start_session_set_rate_policy(action
, policy
);
222 if (status
!= LTTNG_ACTION_STATUS_OK
) {
231 lttng_rate_policy_destroy(policy
);
232 lttng_action_start_session_destroy(action
);
237 static enum lttng_error_code
lttng_action_start_session_mi_serialize(
238 const struct lttng_action
*action
, struct mi_writer
*writer
)
241 enum lttng_error_code ret_code
;
242 enum lttng_action_status status
;
243 const char *session_name
= NULL
;
244 const struct lttng_rate_policy
*policy
= NULL
;
247 assert(IS_START_SESSION_ACTION(action
));
249 status
= lttng_action_start_session_get_session_name(
250 action
, &session_name
);
251 assert(status
== LTTNG_ACTION_STATUS_OK
);
252 assert(session_name
!= NULL
);
254 status
= lttng_action_start_session_get_rate_policy(action
, &policy
);
255 assert(status
== LTTNG_ACTION_STATUS_OK
);
256 assert(policy
!= NULL
);
258 /* Open action start session element. */
259 ret
= mi_lttng_writer_open_element(
260 writer
, mi_lttng_element_action_start_session
);
266 ret
= mi_lttng_writer_write_element_string(
267 writer
, mi_lttng_element_session_name
, session_name
);
273 ret_code
= lttng_rate_policy_mi_serialize(policy
, writer
);
274 if (ret_code
!= LTTNG_OK
) {
278 /* Close action start session element. */
279 ret
= mi_lttng_writer_close_element(writer
);
288 ret_code
= LTTNG_ERR_MI_IO_FAIL
;
293 struct lttng_action
*lttng_action_start_session_create(void)
295 struct lttng_action
*action
= NULL
;
296 struct lttng_rate_policy
*policy
= NULL
;
297 enum lttng_action_status status
;
299 /* Create a every N = 1 rate policy. */
300 policy
= lttng_rate_policy_every_n_create(1);
305 action
= zmalloc(sizeof(struct lttng_action_start_session
));
310 lttng_action_init(action
, LTTNG_ACTION_TYPE_START_SESSION
,
311 lttng_action_start_session_validate
,
312 lttng_action_start_session_serialize
,
313 lttng_action_start_session_is_equal
,
314 lttng_action_start_session_destroy
,
315 lttng_action_start_session_internal_get_rate_policy
,
316 lttng_action_generic_add_error_query_results
,
317 lttng_action_start_session_mi_serialize
);
319 status
= lttng_action_start_session_set_rate_policy(action
, policy
);
320 if (status
!= LTTNG_ACTION_STATUS_OK
) {
327 lttng_rate_policy_destroy(policy
);
331 enum lttng_action_status
lttng_action_start_session_set_session_name(
332 struct lttng_action
*action
, const char *session_name
)
334 struct lttng_action_start_session
*action_start_session
;
335 enum lttng_action_status status
;
337 if (!action
|| !IS_START_SESSION_ACTION(action
) || !session_name
||
338 strlen(session_name
) == 0) {
339 status
= LTTNG_ACTION_STATUS_INVALID
;
343 action_start_session
= action_start_session_from_action(action
);
345 free(action_start_session
->session_name
);
347 action_start_session
->session_name
= strdup(session_name
);
348 if (!action_start_session
->session_name
) {
349 status
= LTTNG_ACTION_STATUS_ERROR
;
353 status
= LTTNG_ACTION_STATUS_OK
;
358 enum lttng_action_status
lttng_action_start_session_get_session_name(
359 const struct lttng_action
*action
, const char **session_name
)
361 const struct lttng_action_start_session
*action_start_session
;
362 enum lttng_action_status status
;
364 if (!action
|| !IS_START_SESSION_ACTION(action
) || !session_name
) {
365 status
= LTTNG_ACTION_STATUS_INVALID
;
369 action_start_session
= action_start_session_from_action_const(action
);
371 *session_name
= action_start_session
->session_name
;
373 status
= LTTNG_ACTION_STATUS_OK
;
378 enum lttng_action_status
lttng_action_start_session_set_rate_policy(
379 struct lttng_action
*action
,
380 const struct lttng_rate_policy
*policy
)
382 enum lttng_action_status status
;
383 struct lttng_action_start_session
*start_session_action
;
384 struct lttng_rate_policy
*copy
= NULL
;
386 if (!action
|| !policy
|| !IS_START_SESSION_ACTION(action
)) {
387 status
= LTTNG_ACTION_STATUS_INVALID
;
391 copy
= lttng_rate_policy_copy(policy
);
393 status
= LTTNG_ACTION_STATUS_ERROR
;
397 start_session_action
= action_start_session_from_action(action
);
399 /* Release the previous rate policy .*/
400 lttng_rate_policy_destroy(start_session_action
->policy
);
402 /* Assign the policy. */
403 start_session_action
->policy
= copy
;
404 status
= LTTNG_ACTION_STATUS_OK
;
408 lttng_rate_policy_destroy(copy
);
412 enum lttng_action_status
lttng_action_start_session_get_rate_policy(
413 const struct lttng_action
*action
,
414 const struct lttng_rate_policy
**policy
)
416 enum lttng_action_status status
;
417 const struct lttng_action_start_session
*start_session_action
;
419 if (!action
|| !policy
|| !IS_START_SESSION_ACTION(action
)) {
420 status
= LTTNG_ACTION_STATUS_INVALID
;
424 start_session_action
= action_start_session_from_action_const(action
);
426 *policy
= start_session_action
->policy
;
427 status
= LTTNG_ACTION_STATUS_OK
;
432 static const struct lttng_rate_policy
*
433 lttng_action_start_session_internal_get_rate_policy(
434 const struct lttng_action
*action
)
436 const struct lttng_action_start_session
*_action
;
437 _action
= action_start_session_from_action_const(action
);
439 return _action
->policy
;