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 <lttng/action/action-internal.h>
12 #include <lttng/action/firing-policy-internal.h>
13 #include <lttng/action/firing-policy.h>
14 #include <lttng/action/start-session-internal.h>
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)
20 struct lttng_action_start_session
{
21 struct lttng_action parent
;
25 struct lttng_firing_policy
*policy
;
28 struct lttng_action_start_session_comm
{
29 /* Includes the trailing \0. */
30 uint32_t session_name_len
;
35 * - session name (null terminated)
41 static struct lttng_action_start_session
*action_start_session_from_action(
42 struct lttng_action
*action
)
46 return container_of(action
, struct lttng_action_start_session
, parent
);
49 static const struct lttng_action_start_session
*
50 action_start_session_from_action_const(const struct lttng_action
*action
)
54 return container_of(action
, struct lttng_action_start_session
, parent
);
57 static bool lttng_action_start_session_validate(struct lttng_action
*action
)
60 struct lttng_action_start_session
*action_start_session
;
67 action_start_session
= action_start_session_from_action(action
);
69 /* A non-empty session name is mandatory. */
70 if (!action_start_session
->session_name
||
71 strlen(action_start_session
->session_name
) == 0) {
81 static bool lttng_action_start_session_is_equal(
82 const struct lttng_action
*_a
, const struct lttng_action
*_b
)
84 bool is_equal
= false;
85 struct lttng_action_start_session
*a
, *b
;
87 a
= container_of(_a
, struct lttng_action_start_session
, parent
);
88 b
= container_of(_b
, struct lttng_action_start_session
, parent
);
90 /* Action is not valid if this is not true. */
91 assert(a
->session_name
);
92 assert(b
->session_name
);
93 if (strcmp(a
->session_name
, b
->session_name
)) {
97 is_equal
= lttng_firing_policy_is_equal(a
->policy
, b
->policy
);
102 static int lttng_action_start_session_serialize(
103 struct lttng_action
*action
, struct lttng_payload
*payload
)
105 struct lttng_action_start_session
*action_start_session
;
106 struct lttng_action_start_session_comm comm
;
107 size_t session_name_len
;
113 action_start_session
= action_start_session_from_action(action
);
115 assert(action_start_session
->session_name
);
117 DBG("Serializing start session action: session-name: %s",
118 action_start_session
->session_name
);
120 session_name_len
= strlen(action_start_session
->session_name
) + 1;
121 comm
.session_name_len
= session_name_len
;
123 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, &comm
, sizeof(comm
));
129 ret
= lttng_dynamic_buffer_append(&payload
->buffer
,
130 action_start_session
->session_name
, session_name_len
);
136 ret
= lttng_firing_policy_serialize(
137 action_start_session
->policy
, payload
);
148 static void lttng_action_start_session_destroy(struct lttng_action
*action
)
150 struct lttng_action_start_session
*action_start_session
;
156 action_start_session
= action_start_session_from_action(action
);
158 lttng_firing_policy_destroy(action_start_session
->policy
);
159 free(action_start_session
->session_name
);
160 free(action_start_session
);
166 ssize_t
lttng_action_start_session_create_from_payload(
167 struct lttng_payload_view
*view
,
168 struct lttng_action
**p_action
)
170 ssize_t consumed_len
, ret
;
171 const struct lttng_action_start_session_comm
*comm
;
172 const char *session_name
;
173 struct lttng_action
*action
= NULL
;
174 enum lttng_action_status status
;
175 struct lttng_firing_policy
*policy
= NULL
;
177 comm
= (typeof(comm
)) view
->buffer
.data
;
178 session_name
= (const char *) &comm
->data
;
181 if (!lttng_buffer_view_contains_string(&view
->buffer
, session_name
,
182 comm
->session_name_len
)) {
186 consumed_len
= sizeof(*comm
) + comm
->session_name_len
;
190 struct lttng_payload_view policy_view
=
191 lttng_payload_view_from_view(
192 view
, consumed_len
, -1);
193 ret
= lttng_firing_policy_create_from_payload(
194 &policy_view
, &policy
);
202 action
= lttng_action_start_session_create();
208 status
= lttng_action_start_session_set_session_name(
209 action
, session_name
);
210 if (status
!= LTTNG_ACTION_STATUS_OK
) {
216 status
= lttng_action_start_session_set_firing_policy(action
, policy
);
217 if (status
!= LTTNG_ACTION_STATUS_OK
) {
226 lttng_firing_policy_destroy(policy
);
227 lttng_action_start_session_destroy(action
);
232 struct lttng_action
*lttng_action_start_session_create(void)
234 struct lttng_action
*action
= NULL
;
235 struct lttng_firing_policy
*policy
= NULL
;
236 enum lttng_action_status status
;
238 /* Create a every N = 1 firing policy. */
239 policy
= lttng_firing_policy_every_n_create(1);
244 action
= zmalloc(sizeof(struct lttng_action_start_session
));
249 lttng_action_init(action
, LTTNG_ACTION_TYPE_START_SESSION
,
250 lttng_action_start_session_validate
,
251 lttng_action_start_session_serialize
,
252 lttng_action_start_session_is_equal
,
253 lttng_action_start_session_destroy
);
255 status
= lttng_action_start_session_set_firing_policy(action
, policy
);
256 if (status
!= LTTNG_ACTION_STATUS_OK
) {
263 lttng_firing_policy_destroy(policy
);
267 enum lttng_action_status
lttng_action_start_session_set_session_name(
268 struct lttng_action
*action
, const char *session_name
)
270 struct lttng_action_start_session
*action_start_session
;
271 enum lttng_action_status status
;
273 if (!action
|| !IS_START_SESSION_ACTION(action
) || !session_name
||
274 strlen(session_name
) == 0) {
275 status
= LTTNG_ACTION_STATUS_INVALID
;
279 action_start_session
= action_start_session_from_action(action
);
281 free(action_start_session
->session_name
);
283 action_start_session
->session_name
= strdup(session_name
);
284 if (!action_start_session
->session_name
) {
285 status
= LTTNG_ACTION_STATUS_ERROR
;
289 status
= LTTNG_ACTION_STATUS_OK
;
294 enum lttng_action_status
lttng_action_start_session_get_session_name(
295 const struct lttng_action
*action
, const char **session_name
)
297 const struct lttng_action_start_session
*action_start_session
;
298 enum lttng_action_status status
;
300 if (!action
|| !IS_START_SESSION_ACTION(action
) || !session_name
) {
301 status
= LTTNG_ACTION_STATUS_INVALID
;
305 action_start_session
= action_start_session_from_action_const(action
);
307 *session_name
= action_start_session
->session_name
;
309 status
= LTTNG_ACTION_STATUS_OK
;
314 enum lttng_action_status
lttng_action_start_session_set_firing_policy(
315 struct lttng_action
*action
,
316 const struct lttng_firing_policy
*policy
)
318 enum lttng_action_status status
;
319 struct lttng_action_start_session
*start_session_action
;
320 struct lttng_firing_policy
*copy
= NULL
;
322 if (!action
|| !policy
|| !IS_START_SESSION_ACTION(action
)) {
323 status
= LTTNG_ACTION_STATUS_INVALID
;
327 copy
= lttng_firing_policy_copy(policy
);
329 status
= LTTNG_ACTION_STATUS_ERROR
;
333 start_session_action
= action_start_session_from_action(action
);
335 /* Release the previous firing policy .*/
336 lttng_firing_policy_destroy(start_session_action
->policy
);
338 /* Assign the policy. */
339 start_session_action
->policy
= copy
;
340 status
= LTTNG_ACTION_STATUS_OK
;
344 lttng_firing_policy_destroy(copy
);
348 enum lttng_action_status
lttng_action_start_session_get_firing_policy(
349 const struct lttng_action
*action
,
350 const struct lttng_firing_policy
**policy
)
352 enum lttng_action_status status
;
353 const struct lttng_action_start_session
*start_session_action
;
355 if (!action
|| !policy
|| !IS_START_SESSION_ACTION(action
)) {
356 status
= LTTNG_ACTION_STATUS_INVALID
;
360 start_session_action
= action_start_session_from_action_const(action
);
362 *policy
= start_session_action
->policy
;
363 status
= LTTNG_ACTION_STATUS_OK
;